LLVM  8.0.1
WebAssemblyRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- WebAssemblyRegisterInfo.cpp - WebAssembly Register Information ----===//
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 contains the WebAssembly implementation of the
12 /// TargetRegisterInfo class.
13 ///
14 //===----------------------------------------------------------------------===//
15 
19 #include "WebAssemblyInstrInfo.h"
21 #include "WebAssemblySubtarget.h"
26 #include "llvm/IR/Function.h"
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "wasm-reg-info"
32 
33 #define GET_REGINFO_TARGET_DESC
34 #include "WebAssemblyGenRegisterInfo.inc"
35 
37  : WebAssemblyGenRegisterInfo(0), TT(TT) {}
38 
39 const MCPhysReg *
41  static const MCPhysReg CalleeSavedRegs[] = {0};
42  return CalleeSavedRegs;
43 }
44 
47  BitVector Reserved(getNumRegs());
48  for (auto Reg : {WebAssembly::SP32, WebAssembly::SP64, WebAssembly::FP32,
49  WebAssembly::FP64})
50  Reserved.set(Reg);
51  return Reserved;
52 }
53 
55  MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum,
56  RegScavenger * /*RS*/) const {
57  assert(SPAdj == 0);
58  MachineInstr &MI = *II;
59 
60  MachineBasicBlock &MBB = *MI.getParent();
61  MachineFunction &MF = *MBB.getParent();
63  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
64  const MachineFrameInfo &MFI = MF.getFrameInfo();
65  int64_t FrameOffset = MFI.getStackSize() + MFI.getObjectOffset(FrameIndex);
66 
67  assert(MFI.getObjectSize(FrameIndex) != 0 &&
68  "We assume that variable-sized objects have already been lowered, "
69  "and don't use FrameIndex operands.");
70  unsigned FrameRegister = getFrameRegister(MF);
71 
72  // If this is the address operand of a load or store, make it relative to SP
73  // and fold the frame offset directly in.
74  if ((MI.mayLoad() && FIOperandNum == WebAssembly::LoadAddressOperandNo) ||
75  (MI.mayStore() && FIOperandNum == WebAssembly::StoreAddressOperandNo)) {
76  assert(FrameOffset >= 0 && MI.getOperand(FIOperandNum - 1).getImm() >= 0);
77  int64_t Offset = MI.getOperand(FIOperandNum - 1).getImm() + FrameOffset;
78 
79  if (static_cast<uint64_t>(Offset) <= std::numeric_limits<uint32_t>::max()) {
80  MI.getOperand(FIOperandNum - 1).setImm(Offset);
81  MI.getOperand(FIOperandNum)
82  .ChangeToRegister(FrameRegister, /*IsDef=*/false);
83  return;
84  }
85  }
86 
87  // If this is an address being added to a constant, fold the frame offset
88  // into the constant.
89  if (MI.getOpcode() == WebAssembly::ADD_I32) {
90  MachineOperand &OtherMO = MI.getOperand(3 - FIOperandNum);
91  if (OtherMO.isReg()) {
92  unsigned OtherMOReg = OtherMO.getReg();
93  if (TargetRegisterInfo::isVirtualRegister(OtherMOReg)) {
94  MachineInstr *Def = MF.getRegInfo().getUniqueVRegDef(OtherMOReg);
95  // TODO: For now we just opportunistically do this in the case where
96  // the CONST_I32 happens to have exactly one def and one use. We
97  // should generalize this to optimize in more cases.
98  if (Def && Def->getOpcode() == WebAssembly::CONST_I32 &&
99  MRI.hasOneNonDBGUse(Def->getOperand(0).getReg())) {
100  MachineOperand &ImmMO = Def->getOperand(1);
101  ImmMO.setImm(ImmMO.getImm() + uint32_t(FrameOffset));
102  MI.getOperand(FIOperandNum)
103  .ChangeToRegister(FrameRegister, /*IsDef=*/false);
104  return;
105  }
106  }
107  }
108  }
109 
110  // Otherwise create an i32.add SP, offset and make it the operand.
111  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
112 
113  unsigned FIRegOperand = FrameRegister;
114  if (FrameOffset) {
115  // Create i32.add SP, offset and make it the operand.
116  const TargetRegisterClass *PtrRC =
118  unsigned OffsetOp = MRI.createVirtualRegister(PtrRC);
119  BuildMI(MBB, *II, II->getDebugLoc(), TII->get(WebAssembly::CONST_I32),
120  OffsetOp)
121  .addImm(FrameOffset);
122  FIRegOperand = MRI.createVirtualRegister(PtrRC);
123  BuildMI(MBB, *II, II->getDebugLoc(), TII->get(WebAssembly::ADD_I32),
124  FIRegOperand)
125  .addReg(FrameRegister)
126  .addReg(OffsetOp);
127  }
128  MI.getOperand(FIOperandNum).ChangeToRegister(FIRegOperand, /*IsDef=*/false);
129 }
130 
131 unsigned
133  static const unsigned Regs[2][2] = {
134  /* !isArch64Bit isArch64Bit */
135  /* !hasFP */ {WebAssembly::SP32, WebAssembly::SP64},
136  /* hasFP */ {WebAssembly::FP32, WebAssembly::FP64}};
137  const WebAssemblyFrameLowering *TFI = getFrameLowering(MF);
138  return Regs[TFI->hasFP(MF)][TT.isArch64Bit()];
139 }
140 
141 const TargetRegisterClass *
143  unsigned Kind) const {
144  assert(Kind == 0 && "Only one kind of pointer on WebAssembly");
146  return &WebAssembly::I64RegClass;
147  return &WebAssembly::I32RegClass;
148 }
static const unsigned LoadAddressOperandNo
The operand number of the load or store address in load/store instructions.
BitVector & set()
Definition: BitVector.h:398
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
bool hasFP(const MachineFunction &MF) const override
Return true if the specified function should have a dedicated frame pointer register.
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
const HexagonInstrInfo * TII
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:409
BitVector getReservedRegs(const MachineFunction &MF) const override
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:820
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
const TargetRegisterInfo * getTargetRegisterInfo() const
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
This file provides WebAssembly-specific target descriptions.
void setImm(int64_t immVal)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
This file contains the WebAssembly implementation of the WebAssemblyRegisterInfo class.
This file declares the WebAssembly-specific subclass of TargetSubtarget.
MachineOperand class - Representation of each machine instruction operand.
This file contains the WebAssembly implementation of the TargetInstrInfo class.
int64_t getImm() const
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
unsigned getFrameRegister(const MachineFunction &MF) const override
static const unsigned StoreAddressOperandNo
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:254
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:64
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
This class implements WebAssembly-specific bits of TargetFrameLowering class.
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1269
This file declares WebAssembly-specific per-machine-function information.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const unsigned Kind
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:807
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:414
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.