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
clone(BumpPtrAllocator & Allocator,MachineFunction & DestMF,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB) const27*cc5a1b3dSMatt Arsenault MachineFunctionInfo *WebAssemblyFunctionInfo::clone(
28*cc5a1b3dSMatt Arsenault BumpPtrAllocator &Allocator, MachineFunction &DestMF,
29*cc5a1b3dSMatt Arsenault const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
30*cc5a1b3dSMatt Arsenault const {
31*cc5a1b3dSMatt Arsenault WebAssemblyFunctionInfo *Clone =
32*cc5a1b3dSMatt Arsenault DestMF.cloneInfo<WebAssemblyFunctionInfo>(*this);
33*cc5a1b3dSMatt Arsenault Clone->MF = &DestMF;
34*cc5a1b3dSMatt Arsenault return Clone;
35*cc5a1b3dSMatt Arsenault }
36*cc5a1b3dSMatt Arsenault
initWARegs(MachineRegisterInfo & MRI)37c5d24009SMatt Arsenault void WebAssemblyFunctionInfo::initWARegs(MachineRegisterInfo &MRI) {
38058fce54SDan Gohman assert(WARegs.empty());
39058fce54SDan Gohman unsigned Reg = UnusedReg;
40c5d24009SMatt Arsenault WARegs.resize(MRI.getNumVirtRegs(), Reg);
41058fce54SDan Gohman }
422726b88cSDan Gohman
computeLegalValueVTs(const WebAssemblyTargetLowering & TLI,LLVMContext & Ctx,const DataLayout & DL,Type * Ty,SmallVectorImpl<MVT> & ValueVTs)43864767abSPaulo Matos void llvm::computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,
44864767abSPaulo Matos LLVMContext &Ctx, const DataLayout &DL,
45864767abSPaulo Matos Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
46864767abSPaulo Matos SmallVector<EVT, 4> VTs;
47864767abSPaulo Matos ComputeValueVTs(TLI, DL, Ty, VTs);
48864767abSPaulo Matos
49864767abSPaulo Matos for (EVT VT : VTs) {
50864767abSPaulo Matos unsigned NumRegs = TLI.getNumRegisters(Ctx, VT);
51864767abSPaulo Matos MVT RegisterVT = TLI.getRegisterType(Ctx, VT);
52864767abSPaulo Matos for (unsigned I = 0; I != NumRegs; ++I)
53864767abSPaulo Matos ValueVTs.push_back(RegisterVT);
54864767abSPaulo Matos }
55864767abSPaulo Matos }
56864767abSPaulo Matos
computeLegalValueVTs(const Function & F,const TargetMachine & TM,Type * Ty,SmallVectorImpl<MVT> & ValueVTs)5718c56a07SHeejin Ahn void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
582726b88cSDan Gohman Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
592726b88cSDan Gohman const DataLayout &DL(F.getParent()->getDataLayout());
602726b88cSDan Gohman const WebAssemblyTargetLowering &TLI =
612726b88cSDan Gohman *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
62864767abSPaulo Matos computeLegalValueVTs(TLI, F.getContext(), DL, Ty, ValueVTs);
632726b88cSDan Gohman }
642726b88cSDan Gohman
computeSignatureVTs(const FunctionType * Ty,const Function * TargetFunc,const Function & ContextFunc,const TargetMachine & TM,SmallVectorImpl<MVT> & Params,SmallVectorImpl<MVT> & Results)6508670d43SYuta Saito void llvm::computeSignatureVTs(const FunctionType *Ty,
6608670d43SYuta Saito const Function *TargetFunc,
6708670d43SYuta Saito const Function &ContextFunc,
6877a7a380SDerek Schuff const TargetMachine &TM,
692726b88cSDan Gohman SmallVectorImpl<MVT> &Params,
702726b88cSDan Gohman SmallVectorImpl<MVT> &Results) {
7108670d43SYuta Saito computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results);
722726b88cSDan Gohman
7377a7a380SDerek Schuff MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
7400f9e5aaSThomas Lively if (Results.size() > 1 &&
7508670d43SYuta Saito !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) {
7600f9e5aaSThomas Lively // WebAssembly can't lower returns of multiple values without demoting to
7700f9e5aaSThomas Lively // sret unless multivalue is enabled (see
7800f9e5aaSThomas Lively // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
7900f9e5aaSThomas Lively // values with a poitner parameter.
802726b88cSDan Gohman Results.clear();
8177a7a380SDerek Schuff Params.push_back(PtrVT);
822726b88cSDan Gohman }
832726b88cSDan Gohman
8477a7a380SDerek Schuff for (auto *Param : Ty->params())
8508670d43SYuta Saito computeLegalValueVTs(ContextFunc, TM, Param, Params);
8677a7a380SDerek Schuff if (Ty->isVarArg())
8777a7a380SDerek Schuff Params.push_back(PtrVT);
8808670d43SYuta Saito
8908670d43SYuta Saito // For swiftcc, emit additional swiftself and swifterror parameters
9008670d43SYuta Saito // if there aren't. These additional parameters are also passed for caller.
9108670d43SYuta Saito // They are necessary to match callee and caller signature for indirect
9208670d43SYuta Saito // call.
9308670d43SYuta Saito
9408670d43SYuta Saito if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) {
9508670d43SYuta Saito MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
9608670d43SYuta Saito bool HasSwiftErrorArg = false;
9708670d43SYuta Saito bool HasSwiftSelfArg = false;
9808670d43SYuta Saito for (const auto &Arg : TargetFunc->args()) {
9908670d43SYuta Saito HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError);
10008670d43SYuta Saito HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf);
10108670d43SYuta Saito }
10208670d43SYuta Saito if (!HasSwiftErrorArg)
10308670d43SYuta Saito Params.push_back(PtrVT);
10408670d43SYuta Saito if (!HasSwiftSelfArg)
10508670d43SYuta Saito Params.push_back(PtrVT);
10608670d43SYuta Saito }
10777a7a380SDerek Schuff }
10877a7a380SDerek Schuff
valTypesFromMVTs(const ArrayRef<MVT> & In,SmallVectorImpl<wasm::ValType> & Out)10918c56a07SHeejin Ahn void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
11049482f82SWouter van Oortmerssen SmallVectorImpl<wasm::ValType> &Out) {
11149482f82SWouter van Oortmerssen for (MVT Ty : In)
11249482f82SWouter van Oortmerssen Out.push_back(WebAssembly::toValType(Ty));
11349482f82SWouter van Oortmerssen }
11449482f82SWouter van Oortmerssen
11577a7a380SDerek Schuff std::unique_ptr<wasm::WasmSignature>
signatureFromMVTs(const SmallVectorImpl<MVT> & Results,const SmallVectorImpl<MVT> & Params)11618c56a07SHeejin Ahn llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
11777a7a380SDerek Schuff const SmallVectorImpl<MVT> &Params) {
1180eaee545SJonas Devlieghere auto Sig = std::make_unique<wasm::WasmSignature>();
11918c56a07SHeejin Ahn valTypesFromMVTs(Results, Sig->Returns);
12018c56a07SHeejin Ahn valTypesFromMVTs(Params, Sig->Params);
12177a7a380SDerek Schuff return Sig;
1222726b88cSDan Gohman }
12352221d56SHeejin Ahn
WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo & MFI)12452221d56SHeejin Ahn yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
1251aaa481fSHeejin Ahn const llvm::WebAssemblyFunctionInfo &MFI)
12651fb5bf4SHeejin Ahn : CFGStackified(MFI.isCFGStackified()) {
12751fb5bf4SHeejin Ahn auto *EHInfo = MFI.getWasmEHFuncInfo();
12851fb5bf4SHeejin Ahn const llvm::MachineFunction &MF = MFI.getMachineFunction();
129b3e88ccbSHeejin Ahn
130b3e88ccbSHeejin Ahn for (auto VT : MFI.getParams())
131b3e88ccbSHeejin Ahn Params.push_back(EVT(VT).getEVTString());
132b3e88ccbSHeejin Ahn for (auto VT : MFI.getResults())
133b3e88ccbSHeejin Ahn Results.push_back(EVT(VT).getEVTString());
134b3e88ccbSHeejin Ahn
13551fb5bf4SHeejin Ahn // MFI.getWasmEHFuncInfo() is non-null only for functions with the
13651fb5bf4SHeejin Ahn // personality function.
13751fb5bf4SHeejin Ahn if (EHInfo) {
13851fb5bf4SHeejin Ahn // SrcToUnwindDest can contain stale mappings in case BBs are removed in
13951fb5bf4SHeejin Ahn // optimizations, in case, for example, they are unreachable. We should not
14051fb5bf4SHeejin Ahn // include their info.
14151fb5bf4SHeejin Ahn SmallPtrSet<const MachineBasicBlock *, 16> MBBs;
14251fb5bf4SHeejin Ahn for (const auto &MBB : MF)
14351fb5bf4SHeejin Ahn MBBs.insert(&MBB);
14451fb5bf4SHeejin Ahn for (auto KV : EHInfo->SrcToUnwindDest) {
14551fb5bf4SHeejin Ahn auto *SrcBB = KV.first.get<MachineBasicBlock *>();
14651fb5bf4SHeejin Ahn auto *DestBB = KV.second.get<MachineBasicBlock *>();
14751fb5bf4SHeejin Ahn if (MBBs.count(SrcBB) && MBBs.count(DestBB))
14851fb5bf4SHeejin Ahn SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber();
14951fb5bf4SHeejin Ahn }
15051fb5bf4SHeejin Ahn }
15151fb5bf4SHeejin Ahn }
15252221d56SHeejin Ahn
mappingImpl(yaml::IO & YamlIO)15352221d56SHeejin Ahn void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
15452221d56SHeejin Ahn MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
15552221d56SHeejin Ahn }
15652221d56SHeejin Ahn
initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo & YamlMFI)15752221d56SHeejin Ahn void WebAssemblyFunctionInfo::initializeBaseYamlFields(
1581aaa481fSHeejin Ahn const yaml::WebAssemblyFunctionInfo &YamlMFI) {
1591aaa481fSHeejin Ahn CFGStackified = YamlMFI.CFGStackified;
160b3e88ccbSHeejin Ahn for (auto VT : YamlMFI.Params)
161b3e88ccbSHeejin Ahn addParam(WebAssembly::parseMVT(VT.Value));
162b3e88ccbSHeejin Ahn for (auto VT : YamlMFI.Results)
163b3e88ccbSHeejin Ahn addResult(WebAssembly::parseMVT(VT.Value));
16451fb5bf4SHeejin Ahn if (WasmEHInfo) {
16551fb5bf4SHeejin Ahn for (auto KV : YamlMFI.SrcToUnwindDest)
166*cc5a1b3dSMatt Arsenault WasmEHInfo->setUnwindDest(MF->getBlockNumbered(KV.first),
167*cc5a1b3dSMatt Arsenault MF->getBlockNumbered(KV.second));
16851fb5bf4SHeejin Ahn }
1691aaa481fSHeejin Ahn }
170