aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h235
1 files changed, 235 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
new file mode 100644
index 000000000000..413d0d1dc554
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h
@@ -0,0 +1,235 @@
+// 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 {
+ const MachineFunction &MF;
+
+ 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;
+
+ // Catchpad unwind destination info for wasm EH.
+ WasmEHFuncInfo *WasmEHInfo = nullptr;
+
+public:
+ explicit WebAssemblyFunctionInfo(MachineFunction &MF)
+ : MF(MF), WasmEHInfo(MF.getWasmEHFuncInfo()) {}
+ ~WebAssemblyFunctionInfo() override;
+
+ const MachineFunction &getMachineFunction() const { return MF; }
+
+ void initializeBaseYamlFields(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; }
+
+ WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; }
+ void setWasmEHFuncInfo(WasmEHFuncInfo *Info) { WasmEHInfo = Info; }
+};
+
+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::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