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