WebAssemblyMachineFunctionInfo.h 8.2 KB

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