1 // WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*- 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 declares WebAssembly-specific per-machine-function 11 /// information. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 16 #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 17 18 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 19 #include "llvm/CodeGen/MIRYamlMapping.h" 20 #include "llvm/CodeGen/MachineRegisterInfo.h" 21 #include "llvm/MC/MCSymbolWasm.h" 22 23 namespace llvm { 24 class WebAssemblyTargetLowering; 25 26 struct WasmEHFuncInfo; 27 28 namespace yaml { 29 struct WebAssemblyFunctionInfo; 30 } 31 32 /// This class is derived from MachineFunctionInfo and contains private 33 /// WebAssembly-specific information for each MachineFunction. 34 class WebAssemblyFunctionInfo final : public MachineFunctionInfo { 35 std::vector<MVT> Params; 36 std::vector<MVT> Results; 37 std::vector<MVT> Locals; 38 39 /// A mapping from CodeGen vreg index to WebAssembly register number. 40 std::vector<unsigned> WARegs; 41 42 /// A mapping from CodeGen vreg index to a boolean value indicating whether 43 /// the given register is considered to be "stackified", meaning it has been 44 /// determined or made to meet the stack requirements: 45 /// - single use (per path) 46 /// - single def (per path) 47 /// - defined and used in LIFO order with other stack registers 48 BitVector VRegStackified; 49 50 // A virtual register holding the pointer to the vararg buffer for vararg 51 // functions. It is created and set in TLI::LowerFormalArguments and read by 52 // TLI::LowerVASTART 53 unsigned VarargVreg = -1U; 54 55 // A virtual register holding the base pointer for functions that have 56 // overaligned values on the user stack. 57 unsigned BasePtrVreg = -1U; 58 // A virtual register holding the frame base. This is either FP or SP 59 // after it has been replaced by a vreg 60 unsigned FrameBaseVreg = -1U; 61 // The local holding the frame base. This is either FP or SP 62 // after WebAssemblyExplicitLocals 63 unsigned FrameBaseLocal = -1U; 64 65 // Function properties. 66 bool CFGStackified = false; 67 68 public: WebAssemblyFunctionInfo(const Function & F,const TargetSubtargetInfo * STI)69 explicit WebAssemblyFunctionInfo(const Function &F, 70 const TargetSubtargetInfo *STI) {} 71 ~WebAssemblyFunctionInfo() override; 72 73 MachineFunctionInfo * 74 clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 75 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 76 const override; 77 78 void initializeBaseYamlFields(MachineFunction &MF, 79 const yaml::WebAssemblyFunctionInfo &YamlMFI); 80 addParam(MVT VT)81 void addParam(MVT VT) { Params.push_back(VT); } getParams()82 const std::vector<MVT> &getParams() const { return Params; } 83 addResult(MVT VT)84 void addResult(MVT VT) { Results.push_back(VT); } getResults()85 const std::vector<MVT> &getResults() const { return Results; } 86 clearParamsAndResults()87 void clearParamsAndResults() { 88 Params.clear(); 89 Results.clear(); 90 } 91 setNumLocals(size_t NumLocals)92 void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } setLocal(size_t i,MVT VT)93 void setLocal(size_t i, MVT VT) { Locals[i] = VT; } addLocal(MVT VT)94 void addLocal(MVT VT) { Locals.push_back(VT); } getLocals()95 const std::vector<MVT> &getLocals() const { return Locals; } 96 getVarargBufferVreg()97 unsigned getVarargBufferVreg() const { 98 assert(VarargVreg != -1U && "Vararg vreg hasn't been set"); 99 return VarargVreg; 100 } setVarargBufferVreg(unsigned Reg)101 void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; } 102 getBasePointerVreg()103 unsigned getBasePointerVreg() const { 104 assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set"); 105 return BasePtrVreg; 106 } setFrameBaseVreg(unsigned Reg)107 void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; } getFrameBaseVreg()108 unsigned getFrameBaseVreg() const { 109 assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set"); 110 return FrameBaseVreg; 111 } clearFrameBaseVreg()112 void clearFrameBaseVreg() { FrameBaseVreg = -1U; } 113 // Return true if the frame base physreg has been replaced by a virtual reg. isFrameBaseVirtual()114 bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; } setFrameBaseLocal(unsigned Local)115 void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; } getFrameBaseLocal()116 unsigned getFrameBaseLocal() const { 117 assert(FrameBaseLocal != -1U && "Frame base local hasn't been set"); 118 return FrameBaseLocal; 119 } setBasePointerVreg(unsigned Reg)120 void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; } 121 stackifyVReg(MachineRegisterInfo & MRI,unsigned VReg)122 void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg) { 123 assert(MRI.getUniqueVRegDef(VReg)); 124 auto I = Register::virtReg2Index(VReg); 125 if (I >= VRegStackified.size()) 126 VRegStackified.resize(I + 1); 127 VRegStackified.set(I); 128 } unstackifyVReg(unsigned VReg)129 void unstackifyVReg(unsigned VReg) { 130 auto I = Register::virtReg2Index(VReg); 131 if (I < VRegStackified.size()) 132 VRegStackified.reset(I); 133 } isVRegStackified(unsigned VReg)134 bool isVRegStackified(unsigned VReg) const { 135 auto I = Register::virtReg2Index(VReg); 136 if (I >= VRegStackified.size()) 137 return false; 138 return VRegStackified.test(I); 139 } 140 141 void initWARegs(MachineRegisterInfo &MRI); setWAReg(unsigned VReg,unsigned WAReg)142 void setWAReg(unsigned VReg, unsigned WAReg) { 143 assert(WAReg != WebAssembly::UnusedReg); 144 auto I = Register::virtReg2Index(VReg); 145 assert(I < WARegs.size()); 146 WARegs[I] = WAReg; 147 } getWAReg(unsigned VReg)148 unsigned getWAReg(unsigned VReg) const { 149 auto I = Register::virtReg2Index(VReg); 150 assert(I < WARegs.size()); 151 return WARegs[I]; 152 } 153 isCFGStackified()154 bool isCFGStackified() const { return CFGStackified; } 155 void setCFGStackified(bool Value = true) { CFGStackified = Value; } 156 }; 157 158 void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, 159 LLVMContext &Ctx, const DataLayout &DL, Type *Ty, 160 SmallVectorImpl<MVT> &ValueVTs); 161 162 void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, 163 SmallVectorImpl<MVT> &ValueVTs); 164 165 // Compute the signature for a given FunctionType (Ty). Note that it's not the 166 // signature for ContextFunc (ContextFunc is just used to get varous context) 167 void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, 168 const Function &ContextFunc, const TargetMachine &TM, 169 SmallVectorImpl<MVT> &Params, 170 SmallVectorImpl<MVT> &Results); 171 172 void valTypesFromMVTs(ArrayRef<MVT> In, SmallVectorImpl<wasm::ValType> &Out); 173 174 wasm::WasmSignature *signatureFromMVTs(MCContext &Ctx, 175 const SmallVectorImpl<MVT> &Results, 176 const SmallVectorImpl<MVT> &Params); 177 178 namespace yaml { 179 180 using BBNumberMap = DenseMap<int, int>; 181 182 struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { 183 std::vector<FlowStringValue> Params; 184 std::vector<FlowStringValue> Results; 185 bool CFGStackified = false; 186 // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of 187 // BB numbers 188 BBNumberMap SrcToUnwindDest; 189 190 WebAssemblyFunctionInfo() = default; 191 WebAssemblyFunctionInfo(const llvm::MachineFunction &MF, 192 const llvm::WebAssemblyFunctionInfo &MFI); 193 194 void mappingImpl(yaml::IO &YamlIO) override; 195 ~WebAssemblyFunctionInfo() = default; 196 }; 197 198 template <> struct MappingTraits<WebAssemblyFunctionInfo> { 199 static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { 200 YamlIO.mapOptional("params", MFI.Params, std::vector<FlowStringValue>()); 201 YamlIO.mapOptional("results", MFI.Results, std::vector<FlowStringValue>()); 202 YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); 203 YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest); 204 } 205 }; 206 207 template <> struct CustomMappingTraits<BBNumberMap> { 208 static void inputOne(IO &YamlIO, StringRef Key, 209 BBNumberMap &SrcToUnwindDest) { 210 YamlIO.mapRequired(Key.str().c_str(), 211 SrcToUnwindDest[std::atoi(Key.str().c_str())]); 212 } 213 214 static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) { 215 for (auto KV : SrcToUnwindDest) 216 YamlIO.mapRequired(std::to_string(KV.first).c_str(), KV.second); 217 } 218 }; 219 220 } // end namespace yaml 221 222 } // end namespace llvm 223 224 #endif 225