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