110e730a2SDan Gohman //=- WebAssemblyMachineFunctionInfo.cpp - WebAssembly Machine Function Info -=// 210e730a2SDan Gohman // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 610e730a2SDan Gohman // 710e730a2SDan Gohman //===----------------------------------------------------------------------===// 810e730a2SDan Gohman /// 910e730a2SDan Gohman /// \file 105f8f34e4SAdrian Prantl /// This file implements WebAssembly-specific per-machine-function 1110e730a2SDan Gohman /// information. 1210e730a2SDan Gohman /// 1310e730a2SDan Gohman //===----------------------------------------------------------------------===// 1410e730a2SDan Gohman 1510e730a2SDan Gohman #include "WebAssemblyMachineFunctionInfo.h" 16b3e88ccbSHeejin Ahn #include "MCTargetDesc/WebAssemblyInstPrinter.h" 170b2bc69bSHeejin Ahn #include "Utils/WebAssemblyTypeUtilities.h" 182726b88cSDan Gohman #include "WebAssemblyISelLowering.h" 192726b88cSDan Gohman #include "WebAssemblySubtarget.h" 202726b88cSDan Gohman #include "llvm/CodeGen/Analysis.h" 210b2bc69bSHeejin Ahn #include "llvm/CodeGen/WasmEHFuncInfo.h" 22fe0006c8SSimon Pilgrim #include "llvm/Target/TargetMachine.h" 2310e730a2SDan Gohman using namespace llvm; 2410e730a2SDan Gohman 2518c56a07SHeejin Ahn WebAssemblyFunctionInfo::~WebAssemblyFunctionInfo() = default; // anchor. 26058fce54SDan Gohman 27c5d24009SMatt Arsenault void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) { 28058fce54SDan Gohman assert(WARegs.empty()); 29058fce54SDan Gohman unsigned Reg = UnusedReg; 30c5d24009SMatt Arsenault WARegs.resize(MRI.getNumVirtRegs(), Reg); 31058fce54SDan Gohman } 322726b88cSDan Gohman 33*864767abSPaulo Matos void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, 34*864767abSPaulo Matos LLVMContext &Ctx, const DataLayout &DL, 35*864767abSPaulo Matos Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 36*864767abSPaulo Matos SmallVector<EVT, 4> VTs; 37*864767abSPaulo Matos ComputeValueVTs(TLI, DL, Ty, VTs); 38*864767abSPaulo Matos 39*864767abSPaulo Matos for (EVT VT : VTs) { 40*864767abSPaulo Matos unsigned NumRegs = TLI.getNumRegisters(Ctx, VT); 41*864767abSPaulo Matos MVT RegisterVT = TLI.getRegisterType(Ctx, VT); 42*864767abSPaulo Matos for (unsigned I = 0; I != NumRegs; ++I) 43*864767abSPaulo Matos ValueVTs.push_back(RegisterVT); 44*864767abSPaulo Matos } 45*864767abSPaulo Matos } 46*864767abSPaulo Matos 4718c56a07SHeejin Ahn void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM, 482726b88cSDan Gohman Type *Ty, SmallVectorImpl<MVT> &ValueVTs) { 492726b88cSDan Gohman const DataLayout &DL(F.getParent()->getDataLayout()); 502726b88cSDan Gohman const WebAssemblyTargetLowering &TLI = 512726b88cSDan Gohman *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering(); 52*864767abSPaulo Matos computeLegalValueVTs(TLI, F.getContext(), DL, Ty, ValueVTs); 532726b88cSDan Gohman } 542726b88cSDan Gohman 5508670d43SYuta Saito void llvm::computeSignatureVTs(const FunctionType *Ty, 5608670d43SYuta Saito const Function *TargetFunc, 5708670d43SYuta Saito const Function &ContextFunc, 5877a7a380SDerek Schuff const TargetMachine &TM, 592726b88cSDan Gohman SmallVectorImpl<MVT> &Params, 602726b88cSDan Gohman SmallVectorImpl<MVT> &Results) { 6108670d43SYuta Saito computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results); 622726b88cSDan Gohman 6377a7a380SDerek Schuff MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 6400f9e5aaSThomas Lively if (Results.size() > 1 && 6508670d43SYuta Saito !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) { 6600f9e5aaSThomas Lively // WebAssembly can't lower returns of multiple values without demoting to 6700f9e5aaSThomas Lively // sret unless multivalue is enabled (see 6800f9e5aaSThomas Lively // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return 6900f9e5aaSThomas Lively // values with a poitner parameter. 702726b88cSDan Gohman Results.clear(); 7177a7a380SDerek Schuff Params.push_back(PtrVT); 722726b88cSDan Gohman } 732726b88cSDan Gohman 7477a7a380SDerek Schuff for (auto *Param : Ty->params()) 7508670d43SYuta Saito computeLegalValueVTs(ContextFunc, TM, Param, Params); 7677a7a380SDerek Schuff if (Ty->isVarArg()) 7777a7a380SDerek Schuff Params.push_back(PtrVT); 7808670d43SYuta Saito 7908670d43SYuta Saito // For swiftcc, emit additional swiftself and swifterror parameters 8008670d43SYuta Saito // if there aren't. These additional parameters are also passed for caller. 8108670d43SYuta Saito // They are necessary to match callee and caller signature for indirect 8208670d43SYuta Saito // call. 8308670d43SYuta Saito 8408670d43SYuta Saito if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) { 8508670d43SYuta Saito MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits()); 8608670d43SYuta Saito bool HasSwiftErrorArg = false; 8708670d43SYuta Saito bool HasSwiftSelfArg = false; 8808670d43SYuta Saito for (const auto &Arg : TargetFunc->args()) { 8908670d43SYuta Saito HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError); 9008670d43SYuta Saito HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf); 9108670d43SYuta Saito } 9208670d43SYuta Saito if (!HasSwiftErrorArg) 9308670d43SYuta Saito Params.push_back(PtrVT); 9408670d43SYuta Saito if (!HasSwiftSelfArg) 9508670d43SYuta Saito Params.push_back(PtrVT); 9608670d43SYuta Saito } 9777a7a380SDerek Schuff } 9877a7a380SDerek Schuff 9918c56a07SHeejin Ahn void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In, 10049482f82SWouter van Oortmerssen SmallVectorImpl<wasm::ValType> &Out) { 10149482f82SWouter van Oortmerssen for (MVT Ty : In) 10249482f82SWouter van Oortmerssen Out.push_back(WebAssembly::toValType(Ty)); 10349482f82SWouter van Oortmerssen } 10449482f82SWouter van Oortmerssen 10577a7a380SDerek Schuff std::unique_ptr<wasm::WasmSignature> 10618c56a07SHeejin Ahn llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 10777a7a380SDerek Schuff const SmallVectorImpl<MVT> &Params) { 1080eaee545SJonas Devlieghere auto Sig = std::make_unique<wasm::WasmSignature>(); 10918c56a07SHeejin Ahn valTypesFromMVTs(Results, Sig->Returns); 11018c56a07SHeejin Ahn valTypesFromMVTs(Params, Sig->Params); 11177a7a380SDerek Schuff return Sig; 1122726b88cSDan Gohman } 11352221d56SHeejin Ahn 11452221d56SHeejin Ahn yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo( 1151aaa481fSHeejin Ahn const llvm::WebAssemblyFunctionInfo &MFI) 11651fb5bf4SHeejin Ahn : CFGStackified(MFI.isCFGStackified()) { 11751fb5bf4SHeejin Ahn auto *EHInfo = MFI.getWasmEHFuncInfo(); 11851fb5bf4SHeejin Ahn const llvm::MachineFunction &MF = MFI.getMachineFunction(); 119b3e88ccbSHeejin Ahn 120b3e88ccbSHeejin Ahn for (auto VT : MFI.getParams()) 121b3e88ccbSHeejin Ahn Params.push_back(EVT(VT).getEVTString()); 122b3e88ccbSHeejin Ahn for (auto VT : MFI.getResults()) 123b3e88ccbSHeejin Ahn Results.push_back(EVT(VT).getEVTString()); 124b3e88ccbSHeejin Ahn 12551fb5bf4SHeejin Ahn // MFI.getWasmEHFuncInfo() is non-null only for functions with the 12651fb5bf4SHeejin Ahn // personality function. 12751fb5bf4SHeejin Ahn if (EHInfo) { 12851fb5bf4SHeejin Ahn // SrcToUnwindDest can contain stale mappings in case BBs are removed in 12951fb5bf4SHeejin Ahn // optimizations, in case, for example, they are unreachable. We should not 13051fb5bf4SHeejin Ahn // include their info. 13151fb5bf4SHeejin Ahn SmallPtrSet<const MachineBasicBlock *, 16> MBBs; 13251fb5bf4SHeejin Ahn for (const auto &MBB : MF) 13351fb5bf4SHeejin Ahn MBBs.insert(&MBB); 13451fb5bf4SHeejin Ahn for (auto KV : EHInfo->SrcToUnwindDest) { 13551fb5bf4SHeejin Ahn auto *SrcBB = KV.first.get<MachineBasicBlock *>(); 13651fb5bf4SHeejin Ahn auto *DestBB = KV.second.get<MachineBasicBlock *>(); 13751fb5bf4SHeejin Ahn if (MBBs.count(SrcBB) && MBBs.count(DestBB)) 13851fb5bf4SHeejin Ahn SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber(); 13951fb5bf4SHeejin Ahn } 14051fb5bf4SHeejin Ahn } 14151fb5bf4SHeejin Ahn } 14252221d56SHeejin Ahn 14352221d56SHeejin Ahn void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) { 14452221d56SHeejin Ahn MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this); 14552221d56SHeejin Ahn } 14652221d56SHeejin Ahn 14752221d56SHeejin Ahn void WebAssemblyFunctionInfo::initializeBaseYamlFields( 1481aaa481fSHeejin Ahn const yaml::WebAssemblyFunctionInfo &YamlMFI) { 1491aaa481fSHeejin Ahn CFGStackified = YamlMFI.CFGStackified; 150b3e88ccbSHeejin Ahn for (auto VT : YamlMFI.Params) 151b3e88ccbSHeejin Ahn addParam(WebAssembly::parseMVT(VT.Value)); 152b3e88ccbSHeejin Ahn for (auto VT : YamlMFI.Results) 153b3e88ccbSHeejin Ahn addResult(WebAssembly::parseMVT(VT.Value)); 15451fb5bf4SHeejin Ahn if (WasmEHInfo) { 15551fb5bf4SHeejin Ahn for (auto KV : YamlMFI.SrcToUnwindDest) 15651fb5bf4SHeejin Ahn WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first), 15751fb5bf4SHeejin Ahn MF.getBlockNumbered(KV.second)); 15851fb5bf4SHeejin Ahn } 1591aaa481fSHeejin Ahn } 160