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
initWARegs()23 void WebAssemblyFunctionInfo::initWARegs() {
24 assert(WARegs.empty());
25 unsigned Reg = UnusedReg;
26 WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
27 }
28
computeLegalValueVTs(const Function & F,const TargetMachine & TM,Type * Ty,SmallVectorImpl<MVT> & ValueVTs)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
computeSignatureVTs(const FunctionType * Ty,const Function & F,const TargetMachine & TM,SmallVectorImpl<MVT> & Params,SmallVectorImpl<MVT> & Results)45 void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F,
46 const TargetMachine &TM,
47 SmallVectorImpl<MVT> &Params,
48 SmallVectorImpl<MVT> &Results) {
49 computeLegalValueVTs(F, TM, Ty->getReturnType(), Results);
50
51 MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
52 if (Results.size() > 1 &&
53 !TM.getSubtarget<WebAssemblySubtarget>(F).hasMultivalue()) {
54 // WebAssembly can't lower returns of multiple values without demoting to
55 // sret unless multivalue is enabled (see
56 // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
57 // values with a poitner parameter.
58 Results.clear();
59 Params.push_back(PtrVT);
60 }
61
62 for (auto *Param : Ty->params())
63 computeLegalValueVTs(F, TM, Param, Params);
64 if (Ty->isVarArg())
65 Params.push_back(PtrVT);
66 }
67
valTypesFromMVTs(const ArrayRef<MVT> & In,SmallVectorImpl<wasm::ValType> & Out)68 void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
69 SmallVectorImpl<wasm::ValType> &Out) {
70 for (MVT Ty : In)
71 Out.push_back(WebAssembly::toValType(Ty));
72 }
73
74 std::unique_ptr<wasm::WasmSignature>
signatureFromMVTs(const SmallVectorImpl<MVT> & Results,const SmallVectorImpl<MVT> & Params)75 llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
76 const SmallVectorImpl<MVT> &Params) {
77 auto Sig = std::make_unique<wasm::WasmSignature>();
78 valTypesFromMVTs(Results, Sig->Returns);
79 valTypesFromMVTs(Params, Sig->Params);
80 return Sig;
81 }
82
WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo & MFI)83 yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
84 const llvm::WebAssemblyFunctionInfo &MFI)
85 : CFGStackified(MFI.isCFGStackified()) {}
86
mappingImpl(yaml::IO & YamlIO)87 void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
88 MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
89 }
90
initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo & YamlMFI)91 void WebAssemblyFunctionInfo::initializeBaseYamlFields(
92 const yaml::WebAssemblyFunctionInfo &YamlMFI) {
93 CFGStackified = YamlMFI.CFGStackified;
94 }
95