123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- // WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// This file declares WebAssembly-specific per-machine-function
- /// information.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
- #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
- #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
- #include "llvm/CodeGen/MIRYamlMapping.h"
- #include "llvm/CodeGen/MachineRegisterInfo.h"
- #include "llvm/MC/MCSymbolWasm.h"
- namespace llvm {
- struct WasmEHFuncInfo;
- namespace yaml {
- struct WebAssemblyFunctionInfo;
- }
- /// This class is derived from MachineFunctionInfo and contains private
- /// WebAssembly-specific information for each MachineFunction.
- class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
- std::vector<MVT> Params;
- std::vector<MVT> Results;
- std::vector<MVT> Locals;
- /// A mapping from CodeGen vreg index to WebAssembly register number.
- std::vector<unsigned> WARegs;
- /// A mapping from CodeGen vreg index to a boolean value indicating whether
- /// the given register is considered to be "stackified", meaning it has been
- /// determined or made to meet the stack requirements:
- /// - single use (per path)
- /// - single def (per path)
- /// - defined and used in LIFO order with other stack registers
- BitVector VRegStackified;
- // A virtual register holding the pointer to the vararg buffer for vararg
- // functions. It is created and set in TLI::LowerFormalArguments and read by
- // TLI::LowerVASTART
- unsigned VarargVreg = -1U;
- // A virtual register holding the base pointer for functions that have
- // overaligned values on the user stack.
- unsigned BasePtrVreg = -1U;
- // A virtual register holding the frame base. This is either FP or SP
- // after it has been replaced by a vreg
- unsigned FrameBaseVreg = -1U;
- // The local holding the frame base. This is either FP or SP
- // after WebAssemblyExplicitLocals
- unsigned FrameBaseLocal = -1U;
- // Function properties.
- bool CFGStackified = false;
- public:
- explicit WebAssemblyFunctionInfo(const Function &F,
- const TargetSubtargetInfo *STI) {}
- ~WebAssemblyFunctionInfo() override;
- MachineFunctionInfo *
- clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
- const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
- const override;
- void initializeBaseYamlFields(MachineFunction &MF,
- const yaml::WebAssemblyFunctionInfo &YamlMFI);
- void addParam(MVT VT) { Params.push_back(VT); }
- const std::vector<MVT> &getParams() const { return Params; }
- void addResult(MVT VT) { Results.push_back(VT); }
- const std::vector<MVT> &getResults() const { return Results; }
- void clearParamsAndResults() {
- Params.clear();
- Results.clear();
- }
- void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }
- void setLocal(size_t i, MVT VT) { Locals[i] = VT; }
- void addLocal(MVT VT) { Locals.push_back(VT); }
- const std::vector<MVT> &getLocals() const { return Locals; }
- unsigned getVarargBufferVreg() const {
- assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
- return VarargVreg;
- }
- void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }
- unsigned getBasePointerVreg() const {
- assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set");
- return BasePtrVreg;
- }
- void setFrameBaseVreg(unsigned Reg) { FrameBaseVreg = Reg; }
- unsigned getFrameBaseVreg() const {
- assert(FrameBaseVreg != -1U && "Frame base vreg hasn't been set");
- return FrameBaseVreg;
- }
- void clearFrameBaseVreg() { FrameBaseVreg = -1U; }
- // Return true if the frame base physreg has been replaced by a virtual reg.
- bool isFrameBaseVirtual() const { return FrameBaseVreg != -1U; }
- void setFrameBaseLocal(unsigned Local) { FrameBaseLocal = Local; }
- unsigned getFrameBaseLocal() const {
- assert(FrameBaseLocal != -1U && "Frame base local hasn't been set");
- return FrameBaseLocal;
- }
- void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; }
- static const unsigned UnusedReg = -1u;
- void stackifyVReg(MachineRegisterInfo &MRI, unsigned VReg) {
- assert(MRI.getUniqueVRegDef(VReg));
- auto I = Register::virtReg2Index(VReg);
- if (I >= VRegStackified.size())
- VRegStackified.resize(I + 1);
- VRegStackified.set(I);
- }
- void unstackifyVReg(unsigned VReg) {
- auto I = Register::virtReg2Index(VReg);
- if (I < VRegStackified.size())
- VRegStackified.reset(I);
- }
- bool isVRegStackified(unsigned VReg) const {
- auto I = Register::virtReg2Index(VReg);
- if (I >= VRegStackified.size())
- return false;
- return VRegStackified.test(I);
- }
- void initWARegs(MachineRegisterInfo &MRI);
- void setWAReg(unsigned VReg, unsigned WAReg) {
- assert(WAReg != UnusedReg);
- auto I = Register::virtReg2Index(VReg);
- assert(I < WARegs.size());
- WARegs[I] = WAReg;
- }
- unsigned getWAReg(unsigned VReg) const {
- auto I = Register::virtReg2Index(VReg);
- assert(I < WARegs.size());
- return WARegs[I];
- }
- // For a given stackified WAReg, return the id number to print with push/pop.
- static unsigned getWARegStackId(unsigned Reg) {
- assert(Reg & INT32_MIN);
- return Reg & INT32_MAX;
- }
- bool isCFGStackified() const { return CFGStackified; }
- void setCFGStackified(bool Value = true) { CFGStackified = Value; }
- };
- void computeLegalValueVTs(const WebAssemblyTargetLowering &TLI,
- LLVMContext &Ctx, const DataLayout &DL, Type *Ty,
- SmallVectorImpl<MVT> &ValueVTs);
- void computeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
- SmallVectorImpl<MVT> &ValueVTs);
- // Compute the signature for a given FunctionType (Ty). Note that it's not the
- // signature for ContextFunc (ContextFunc is just used to get varous context)
- void computeSignatureVTs(const FunctionType *Ty, const Function *TargetFunc,
- const Function &ContextFunc, const TargetMachine &TM,
- SmallVectorImpl<MVT> &Params,
- SmallVectorImpl<MVT> &Results);
- void valTypesFromMVTs(const ArrayRef<MVT> &In,
- SmallVectorImpl<wasm::ValType> &Out);
- std::unique_ptr<wasm::WasmSignature>
- signatureFromMVTs(const SmallVectorImpl<MVT> &Results,
- const SmallVectorImpl<MVT> &Params);
- namespace yaml {
- using BBNumberMap = DenseMap<int, int>;
- struct WebAssemblyFunctionInfo final : public yaml::MachineFunctionInfo {
- std::vector<FlowStringValue> Params;
- std::vector<FlowStringValue> Results;
- bool CFGStackified = false;
- // The same as WasmEHFuncInfo's SrcToUnwindDest, but stored in the mapping of
- // BB numbers
- BBNumberMap SrcToUnwindDest;
- WebAssemblyFunctionInfo() = default;
- WebAssemblyFunctionInfo(const llvm::MachineFunction &MF,
- const llvm::WebAssemblyFunctionInfo &MFI);
- void mappingImpl(yaml::IO &YamlIO) override;
- ~WebAssemblyFunctionInfo() = default;
- };
- template <> struct MappingTraits<WebAssemblyFunctionInfo> {
- static void mapping(IO &YamlIO, WebAssemblyFunctionInfo &MFI) {
- YamlIO.mapOptional("params", MFI.Params, std::vector<FlowStringValue>());
- YamlIO.mapOptional("results", MFI.Results, std::vector<FlowStringValue>());
- YamlIO.mapOptional("isCFGStackified", MFI.CFGStackified, false);
- YamlIO.mapOptional("wasmEHFuncInfo", MFI.SrcToUnwindDest);
- }
- };
- template <> struct CustomMappingTraits<BBNumberMap> {
- static void inputOne(IO &YamlIO, StringRef Key,
- BBNumberMap &SrcToUnwindDest) {
- YamlIO.mapRequired(Key.str().c_str(),
- SrcToUnwindDest[std::atoi(Key.str().c_str())]);
- }
- static void output(IO &YamlIO, BBNumberMap &SrcToUnwindDest) {
- for (auto KV : SrcToUnwindDest)
- YamlIO.mapRequired(std::to_string(KV.first).c_str(), KV.second);
- }
- };
- } // end namespace yaml
- } // end namespace llvm
- #endif
|