LLVM  7.0.0svn
ARCInstrInfo.cpp
Go to the documentation of this file.
1 //===- ARCInstrInfo.cpp - ARC Instruction Information -----------*- C++ -*-===//
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 // This file contains the ARC implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARCInstrInfo.h"
15 #include "ARC.h"
16 #include "ARCMachineFunctionInfo.h"
17 #include "ARCSubtarget.h"
18 #include "MCTargetDesc/ARCInfo.h"
22 #include "llvm/Support/Debug.h"
24 
25 using namespace llvm;
26 
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "ARCGenInstrInfo.inc"
29 
30 #define DEBUG_TYPE "arc-inst-info"
31 // Pin the vtable to this file.
32 void ARCInstrInfo::anchor() {}
33 
35  : ARCGenInstrInfo(ARC::ADJCALLSTACKDOWN, ARC::ADJCALLSTACKUP), RI() {}
36 
37 static bool isZeroImm(const MachineOperand &Op) {
38  return Op.isImm() && Op.getImm() == 0;
39 }
40 
41 static bool isLoad(int Opcode) {
42  return Opcode == ARC::LD_rs9 || Opcode == ARC::LDH_rs9 ||
43  Opcode == ARC::LDB_rs9;
44 }
45 
46 static bool isStore(int Opcode) {
47  return Opcode == ARC::ST_rs9 || Opcode == ARC::STH_rs9 ||
48  Opcode == ARC::STB_rs9;
49 }
50 
51 /// If the specified machine instruction is a direct
52 /// load from a stack slot, return the virtual or physical register number of
53 /// the destination along with the FrameIndex of the loaded stack slot. If
54 /// not, return 0. This predicate must return 0 if the instruction has
55 /// any side effects other than loading from the stack slot.
57  int &FrameIndex) const {
58  int Opcode = MI.getOpcode();
59  if (isLoad(Opcode)) {
60  if ((MI.getOperand(1).isFI()) && // is a stack slot
61  (MI.getOperand(2).isImm()) && // the imm is zero
62  (isZeroImm(MI.getOperand(2)))) {
63  FrameIndex = MI.getOperand(1).getIndex();
64  return MI.getOperand(0).getReg();
65  }
66  }
67  return 0;
68 }
69 
70 /// If the specified machine instruction is a direct
71 /// store to a stack slot, return the virtual or physical register number of
72 /// the source reg along with the FrameIndex of the loaded stack slot. If
73 /// not, return 0. This predicate must return 0 if the instruction has
74 /// any side effects other than storing to the stack slot.
76  int &FrameIndex) const {
77  int Opcode = MI.getOpcode();
78  if (isStore(Opcode)) {
79  if ((MI.getOperand(1).isFI()) && // is a stack slot
80  (MI.getOperand(2).isImm()) && // the imm is zero
81  (isZeroImm(MI.getOperand(2)))) {
82  FrameIndex = MI.getOperand(1).getIndex();
83  return MI.getOperand(0).getReg();
84  }
85  }
86  return 0;
87 }
88 
89 /// Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
91  switch (CC) {
92  default:
93  llvm_unreachable("Illegal condition code!");
94  case ARCCC::EQ:
95  return ARCCC::NE;
96  case ARCCC::NE:
97  return ARCCC::EQ;
98  case ARCCC::LO:
99  return ARCCC::HS;
100  case ARCCC::HS:
101  return ARCCC::LO;
102  case ARCCC::GT:
103  return ARCCC::LE;
104  case ARCCC::GE:
105  return ARCCC::LT;
106  case ARCCC::VS:
107  return ARCCC::VC;
108  case ARCCC::VC:
109  return ARCCC::VS;
110  case ARCCC::LT:
111  return ARCCC::GE;
112  case ARCCC::LE:
113  return ARCCC::GT;
114  case ARCCC::HI:
115  return ARCCC::LS;
116  case ARCCC::LS:
117  return ARCCC::HI;
118  case ARCCC::NZ:
119  return ARCCC::Z;
120  case ARCCC::Z:
121  return ARCCC::NZ;
122  }
123 }
124 
125 static bool isUncondBranchOpcode(int Opc) { return Opc == ARC::BR; }
126 
127 static bool isCondBranchOpcode(int Opc) {
128  return Opc == ARC::BRcc_rr_p || Opc == ARC::BRcc_ru6_p;
129 }
130 
131 static bool isJumpOpcode(int Opc) { return Opc == ARC::J; }
132 
133 /// Analyze the branching code at the end of MBB, returning
134 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
135 /// implemented for a target). Upon success, this returns false and returns
136 /// with the following information in various cases:
137 ///
138 /// 1. If this block ends with no branches (it just falls through to its succ)
139 /// just return false, leaving TBB/FBB null.
140 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
141 /// the destination block.
142 /// 3. If this block ends with a conditional branch and it falls through to a
143 /// successor block, it sets TBB to be the branch destination block and a
144 /// list of operands that evaluate the condition. These operands can be
145 /// passed to other TargetInstrInfo methods to create new branches.
146 /// 4. If this block ends with a conditional branch followed by an
147 /// unconditional branch, it returns the 'true' destination in TBB, the
148 /// 'false' destination in FBB, and a list of operands that evaluate the
149 /// condition. These operands can be passed to other TargetInstrInfo
150 /// methods to create new branches.
151 ///
152 /// Note that RemoveBranch and InsertBranch must be implemented to support
153 /// cases where this method returns success.
154 ///
155 /// If AllowModify is true, then this routine is allowed to modify the basic
156 /// block (e.g. delete instructions after the unconditional branch).
157 
159  MachineBasicBlock *&TBB,
160  MachineBasicBlock *&FBB,
162  bool AllowModify) const {
163  TBB = FBB = nullptr;
165  if (I == MBB.begin())
166  return false;
167  --I;
168 
169  while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
170  // Flag to be raised on unanalyzeable instructions. This is useful in cases
171  // where we want to clean up on the end of the basic block before we bail
172  // out.
173  bool CantAnalyze = false;
174 
175  // Skip over DEBUG values and predicated nonterminators.
176  while (I->isDebugValue() || !I->isTerminator()) {
177  if (I == MBB.begin())
178  return false;
179  --I;
180  }
181 
182  if (isJumpOpcode(I->getOpcode())) {
183  // Indirect branches and jump tables can't be analyzed, but we still want
184  // to clean up any instructions at the tail of the basic block.
185  CantAnalyze = true;
186  } else if (isUncondBranchOpcode(I->getOpcode())) {
187  TBB = I->getOperand(0).getMBB();
188  } else if (isCondBranchOpcode(I->getOpcode())) {
189  // Bail out if we encounter multiple conditional branches.
190  if (!Cond.empty())
191  return true;
192 
193  assert(!FBB && "FBB should have been null.");
194  FBB = TBB;
195  TBB = I->getOperand(0).getMBB();
196  Cond.push_back(I->getOperand(1));
197  Cond.push_back(I->getOperand(2));
198  Cond.push_back(I->getOperand(3));
199  } else if (I->isReturn()) {
200  // Returns can't be analyzed, but we should run cleanup.
201  CantAnalyze = !isPredicated(*I);
202  } else {
203  // We encountered other unrecognized terminator. Bail out immediately.
204  return true;
205  }
206 
207  // Cleanup code - to be run for unpredicated unconditional branches and
208  // returns.
209  if (!isPredicated(*I) && (isUncondBranchOpcode(I->getOpcode()) ||
210  isJumpOpcode(I->getOpcode()) || I->isReturn())) {
211  // Forget any previous condition branch information - it no longer
212  // applies.
213  Cond.clear();
214  FBB = nullptr;
215 
216  // If we can modify the function, delete everything below this
217  // unconditional branch.
218  if (AllowModify) {
219  MachineBasicBlock::iterator DI = std::next(I);
220  while (DI != MBB.end()) {
221  MachineInstr &InstToDelete = *DI;
222  ++DI;
223  InstToDelete.eraseFromParent();
224  }
225  }
226  }
227 
228  if (CantAnalyze)
229  return true;
230 
231  if (I == MBB.begin())
232  return false;
233 
234  --I;
235  }
236 
237  // We made it past the terminators without bailing out - we must have
238  // analyzed this branch successfully.
239  return false;
240 }
241 
243  int *BytesRemoved) const {
244  assert(!BytesRemoved && "Code size not handled");
246  if (I == MBB.end())
247  return 0;
248 
249  if (!isUncondBranchOpcode(I->getOpcode()) &&
250  !isCondBranchOpcode(I->getOpcode()))
251  return 0;
252 
253  // Remove the branch.
254  I->eraseFromParent();
255 
256  I = MBB.end();
257 
258  if (I == MBB.begin())
259  return 1;
260  --I;
261  if (!isCondBranchOpcode(I->getOpcode()))
262  return 1;
263 
264  // Remove the branch.
265  I->eraseFromParent();
266  return 2;
267 }
268 
271  const DebugLoc &dl, unsigned DestReg,
272  unsigned SrcReg, bool KillSrc) const {
273  assert(ARC::GPR32RegClass.contains(SrcReg) &&
274  "Only GPR32 src copy supported.");
275  assert(ARC::GPR32RegClass.contains(DestReg) &&
276  "Only GPR32 dest copy supported.");
277  BuildMI(MBB, I, dl, get(ARC::MOV_rr), DestReg)
278  .addReg(SrcReg, getKillRegState(KillSrc));
279 }
280 
283  unsigned SrcReg, bool isKill,
284  int FrameIndex,
285  const TargetRegisterClass *RC,
286  const TargetRegisterInfo *TRI) const {
287  DebugLoc dl = MBB.findDebugLoc(I);
288  MachineFunction &MF = *MBB.getParent();
289  MachineFrameInfo &MFI = MF.getFrameInfo();
290  unsigned Align = MFI.getObjectAlignment(FrameIndex);
291 
293  MachinePointerInfo::getFixedStack(MF, FrameIndex),
295 
296  assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
297  assert(TRI->getSpillSize(*RC) == 4 &&
298  "Only support 4-byte stores to stack now.");
299  assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
300  "Only support GPR32 stores to stack now.");
301  DEBUG(dbgs() << "Created store reg=" << printReg(SrcReg, TRI)
302  << " to FrameIndex=" << FrameIndex << "\n");
303  BuildMI(MBB, I, dl, get(ARC::ST_rs9))
304  .addReg(SrcReg, getKillRegState(isKill))
305  .addFrameIndex(FrameIndex)
306  .addImm(0)
307  .addMemOperand(MMO);
308 }
309 
312  unsigned DestReg, int FrameIndex,
313  const TargetRegisterClass *RC,
314  const TargetRegisterInfo *TRI) const {
315  DebugLoc dl = MBB.findDebugLoc(I);
316  MachineFunction &MF = *MBB.getParent();
317  MachineFrameInfo &MFI = MF.getFrameInfo();
318  unsigned Align = MFI.getObjectAlignment(FrameIndex);
320  MachinePointerInfo::getFixedStack(MF, FrameIndex),
321  MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), Align);
322 
323  assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
324  assert(TRI->getSpillSize(*RC) == 4 &&
325  "Only support 4-byte loads from stack now.");
326  assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
327  "Only support GPR32 stores to stack now.");
328  DEBUG(dbgs() << "Created load reg=" << printReg(DestReg, TRI)
329  << " from FrameIndex=" << FrameIndex << "\n");
330  BuildMI(MBB, I, dl, get(ARC::LD_rs9))
331  .addReg(DestReg, RegState::Define)
332  .addFrameIndex(FrameIndex)
333  .addImm(0)
334  .addMemOperand(MMO);
335 }
336 
337 /// Return the inverse opcode of the specified Branch instruction.
339  SmallVectorImpl<MachineOperand> &Cond) const {
340  assert((Cond.size() == 3) && "Invalid ARC branch condition!");
341  Cond[2].setImm(GetOppositeBranchCondition((ARCCC::CondCode)Cond[2].getImm()));
342  return false;
343 }
344 
348  uint64_t Value) const {
349  DebugLoc dl = MBB.findDebugLoc(MI);
350  if (isInt<12>(Value)) {
351  return BuildMI(MBB, MI, dl, get(ARC::MOV_rs12), Reg)
352  .addImm(Value)
353  .getInstr();
354  }
355  llvm_unreachable("Need Arc long immediate instructions.");
356 }
357 
359  MachineBasicBlock *TBB,
360  MachineBasicBlock *FBB,
362  const DebugLoc &dl, int *BytesAdded) const {
363  assert(!BytesAdded && "Code size not handled.");
364 
365  // Shouldn't be a fall through.
366  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
367  assert((Cond.size() == 3 || Cond.size() == 0) &&
368  "ARC branch conditions have two components!");
369 
370  if (Cond.empty()) {
371  BuildMI(&MBB, dl, get(ARC::BR)).addMBB(TBB);
372  return 1;
373  }
374  int BccOpc = Cond[1].isImm() ? ARC::BRcc_ru6_p : ARC::BRcc_rr_p;
375  MachineInstrBuilder MIB = BuildMI(&MBB, dl, get(BccOpc));
376  MIB.addMBB(TBB);
377  for (unsigned i = 0; i < 3; i++) {
378  MIB.add(Cond[i]);
379  }
380 
381  // One-way conditional branch.
382  if (!FBB) {
383  return 1;
384  }
385 
386  // Two-way conditional branch.
387  BuildMI(&MBB, dl, get(ARC::BR)).addMBB(FBB);
388  return 2;
389 }
390 
392  if (MI.getOpcode() == TargetOpcode::INLINEASM) {
393  const MachineFunction *MF = MI.getParent()->getParent();
394  const char *AsmStr = MI.getOperand(0).getSymbolName();
395  return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
396  }
397  return MI.getDesc().getSize();
398 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &dl, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
unsigned getReg() const
getReg - Returns the register number.
A debug info location.
Definition: DebugLoc.h:34
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
return AArch64::GPR64RegClass contains(Reg)
A description of a memory reference used in the backend.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
static bool isZeroImm(const MachineOperand &Op)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
static bool isLoad(int Opcode)
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
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...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:293
const char * getSymbolName() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:635
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:290
static bool isStore(int Opcode)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
static bool isJumpOpcode(int Opc)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getKillRegState(bool B)
static ARCCC::CondCode GetOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
static bool isCondBranchOpcode(int Opc)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:597
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE instructions.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
const MachineInstrBuilder & addFrameIndex(int Idx) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The memory access writes data.
static bool isUncondBranchOpcode(int Opc)
MachineOperand class - Representation of each machine instruction operand.
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Return the inverse opcode of the specified Branch instruction.
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e...
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:142
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
Definition: MachineInstr.h:60
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
#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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
#define DEBUG(X)
Definition: Debug.h:118
IRTranslator LLVM IR MI
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:298
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:569
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct load from a stack slot, return the virtual or physic...