1296417Sdim// WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*- 2285163Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6285163Sdim// 7285163Sdim//===----------------------------------------------------------------------===// 8285163Sdim/// 9285163Sdim/// \file 10341825Sdim/// This file declares WebAssembly-specific per-machine-function 11285163Sdim/// information. 12285163Sdim/// 13285163Sdim//===----------------------------------------------------------------------===// 14285163Sdim 15285163Sdim#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 16285163Sdim#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H 17285163Sdim 18296417Sdim#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 19344779Sdim#include "llvm/BinaryFormat/Wasm.h" 20353358Sdim#include "llvm/CodeGen/MIRYamlMapping.h" 21285163Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 22344779Sdim#include "llvm/MC/MCSymbolWasm.h" 23285163Sdim 24285163Sdimnamespace llvm { 25285163Sdim 26353358Sdimnamespace yaml { 27353358Sdimstruct WebAssemblyFunctionInfo; 28353358Sdim} 29353358Sdim 30285163Sdim/// This class is derived from MachineFunctionInfo and contains private 31285163Sdim/// WebAssembly-specific information for each MachineFunction. 32285163Sdimclass WebAssemblyFunctionInfo final : public MachineFunctionInfo { 33285163Sdim MachineFunction &MF; 34285163Sdim 35296417Sdim std::vector<MVT> Params; 36314564Sdim std::vector<MVT> Results; 37314564Sdim std::vector<MVT> Locals; 38296417Sdim 39296417Sdim /// A mapping from CodeGen vreg index to WebAssembly register number. 40296417Sdim std::vector<unsigned> WARegs; 41296417Sdim 42296417Sdim /// A mapping from CodeGen vreg index to a boolean value indicating whether 43296417Sdim /// the given register is considered to be "stackified", meaning it has been 44296417Sdim /// determined or made to meet the stack requirements: 45296417Sdim /// - single use (per path) 46296417Sdim /// - single def (per path) 47296417Sdim /// - defined and used in LIFO order with other stack registers 48296417Sdim BitVector VRegStackified; 49296417Sdim 50309124Sdim // A virtual register holding the pointer to the vararg buffer for vararg 51309124Sdim // functions. It is created and set in TLI::LowerFormalArguments and read by 52309124Sdim // TLI::LowerVASTART 53309124Sdim unsigned VarargVreg = -1U; 54296417Sdim 55314564Sdim // A virtual register holding the base pointer for functions that have 56314564Sdim // overaligned values on the user stack. 57314564Sdim unsigned BasePtrVreg = -1U; 58314564Sdim 59353358Sdim // Function properties. 60353358Sdim bool CFGStackified = false; 61353358Sdim 62344779Sdimpublic: 63309124Sdim explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {} 64285163Sdim ~WebAssemblyFunctionInfo() override; 65353358Sdim void initializeBaseYamlFields(const yaml::WebAssemblyFunctionInfo &YamlMFI); 66296417Sdim 67296417Sdim void addParam(MVT VT) { Params.push_back(VT); } 68296417Sdim const std::vector<MVT> &getParams() const { return Params; } 69296417Sdim 70314564Sdim void addResult(MVT VT) { Results.push_back(VT); } 71314564Sdim const std::vector<MVT> &getResults() const { return Results; } 72314564Sdim 73344779Sdim void clearParamsAndResults() { 74344779Sdim Params.clear(); 75344779Sdim Results.clear(); 76344779Sdim } 77341825Sdim 78321369Sdim void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } 79321369Sdim void setLocal(size_t i, MVT VT) { Locals[i] = VT; } 80314564Sdim void addLocal(MVT VT) { Locals.push_back(VT); } 81314564Sdim const std::vector<MVT> &getLocals() const { return Locals; } 82314564Sdim 83309124Sdim unsigned getVarargBufferVreg() const { 84309124Sdim assert(VarargVreg != -1U && "Vararg vreg hasn't been set"); 85309124Sdim return VarargVreg; 86309124Sdim } 87309124Sdim void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; } 88309124Sdim 89314564Sdim unsigned getBasePointerVreg() const { 90314564Sdim assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set"); 91314564Sdim return BasePtrVreg; 92314564Sdim } 93314564Sdim void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; } 94314564Sdim 95296417Sdim static const unsigned UnusedReg = -1u; 96296417Sdim 97296417Sdim void stackifyVReg(unsigned VReg) { 98314564Sdim assert(MF.getRegInfo().getUniqueVRegDef(VReg)); 99360784Sdim auto I = Register::virtReg2Index(VReg); 100341825Sdim if (I >= VRegStackified.size()) 101341825Sdim VRegStackified.resize(I + 1); 102341825Sdim VRegStackified.set(I); 103296417Sdim } 104360784Sdim void unstackifyVReg(unsigned VReg) { 105360784Sdim auto I = Register::virtReg2Index(VReg); 106360784Sdim if (I < VRegStackified.size()) 107360784Sdim VRegStackified.reset(I); 108360784Sdim } 109296417Sdim bool isVRegStackified(unsigned VReg) const { 110360784Sdim auto I = Register::virtReg2Index(VReg); 111341825Sdim if (I >= VRegStackified.size()) 112296417Sdim return false; 113341825Sdim return VRegStackified.test(I); 114296417Sdim } 115296417Sdim 116296417Sdim void initWARegs(); 117296417Sdim void setWAReg(unsigned VReg, unsigned WAReg) { 118296417Sdim assert(WAReg != UnusedReg); 119360784Sdim auto I = Register::virtReg2Index(VReg); 120341825Sdim assert(I < WARegs.size()); 121341825Sdim WARegs[I] = WAReg; 122296417Sdim } 123341825Sdim unsigned getWAReg(unsigned VReg) const { 124360784Sdim auto I = Register::virtReg2Index(VReg); 125341825Sdim assert(I < WARegs.size()); 126341825Sdim return WARegs[I]; 127296417Sdim } 128296417Sdim 129309124Sdim // For a given stackified WAReg, return the id number to print with push/pop. 130309124Sdim static unsigned getWARegStackId(unsigned Reg) { 131309124Sdim assert(Reg & INT32_MIN); 132309124Sdim return Reg & INT32_MAX; 133296417Sdim } 134353358Sdim 135353358Sdim bool isCFGStackified() const { return CFGStackified; } 136353358Sdim void setCFGStackified(bool Value = true) { CFGStackified = Value; } 137285163Sdim}; 138285163Sdim 139353358Sdimvoid computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty, 140344779Sdim SmallVectorImpl<MVT> &ValueVTs); 141314564Sdim 142344779Sdim// Compute the signature for a given FunctionType (Ty). Note that it's not the 143344779Sdim// signature for F (F is just used to get varous context) 144353358Sdimvoid computeSignatureVTs(const FunctionType *Ty, const Function &F, 145344779Sdim const TargetMachine &TM, SmallVectorImpl<MVT> &Params, 146314564Sdim SmallVectorImpl<MVT> &Results); 147314564Sdim 148353358Sdimvoid valTypesFromMVTs(const ArrayRef<MVT> &In, 149344779Sdim SmallVectorImpl<wasm::ValType> &Out); 150344779Sdim 151344779Sdimstd::unique_ptr<wasm::WasmSignature> 152353358SdimsignatureFromMVTs(const SmallVectorImpl<MVT> &Results, 153344779Sdim const SmallVectorImpl<MVT> &Params); 154344779Sdim 155353358Sdimnamespace yaml { 156353358Sdim 157353358Sdimstruct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo { 158353358Sdim bool CFGStackified = false; 159353358Sdim 160353358Sdim WebAssemblyFunctionInfo() = default; 161353358Sdim WebAssemblyFunctionInfo(const llvm::WebAssemblyFunctionInfo &MFI); 162353358Sdim 163353358Sdim void mappingImpl(yaml::IO &YamlIO) override; 164353358Sdim ~WebAssemblyFunctionInfo() = default; 165353358Sdim}; 166353358Sdim 167353358Sdimtemplate <> struct MappingTraits<WebAssemblyFunctionInfo> { 168353358Sdim static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) { 169353358Sdim YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false); 170353358Sdim } 171353358Sdim}; 172353358Sdim 173353358Sdim} // end namespace yaml 174353358Sdim 175285163Sdim} // end namespace llvm 176285163Sdim 177285163Sdim#endif 178