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/BinaryFormat/Wasm.h" 20 #include "llvm/CodeGen/MIRYamlMapping.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/MC/MCSymbolWasm.h" 23 24 namespace llvm { 25 26 namespace yaml { 27 struct WebAssemblyFunctionInfo; 28 } 29 30 /// This class is derived from MachineFunctionInfo and contains private 31 /// WebAssembly-specific information for each MachineFunction. 32 class WebAssemblyFunctionInfo final : public MachineFunctionInfo { 33 MachineFunction &MF; 34 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: 69 explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {} 70 ~WebAssemblyFunctionInfo() override; 71 void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI); 72 73 void addParam(MVT VT) { Params.push_back(VT); } 74 const std::vector<MVT> &getParams() const { return Params; } 75 76 void addResult(MVT VT) { Results.push_back(VT); } 77 const std::vector<MVT> &getResults() const { return Results; } 78 79 void clearParamsAndResults() { 80 Params.clear(); 81 Results.clear(); 82 } 83 84 void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } 85 void setLocal(size_t i, MVT VT) { Locals[i] = VT; } 86 void addLocal(MVT VT) { Locals.push_back(VT); } 87 const std::vector<MVT> &getLocals() const { return Locals; } 88 89 unsigned getVarargBufferVreg() const { 90 assert(VarargVreg != -1U && "Vararg vreg hasn't been set"); 91 return VarargVreg; 92 } 93 void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; } 94 95 unsigned getBasePointerVreg() const { 96 assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set"); 97 return BasePtrVreg; 98 } 99 void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; } 100 unsigned getFrameBaseVreg() const { 101 assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set"); 102 return FrameBaseVreg; 103 } 104 void clearFrameBaseVreg() { FrameBaseVreg = -1U; } 105 // Return true if the frame base physreg has been replaced by a virtual reg. 106 bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; } 107 void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; } 108 unsigned getFrameBaseLocal() const { 109 assert(FrameBaseLocal != -1U && "Frame base local hasn't been set"); 110 return FrameBaseLocal; 111 } 112 void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; } 113 114 static const unsigned UnusedReg = -1u; 115 116 void stackifyVReg(unsigned VReg) { 117 assert(MF.getRegInfo().getUniqueVRegDef(VReg)); 118 auto I = Register::virtReg2Index(VReg); 119 if (I >= VRegStackified.size()) 120 VRegStackified.resize(I + 1); 121 VRegStackified.set(I); 122 } 123 void unstackifyVReg(unsigned VReg) { 124 auto I = Register::virtReg2Index(VReg); 125 if (I < VRegStackified.size()) 126 VRegStackified.reset(I); 127 } 128 bool isVRegStackified(unsigned VReg) const { 129 auto I = Register::virtReg2Index(VReg); 130 if (I >= VRegStackified.size()) 131 return false; 132 return VRegStackified.test(I); 133 } 134 135 void initWARegs(); 136 void setWAReg(unsigned VReg, unsigned WAReg) { 137 assert(WAReg != UnusedReg); 138 auto I = Register::virtReg2Index(VReg); 139 assert(I < WARegs.size()); 140 WARegs[I] = WAReg; 141 } 142 unsigned getWAReg(unsigned VReg) const { 143 auto I = Register::virtReg2Index(VReg); 144 assert(I < WARegs.size()); 145 return WARegs[I]; 146 } 147 148 // For a given stackified WAReg, return the id number to print with push/pop. 149 static unsigned getWARegStackId(unsigned Reg) { 150 assert(Reg & INT32_MIN); 151 return Reg & INT32_MAX; 152 } 153 154 bool isCFGStackified() const { return CFGStackified; } 155 void setCFGStackified(bool Value = true) { CFGStackified = Value; } 156 }; 157 158 void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, 159 SmallVectorImpl<MVT> &ValueVTs); 160 161 // Compute the signature for a given FunctionType (Ty). Note that it's not the 162 // signature for ContextFunc (ContextFunc is just used to get varous context) 163 void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, 164 const Function &ContextFunc, const TargetMachine &TM, 165 SmallVectorImpl<MVT> &Params, 166 SmallVectorImpl<MVT> &Results); 167 168 void valTypesFromMVTs(const ArrayRef<MVT> &In, 169 SmallVectorImpl<wasm::ValType> &Out); 170 171 std::unique_ptr<wasm::WasmSignature> 172 signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 173 const SmallVectorImpl<MVT> &Params); 174 175 namespace yaml { 176 177 struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { 178 bool CFGStackified = false; 179 180 WebAssemblyFunctionInfo() = default; 181 WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI); 182 183 void mappingImpl(yaml::IO &YamlIO) override; 184 ~WebAssemblyFunctionInfo() = default; 185 }; 186 187 template <> struct MappingTraits<WebAssemblyFunctionInfo> { 188 static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { 189 YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); 190 } 191 }; 192 193 } // end namespace yaml 194 195 } // end namespace llvm 196 197 #endif 198