1 //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file implements WebAssembly-specific per-machine-function 11 /// information. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "WebAssemblyMachineFunctionInfo.h" 16 #include "MCTargetDesc/WebAssemblyInstPrinter.h" 17 #include "Utils/WebAssemblyTypeUtilities.h" 18 #include "WebAssemblyISelLowering.h" 19 #include "WebAssemblySubtarget.h" 20 #include "llvm/CodeGen/Analysis.h" 21 #include "llvm/CodeGen/WasmEHFuncInfo.h" 22 #include "llvm/Target/TargetMachine.h" 23 using namespace llvm; 24 25 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor. 26 27 MachineFunctionInfo *WebAssemblyFunctionInfo::clone( 28 BumpPtrAllocator &Allocator, MachineFunction &DestMF, 29 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 30 const { 31 // TODO: Implement cloning for WasmEHFuncInfo. This will have invalid block 32 // references. 33 return DestMF.cloneInfo<WebAssemblyFunctionInfo>(*this); 34 } 35 36 void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) { 37 assert(WARegs.empty()); 38 unsigned Reg = WebAssembly::UnusedReg; 39 WARegs.resize(MRI.getNumVirtRegs(), Reg); 40 } 41 42 void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, 43 LLVMContext &Ctx, const DataLayout &DL, 44 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 45 SmallVector<EVT, 4> VTs; 46 ComputeValueVTs(TLI, DL, Ty, VTs); 47 48 for (EVT VT : VTs) { 49 unsigned NumRegs = TLI.getNumRegisters(Ctx, VT); 50 MVT RegisterVT = TLI.getRegisterType(Ctx, VT); 51 for (unsigned I = 0; I != NumRegs; ++I) 52 ValueVTs.push_back(RegisterVT); 53 } 54 } 55 56 void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM, 57 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 58 const DataLayout &DL(F.getParent()->getDataLayout()); 59 const WebAssemblyTargetLowering &TLI = 60 *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering(); 61 computeLegalValueVTs(TLI, F.getContext(), DL, Ty, ValueVTs); 62 } 63 64 void llvm::computeSignatureVTs(const FunctionType *Ty, 65 const Function *TargetFunc, 66 const Function &ContextFunc, 67 const TargetMachine &TM, 68 SmallVectorImpl<MVT> &Params, 69 SmallVectorImpl<MVT> &Results) { 70 computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results); 71 72 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 73 if (Results.size() > 1 && 74 !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) { 75 // WebAssembly can't lower returns of multiple values without demoting to 76 // sret unless multivalue is enabled (see 77 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return 78 // values with a poitner parameter. 79 Results.clear(); 80 Params.push_back(PtrVT); 81 } 82 83 for (auto *Param : Ty->params()) 84 computeLegalValueVTs(ContextFunc, TM, Param, Params); 85 if (Ty->isVarArg()) 86 Params.push_back(PtrVT); 87 88 // For swiftcc, emit additional swiftself and swifterror parameters 89 // if there aren't. These additional parameters are also passed for caller. 90 // They are necessary to match callee and caller signature for indirect 91 // call. 92 93 if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) { 94 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 95 bool HasSwiftErrorArg = false; 96 bool HasSwiftSelfArg = false; 97 for (const auto &Arg : TargetFunc->args()) { 98 HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError); 99 HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf); 100 } 101 if (!HasSwiftErrorArg) 102 Params.push_back(PtrVT); 103 if (!HasSwiftSelfArg) 104 Params.push_back(PtrVT); 105 } 106 } 107 108 void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In, 109 SmallVectorImpl<wasm::ValType> &Out) { 110 for (MVT Ty : In) 111 Out.push_back(WebAssembly::toValType(Ty)); 112 } 113 114 std::unique_ptr<wasm::WasmSignature> 115 llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 116 const SmallVectorImpl<MVT> &Params) { 117 auto Sig = std::make_unique<wasm::WasmSignature>(); 118 valTypesFromMVTs(Results, Sig->Returns); 119 valTypesFromMVTs(Params, Sig->Params); 120 return Sig; 121 } 122 123 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo( 124 const llvm::MachineFunction &MF, const llvm::WebAssemblyFunctionInfo &MFI) 125 : CFGStackified(MFI.isCFGStackified()) { 126 for (auto VT : MFI.getParams()) 127 Params.push_back(EVT(VT).getEVTString()); 128 for (auto VT : MFI.getResults()) 129 Results.push_back(EVT(VT).getEVTString()); 130 131 // MFI.getWasmEHFuncInfo() is non-null only for functions with the 132 // personality function. 133 134 if (auto *EHInfo = MF.getWasmEHFuncInfo()) { 135 // SrcToUnwindDest can contain stale mappings in case BBs are removed in 136 // optimizations, in case, for example, they are unreachable. We should not 137 // include their info. 138 SmallPtrSet<const MachineBasicBlock *, 16> MBBs; 139 for (const auto &MBB : MF) 140 MBBs.insert(&MBB); 141 for (auto KV : EHInfo->SrcToUnwindDest) { 142 auto *SrcBB = KV.first.get<MachineBasicBlock *>(); 143 auto *DestBB = KV.second.get<MachineBasicBlock *>(); 144 if (MBBs.count(SrcBB) && MBBs.count(DestBB)) 145 SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber(); 146 } 147 } 148 } 149 150 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 151 MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this); 152 } 153 154 void WebAssemblyFunctionInfo::initializeBaseYamlFields( 155 MachineFunction &MF, const yaml::WebAssemblyFunctionInfo &YamlMFI) { 156 CFGStackified = YamlMFI.CFGStackified; 157 for (auto VT : YamlMFI.Params) 158 addParam(WebAssembly::parseMVT(VT.Value)); 159 for (auto VT : YamlMFI.Results) 160 addResult(WebAssembly::parseMVT(VT.Value)); 161 162 // FIXME: WasmEHInfo is defined in the MachineFunction, but serialized 163 // here. Either WasmEHInfo should be moved out of MachineFunction, or the 164 // serialization handling should be moved to MachineFunction. 165 if (WasmEHFuncInfo *WasmEHInfo = MF.getWasmEHFuncInfo()) { 166 for (auto KV : YamlMFI.SrcToUnwindDest) 167 WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first), 168 MF.getBlockNumbered(KV.second)); 169 } 170 } 171