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/// \brief 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/CodeGen/MachineRegisterInfo.h"
21
22namespace llvm {
23
24/// This class is derived from MachineFunctionInfo and contains private
25/// WebAssembly-specific information for each MachineFunction.
26class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
27  MachineFunction &MF;
28
29  std::vector<MVT> Params;
30
31  /// A mapping from CodeGen vreg index to WebAssembly register number.
32  std::vector<unsigned> WARegs;
33
34  /// A mapping from CodeGen vreg index to a boolean value indicating whether
35  /// the given register is considered to be "stackified", meaning it has been
36  /// determined or made to meet the stack requirements:
37  ///   - single use (per path)
38  ///   - single def (per path)
39  ///   - defined and used in LIFO order with other stack registers
40  BitVector VRegStackified;
41
42  // One entry for each possible target reg. we expect it to be small.
43  std::vector<unsigned> PhysRegs;
44
45public:
46  explicit WebAssemblyFunctionInfo(MachineFunction &MF) : MF(MF) {
47    PhysRegs.resize(WebAssembly::NUM_TARGET_REGS, -1U);
48  }
49  ~WebAssemblyFunctionInfo() override;
50
51  void addParam(MVT VT) { Params.push_back(VT); }
52  const std::vector<MVT> &getParams() const { return Params; }
53
54  static const unsigned UnusedReg = -1u;
55
56  void stackifyVReg(unsigned VReg) {
57    if (TargetRegisterInfo::virtReg2Index(VReg) >= VRegStackified.size())
58      VRegStackified.resize(TargetRegisterInfo::virtReg2Index(VReg) + 1);
59    VRegStackified.set(TargetRegisterInfo::virtReg2Index(VReg));
60  }
61  bool isVRegStackified(unsigned VReg) const {
62    if (TargetRegisterInfo::virtReg2Index(VReg) >= VRegStackified.size())
63      return false;
64    return VRegStackified.test(TargetRegisterInfo::virtReg2Index(VReg));
65  }
66
67  void initWARegs();
68  void setWAReg(unsigned VReg, unsigned WAReg) {
69    assert(WAReg != UnusedReg);
70    assert(TargetRegisterInfo::virtReg2Index(VReg) < WARegs.size());
71    WARegs[TargetRegisterInfo::virtReg2Index(VReg)] = WAReg;
72  }
73  unsigned getWAReg(unsigned Reg) const {
74    if (TargetRegisterInfo::isVirtualRegister(Reg)) {
75      assert(TargetRegisterInfo::virtReg2Index(Reg) < WARegs.size());
76      return WARegs[TargetRegisterInfo::virtReg2Index(Reg)];
77    }
78    return PhysRegs[Reg];
79  }
80  // If new virtual registers are created after initWARegs has been called,
81  // this function can be used to add WebAssembly register mappings for them.
82  void addWAReg(unsigned VReg, unsigned WAReg) {
83    assert(VReg = WARegs.size());
84    WARegs.push_back(WAReg);
85  }
86
87  void addPReg(unsigned PReg, unsigned WAReg) {
88    assert(PReg < WebAssembly::NUM_TARGET_REGS);
89    assert(WAReg < -1U);
90    PhysRegs[PReg] = WAReg;
91  }
92  const std::vector<unsigned> &getPhysRegs() const { return PhysRegs; }
93};
94
95} // end namespace llvm
96
97#endif
98