LLVM  9.0.0svn
RISCVInstrInfo.cpp
Go to the documentation of this file.
1 //===-- RISCVInstrInfo.cpp - RISCV Instruction Information ------*- C++ -*-===//
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 // This file contains the RISCV implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "RISCVInstrInfo.h"
14 #include "RISCV.h"
15 #include "RISCVSubtarget.h"
16 #include "RISCVTargetMachine.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
25 
26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "RISCVGenInstrInfo.inc"
28 
29 using namespace llvm;
30 
32  : RISCVGenInstrInfo(RISCV::ADJCALLSTACKDOWN, RISCV::ADJCALLSTACKUP) {}
33 
35  int &FrameIndex) const {
36  switch (MI.getOpcode()) {
37  default:
38  return 0;
39  case RISCV::LB:
40  case RISCV::LBU:
41  case RISCV::LH:
42  case RISCV::LHU:
43  case RISCV::LW:
44  case RISCV::FLW:
45  case RISCV::LWU:
46  case RISCV::LD:
47  case RISCV::FLD:
48  break;
49  }
50 
51  if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
52  MI.getOperand(2).getImm() == 0) {
53  FrameIndex = MI.getOperand(1).getIndex();
54  return MI.getOperand(0).getReg();
55  }
56 
57  return 0;
58 }
59 
61  int &FrameIndex) const {
62  switch (MI.getOpcode()) {
63  default:
64  return 0;
65  case RISCV::SB:
66  case RISCV::SH:
67  case RISCV::SW:
68  case RISCV::FSW:
69  case RISCV::SD:
70  case RISCV::FSD:
71  break;
72  }
73 
74  if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
75  MI.getOperand(1).getImm() == 0) {
76  FrameIndex = MI.getOperand(0).getIndex();
77  return MI.getOperand(2).getReg();
78  }
79 
80  return 0;
81 }
82 
85  const DebugLoc &DL, unsigned DstReg,
86  unsigned SrcReg, bool KillSrc) const {
87  if (RISCV::GPRRegClass.contains(DstReg, SrcReg)) {
88  BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
89  .addReg(SrcReg, getKillRegState(KillSrc))
90  .addImm(0);
91  return;
92  }
93 
94  // FPR->FPR copies
95  unsigned Opc;
96  if (RISCV::FPR32RegClass.contains(DstReg, SrcReg))
97  Opc = RISCV::FSGNJ_S;
98  else if (RISCV::FPR64RegClass.contains(DstReg, SrcReg))
99  Opc = RISCV::FSGNJ_D;
100  else
101  llvm_unreachable("Impossible reg-to-reg copy");
102 
103  BuildMI(MBB, MBBI, DL, get(Opc), DstReg)
104  .addReg(SrcReg, getKillRegState(KillSrc))
105  .addReg(SrcReg, getKillRegState(KillSrc));
106 }
107 
110  unsigned SrcReg, bool IsKill, int FI,
111  const TargetRegisterClass *RC,
112  const TargetRegisterInfo *TRI) const {
113  DebugLoc DL;
114  if (I != MBB.end())
115  DL = I->getDebugLoc();
116 
117  unsigned Opcode;
118 
119  if (RISCV::GPRRegClass.hasSubClassEq(RC))
120  Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
121  RISCV::SW : RISCV::SD;
122  else if (RISCV::FPR32RegClass.hasSubClassEq(RC))
123  Opcode = RISCV::FSW;
124  else if (RISCV::FPR64RegClass.hasSubClassEq(RC))
125  Opcode = RISCV::FSD;
126  else
127  llvm_unreachable("Can't store this register to stack slot");
128 
129  BuildMI(MBB, I, DL, get(Opcode))
130  .addReg(SrcReg, getKillRegState(IsKill))
131  .addFrameIndex(FI)
132  .addImm(0);
133 }
134 
137  unsigned DstReg, int FI,
138  const TargetRegisterClass *RC,
139  const TargetRegisterInfo *TRI) const {
140  DebugLoc DL;
141  if (I != MBB.end())
142  DL = I->getDebugLoc();
143 
144  unsigned Opcode;
145 
146  if (RISCV::GPRRegClass.hasSubClassEq(RC))
147  Opcode = TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
148  RISCV::LW : RISCV::LD;
149  else if (RISCV::FPR32RegClass.hasSubClassEq(RC))
150  Opcode = RISCV::FLW;
151  else if (RISCV::FPR64RegClass.hasSubClassEq(RC))
152  Opcode = RISCV::FLD;
153  else
154  llvm_unreachable("Can't load this register from stack slot");
155 
156  BuildMI(MBB, I, DL, get(Opcode), DstReg).addFrameIndex(FI).addImm(0);
157 }
158 
161  const DebugLoc &DL, unsigned DstReg, uint64_t Val,
162  MachineInstr::MIFlag Flag) const {
163  assert(isInt<32>(Val) && "Can only materialize 32-bit constants");
164 
165  // TODO: If the value can be materialized using only one instruction, only
166  // insert a single instruction.
167 
168  uint64_t Hi20 = ((Val + 0x800) >> 12) & 0xfffff;
169  uint64_t Lo12 = SignExtend64<12>(Val);
170  BuildMI(MBB, MBBI, DL, get(RISCV::LUI), DstReg)
171  .addImm(Hi20)
172  .setMIFlag(Flag);
173  BuildMI(MBB, MBBI, DL, get(RISCV::ADDI), DstReg)
174  .addReg(DstReg, RegState::Kill)
175  .addImm(Lo12)
176  .setMIFlag(Flag);
177 }
178 
179 // The contents of values added to Cond are not examined outside of
180 // RISCVInstrInfo, giving us flexibility in what to push to it. For RISCV, we
181 // push BranchOpcode, Reg1, Reg2.
184  // Block ends with fall-through condbranch.
185  assert(LastInst.getDesc().isConditionalBranch() &&
186  "Unknown conditional branch");
187  Target = LastInst.getOperand(2).getMBB();
189  Cond.push_back(LastInst.getOperand(0));
190  Cond.push_back(LastInst.getOperand(1));
191 }
192 
193 static unsigned getOppositeBranchOpcode(int Opc) {
194  switch (Opc) {
195  default:
196  llvm_unreachable("Unrecognized conditional branch");
197  case RISCV::BEQ:
198  return RISCV::BNE;
199  case RISCV::BNE:
200  return RISCV::BEQ;
201  case RISCV::BLT:
202  return RISCV::BGE;
203  case RISCV::BGE:
204  return RISCV::BLT;
205  case RISCV::BLTU:
206  return RISCV::BGEU;
207  case RISCV::BGEU:
208  return RISCV::BLTU;
209  }
210 }
211 
213  MachineBasicBlock *&TBB,
214  MachineBasicBlock *&FBB,
216  bool AllowModify) const {
217  TBB = FBB = nullptr;
218  Cond.clear();
219 
220  // If the block has no terminators, it just falls into the block after it.
222  if (I == MBB.end() || !isUnpredicatedTerminator(*I))
223  return false;
224 
225  // Count the number of terminators and find the first unconditional or
226  // indirect branch.
227  MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
228  int NumTerminators = 0;
229  for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
230  J++) {
231  NumTerminators++;
232  if (J->getDesc().isUnconditionalBranch() ||
233  J->getDesc().isIndirectBranch()) {
234  FirstUncondOrIndirectBr = J.getReverse();
235  }
236  }
237 
238  // If AllowModify is true, we can erase any terminators after
239  // FirstUncondOrIndirectBR.
240  if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
241  while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
242  std::next(FirstUncondOrIndirectBr)->eraseFromParent();
243  NumTerminators--;
244  }
245  I = FirstUncondOrIndirectBr;
246  }
247 
248  // We can't handle blocks that end in an indirect branch.
249  if (I->getDesc().isIndirectBranch())
250  return true;
251 
252  // We can't handle blocks with more than 2 terminators.
253  if (NumTerminators > 2)
254  return true;
255 
256  // Handle a single unconditional branch.
257  if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
258  TBB = I->getOperand(0).getMBB();
259  return false;
260  }
261 
262  // Handle a single conditional branch.
263  if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
264  parseCondBranch(*I, TBB, Cond);
265  return false;
266  }
267 
268  // Handle a conditional branch followed by an unconditional branch.
269  if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
270  I->getDesc().isUnconditionalBranch()) {
271  parseCondBranch(*std::prev(I), TBB, Cond);
272  FBB = I->getOperand(0).getMBB();
273  return false;
274  }
275 
276  // Otherwise, we can't handle this.
277  return true;
278 }
279 
281  int *BytesRemoved) const {
282  if (BytesRemoved)
283  *BytesRemoved = 0;
285  if (I == MBB.end())
286  return 0;
287 
288  if (!I->getDesc().isUnconditionalBranch() &&
289  !I->getDesc().isConditionalBranch())
290  return 0;
291 
292  // Remove the branch.
293  I->eraseFromParent();
294  if (BytesRemoved)
295  *BytesRemoved += getInstSizeInBytes(*I);
296 
297  I = MBB.end();
298 
299  if (I == MBB.begin())
300  return 1;
301  --I;
302  if (!I->getDesc().isConditionalBranch())
303  return 1;
304 
305  // Remove the branch.
306  I->eraseFromParent();
307  if (BytesRemoved)
308  *BytesRemoved += getInstSizeInBytes(*I);
309  return 2;
310 }
311 
312 // Inserts a branch into the end of the specific MachineBasicBlock, returning
313 // the number of instructions inserted.
316  ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
317  if (BytesAdded)
318  *BytesAdded = 0;
319 
320  // Shouldn't be a fall through.
321  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
322  assert((Cond.size() == 3 || Cond.size() == 0) &&
323  "RISCV branch conditions have two components!");
324 
325  // Unconditional branch.
326  if (Cond.empty()) {
327  MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(TBB);
328  if (BytesAdded)
329  *BytesAdded += getInstSizeInBytes(MI);
330  return 1;
331  }
332 
333  // Either a one or two-way conditional branch.
334  unsigned Opc = Cond[0].getImm();
335  MachineInstr &CondMI =
336  *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).add(Cond[2]).addMBB(TBB);
337  if (BytesAdded)
338  *BytesAdded += getInstSizeInBytes(CondMI);
339 
340  // One-way conditional branch.
341  if (!FBB)
342  return 1;
343 
344  // Two-way conditional branch.
345  MachineInstr &MI = *BuildMI(&MBB, DL, get(RISCV::PseudoBR)).addMBB(FBB);
346  if (BytesAdded)
347  *BytesAdded += getInstSizeInBytes(MI);
348  return 2;
349 }
350 
352  MachineBasicBlock &DestBB,
353  const DebugLoc &DL,
354  int64_t BrOffset,
355  RegScavenger *RS) const {
356  assert(RS && "RegScavenger required for long branching");
357  assert(MBB.empty() &&
358  "new block should be inserted for expanding unconditional branch");
359  assert(MBB.pred_size() == 1);
360 
361  MachineFunction *MF = MBB.getParent();
362  MachineRegisterInfo &MRI = MF->getRegInfo();
363  const auto &TM = static_cast<const RISCVTargetMachine &>(MF->getTarget());
364 
365  if (TM.isPositionIndependent())
366  report_fatal_error("Unable to insert indirect branch");
367 
368  if (!isInt<32>(BrOffset))
370  "Branch offsets outside of the signed 32-bit range not supported");
371 
372  // FIXME: A virtual register must be used initially, as the register
373  // scavenger won't work with empty blocks (SIInstrInfo::insertIndirectBranch
374  // uses the same workaround).
375  unsigned ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
376  auto II = MBB.end();
377 
378  MachineInstr &LuiMI = *BuildMI(MBB, II, DL, get(RISCV::LUI), ScratchReg)
379  .addMBB(&DestBB, RISCVII::MO_HI);
380  BuildMI(MBB, II, DL, get(RISCV::PseudoBRIND))
381  .addReg(ScratchReg, RegState::Kill)
382  .addMBB(&DestBB, RISCVII::MO_LO);
383 
384  RS->enterBasicBlockEnd(MBB);
385  unsigned Scav = RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
386  LuiMI.getIterator(), false, 0);
387  MRI.replaceRegWith(ScratchReg, Scav);
388  MRI.clearVirtRegs();
389  RS->setRegUsed(Scav);
390  return 8;
391 }
392 
394  SmallVectorImpl<MachineOperand> &Cond) const {
395  assert((Cond.size() == 3) && "Invalid branch condition!");
396  Cond[0].setImm(getOppositeBranchOpcode(Cond[0].getImm()));
397  return false;
398 }
399 
402  assert(MI.getDesc().isBranch() && "Unexpected opcode!");
403  // The branch target is always the last operand.
404  int NumOp = MI.getNumExplicitOperands();
405  return MI.getOperand(NumOp - 1).getMBB();
406 }
407 
409  int64_t BrOffset) const {
410  // Ideally we could determine the supported branch offset from the
411  // RISCVII::FormMask, but this can't be used for Pseudo instructions like
412  // PseudoBR.
413  switch (BranchOp) {
414  default:
415  llvm_unreachable("Unexpected opcode!");
416  case RISCV::BEQ:
417  case RISCV::BNE:
418  case RISCV::BLT:
419  case RISCV::BGE:
420  case RISCV::BLTU:
421  case RISCV::BGEU:
422  return isIntN(13, BrOffset);
423  case RISCV::JAL:
424  case RISCV::PseudoBR:
425  return isIntN(21, BrOffset);
426  }
427 }
428 
430  unsigned Opcode = MI.getOpcode();
431 
432  switch (Opcode) {
433  default: { return get(Opcode).getSize(); }
435  case TargetOpcode::IMPLICIT_DEF:
436  case TargetOpcode::KILL:
437  case TargetOpcode::DBG_VALUE:
438  return 0;
439  case RISCV::PseudoCALL:
440  case RISCV::PseudoTAIL:
441  case RISCV::PseudoLLA:
442  case RISCV::PseudoLA:
443  return 8;
446  const MachineFunction &MF = *MI.getParent()->getParent();
447  const auto &TM = static_cast<const RISCVTargetMachine &>(MF.getTarget());
448  return getInlineAsmLength(MI.getOperand(0).getSymbolName(),
449  *TM.getMCAsmInfo());
450  }
451  }
452 }
453 
455  const unsigned Opcode = MI.getOpcode();
456  switch(Opcode) {
457  default:
458  break;
459  case RISCV::ADDI:
460  case RISCV::ORI:
461  case RISCV::XORI:
462  return (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == RISCV::X0);
463  }
464  return MI.isAsCheapAsAMove();
465 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
MachineBasicBlock * getMBB() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned getReg() const
getReg - Returns the register number.
unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
return AArch64::GPR64RegClass contains(Reg)
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:277
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:410
const char * getSymbolName() const
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:695
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:407
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
void movImm32(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
reverse_iterator rend()
unsigned getKillRegState(bool B)
bool isAsCheapAsAMove(const MachineInstr &MI) const override
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:117
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
This instruction implements an extending load to FP stack slots.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
Definition: MCInstrDesc.h:287
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned DstReg, unsigned SrcReg, bool KillSrc) const override
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
self_iterator getIterator()
Definition: ilist_node.h:81
const MachineInstrBuilder & addFrameIndex(int Idx) const
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:397
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
size_t size() const
Definition: SmallVector.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
Definition: ISDOpcodes.h:703
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:308
static unsigned getOppositeBranchOpcode(int Opc)
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
int64_t getImm() const
unsigned pred_size() const
Target - Wrapper for Target specific information.
void replaceRegWith(unsigned FromReg, unsigned ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:255
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:63
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
unsigned insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS=nullptr) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:58
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
INLINEASM_BR - Terminator version of inline asm. Used by asm-goto.
Definition: ISDOpcodes.h:698
void setRegUsed(unsigned Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
IRTranslator LLVM IR MI
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:415
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
Returns true if this instruction has the same cost (or less) than a move instruction.
Definition: MachineInstr.h:918
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:143