1 // WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-
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
7 //===----------------------------------------------------------------------===//
10 /// This file declares WebAssembly-specific per-machine-function
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
16 #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
18 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
19 #include "llvm/CodeGen/MIRYamlMapping.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/MC/MCSymbolWasm.h"
24 class WebAssemblyTargetLowering
;
26 struct WasmEHFuncInfo
;
29 struct WebAssemblyFunctionInfo
;
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
;
39 /// A mapping from CodeGen vreg index to WebAssembly register number.
40 std::vector
<unsigned> WARegs
;
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
;
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
53 unsigned VarargVreg
= -1U;
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;
65 // Function properties.
66 bool CFGStackified
= false;
69 explicit WebAssemblyFunctionInfo(const Function
&F
,
70 const TargetSubtargetInfo
*STI
) {}
71 ~WebAssemblyFunctionInfo() override
;
74 clone(BumpPtrAllocator
&Allocator
, MachineFunction
&DestMF
,
75 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
)
78 void initializeBaseYamlFields(MachineFunction
&MF
,
79 const yaml::WebAssemblyFunctionInfo
&YamlMFI
);
81 void addParam(MVT VT
) { Params
.push_back(VT
); }
82 const std::vector
<MVT
> &getParams() const { return Params
; }
84 void addResult(MVT VT
) { Results
.push_back(VT
); }
85 const std::vector
<MVT
> &getResults() const { return Results
; }
87 void clearParamsAndResults() {
92 void setNumLocals(size_t NumLocals
) { Locals
.resize(NumLocals
, MVT::i32
); }
93 void setLocal(size_t i
, MVT VT
) { Locals
[i
] = VT
; }
94 void addLocal(MVT VT
) { Locals
.push_back(VT
); }
95 const std::vector
<MVT
> &getLocals() const { return Locals
; }
97 unsigned getVarargBufferVreg() const {
98 assert(VarargVreg
!= -1U && "Vararg vreg hasn't been set");
101 void setVarargBufferVreg(unsigned Reg
) { VarargVreg
= Reg
; }
103 unsigned getBasePointerVreg() const {
104 assert(BasePtrVreg
!= -1U && "Base ptr vreg hasn't been set");
107 void setFrameBaseVreg(unsigned Reg
) { FrameBaseVreg
= Reg
; }
108 unsigned getFrameBaseVreg() const {
109 assert(FrameBaseVreg
!= -1U && "Frame base vreg hasn't been set");
110 return FrameBaseVreg
;
112 void clearFrameBaseVreg() { FrameBaseVreg
= -1U; }
113 // Return true if the frame base physreg has been replaced by a virtual reg.
114 bool isFrameBaseVirtual() const { return FrameBaseVreg
!= -1U; }
115 void setFrameBaseLocal(unsigned Local
) { FrameBaseLocal
= Local
; }
116 unsigned getFrameBaseLocal() const {
117 assert(FrameBaseLocal
!= -1U && "Frame base local hasn't been set");
118 return FrameBaseLocal
;
120 void setBasePointerVreg(unsigned Reg
) { BasePtrVreg
= Reg
; }
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
);
129 void unstackifyVReg(unsigned VReg
) {
130 auto I
= Register::virtReg2Index(VReg
);
131 if (I
< VRegStackified
.size())
132 VRegStackified
.reset(I
);
134 bool isVRegStackified(unsigned VReg
) const {
135 auto I
= Register::virtReg2Index(VReg
);
136 if (I
>= VRegStackified
.size())
138 return VRegStackified
.test(I
);
141 void initWARegs(MachineRegisterInfo
&MRI
);
142 void setWAReg(unsigned VReg
, unsigned WAReg
) {
143 assert(WAReg
!= WebAssembly::UnusedReg
);
144 auto I
= Register::virtReg2Index(VReg
);
145 assert(I
< WARegs
.size());
148 unsigned getWAReg(unsigned VReg
) const {
149 auto I
= Register::virtReg2Index(VReg
);
150 assert(I
< WARegs
.size());
154 bool isCFGStackified() const { return CFGStackified
; }
155 void setCFGStackified(bool Value
= true) { CFGStackified
= Value
; }
158 void computeLegalValueVTs(const WebAssemblyTargetLowering
&TLI
,
159 LLVMContext
&Ctx
, const DataLayout
&DL
, Type
*Ty
,
160 SmallVectorImpl
<MVT
> &ValueVTs
);
162 void computeLegalValueVTs(const Function
&F
, const TargetMachine
&TM
, Type
*Ty
,
163 SmallVectorImpl
<MVT
> &ValueVTs
);
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
);
172 void valTypesFromMVTs(ArrayRef
<MVT
> In
, SmallVectorImpl
<wasm::ValType
> &Out
);
174 wasm::WasmSignature
*signatureFromMVTs(MCContext
&Ctx
,
175 const SmallVectorImpl
<MVT
> &Results
,
176 const SmallVectorImpl
<MVT
> &Params
);
180 using BBNumberMap
= DenseMap
<int, int>;
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
188 BBNumberMap SrcToUnwindDest
;
190 WebAssemblyFunctionInfo() = default;
191 WebAssemblyFunctionInfo(const llvm::MachineFunction
&MF
,
192 const llvm::WebAssemblyFunctionInfo
&MFI
);
194 void mappingImpl(yaml::IO
&YamlIO
) override
;
195 ~WebAssemblyFunctionInfo() = default;
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
);
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())]);
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
);
220 } // end namespace yaml
222 } // end namespace llvm