1 //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
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 implements WebAssembly-specific per-machine-function
11 /// information.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "WebAssemblyMachineFunctionInfo.h"
16 #include "WebAssemblyISelLowering.h"
17 #include "WebAssemblySubtarget.h"
18 #include "llvm/CodeGen/Analysis.h"
19 #include "llvm/Target/TargetMachine.h"
20 using namespace llvm;
21
22 WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
23
initWARegs(MachineRegisterInfo & MRI)24 void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) {
25 assert(WARegs.empty());
26 unsigned Reg = UnusedReg;
27 WARegs.resize(MRI.getNumVirtRegs(), Reg);
28 }
29
computeLegalValueVTs(const Function & F,const TargetMachine & TM,Type * Ty,SmallVectorImpl<MVT> & ValueVTs)30 void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
31 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
32 const DataLayout &DL(F.getParent()->getDataLayout());
33 const WebAssemblyTargetLowering &TLI =
34 *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
35 SmallVector<EVT, 4> VTs;
36 ComputeValueVTs(TLI, DL, Ty, VTs);
37
38 for (EVT VT : VTs) {
39 unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
40 MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
41 for (unsigned I = 0; I != NumRegs; ++I)
42 ValueVTs.push_back(RegisterVT);
43 }
44 }
45
computeSignatureVTs(const FunctionType * Ty,const Function * TargetFunc,const Function & ContextFunc,const TargetMachine & TM,SmallVectorImpl<MVT> & Params,SmallVectorImpl<MVT> & Results)46 void llvm::computeSignatureVTs(const FunctionType *Ty,
47 const Function *TargetFunc,
48 const Function &ContextFunc,
49 const TargetMachine &TM,
50 SmallVectorImpl<MVT> &Params,
51 SmallVectorImpl<MVT> &Results) {
52 computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results);
53
54 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
55 if (Results.size() > 1 &&
56 !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) {
57 // WebAssembly can't lower returns of multiple values without demoting to
58 // sret unless multivalue is enabled (see
59 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
60 // values with a poitner parameter.
61 Results.clear();
62 Params.push_back(PtrVT);
63 }
64
65 for (auto *Param : Ty->params())
66 computeLegalValueVTs(ContextFunc, TM, Param, Params);
67 if (Ty->isVarArg())
68 Params.push_back(PtrVT);
69
70 // For swiftcc, emit additional swiftself and swifterror parameters
71 // if there aren't. These additional parameters are also passed for caller.
72 // They are necessary to match callee and caller signature for indirect
73 // call.
74
75 if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) {
76 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
77 bool HasSwiftErrorArg = false;
78 bool HasSwiftSelfArg = false;
79 for (const auto &Arg : TargetFunc->args()) {
80 HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError);
81 HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf);
82 }
83 if (!HasSwiftErrorArg)
84 Params.push_back(PtrVT);
85 if (!HasSwiftSelfArg)
86 Params.push_back(PtrVT);
87 }
88 }
89
valTypesFromMVTs(const ArrayRef<MVT> & In,SmallVectorImpl<wasm::ValType> & Out)90 void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
91 SmallVectorImpl<wasm::ValType> &Out) {
92 for (MVT Ty : In)
93 Out.push_back(WebAssembly::toValType(Ty));
94 }
95
96 std::unique_ptr<wasm::WasmSignature>
signatureFromMVTs(const SmallVectorImpl<MVT> & Results,const SmallVectorImpl<MVT> & Params)97 llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
98 const SmallVectorImpl<MVT> &Params) {
99 auto Sig = std::make_unique<wasm::WasmSignature>();
100 valTypesFromMVTs(Results, Sig->Returns);
101 valTypesFromMVTs(Params, Sig->Params);
102 return Sig;
103 }
104
WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo & MFI)105 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
106 const llvm::WebAssemblyFunctionInfo &MFI)
107 : CFGStackified(MFI.isCFGStackified()) {}
108
mappingImpl(yaml::IO & YamlIO)109 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
110 MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
111 }
112
initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo & YamlMFI)113 void WebAssemblyFunctionInfo::initializeBaseYamlFields(
114 const yaml::WebAssemblyFunctionInfo &YamlMFI) {
115 CFGStackified = YamlMFI.CFGStackified;
116 }
117