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 "llvm/CodeGen/Analysis.h"
21 #include "llvm/CodeGen/WasmEHFuncInfo.h"
22 #include "llvm/Target/TargetMachine.h"
25 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
27 void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo
&MRI
) {
28 assert(WARegs
.empty());
29 unsigned Reg
= UnusedReg
;
30 WARegs
.resize(MRI
.getNumVirtRegs(), Reg
);
33 void llvm::computeLegalValueVTs(const Function
&F
, const TargetMachine
&TM
,
34 Type
*Ty
, SmallVectorImpl
<MVT
> &ValueVTs
) {
35 const DataLayout
&DL(F
.getParent()->getDataLayout());
36 const WebAssemblyTargetLowering
&TLI
=
37 *TM
.getSubtarget
<WebAssemblySubtarget
>(F
).getTargetLowering();
38 SmallVector
<EVT
, 4> VTs
;
39 ComputeValueVTs(TLI
, DL
, Ty
, VTs
);
42 unsigned NumRegs
= TLI
.getNumRegisters(F
.getContext(), VT
);
43 MVT RegisterVT
= TLI
.getRegisterType(F
.getContext(), VT
);
44 for (unsigned I
= 0; I
!= NumRegs
; ++I
)
45 ValueVTs
.push_back(RegisterVT
);
49 void llvm::computeSignatureVTs(const FunctionType
*Ty
,
50 const Function
*TargetFunc
,
51 const Function
&ContextFunc
,
52 const TargetMachine
&TM
,
53 SmallVectorImpl
<MVT
> &Params
,
54 SmallVectorImpl
<MVT
> &Results
) {
55 computeLegalValueVTs(ContextFunc
, TM
, Ty
->getReturnType(), Results
);
57 MVT PtrVT
= MVT::getIntegerVT(TM
.createDataLayout().getPointerSizeInBits());
58 if (Results
.size() > 1 &&
59 !TM
.getSubtarget
<WebAssemblySubtarget
>(ContextFunc
).hasMultivalue()) {
60 // WebAssembly can't lower returns of multiple values without demoting to
61 // sret unless multivalue is enabled (see
62 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
63 // values with a poitner parameter.
65 Params
.push_back(PtrVT
);
68 for (auto *Param
: Ty
->params())
69 computeLegalValueVTs(ContextFunc
, TM
, Param
, Params
);
71 Params
.push_back(PtrVT
);
73 // For swiftcc, emit additional swiftself and swifterror parameters
74 // if there aren't. These additional parameters are also passed for caller.
75 // They are necessary to match callee and caller signature for indirect
78 if (TargetFunc
&& TargetFunc
->getCallingConv() == CallingConv::Swift
) {
79 MVT PtrVT
= MVT::getIntegerVT(TM
.createDataLayout().getPointerSizeInBits());
80 bool HasSwiftErrorArg
= false;
81 bool HasSwiftSelfArg
= false;
82 for (const auto &Arg
: TargetFunc
->args()) {
83 HasSwiftErrorArg
|= Arg
.hasAttribute(Attribute::SwiftError
);
84 HasSwiftSelfArg
|= Arg
.hasAttribute(Attribute::SwiftSelf
);
86 if (!HasSwiftErrorArg
)
87 Params
.push_back(PtrVT
);
89 Params
.push_back(PtrVT
);
93 void llvm::valTypesFromMVTs(const ArrayRef
<MVT
> &In
,
94 SmallVectorImpl
<wasm::ValType
> &Out
) {
96 Out
.push_back(WebAssembly::toValType(Ty
));
99 std::unique_ptr
<wasm::WasmSignature
>
100 llvm::signatureFromMVTs(const SmallVectorImpl
<MVT
> &Results
,
101 const SmallVectorImpl
<MVT
> &Params
) {
102 auto Sig
= std::make_unique
<wasm::WasmSignature
>();
103 valTypesFromMVTs(Results
, Sig
->Returns
);
104 valTypesFromMVTs(Params
, Sig
->Params
);
108 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
109 const llvm::WebAssemblyFunctionInfo
&MFI
)
110 : CFGStackified(MFI
.isCFGStackified()) {
111 auto *EHInfo
= MFI
.getWasmEHFuncInfo();
112 const llvm::MachineFunction
&MF
= MFI
.getMachineFunction();
114 for (auto VT
: MFI
.getParams())
115 Params
.push_back(EVT(VT
).getEVTString());
116 for (auto VT
: MFI
.getResults())
117 Results
.push_back(EVT(VT
).getEVTString());
119 // MFI.getWasmEHFuncInfo() is non-null only for functions with the
120 // personality function.
122 // SrcToUnwindDest can contain stale mappings in case BBs are removed in
123 // optimizations, in case, for example, they are unreachable. We should not
124 // include their info.
125 SmallPtrSet
<const MachineBasicBlock
*, 16> MBBs
;
126 for (const auto &MBB
: MF
)
128 for (auto KV
: EHInfo
->SrcToUnwindDest
) {
129 auto *SrcBB
= KV
.first
.get
<MachineBasicBlock
*>();
130 auto *DestBB
= KV
.second
.get
<MachineBasicBlock
*>();
131 if (MBBs
.count(SrcBB
) && MBBs
.count(DestBB
))
132 SrcToUnwindDest
[SrcBB
->getNumber()] = DestBB
->getNumber();
137 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO
&YamlIO
) {
138 MappingTraits
<WebAssemblyFunctionInfo
>::mapping(YamlIO
, *this);
141 void WebAssemblyFunctionInfo::initializeBaseYamlFields(
142 const yaml::WebAssemblyFunctionInfo
&YamlMFI
) {
143 CFGStackified
= YamlMFI
.CFGStackified
;
144 for (auto VT
: YamlMFI
.Params
)
145 addParam(WebAssembly::parseMVT(VT
.Value
));
146 for (auto VT
: YamlMFI
.Results
)
147 addResult(WebAssembly::parseMVT(VT
.Value
));
149 for (auto KV
: YamlMFI
.SrcToUnwindDest
)
150 WasmEHInfo
->setUnwindDest(MF
.getBlockNumbered(KV
.first
),
151 MF
.getBlockNumbered(KV
.second
));