224 lines · c
1// WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file declares WebAssembly-specific per-machine-function11/// information.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H16#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H17 18#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"19#include "llvm/CodeGen/MIRYamlMapping.h"20#include "llvm/CodeGen/MachineRegisterInfo.h"21#include "llvm/MC/MCSymbolWasm.h"22 23namespace llvm {24class WebAssemblyTargetLowering;25 26struct WasmEHFuncInfo;27 28namespace yaml {29struct WebAssemblyFunctionInfo;30}31 32/// This class is derived from MachineFunctionInfo and contains private33/// WebAssembly-specific information for each MachineFunction.34class WebAssemblyFunctionInfo final : public MachineFunctionInfo {35 std::vector<MVT> Params;36 std::vector<MVT> Results;37 std::vector<MVT> Locals;38 39 /// A mapping from CodeGen vreg index to WebAssembly register number.40 std::vector<unsigned> WARegs;41 42 /// A mapping from CodeGen vreg index to a boolean value indicating whether43 /// the given register is considered to be "stackified", meaning it has been44 /// determined or made to meet the stack requirements:45 /// - single use (per path)46 /// - single def (per path)47 /// - defined and used in LIFO order with other stack registers48 BitVector VRegStackified;49 50 // A virtual register holding the pointer to the vararg buffer for vararg51 // functions. It is created and set in TLI::LowerFormalArguments and read by52 // TLI::LowerVASTART53 unsigned VarargVreg = -1U;54 55 // A virtual register holding the base pointer for functions that have56 // overaligned values on the user stack.57 unsigned BasePtrVreg = -1U;58 // A virtual register holding the frame base. This is either FP or SP59 // after it has been replaced by a vreg60 unsigned FrameBaseVreg = -1U;61 // The local holding the frame base. This is either FP or SP62 // after WebAssemblyExplicitLocals63 unsigned FrameBaseLocal = -1U;64 65 // Function properties.66 bool CFGStackified = false;67 68public:69 explicit WebAssemblyFunctionInfo(const Function &F,70 const TargetSubtargetInfo *STI) {}71 ~WebAssemblyFunctionInfo() override;72 73 MachineFunctionInfo *74 clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,75 const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)76 const override;77 78 void initializeBaseYamlFields(MachineFunction &MF,79 const yaml::WebAssemblyFunctionInfo &YamlMFI);80 81 void addParam(MVT VT) { Params.push_back(VT); }82 const std::vector<MVT> &getParams() const { return Params; }83 84 void addResult(MVT VT) { Results.push_back(VT); }85 const std::vector<MVT> &getResults() const { return Results; }86 87 void clearParamsAndResults() {88 Params.clear();89 Results.clear();90 }91 92 void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }93 void setLocal(size_t i, MVT VT) { Locals[i] = VT; }94 void addLocal(MVT VT) { Locals.push_back(VT); }95 const std::vector<MVT> &getLocals() const { return Locals; }96 97 unsigned getVarargBufferVreg() const {98 assert(VarargVreg != -1U && "Vararg vreg hasn't been set");99 return VarargVreg;100 }101 void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }102 103 unsigned getBasePointerVreg() const {104 assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set");105 return BasePtrVreg;106 }107 void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; }108 unsigned getFrameBaseVreg() const {109 assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set");110 return FrameBaseVreg;111 }112 void clearFrameBaseVreg() { FrameBaseVreg = -1U; }113 // Return true if the frame base physreg has been replaced by a virtual reg.114 bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; }115 void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; }116 unsigned getFrameBaseLocal() const {117 assert(FrameBaseLocal != -1U && "Frame base local hasn't been set");118 return FrameBaseLocal;119 }120 void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; }121 122 void stackifyVReg(MachineRegisterInfo &MRI, Register VReg) {123 assert(MRI.getUniqueVRegDef(VReg));124 auto I = VReg.virtRegIndex();125 if (I >= VRegStackified.size())126 VRegStackified.resize(I + 1);127 VRegStackified.set(I);128 }129 void unstackifyVReg(Register VReg) {130 auto I = VReg.virtRegIndex();131 if (I < VRegStackified.size())132 VRegStackified.reset(I);133 }134 bool isVRegStackified(Register VReg) const {135 auto I = VReg.virtRegIndex();136 if (I >= VRegStackified.size())137 return false;138 return VRegStackified.test(I);139 }140 141 void initWARegs(MachineRegisterInfo &MRI);142 void setWAReg(Register VReg, unsigned WAReg) {143 assert(WAReg != WebAssembly::UnusedReg);144 auto I = VReg.virtRegIndex();145 assert(I < WARegs.size());146 WARegs[I] = WAReg;147 }148 unsigned getWAReg(Register VReg) const {149 auto I = VReg.virtRegIndex();150 assert(I < WARegs.size());151 return WARegs[I];152 }153 154 bool isCFGStackified() const { return CFGStackified; }155 void setCFGStackified(bool Value = true) { CFGStackified = Value; }156};157 158void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,159 LLVMContext &Ctx, const DataLayout &DL, Type *Ty,160 SmallVectorImpl<MVT> &ValueVTs);161 162void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,163 SmallVectorImpl<MVT> &ValueVTs);164 165// Compute the signature for a given FunctionType (Ty). Note that it's not the166// signature for ContextFunc (ContextFunc is just used to get varous context)167void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc,168 const Function &ContextFunc, const TargetMachine &TM,169 SmallVectorImpl<MVT> &Params,170 SmallVectorImpl<MVT> &Results);171 172void valTypesFromMVTs(ArrayRef<MVT> In, SmallVectorImpl<wasm::ValType> &Out);173 174wasm::WasmSignature *signatureFromMVTs(MCContext &Ctx,175 const SmallVectorImpl<MVT> &Results,176 const SmallVectorImpl<MVT> &Params);177 178namespace yaml {179 180using BBNumberMap = DenseMap<int, int>;181 182struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo {183 std::vector<FlowStringValue> Params;184 std::vector<FlowStringValue> Results;185 bool CFGStackified = false;186 // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of187 // BB numbers188 BBNumberMap SrcToUnwindDest;189 190 WebAssemblyFunctionInfo() = default;191 WebAssemblyFunctionInfo(const llvm::MachineFunction &MF,192 const llvm::WebAssemblyFunctionInfo &MFI);193 194 void mappingImpl(yaml::IO &YamlIO) override;195 ~WebAssemblyFunctionInfo() override = default;196};197 198template <> struct MappingTraits<WebAssemblyFunctionInfo> {199 static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) {200 YamlIO.mapOptional("params", MFI.Params, std::vector<FlowStringValue>());201 YamlIO.mapOptional("results", MFI.Results, std::vector<FlowStringValue>());202 YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false);203 YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest);204 }205};206 207template <> struct CustomMappingTraits<BBNumberMap> {208 static void inputOne(IO &YamlIO, StringRef Key,209 BBNumberMap &SrcToUnwindDest) {210 YamlIO.mapRequired(Key, SrcToUnwindDest[std::atoi(Key.str().c_str())]);211 }212 213 static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) {214 for (auto [Src, Dest] : SrcToUnwindDest)215 YamlIO.mapRequired(std::to_string(Src), Dest);216 }217};218 219} // end namespace yaml220 221} // end namespace llvm222 223#endif224