xref: /freebsd/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h (revision 6966ac055c3b7a39266fb982493330df7a097997)
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 
59   // Function properties.
60   bool CFGStackified = false;
61 
62 public:
63   explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
64   ~WebAssemblyFunctionInfo() override;
65   void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI);
66 
67   void addParam(MVT VT) { Params.push_back(VT); }
68   const std::vector<MVT> &getParams() const { return Params; }
69 
70   void addResult(MVT VT) { Results.push_back(VT); }
71   const std::vector<MVT> &getResults() const { return Results; }
72 
73   void clearParamsAndResults() {
74     Params.clear();
75     Results.clear();
76   }
77 
78   void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }
79   void setLocal(size_t i, MVT VT) { Locals[i] = VT; }
80   void addLocal(MVT VT) { Locals.push_back(VT); }
81   const std::vector<MVT> &getLocals() const { return Locals; }
82 
83   unsigned getVarargBufferVreg() const {
84     assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
85     return VarargVreg;
86   }
87   void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }
88 
89   unsigned getBasePointerVreg() const {
90     assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set");
91     return BasePtrVreg;
92   }
93   void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; }
94 
95   static const unsigned UnusedReg = -1u;
96 
97   void stackifyVReg(unsigned VReg) {
98     assert(MF.getRegInfo().getUniqueVRegDef(VReg));
99     auto I = TargetRegisterInfo::virtReg2Index(VReg);
100     if (I >= VRegStackified.size())
101       VRegStackified.resize(I + 1);
102     VRegStackified.set(I);
103   }
104   bool isVRegStackified(unsigned VReg) const {
105     auto I = TargetRegisterInfo::virtReg2Index(VReg);
106     if (I >= VRegStackified.size())
107       return false;
108     return VRegStackified.test(I);
109   }
110 
111   void initWARegs();
112   void setWAReg(unsigned VReg, unsigned WAReg) {
113     assert(WAReg != UnusedReg);
114     auto I = TargetRegisterInfo::virtReg2Index(VReg);
115     assert(I < WARegs.size());
116     WARegs[I] = WAReg;
117   }
118   unsigned getWAReg(unsigned VReg) const {
119     auto I = TargetRegisterInfo::virtReg2Index(VReg);
120     assert(I < WARegs.size());
121     return WARegs[I];
122   }
123 
124   // For a given stackified WAReg, return the id number to print with push/pop.
125   static unsigned getWARegStackId(unsigned Reg) {
126     assert(Reg & INT32_MIN);
127     return Reg & INT32_MAX;
128   }
129 
130   bool isCFGStackified() const { return CFGStackified; }
131   void setCFGStackified(bool Value = true) { CFGStackified = Value; }
132 };
133 
134 void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
135                           SmallVectorImpl<MVT> &ValueVTs);
136 
137 // Compute the signature for a given FunctionType (Ty). Note that it's not the
138 // signature for F (F is just used to get varous context)
139 void computeSignatureVTs(const FunctionType *Ty, const Function &F,
140                          const TargetMachine &TM, SmallVectorImpl<MVT> &Params,
141                          SmallVectorImpl<MVT> &Results);
142 
143 void valTypesFromMVTs(const ArrayRef<MVT> &In,
144                       SmallVectorImpl<wasm::ValType> &Out);
145 
146 std::unique_ptr<wasm::WasmSignature>
147 signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
148                   const SmallVectorImpl<MVT> &Params);
149 
150 namespace yaml {
151 
152 struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo {
153   bool CFGStackified = false;
154 
155   WebAssemblyFunctionInfo() = default;
156   WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI);
157 
158   void mappingImpl(yaml::IO &YamlIO) override;
159   ~WebAssemblyFunctionInfo() = default;
160 };
161 
162 template <> struct MappingTraits<WebAssemblyFunctionInfo> {
163   static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) {
164     YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false);
165   }
166 };
167 
168 } // end namespace yaml
169 
170 } // end namespace llvm
171 
172 #endif
173