WebAssemblyMachineFunctionInfo.h revision 344779
1// WebAssemblyMachineFunctionInfo.h-WebAssembly machine function info-*- C++ -*-
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// This file declares WebAssembly-specific per-machine-function
12/// information.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
17#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYMACHINEFUNCTIONINFO_H
18
19#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
20#include "llvm/BinaryFormat/Wasm.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/MC/MCSymbolWasm.h"
23
24namespace llvm {
25
26/// This class is derived from MachineFunctionInfo and contains private
27/// WebAssembly-specific information for each MachineFunction.
28class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
29  MachineFunction &MF;
30
31  std::vector<MVT> Params;
32  std::vector<MVT> Results;
33  std::vector<MVT> Locals;
34
35  /// A mapping from CodeGen vreg index to WebAssembly register number.
36  std::vector<unsigned> WARegs;
37
38  /// A mapping from CodeGen vreg index to a boolean value indicating whether
39  /// the given register is considered to be "stackified", meaning it has been
40  /// determined or made to meet the stack requirements:
41  ///   - single use (per path)
42  ///   - single def (per path)
43  ///   - defined and used in LIFO order with other stack registers
44  BitVector VRegStackified;
45
46  // A virtual register holding the pointer to the vararg buffer for vararg
47  // functions. It is created and set in TLI::LowerFormalArguments and read by
48  // TLI::LowerVASTART
49  unsigned VarargVreg = -1U;
50
51  // A virtual register holding the base pointer for functions that have
52  // overaligned values on the user stack.
53  unsigned BasePtrVreg = -1U;
54
55public:
56  explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {}
57  ~WebAssemblyFunctionInfo() override;
58
59  void addParam(MVT VT) { Params.push_back(VT); }
60  const std::vector<MVT> &getParams() const { return Params; }
61
62  void addResult(MVT VT) { Results.push_back(VT); }
63  const std::vector<MVT> &getResults() const { return Results; }
64
65  void clearParamsAndResults() {
66    Params.clear();
67    Results.clear();
68  }
69
70  void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); }
71  void setLocal(size_t i, MVT VT) { Locals[i] = VT; }
72  void addLocal(MVT VT) { Locals.push_back(VT); }
73  const std::vector<MVT> &getLocals() const { return Locals; }
74
75  unsigned getVarargBufferVreg() const {
76    assert(VarargVreg != -1U && "Vararg vreg hasn't been set");
77    return VarargVreg;
78  }
79  void setVarargBufferVreg(unsigned Reg) { VarargVreg = Reg; }
80
81  unsigned getBasePointerVreg() const {
82    assert(BasePtrVreg != -1U && "Base ptr vreg hasn't been set");
83    return BasePtrVreg;
84  }
85  void setBasePointerVreg(unsigned Reg) { BasePtrVreg = Reg; }
86
87  static const unsigned UnusedReg = -1u;
88
89  void stackifyVReg(unsigned VReg) {
90    assert(MF.getRegInfo().getUniqueVRegDef(VReg));
91    auto I = TargetRegisterInfo::virtReg2Index(VReg);
92    if (I >= VRegStackified.size())
93      VRegStackified.resize(I + 1);
94    VRegStackified.set(I);
95  }
96  bool isVRegStackified(unsigned VReg) const {
97    auto I = TargetRegisterInfo::virtReg2Index(VReg);
98    if (I >= VRegStackified.size())
99      return false;
100    return VRegStackified.test(I);
101  }
102
103  void initWARegs();
104  void setWAReg(unsigned VReg, unsigned WAReg) {
105    assert(WAReg != UnusedReg);
106    auto I = TargetRegisterInfo::virtReg2Index(VReg);
107    assert(I < WARegs.size());
108    WARegs[I] = WAReg;
109  }
110  unsigned getWAReg(unsigned VReg) const {
111    auto I = TargetRegisterInfo::virtReg2Index(VReg);
112    assert(I < WARegs.size());
113    return WARegs[I];
114  }
115
116  // For a given stackified WAReg, return the id number to print with push/pop.
117  static unsigned getWARegStackId(unsigned Reg) {
118    assert(Reg & INT32_MIN);
119    return Reg & INT32_MAX;
120  }
121};
122
123void ComputeLegalValueVTs(const Function &F, const TargetMachine &TM, Type *Ty,
124                          SmallVectorImpl<MVT> &ValueVTs);
125
126// Compute the signature for a given FunctionType (Ty). Note that it's not the
127// signature for F (F is just used to get varous context)
128void ComputeSignatureVTs(const FunctionType *Ty, const Function &F,
129                         const TargetMachine &TM, SmallVectorImpl<MVT> &Params,
130                         SmallVectorImpl<MVT> &Results);
131
132void ValTypesFromMVTs(const ArrayRef<MVT> &In,
133                      SmallVectorImpl<wasm::ValType> &Out);
134
135std::unique_ptr<wasm::WasmSignature>
136SignatureFromMVTs(const SmallVectorImpl<MVT> &Results,
137                  const SmallVectorImpl<MVT> &Params);
138
139} // end namespace llvm
140
141#endif
142