LLVM  16.0.0git
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 false;
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() == WebAssemblyFrameLowering::getOpcAdd(MF)) {
92  MachineOperand &OtherMO = MI.getOperand(3 - FIOperandNum);
93  if (OtherMO.isReg()) {
94  Register OtherMOReg = OtherMO.getReg();
95  if (Register::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/64 happens to have exactly one def and one use. We
99  // should generalize this to optimize in more cases.
100  if (Def && Def->getOpcode() ==
102  MRI.hasOneNonDBGUse(Def->getOperand(0).getReg())) {
103  MachineOperand &ImmMO = Def->getOperand(1);
104  if (ImmMO.isImm()) {
105  ImmMO.setImm(ImmMO.getImm() + uint32_t(FrameOffset));
106  MI.getOperand(FIOperandNum)
107  .ChangeToRegister(FrameRegister, /*isDef=*/false);
108  return false;
109  }
110  }
111  }
112  }
113  }
114 
115  // Otherwise create an i32/64.add SP, offset and make it the operand.
116  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
117 
118  unsigned FIRegOperand = FrameRegister;
119  if (FrameOffset) {
120  // Create i32/64.add SP, offset and make it the operand.
121  const TargetRegisterClass *PtrRC =
123  Register OffsetOp = MRI.createVirtualRegister(PtrRC);
124  BuildMI(MBB, *II, II->getDebugLoc(),
126  OffsetOp)
127  .addImm(FrameOffset);
128  FIRegOperand = MRI.createVirtualRegister(PtrRC);
129  BuildMI(MBB, *II, II->getDebugLoc(),
131  FIRegOperand)
132  .addReg(FrameRegister)
133  .addReg(OffsetOp);
134  }
135  MI.getOperand(FIOperandNum).ChangeToRegister(FIRegOperand, /*isDef=*/false);
136  return false;
137 }
138 
139 Register
141  // If the PReg has been replaced by a VReg, return that.
142  const auto &MFI = MF.getInfo<WebAssemblyFunctionInfo>();
143  if (MFI->isFrameBaseVirtual())
144  return MFI->getFrameBaseVreg();
145  static const unsigned Regs[2][2] = {
146  /* !isArch64Bit isArch64Bit */
147  /* !hasFP */ {WebAssembly::SP32, WebAssembly::SP64},
148  /* hasFP */ {WebAssembly::FP32, WebAssembly::FP64}};
149  const WebAssemblyFrameLowering *TFI = getFrameLowering(MF);
150  return Regs[TFI->hasFP(MF)][TT.isArch64Bit()];
151 }
152 
153 const TargetRegisterClass *
155  unsigned Kind) const {
156  assert(Kind == 0 && "Only one kind of pointer on WebAssembly");
158  return &WebAssembly::I64RegClass;
159  return &WebAssembly::I32RegClass;
160 }
llvm::WebAssemblyFrameLowering::getOpcAdd
static unsigned getOpcAdd(const MachineFunction &MF)
Definition: WebAssemblyFrameLowering.cpp:192
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
TargetFrameLowering.h
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:156
llvm::WebAssemblyFrameLowering
Definition: WebAssemblyFrameLowering.h:22
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::WebAssemblyRegisterInfo::getCalleeSavedRegs
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Definition: WebAssemblyRegisterInfo.cpp:39
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::MachineRegisterInfo::getTargetRegisterInfo
const TargetRegisterInfo * getTargetRegisterInfo() const
Definition: MachineRegisterInfo.h:151
llvm::MachineRegisterInfo::getUniqueVRegDef
MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Definition: MachineRegisterInfo.cpp:407
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::MachineOperand::setImm
void setImm(int64_t immVal)
Definition: MachineOperand.h:664
llvm::WebAssemblySubtarget::hasAddr64
bool hasAddr64() const
Definition: WebAssemblySubtarget.h:92
llvm::WebAssemblyRegisterInfo::WebAssemblyRegisterInfo
WebAssemblyRegisterInfo(const Triple &TT)
Definition: WebAssemblyRegisterInfo.cpp:35
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
MachineRegisterInfo.h
llvm::Triple::isArch64Bit
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1462
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:667
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:546
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:755
llvm::WebAssemblyRegisterInfo::eliminateFrameIndex
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
Definition: WebAssemblyRegisterInfo.cpp:53
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::WebAssemblyFrameLowering::getOpcConst
static unsigned getOpcConst(const MachineFunction &MF)
Definition: WebAssemblyFrameLowering.cpp:186
WebAssemblyInstrInfo.h
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::MachineFrameInfo::getStackSize
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Definition: MachineFrameInfo.h:585
llvm::MachineFrameInfo::getObjectOffset
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
Definition: MachineFrameInfo.h:526
llvm::BitVector
Definition: BitVector.h:75
llvm::WebAssemblyRegisterInfo::getPointerRegClass
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
Definition: WebAssemblyRegisterInfo.cpp:154
llvm::WebAssemblyRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: WebAssemblyRegisterInfo.cpp:140
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
WebAssemblyMCTargetDesc.h
llvm::TargetRegisterInfo::getPointerRegClass
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
Definition: TargetRegisterInfo.h:791
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
WebAssemblyFrameLowering.h
llvm::MachineFrameInfo::getObjectSize
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Definition: MachineFrameInfo.h:470
llvm::RegScavenger
Definition: RegisterScavenging.h:34
llvm::Register::isVirtualRegister
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:673
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:261
llvm::WebAssemblyFunctionInfo
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
Definition: WebAssemblyMachineFunctionInfo.h:33
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
WebAssemblyMachineFunctionInfo.h
llvm::MachineFunction
Definition: MachineFunction.h:257
TargetOptions.h
llvm::MachineRegisterInfo::hasOneNonDBGUse
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
Definition: MachineRegisterInfo.cpp:415
uint32_t
llvm::WebAssemblySubtarget
Definition: WebAssemblySubtarget.h:35
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::ISD::FrameIndex
@ FrameIndex
Definition: ISDOpcodes.h:80
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
uint16_t
MachineFrameInfo.h
WebAssemblyRegisterInfo.h
Function.h
WebAssemblySubtarget.h
llvm::WebAssemblyFrameLowering::hasFP
bool hasFP(const MachineFunction &MF) const override
Return true if the specified function should have a dedicated frame pointer register.
Definition: WebAssemblyFrameLowering.cpp:101
llvm::WebAssemblyRegisterInfo::getReservedRegs
BitVector getReservedRegs(const MachineFunction &MF) const override
Definition: WebAssemblyRegisterInfo.cpp:45
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:322
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:106
WebAssemblyGenRegisterInfo
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
MachineInstrBuilder.h
llvm::PseudoProbeAttributes::Reserved
@ Reserved
llvm::WebAssemblyFunctionInfo::getFrameBaseVreg
unsigned getFrameBaseVreg() const
Definition: WebAssemblyMachineFunctionInfo.h:106
raw_ostream.h
llvm::WebAssembly::getNamedOperandIdx
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
llvm::MachineInstrBundleIterator< MachineInstr >