1 //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
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 implements WebAssembly-specific per-machine-function
13 //===----------------------------------------------------------------------===//
15 #include "WebAssemblyMachineFunctionInfo.h"
16 #include "MCTargetDesc/WebAssemblyInstPrinter.h"
17 #include "Utils/WebAssemblyTypeUtilities.h"
18 #include "WebAssemblyISelLowering.h"
19 #include "WebAssemblySubtarget.h"
20 #include "WebAssemblyUtilities.h"
21 #include "llvm/CodeGen/Analysis.h"
22 #include "llvm/CodeGen/WasmEHFuncInfo.h"
23 #include "llvm/Target/TargetMachine.h"
26 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
28 MachineFunctionInfo
*WebAssemblyFunctionInfo::clone(
29 BumpPtrAllocator
&Allocator
, MachineFunction
&DestMF
,
30 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
)
32 // TODO: Implement cloning for WasmEHFuncInfo. This will have invalid block
34 return DestMF
.cloneInfo
<WebAssemblyFunctionInfo
>(*this);
37 void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo
&MRI
) {
38 assert(WARegs
.empty());
39 unsigned Reg
= WebAssembly::UnusedReg
;
40 WARegs
.resize(MRI
.getNumVirtRegs(), Reg
);
43 void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering
&TLI
,
44 LLVMContext
&Ctx
, const DataLayout
&DL
,
45 Type
*Ty
, SmallVectorImpl
<MVT
> &ValueVTs
) {
46 SmallVector
<EVT
, 4> VTs
;
47 ComputeValueVTs(TLI
, DL
, Ty
, VTs
);
50 unsigned NumRegs
= TLI
.getNumRegisters(Ctx
, VT
);
51 MVT RegisterVT
= TLI
.getRegisterType(Ctx
, VT
);
52 for (unsigned I
= 0; I
!= NumRegs
; ++I
)
53 ValueVTs
.push_back(RegisterVT
);
57 void llvm::computeLegalValueVTs(const Function
&F
, const TargetMachine
&TM
,
58 Type
*Ty
, SmallVectorImpl
<MVT
> &ValueVTs
) {
59 const DataLayout
&DL(F
.getDataLayout());
60 const WebAssemblyTargetLowering
&TLI
=
61 *TM
.getSubtarget
<WebAssemblySubtarget
>(F
).getTargetLowering();
62 computeLegalValueVTs(TLI
, F
.getContext(), DL
, Ty
, ValueVTs
);
65 void llvm::computeSignatureVTs(const FunctionType
*Ty
,
66 const Function
*TargetFunc
,
67 const Function
&ContextFunc
,
68 const TargetMachine
&TM
,
69 SmallVectorImpl
<MVT
> &Params
,
70 SmallVectorImpl
<MVT
> &Results
) {
71 computeLegalValueVTs(ContextFunc
, TM
, Ty
->getReturnType(), Results
);
73 MVT PtrVT
= MVT::getIntegerVT(TM
.createDataLayout().getPointerSizeInBits());
74 if (!WebAssembly::canLowerReturn(
76 &TM
.getSubtarget
<WebAssemblySubtarget
>(ContextFunc
))) {
77 // WebAssembly can't lower returns of multiple values without demoting to
78 // sret unless multivalue is enabled (see
79 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
80 // values with a poitner parameter.
82 Params
.push_back(PtrVT
);
85 for (auto *Param
: Ty
->params())
86 computeLegalValueVTs(ContextFunc
, TM
, Param
, Params
);
88 Params
.push_back(PtrVT
);
90 // For swiftcc, emit additional swiftself and swifterror parameters
91 // if there aren't. These additional parameters are also passed for caller.
92 // They are necessary to match callee and caller signature for indirect
95 if (TargetFunc
&& TargetFunc
->getCallingConv() == CallingConv::Swift
) {
96 MVT PtrVT
= MVT::getIntegerVT(TM
.createDataLayout().getPointerSizeInBits());
97 bool HasSwiftErrorArg
= false;
98 bool HasSwiftSelfArg
= false;
99 for (const auto &Arg
: TargetFunc
->args()) {
100 HasSwiftErrorArg
|= Arg
.hasAttribute(Attribute::SwiftError
);
101 HasSwiftSelfArg
|= Arg
.hasAttribute(Attribute::SwiftSelf
);
103 if (!HasSwiftErrorArg
)
104 Params
.push_back(PtrVT
);
105 if (!HasSwiftSelfArg
)
106 Params
.push_back(PtrVT
);
110 void llvm::valTypesFromMVTs(ArrayRef
<MVT
> In
,
111 SmallVectorImpl
<wasm::ValType
> &Out
) {
113 Out
.push_back(WebAssembly::toValType(Ty
));
116 wasm::WasmSignature
*
117 llvm::signatureFromMVTs(MCContext
&Ctx
, const SmallVectorImpl
<MVT
> &Results
,
118 const SmallVectorImpl
<MVT
> &Params
) {
119 auto Sig
= Ctx
.createWasmSignature();
120 valTypesFromMVTs(Results
, Sig
->Returns
);
121 valTypesFromMVTs(Params
, Sig
->Params
);
125 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
126 const llvm::MachineFunction
&MF
, const llvm::WebAssemblyFunctionInfo
&MFI
)
127 : CFGStackified(MFI
.isCFGStackified()) {
128 for (auto VT
: MFI
.getParams())
129 Params
.push_back(EVT(VT
).getEVTString());
130 for (auto VT
: MFI
.getResults())
131 Results
.push_back(EVT(VT
).getEVTString());
133 // MFI.getWasmEHFuncInfo() is non-null only for functions with the
134 // personality function.
136 if (auto *EHInfo
= MF
.getWasmEHFuncInfo()) {
137 // SrcToUnwindDest can contain stale mappings in case BBs are removed in
138 // optimizations, in case, for example, they are unreachable. We should not
139 // include their info.
140 SmallPtrSet
<const MachineBasicBlock
*, 16> MBBs
;
141 for (const auto &MBB
: MF
)
143 for (auto KV
: EHInfo
->SrcToUnwindDest
) {
144 auto *SrcBB
= KV
.first
.get
<MachineBasicBlock
*>();
145 auto *DestBB
= KV
.second
.get
<MachineBasicBlock
*>();
146 if (MBBs
.count(SrcBB
) && MBBs
.count(DestBB
))
147 SrcToUnwindDest
[SrcBB
->getNumber()] = DestBB
->getNumber();
152 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO
&YamlIO
) {
153 MappingTraits
<WebAssemblyFunctionInfo
>::mapping(YamlIO
, *this);
156 void WebAssemblyFunctionInfo::initializeBaseYamlFields(
157 MachineFunction
&MF
, const yaml::WebAssemblyFunctionInfo
&YamlMFI
) {
158 CFGStackified
= YamlMFI
.CFGStackified
;
159 for (auto VT
: YamlMFI
.Params
)
160 addParam(WebAssembly::parseMVT(VT
.Value
));
161 for (auto VT
: YamlMFI
.Results
)
162 addResult(WebAssembly::parseMVT(VT
.Value
));
164 // FIXME: WasmEHInfo is defined in the MachineFunction, but serialized
165 // here. Either WasmEHInfo should be moved out of MachineFunction, or the
166 // serialization handling should be moved to MachineFunction.
167 if (WasmEHFuncInfo
*WasmEHInfo
= MF
.getWasmEHFuncInfo()) {
168 for (auto KV
: YamlMFI
.SrcToUnwindDest
)
169 WasmEHInfo
->setUnwindDest(MF
.getBlockNumbered(KV
.first
),
170 MF
.getBlockNumbered(KV
.second
));