xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric ///
9*0b57cec5SDimitry Andric /// \file
10*0b57cec5SDimitry Andric /// This file implements WebAssembly-specific per-machine-function
11*0b57cec5SDimitry Andric /// information.
12*0b57cec5SDimitry Andric ///
13*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
14*0b57cec5SDimitry Andric 
15*0b57cec5SDimitry Andric #include "WebAssemblyMachineFunctionInfo.h"
16*0b57cec5SDimitry Andric #include "WebAssemblyISelLowering.h"
17*0b57cec5SDimitry Andric #include "WebAssemblySubtarget.h"
18*0b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h"
19*0b57cec5SDimitry Andric using namespace llvm;
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor.
22*0b57cec5SDimitry Andric 
23*0b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initWARegs() {
24*0b57cec5SDimitry Andric   assert(WARegs.empty());
25*0b57cec5SDimitry Andric   unsigned Reg = UnusedReg;
26*0b57cec5SDimitry Andric   WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg);
27*0b57cec5SDimitry Andric }
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
30*0b57cec5SDimitry Andric                                 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
31*0b57cec5SDimitry Andric   const DataLayout &DL(F.getParent()->getDataLayout());
32*0b57cec5SDimitry Andric   const WebAssemblyTargetLowering &TLI =
33*0b57cec5SDimitry Andric       *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
34*0b57cec5SDimitry Andric   SmallVector<EVT, 4> VTs;
35*0b57cec5SDimitry Andric   ComputeValueVTs(TLI, DL, Ty, VTs);
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric   for (EVT VT : VTs) {
38*0b57cec5SDimitry Andric     unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
39*0b57cec5SDimitry Andric     MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
40*0b57cec5SDimitry Andric     for (unsigned I = 0; I != NumRegs; ++I)
41*0b57cec5SDimitry Andric       ValueVTs.push_back(RegisterVT);
42*0b57cec5SDimitry Andric   }
43*0b57cec5SDimitry Andric }
44*0b57cec5SDimitry Andric 
45*0b57cec5SDimitry Andric void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F,
46*0b57cec5SDimitry Andric                                const TargetMachine &TM,
47*0b57cec5SDimitry Andric                                SmallVectorImpl<MVT> &Params,
48*0b57cec5SDimitry Andric                                SmallVectorImpl<MVT> &Results) {
49*0b57cec5SDimitry Andric   computeLegalValueVTs(F, TM, Ty->getReturnType(), Results);
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric   MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
52*0b57cec5SDimitry Andric   if (Results.size() > 1) {
53*0b57cec5SDimitry Andric     // WebAssembly currently can't lower returns of multiple values without
54*0b57cec5SDimitry Andric     // demoting to sret (see WebAssemblyTargetLowering::CanLowerReturn). So
55*0b57cec5SDimitry Andric     // replace multiple return values with a pointer parameter.
56*0b57cec5SDimitry Andric     Results.clear();
57*0b57cec5SDimitry Andric     Params.push_back(PtrVT);
58*0b57cec5SDimitry Andric   }
59*0b57cec5SDimitry Andric 
60*0b57cec5SDimitry Andric   for (auto *Param : Ty->params())
61*0b57cec5SDimitry Andric     computeLegalValueVTs(F, TM, Param, Params);
62*0b57cec5SDimitry Andric   if (Ty->isVarArg())
63*0b57cec5SDimitry Andric     Params.push_back(PtrVT);
64*0b57cec5SDimitry Andric }
65*0b57cec5SDimitry Andric 
66*0b57cec5SDimitry Andric void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
67*0b57cec5SDimitry Andric                             SmallVectorImpl<wasm::ValType> &Out) {
68*0b57cec5SDimitry Andric   for (MVT Ty : In)
69*0b57cec5SDimitry Andric     Out.push_back(WebAssembly::toValType(Ty));
70*0b57cec5SDimitry Andric }
71*0b57cec5SDimitry Andric 
72*0b57cec5SDimitry Andric std::unique_ptr<wasm::WasmSignature>
73*0b57cec5SDimitry Andric llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
74*0b57cec5SDimitry Andric                         const SmallVectorImpl<MVT> &Params) {
75*0b57cec5SDimitry Andric   auto Sig = make_unique<wasm::WasmSignature>();
76*0b57cec5SDimitry Andric   valTypesFromMVTs(Results, Sig->Returns);
77*0b57cec5SDimitry Andric   valTypesFromMVTs(Params, Sig->Params);
78*0b57cec5SDimitry Andric   return Sig;
79*0b57cec5SDimitry Andric }
80*0b57cec5SDimitry Andric 
81*0b57cec5SDimitry Andric yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
82*0b57cec5SDimitry Andric     const llvm::WebAssemblyFunctionInfo &MFI)
83*0b57cec5SDimitry Andric     : CFGStackified(MFI.isCFGStackified()) {}
84*0b57cec5SDimitry Andric 
85*0b57cec5SDimitry Andric void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
86*0b57cec5SDimitry Andric   MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
87*0b57cec5SDimitry Andric }
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initializeBaseYamlFields(
90*0b57cec5SDimitry Andric     const yaml::WebAssemblyFunctionInfo &YamlMFI) {
91*0b57cec5SDimitry Andric   CFGStackified = YamlMFI.CFGStackified;
92*0b57cec5SDimitry Andric }
93