10b57cec5SDimitry Andric //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// This file implements WebAssembly-specific per-machine-function 110b57cec5SDimitry Andric /// information. 120b57cec5SDimitry Andric /// 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "WebAssemblyMachineFunctionInfo.h" 160b57cec5SDimitry Andric #include "WebAssemblyISelLowering.h" 170b57cec5SDimitry Andric #include "WebAssemblySubtarget.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h" 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor. 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initWARegs() { 240b57cec5SDimitry Andric assert(WARegs.empty()); 250b57cec5SDimitry Andric unsigned Reg = UnusedReg; 260b57cec5SDimitry Andric WARegs.resize(MF.getRegInfo().getNumVirtRegs(), Reg); 270b57cec5SDimitry Andric } 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM, 300b57cec5SDimitry Andric Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 310b57cec5SDimitry Andric const DataLayout &DL(F.getParent()->getDataLayout()); 320b57cec5SDimitry Andric const WebAssemblyTargetLowering &TLI = 330b57cec5SDimitry Andric *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering(); 340b57cec5SDimitry Andric SmallVector<EVT, 4> VTs; 350b57cec5SDimitry Andric ComputeValueVTs(TLI, DL, Ty, VTs); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric for (EVT VT : VTs) { 380b57cec5SDimitry Andric unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT); 390b57cec5SDimitry Andric MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT); 400b57cec5SDimitry Andric for (unsigned I = 0; I != NumRegs; ++I) 410b57cec5SDimitry Andric ValueVTs.push_back(RegisterVT); 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric void llvm::computeSignatureVTs(const FunctionType *Ty, const Function &F, 460b57cec5SDimitry Andric const TargetMachine &TM, 470b57cec5SDimitry Andric SmallVectorImpl<MVT> &Params, 480b57cec5SDimitry Andric SmallVectorImpl<MVT> &Results) { 490b57cec5SDimitry Andric computeLegalValueVTs(F, TM, Ty->getReturnType(), Results); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 52*8bcb0991SDimitry Andric if (Results.size() > 1 && 53*8bcb0991SDimitry Andric !TM.getSubtarget<WebAssemblySubtarget>(F).hasMultivalue()) { 54*8bcb0991SDimitry Andric // WebAssembly can't lower returns of multiple values without demoting to 55*8bcb0991SDimitry Andric // sret unless multivalue is enabled (see 56*8bcb0991SDimitry Andric // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return 57*8bcb0991SDimitry Andric // values with a poitner parameter. 580b57cec5SDimitry Andric Results.clear(); 590b57cec5SDimitry Andric Params.push_back(PtrVT); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric for (auto *Param : Ty->params()) 630b57cec5SDimitry Andric computeLegalValueVTs(F, TM, Param, Params); 640b57cec5SDimitry Andric if (Ty->isVarArg()) 650b57cec5SDimitry Andric Params.push_back(PtrVT); 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In, 690b57cec5SDimitry Andric SmallVectorImpl<wasm::ValType> &Out) { 700b57cec5SDimitry Andric for (MVT Ty : In) 710b57cec5SDimitry Andric Out.push_back(WebAssembly::toValType(Ty)); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric std::unique_ptr<wasm::WasmSignature> 750b57cec5SDimitry Andric llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 760b57cec5SDimitry Andric const SmallVectorImpl<MVT> &Params) { 77*8bcb0991SDimitry Andric auto Sig = std::make_unique<wasm::WasmSignature>(); 780b57cec5SDimitry Andric valTypesFromMVTs(Results, Sig->Returns); 790b57cec5SDimitry Andric valTypesFromMVTs(Params, Sig->Params); 800b57cec5SDimitry Andric return Sig; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo( 840b57cec5SDimitry Andric const llvm::WebAssemblyFunctionInfo &MFI) 850b57cec5SDimitry Andric : CFGStackified(MFI.isCFGStackified()) {} 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 880b57cec5SDimitry Andric MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric void WebAssemblyFunctionInfo::initializeBaseYamlFields( 920b57cec5SDimitry Andric const yaml::WebAssemblyFunctionInfo &YamlMFI) { 930b57cec5SDimitry Andric CFGStackified = YamlMFI.CFGStackified; 940b57cec5SDimitry Andric } 95