LLVM  10.0.0svn
WebAssemblyRegisterInfo.cpp
Go to the documentation of this file.
1 //===-- WebAssemblyRegisterInfo.cpp - WebAssembly Register Information ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file contains the WebAssembly implementation of the
11 /// TargetRegisterInfo class.
12 ///
13 //===----------------------------------------------------------------------===//
14 
18 #include "WebAssemblyInstrInfo.h"
20 #include "WebAssemblySubtarget.h"
25 #include "llvm/IR/Function.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "wasm-reg-info"
31 
32 #define GET_REGINFO_TARGET_DESC
33 #include "WebAssemblyGenRegisterInfo.inc"
34 
36  : WebAssemblyGenRegisterInfo(0), TT(TT) {}
37 
38 const MCPhysReg *
40  static const MCPhysReg CalleeSavedRegs[] = {0};
41  return CalleeSavedRegs;
42 }
43 
46  BitVector Reserved(getNumRegs());
47  for (auto Reg : {WebAssembly::SP32, WebAssembly::SP64, WebAssembly::FP32,
48  WebAssembly::FP64})
49  Reserved.set(Reg);
50  return Reserved;
51 }
52 
54  MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum,
55  RegScavenger * /*RS*/) const {
56  assert(SPAdj == 0);
57  MachineInstr &MI = *II;
58 
59  MachineBasicBlock &MBB = *MI.getParent();
60  MachineFunction &MF = *MBB.getParent();
62  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
63  const MachineFrameInfo &MFI = MF.getFrameInfo();
64  int64_t FrameOffset = MFI.getStackSize() + MFI.getObjectOffset(FrameIndex);
65 
66  assert(MFI.getObjectSize(FrameIndex) != 0 &&
67  "We assume that variable-sized objects have already been lowered, "
68  "and don't use FrameIndex operands.");
69  Register FrameRegister = getFrameRegister(MF);
70 
71  // If this is the address operand of a load or store, make it relative to SP
72  // and fold the frame offset directly in.
73  unsigned AddrOperandNum = WebAssembly::getNamedOperandIdx(
74  MI.getOpcode(), WebAssembly::OpName::addr);
75  if (AddrOperandNum == FIOperandNum) {
76  unsigned OffsetOperandNum = WebAssembly::getNamedOperandIdx(
77  MI.getOpcode(), WebAssembly::OpName::off);
78  assert(FrameOffset >= 0 && MI.getOperand(OffsetOperandNum).getImm() >= 0);
79  int64_t Offset = MI.getOperand(OffsetOperandNum).getImm() + FrameOffset;
80 
81  if (static_cast<uint64_t>(Offset) <= std::numeric_limits<uint32_t>::max()) {
82  MI.getOperand(OffsetOperandNum).setImm(Offset);
83  MI.getOperand(FIOperandNum)
84  .ChangeToRegister(FrameRegister, /*isDef=*/false);
85  return;
86  }
87  }
88 
89  // If this is an address being added to a constant, fold the frame offset
90  // into the constant.
91  if (MI.getOpcode() == WebAssembly::ADD_I32) {
92  MachineOperand &OtherMO = MI.getOperand(3 - FIOperandNum);
93  if (OtherMO.isReg()) {
94  unsigned OtherMOReg = OtherMO.getReg();
95  if (TargetRegisterInfo::isVirtualRegister(OtherMOReg)) {
96  MachineInstr *Def = MF.getRegInfo().getUniqueVRegDef(OtherMOReg);
97  // TODO: For now we just opportunistically do this in the case where
98  // the CONST_I32 happens to have exactly one def and one use. We
99  // should generalize this to optimize in more cases.
100  if (Def && Def->getOpcode() == WebAssembly::CONST_I32 &&
101  MRI.hasOneNonDBGUse(Def->getOperand(0).getReg())) {
102  MachineOperand &ImmMO = Def->getOperand(1);
103  ImmMO.setImm(ImmMO.getImm() + uint32_t(FrameOffset));
104  MI.getOperand(FIOperandNum)
105  .ChangeToRegister(FrameRegister, /*isDef=*/false);
106  return;
107  }
108  }
109  }
110  }
111 
112  // Otherwise create an i32.add SP, offset and make it the operand.
113  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
114 
115  unsigned FIRegOperand = FrameRegister;
116  if (FrameOffset) {
117  // Create i32.add SP, offset and make it the operand.
118  const TargetRegisterClass *PtrRC =
120  unsigned OffsetOp = MRI.createVirtualRegister(PtrRC);
121  BuildMI(MBB, *II, II->getDebugLoc(), TII->get(WebAssembly::CONST_I32),
122  OffsetOp)
123  .addImm(FrameOffset);
124  FIRegOperand = MRI.createVirtualRegister(PtrRC);
125  BuildMI(MBB, *II, II->getDebugLoc(), TII->get(WebAssembly::ADD_I32),
126  FIRegOperand)
127  .addReg(FrameRegister)
128  .addReg(OffsetOp);
129  }
130  MI.getOperand(FIOperandNum).ChangeToRegister(FIRegOperand, /*isDef=*/false);
131 }
132 
133 Register
135  static const unsigned Regs[2][2] = {
136  /* !isArch64Bit isArch64Bit */
137  /* !hasFP */ {WebAssembly::SP32, WebAssembly::SP64},
138  /* hasFP */ {WebAssembly::FP32, WebAssembly::FP64}};
139  const WebAssemblyFrameLowering *TFI = getFrameLowering(MF);
140  return Regs[TFI->hasFP(MF)][TT.isArch64Bit()];
141 }
142 
143 const TargetRegisterClass *
145  unsigned Kind) const {
146  assert(Kind == 0 && "Only one kind of pointer on WebAssembly");
148  return &WebAssembly::I64RegClass;
149  return &WebAssembly::I32RegClass;
150 }
BitVector & set()
Definition: BitVector.h:397
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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.
Register getFrameRegister(const MachineFunction &MF) const override
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:411
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.
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:43
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...
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:256
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:1292
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 use of the specified register...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
Wrapper class representing virtual and physical registers.
Definition: Register.h:18
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.