1c3890d29SNick Lewycky // WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*- 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 declares WebAssembly-specific per-machine-function 1110e730a2SDan Gohman /// information. 1210e730a2SDan Gohman /// 1310e730a2SDan Gohman //===----------------------------------------------------------------------===// 1410e730a2SDan Gohman 1510e730a2SDan Gohman #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 1610e730a2SDan Gohman #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 1710e730a2SDan Gohman 189769debfSDerek Schuff #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 1952221d56SHeejin Ahn #include "llvm/CodeGen/MIRYamlMapping.h" 2010e730a2SDan Gohman #include "llvm/CodeGen/MachineRegisterInfo.h" 2177a7a380SDerek Schuff #include "llvm/MC/MCSymbolWasm.h" 2210e730a2SDan Gohman 2310e730a2SDan Gohman namespace llvm { 2410e730a2SDan Gohman 250b2bc69bSHeejin Ahn struct WasmEHFuncInfo; 260b2bc69bSHeejin Ahn 2752221d56SHeejin Ahn namespace yaml { 2852221d56SHeejin Ahn struct WebAssemblyFunctionInfo; 2952221d56SHeejin Ahn } 3052221d56SHeejin Ahn 3110e730a2SDan Gohman /// This class is derived from MachineFunctionInfo and contains private 3210e730a2SDan Gohman /// WebAssembly-specific information for each MachineFunction. 3310e730a2SDan Gohman class WebAssemblyFunctionInfo final : public MachineFunctionInfo { 34*cc5a1b3dSMatt Arsenault const MachineFunction *MF; 3551fb5bf4SHeejin Ahn 36754cd11dSDan Gohman std::vector<MVT> Params; 372726b88cSDan Gohman std::vector<MVT> Results; 383acb187dSDan Gohman std::vector<MVT> Locals; 39e51c058eSDan Gohman 40cf4748f1SDan Gohman /// A mapping from CodeGen vreg index to WebAssembly register number. 41cf4748f1SDan Gohman std::vector<unsigned> WARegs; 42cf4748f1SDan Gohman 431462faadSDan Gohman /// A mapping from CodeGen vreg index to a boolean value indicating whether 441462faadSDan Gohman /// the given register is considered to be "stackified", meaning it has been 451462faadSDan Gohman /// determined or made to meet the stack requirements: 461462faadSDan Gohman /// - single use (per path) 471462faadSDan Gohman /// - single def (per path) 4853d13997SDan Gohman /// - defined and used in LIFO order with other stack registers 491462faadSDan Gohman BitVector VRegStackified; 501462faadSDan Gohman 5127501e20SDerek Schuff // A virtual register holding the pointer to the vararg buffer for vararg 5227501e20SDerek Schuff // functions. It is created and set in TLI::LowerFormalArguments and read by 5327501e20SDerek Schuff // TLI::LowerVASTART 5427501e20SDerek Schuff unsigned VarargVreg = -1U; 5527501e20SDerek Schuff 560d41b7b3SDerek Schuff // A virtual register holding the base pointer for functions that have 570d41b7b3SDerek Schuff // overaligned values on the user stack. 580d41b7b3SDerek Schuff unsigned BasePtrVreg = -1U; 59ff171acfSDerek Schuff // A virtual register holding the frame base. This is either FP or SP 60ff171acfSDerek Schuff // after it has been replaced by a vreg 61ff171acfSDerek Schuff unsigned FrameBaseVreg = -1U; 62ff171acfSDerek Schuff // The local holding the frame base. This is either FP or SP 63ff171acfSDerek Schuff // after WebAssemblyExplicitLocals 64ff171acfSDerek Schuff unsigned FrameBaseLocal = -1U; 650d41b7b3SDerek Schuff 661aaa481fSHeejin Ahn // Function properties. 671aaa481fSHeejin Ahn bool CFGStackified = false; 681aaa481fSHeejin Ahn 6951fb5bf4SHeejin Ahn // Catchpad unwind destination info for wasm EH. 7051fb5bf4SHeejin Ahn WasmEHFuncInfo *WasmEHInfo = nullptr; 7151fb5bf4SHeejin Ahn 7210e730a2SDan Gohman public: WebAssemblyFunctionInfo(MachineFunction & MF_)73*cc5a1b3dSMatt Arsenault explicit WebAssemblyFunctionInfo(MachineFunction &MF_) 74*cc5a1b3dSMatt Arsenault : MF(&MF_), WasmEHInfo(MF_.getWasmEHFuncInfo()) {} 7510e730a2SDan Gohman ~WebAssemblyFunctionInfo() override; 7651fb5bf4SHeejin Ahn 77*cc5a1b3dSMatt Arsenault MachineFunctionInfo * 78*cc5a1b3dSMatt Arsenault clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF, 79*cc5a1b3dSMatt Arsenault const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) 80*cc5a1b3dSMatt Arsenault const override; 81*cc5a1b3dSMatt Arsenault getMachineFunction()82*cc5a1b3dSMatt Arsenault const MachineFunction &getMachineFunction() const { return *MF; } 8351fb5bf4SHeejin Ahn 8452221d56SHeejin Ahn void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI); 85e51c058eSDan Gohman addParam(MVT VT)86754cd11dSDan Gohman void addParam(MVT VT) { Params.push_back(VT); } getParams()87754cd11dSDan Gohman const std::vector<MVT> &getParams() const { return Params; } 88754cd11dSDan Gohman addResult(MVT VT)892726b88cSDan Gohman void addResult(MVT VT) { Results.push_back(VT); } getResults()902726b88cSDan Gohman const std::vector<MVT> &getResults() const { return Results; } 912726b88cSDan Gohman clearParamsAndResults()92f208f631SHeejin Ahn void clearParamsAndResults() { 93f208f631SHeejin Ahn Params.clear(); 94f208f631SHeejin Ahn Results.clear(); 95f208f631SHeejin Ahn } 96b8184827SDan Gohman setNumLocals(size_t NumLocals)97d934cb88SDan Gohman void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } setLocal(size_t i,MVT VT)98d934cb88SDan Gohman void setLocal(size_t i, MVT VT) { Locals[i] = VT; } addLocal(MVT VT)993acb187dSDan Gohman void addLocal(MVT VT) { Locals.push_back(VT); } getLocals()1003acb187dSDan Gohman const std::vector<MVT> &getLocals() const { return Locals; } 1013acb187dSDan Gohman getVarargBufferVreg()10227501e20SDerek Schuff unsigned getVarargBufferVreg() const { 10327501e20SDerek Schuff assert(VarargVreg != -1U && "Vararg vreg hasn't been set"); 10427501e20SDerek Schuff return VarargVreg; 10527501e20SDerek Schuff } setVarargBufferVreg(unsigned Reg)10627501e20SDerek Schuff void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; } 10727501e20SDerek Schuff getBasePointerVreg()1080d41b7b3SDerek Schuff unsigned getBasePointerVreg() const { 1090d41b7b3SDerek Schuff assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set"); 1100d41b7b3SDerek Schuff return BasePtrVreg; 1110d41b7b3SDerek Schuff } setFrameBaseVreg(unsigned Reg)112ff171acfSDerek Schuff void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; } getFrameBaseVreg()113ff171acfSDerek Schuff unsigned getFrameBaseVreg() const { 114ff171acfSDerek Schuff assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set"); 115ff171acfSDerek Schuff return FrameBaseVreg; 116ff171acfSDerek Schuff } clearFrameBaseVreg()117d966bf83SDerek Schuff void clearFrameBaseVreg() { FrameBaseVreg = -1U; } 118ff171acfSDerek Schuff // Return true if the frame base physreg has been replaced by a virtual reg. isFrameBaseVirtual()119ff171acfSDerek Schuff bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; } setFrameBaseLocal(unsigned Local)120ff171acfSDerek Schuff void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; } getFrameBaseLocal()121ff171acfSDerek Schuff unsigned getFrameBaseLocal() const { 122ff171acfSDerek Schuff assert(FrameBaseLocal != -1U && "Frame base local hasn't been set"); 123ff171acfSDerek Schuff return FrameBaseLocal; 124ff171acfSDerek Schuff } setBasePointerVreg(unsigned Reg)1250d41b7b3SDerek Schuff void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; } 1260d41b7b3SDerek Schuff 127058fce54SDan Gohman static const unsigned UnusedReg = -1u; 128058fce54SDan Gohman stackifyVReg(MachineRegisterInfo & MRI,unsigned VReg)129c5d24009SMatt Arsenault void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg) { 130c5d24009SMatt Arsenault assert(MRI.getUniqueVRegDef(VReg)); 1312bea69bfSDaniel Sanders auto I = Register::virtReg2Index(VReg); 13278c62966SWouter van Oortmerssen if (I >= VRegStackified.size()) 13378c62966SWouter van Oortmerssen VRegStackified.resize(I + 1); 13478c62966SWouter van Oortmerssen VRegStackified.set(I); 1351462faadSDan Gohman } unstackifyVReg(unsigned VReg)13661d5c76aSHeejin Ahn void unstackifyVReg(unsigned VReg) { 13761d5c76aSHeejin Ahn auto I = Register::virtReg2Index(VReg); 13861d5c76aSHeejin Ahn if (I < VRegStackified.size()) 13961d5c76aSHeejin Ahn VRegStackified.reset(I); 14061d5c76aSHeejin Ahn } isVRegStackified(unsigned VReg)1411462faadSDan Gohman bool isVRegStackified(unsigned VReg) const { 1422bea69bfSDaniel Sanders auto I = Register::virtReg2Index(VReg); 14378c62966SWouter van Oortmerssen if (I >= VRegStackified.size()) 1441462faadSDan Gohman return false; 14578c62966SWouter van Oortmerssen return VRegStackified.test(I); 1461462faadSDan Gohman } 1471462faadSDan Gohman 148c5d24009SMatt Arsenault void initWARegs(MachineRegisterInfo &MRI); setWAReg(unsigned VReg,unsigned WAReg)149cf4748f1SDan Gohman void setWAReg(unsigned VReg, unsigned WAReg) { 150058fce54SDan Gohman assert(WAReg != UnusedReg); 1512bea69bfSDaniel Sanders auto I = Register::virtReg2Index(VReg); 15278c62966SWouter van Oortmerssen assert(I < WARegs.size()); 15378c62966SWouter van Oortmerssen WARegs[I] = WAReg; 154cf4748f1SDan Gohman } getWAReg(unsigned VReg)15578c62966SWouter van Oortmerssen unsigned getWAReg(unsigned VReg) const { 1562bea69bfSDaniel Sanders auto I = Register::virtReg2Index(VReg); 15778c62966SWouter van Oortmerssen assert(I < WARegs.size()); 15878c62966SWouter van Oortmerssen return WARegs[I]; 1599769debfSDerek Schuff } 160b7c2400fSDan Gohman 161b7c2400fSDan Gohman // For a given stackified WAReg, return the id number to print with push/pop. getWARegStackId(unsigned Reg)162b7c2400fSDan Gohman static unsigned getWARegStackId(unsigned Reg) { 163b7c2400fSDan Gohman assert(Reg & INT32_MIN); 164b7c2400fSDan Gohman return Reg & INT32_MAX; 165b7c2400fSDan Gohman } 1661aaa481fSHeejin Ahn isCFGStackified()1671aaa481fSHeejin Ahn bool isCFGStackified() const { return CFGStackified; } 1681aaa481fSHeejin Ahn void setCFGStackified(bool Value = true) { CFGStackified = Value; } 16951fb5bf4SHeejin Ahn getWasmEHFuncInfo()17051fb5bf4SHeejin Ahn WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; } setWasmEHFuncInfo(WasmEHFuncInfo * Info)17151fb5bf4SHeejin Ahn void setWasmEHFuncInfo(WasmEHFuncInfo *Info) { WasmEHInfo = Info; } 17210e730a2SDan Gohman }; 17310e730a2SDan Gohman 174864767abSPaulo Matos void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI, 175864767abSPaulo Matos LLVMContext &Ctx, const DataLayout &DL, Type *Ty, 176864767abSPaulo Matos SmallVectorImpl<MVT> &ValueVTs); 177864767abSPaulo Matos 17818c56a07SHeejin Ahn void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, 179f208f631SHeejin Ahn SmallVectorImpl<MVT> &ValueVTs); 1802726b88cSDan Gohman 18177a7a380SDerek Schuff // Compute the signature for a given FunctionType (Ty). Note that it's not the 18208670d43SYuta Saito // signature for ContextFunc (ContextFunc is just used to get varous context) 18308670d43SYuta Saito void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc, 18408670d43SYuta Saito const Function &ContextFunc, const TargetMachine &TM, 18508670d43SYuta Saito SmallVectorImpl<MVT> &Params, 1862726b88cSDan Gohman SmallVectorImpl<MVT> &Results); 1872726b88cSDan Gohman 18818c56a07SHeejin Ahn void valTypesFromMVTs(const ArrayRef<MVT> &In, 18949482f82SWouter van Oortmerssen SmallVectorImpl<wasm::ValType> &Out); 19049482f82SWouter van Oortmerssen 19177a7a380SDerek Schuff std::unique_ptr<wasm::WasmSignature> 19218c56a07SHeejin Ahn signatureFromMVTs(const SmallVectorImpl<MVT> &Results, 19377a7a380SDerek Schuff const SmallVectorImpl<MVT> &Params); 19477a7a380SDerek Schuff 19552221d56SHeejin Ahn namespace yaml { 19652221d56SHeejin Ahn 19751fb5bf4SHeejin Ahn using BBNumberMap = DenseMap<int, int>; 19851fb5bf4SHeejin Ahn 19952221d56SHeejin Ahn struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { 200b3e88ccbSHeejin Ahn std::vector<FlowStringValue> Params; 201b3e88ccbSHeejin Ahn std::vector<FlowStringValue> Results; 2021aaa481fSHeejin Ahn bool CFGStackified = false; 20351fb5bf4SHeejin Ahn // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of 20451fb5bf4SHeejin Ahn // BB numbers 20551fb5bf4SHeejin Ahn BBNumberMap SrcToUnwindDest; 2061aaa481fSHeejin Ahn 20752221d56SHeejin Ahn WebAssemblyFunctionInfo() = default; 20852221d56SHeejin Ahn WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI); 20952221d56SHeejin Ahn 21052221d56SHeejin Ahn void mappingImpl(yaml::IO &YamlIO) override; 21152221d56SHeejin Ahn ~WebAssemblyFunctionInfo() = default; 21252221d56SHeejin Ahn }; 21352221d56SHeejin Ahn 21452221d56SHeejin Ahn template <> struct MappingTraits<WebAssemblyFunctionInfo> { 2151aaa481fSHeejin Ahn static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { 216b3e88ccbSHeejin Ahn YamlIO.mapOptional("params", MFI.Params, std::vector<FlowStringValue>()); 217b3e88ccbSHeejin Ahn YamlIO.mapOptional("results", MFI.Results, std::vector<FlowStringValue>()); 2181aaa481fSHeejin Ahn YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); 21951fb5bf4SHeejin Ahn YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest); 22051fb5bf4SHeejin Ahn } 22151fb5bf4SHeejin Ahn }; 22251fb5bf4SHeejin Ahn 22351fb5bf4SHeejin Ahn template <> struct CustomMappingTraits<BBNumberMap> { 22451fb5bf4SHeejin Ahn static void inputOne(IO &YamlIO, StringRef Key, 22551fb5bf4SHeejin Ahn BBNumberMap &SrcToUnwindDest) { 22651fb5bf4SHeejin Ahn YamlIO.mapRequired(Key.str().c_str(), 22751fb5bf4SHeejin Ahn SrcToUnwindDest[std::atoi(Key.str().c_str())]); 22851fb5bf4SHeejin Ahn } 22951fb5bf4SHeejin Ahn 23051fb5bf4SHeejin Ahn static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) { 23151fb5bf4SHeejin Ahn for (auto KV : SrcToUnwindDest) 23251fb5bf4SHeejin Ahn YamlIO.mapRequired(std::to_string(KV.first).c_str(), KV.second); 2331aaa481fSHeejin Ahn } 23452221d56SHeejin Ahn }; 23552221d56SHeejin Ahn 23652221d56SHeejin Ahn } // end namespace yaml 23752221d56SHeejin Ahn 23810e730a2SDan Gohman } // end namespace llvm 23910e730a2SDan Gohman 24010e730a2SDan Gohman #endif 241