xref: /freebsd/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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