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"
16*b3e88ccbSHeejin 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 
3318c56a07SHeejin Ahn void llvm::computeLegalValueVTs(const Function &F, const TargetMachine &TM,
342726b88cSDan Gohman                                 Type *Ty, SmallVectorImpl<MVT> &ValueVTs) {
352726b88cSDan Gohman   const DataLayout &DL(F.getParent()->getDataLayout());
362726b88cSDan Gohman   const WebAssemblyTargetLowering &TLI =
372726b88cSDan Gohman       *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
382726b88cSDan Gohman   SmallVector<EVT, 4> VTs;
392726b88cSDan Gohman   ComputeValueVTs(TLI, DL, Ty, VTs);
402726b88cSDan Gohman 
412726b88cSDan Gohman   for (EVT VT : VTs) {
422726b88cSDan Gohman     unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
432726b88cSDan Gohman     MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
4418c56a07SHeejin Ahn     for (unsigned I = 0; I != NumRegs; ++I)
452726b88cSDan Gohman       ValueVTs.push_back(RegisterVT);
462726b88cSDan Gohman   }
472726b88cSDan Gohman }
482726b88cSDan Gohman 
4908670d43SYuta Saito void llvm::computeSignatureVTs(const FunctionType *Ty,
5008670d43SYuta Saito                                const Function *TargetFunc,
5108670d43SYuta Saito                                const Function &ContextFunc,
5277a7a380SDerek Schuff                                const TargetMachine &TM,
532726b88cSDan Gohman                                SmallVectorImpl<MVT> &Params,
542726b88cSDan Gohman                                SmallVectorImpl<MVT> &Results) {
5508670d43SYuta Saito   computeLegalValueVTs(ContextFunc, TM, Ty->getReturnType(), Results);
562726b88cSDan Gohman 
5777a7a380SDerek Schuff   MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
5800f9e5aaSThomas Lively   if (Results.size() > 1 &&
5908670d43SYuta Saito       !TM.getSubtarget<WebAssemblySubtarget>(ContextFunc).hasMultivalue()) {
6000f9e5aaSThomas Lively     // WebAssembly can't lower returns of multiple values without demoting to
6100f9e5aaSThomas Lively     // sret unless multivalue is enabled (see
6200f9e5aaSThomas Lively     // WebAssemblyTargetLowering::CanLowerReturn). So replace multiple return
6300f9e5aaSThomas Lively     // values with a poitner parameter.
642726b88cSDan Gohman     Results.clear();
6577a7a380SDerek Schuff     Params.push_back(PtrVT);
662726b88cSDan Gohman   }
672726b88cSDan Gohman 
6877a7a380SDerek Schuff   for (auto *Param : Ty->params())
6908670d43SYuta Saito     computeLegalValueVTs(ContextFunc, TM, Param, Params);
7077a7a380SDerek Schuff   if (Ty->isVarArg())
7177a7a380SDerek Schuff     Params.push_back(PtrVT);
7208670d43SYuta Saito 
7308670d43SYuta Saito   // For swiftcc, emit additional swiftself and swifterror parameters
7408670d43SYuta Saito   // if there aren't. These additional parameters are also passed for caller.
7508670d43SYuta Saito   // They are necessary to match callee and caller signature for indirect
7608670d43SYuta Saito   // call.
7708670d43SYuta Saito 
7808670d43SYuta Saito   if (TargetFunc && TargetFunc->getCallingConv() == CallingConv::Swift) {
7908670d43SYuta Saito     MVT PtrVT = MVT::getIntegerVT(TM.createDataLayout().getPointerSizeInBits());
8008670d43SYuta Saito     bool HasSwiftErrorArg = false;
8108670d43SYuta Saito     bool HasSwiftSelfArg = false;
8208670d43SYuta Saito     for (const auto &Arg : TargetFunc->args()) {
8308670d43SYuta Saito       HasSwiftErrorArg |= Arg.hasAttribute(Attribute::SwiftError);
8408670d43SYuta Saito       HasSwiftSelfArg |= Arg.hasAttribute(Attribute::SwiftSelf);
8508670d43SYuta Saito     }
8608670d43SYuta Saito     if (!HasSwiftErrorArg)
8708670d43SYuta Saito       Params.push_back(PtrVT);
8808670d43SYuta Saito     if (!HasSwiftSelfArg)
8908670d43SYuta Saito       Params.push_back(PtrVT);
9008670d43SYuta Saito   }
9177a7a380SDerek Schuff }
9277a7a380SDerek Schuff 
9318c56a07SHeejin Ahn void llvm::valTypesFromMVTs(const ArrayRef<MVT> &In,
9449482f82SWouter van Oortmerssen                             SmallVectorImpl<wasm::ValType> &Out) {
9549482f82SWouter van Oortmerssen   for (MVT Ty : In)
9649482f82SWouter van Oortmerssen     Out.push_back(WebAssembly::toValType(Ty));
9749482f82SWouter van Oortmerssen }
9849482f82SWouter van Oortmerssen 
9977a7a380SDerek Schuff std::unique_ptr<wasm::WasmSignature>
10018c56a07SHeejin Ahn llvm::signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
10177a7a380SDerek Schuff                         const SmallVectorImpl<MVT> &Params) {
1020eaee545SJonas Devlieghere   auto Sig = std::make_unique<wasm::WasmSignature>();
10318c56a07SHeejin Ahn   valTypesFromMVTs(Results, Sig->Returns);
10418c56a07SHeejin Ahn   valTypesFromMVTs(Params, Sig->Params);
10577a7a380SDerek Schuff   return Sig;
1062726b88cSDan Gohman }
10752221d56SHeejin Ahn 
10852221d56SHeejin Ahn yaml::WebAssemblyFunctionInfo::WebAssemblyFunctionInfo(
1091aaa481fSHeejin Ahn     const llvm::WebAssemblyFunctionInfo &MFI)
11051fb5bf4SHeejin Ahn     : CFGStackified(MFI.isCFGStackified()) {
11151fb5bf4SHeejin Ahn   auto *EHInfo = MFI.getWasmEHFuncInfo();
11251fb5bf4SHeejin Ahn   const llvm::MachineFunction &MF = MFI.getMachineFunction();
113*b3e88ccbSHeejin Ahn 
114*b3e88ccbSHeejin Ahn   for (auto VT : MFI.getParams())
115*b3e88ccbSHeejin Ahn     Params.push_back(EVT(VT).getEVTString());
116*b3e88ccbSHeejin Ahn   for (auto VT : MFI.getResults())
117*b3e88ccbSHeejin Ahn     Results.push_back(EVT(VT).getEVTString());
118*b3e88ccbSHeejin Ahn 
11951fb5bf4SHeejin Ahn   //  MFI.getWasmEHFuncInfo() is non-null only for functions with the
12051fb5bf4SHeejin Ahn   //  personality function.
12151fb5bf4SHeejin Ahn   if (EHInfo) {
12251fb5bf4SHeejin Ahn     // SrcToUnwindDest can contain stale mappings in case BBs are removed in
12351fb5bf4SHeejin Ahn     // optimizations, in case, for example, they are unreachable. We should not
12451fb5bf4SHeejin Ahn     // include their info.
12551fb5bf4SHeejin Ahn     SmallPtrSet<const MachineBasicBlock *, 16> MBBs;
12651fb5bf4SHeejin Ahn     for (const auto &MBB : MF)
12751fb5bf4SHeejin Ahn       MBBs.insert(&MBB);
12851fb5bf4SHeejin Ahn     for (auto KV : EHInfo->SrcToUnwindDest) {
12951fb5bf4SHeejin Ahn       auto *SrcBB = KV.first.get<MachineBasicBlock *>();
13051fb5bf4SHeejin Ahn       auto *DestBB = KV.second.get<MachineBasicBlock *>();
13151fb5bf4SHeejin Ahn       if (MBBs.count(SrcBB) && MBBs.count(DestBB))
13251fb5bf4SHeejin Ahn         SrcToUnwindDest[SrcBB->getNumber()] = DestBB->getNumber();
13351fb5bf4SHeejin Ahn     }
13451fb5bf4SHeejin Ahn   }
13551fb5bf4SHeejin Ahn }
13652221d56SHeejin Ahn 
13752221d56SHeejin Ahn void yaml::WebAssemblyFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
13852221d56SHeejin Ahn   MappingTraits<WebAssemblyFunctionInfo>::mapping(YamlIO, *this);
13952221d56SHeejin Ahn }
14052221d56SHeejin Ahn 
14152221d56SHeejin Ahn void WebAssemblyFunctionInfo::initializeBaseYamlFields(
1421aaa481fSHeejin Ahn     const yaml::WebAssemblyFunctionInfo &YamlMFI) {
1431aaa481fSHeejin Ahn   CFGStackified = YamlMFI.CFGStackified;
144*b3e88ccbSHeejin Ahn   for (auto VT : YamlMFI.Params)
145*b3e88ccbSHeejin Ahn     addParam(WebAssembly::parseMVT(VT.Value));
146*b3e88ccbSHeejin Ahn   for (auto VT : YamlMFI.Results)
147*b3e88ccbSHeejin Ahn     addResult(WebAssembly::parseMVT(VT.Value));
14851fb5bf4SHeejin Ahn   if (WasmEHInfo) {
14951fb5bf4SHeejin Ahn     for (auto KV : YamlMFI.SrcToUnwindDest)
15051fb5bf4SHeejin Ahn       WasmEHInfo->setUnwindDest(MF.getBlockNumbered(KV.first),
15151fb5bf4SHeejin Ahn                                 MF.getBlockNumbered(KV.second));
15251fb5bf4SHeejin Ahn   }
1531aaa481fSHeejin Ahn }
154