LLVM  4.0.0
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 /// \brief This file contains the WebAssembly implementation of the
12 /// TargetRegisterInfo class.
13 ///
14 //===----------------------------------------------------------------------===//
15 
19 #include "WebAssemblyInstrInfo.h"
21 #include "WebAssemblySubtarget.h"
25 #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 
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 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static const unsigned LoadAddressOperandNo
The operand number of the load or store address in load/store instructions.
BitVector & set()
Definition: BitVector.h:219
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 createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:605
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const HexagonInstrInfo * TII
const TargetRegisterInfo * getTargetRegisterInfo() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:592
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1202
BitVector getReservedRegs(const MachineFunction &MF) const override
MachineBasicBlock * MBB
const RegList & Regs
int64_t getImm() const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
unsigned const MachineRegisterInfo * MRI
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
This file provides WebAssembly-specific target descriptions.
uint32_t Offset
void setImm(int64_t immVal)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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.
unsigned getFrameRegister(const MachineFunction &MF) const override
static const unsigned StoreAddressOperandNo
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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:52
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 hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
This file declares WebAssembly-specific per-machine-function information.
const unsigned Kind
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.