LLVM  6.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::LT:
107  return ARCCC::GE;
108  case ARCCC::LE:
109  return ARCCC::GT;
110  case ARCCC::HI:
111  return ARCCC::LS;
112  case ARCCC::LS:
113  return ARCCC::HI;
114  case ARCCC::NZ:
115  return ARCCC::Z;
116  case ARCCC::Z:
117  return ARCCC::NZ;
118  }
119 }
120 
121 static bool isUncondBranchOpcode(int Opc) { return Opc == ARC::BR; }
122 
123 static bool isCondBranchOpcode(int Opc) {
124  return Opc == ARC::BRcc_rr_p || Opc == ARC::BRcc_ru6_p;
125 }
126 
127 static bool isJumpOpcode(int Opc) { return Opc == ARC::J; }
128 
129 /// Analyze the branching code at the end of MBB, returning
130 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
131 /// implemented for a target). Upon success, this returns false and returns
132 /// with the following information in various cases:
133 ///
134 /// 1. If this block ends with no branches (it just falls through to its succ)
135 /// just return false, leaving TBB/FBB null.
136 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
137 /// the destination block.
138 /// 3. If this block ends with a conditional branch and it falls through to a
139 /// successor block, it sets TBB to be the branch destination block and a
140 /// list of operands that evaluate the condition. These operands can be
141 /// passed to other TargetInstrInfo methods to create new branches.
142 /// 4. If this block ends with a conditional branch followed by an
143 /// unconditional branch, it returns the 'true' destination in TBB, the
144 /// 'false' destination in FBB, and a list of operands that evaluate the
145 /// condition. These operands can be passed to other TargetInstrInfo
146 /// methods to create new branches.
147 ///
148 /// Note that RemoveBranch and InsertBranch must be implemented to support
149 /// cases where this method returns success.
150 ///
151 /// If AllowModify is true, then this routine is allowed to modify the basic
152 /// block (e.g. delete instructions after the unconditional branch).
153 
155  MachineBasicBlock *&TBB,
156  MachineBasicBlock *&FBB,
158  bool AllowModify) const {
159  TBB = FBB = nullptr;
161  if (I == MBB.begin())
162  return false;
163  --I;
164 
165  while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
166  // Flag to be raised on unanalyzeable instructions. This is useful in cases
167  // where we want to clean up on the end of the basic block before we bail
168  // out.
169  bool CantAnalyze = false;
170 
171  // Skip over DEBUG values and predicated nonterminators.
172  while (I->isDebugValue() || !I->isTerminator()) {
173  if (I == MBB.begin())
174  return false;
175  --I;
176  }
177 
178  if (isJumpOpcode(I->getOpcode())) {
179  // Indirect branches and jump tables can't be analyzed, but we still want
180  // to clean up any instructions at the tail of the basic block.
181  CantAnalyze = true;
182  } else if (isUncondBranchOpcode(I->getOpcode())) {
183  TBB = I->getOperand(0).getMBB();
184  } else if (isCondBranchOpcode(I->getOpcode())) {
185  // Bail out if we encounter multiple conditional branches.
186  if (!Cond.empty())
187  return true;
188 
189  assert(!FBB && "FBB should have been null.");
190  FBB = TBB;
191  TBB = I->getOperand(0).getMBB();
192  Cond.push_back(I->getOperand(1));
193  Cond.push_back(I->getOperand(2));
194  Cond.push_back(I->getOperand(3));
195  } else if (I->isReturn()) {
196  // Returns can't be analyzed, but we should run cleanup.
197  CantAnalyze = !isPredicated(*I);
198  } else {
199  // We encountered other unrecognized terminator. Bail out immediately.
200  return true;
201  }
202 
203  // Cleanup code - to be run for unpredicated unconditional branches and
204  // returns.
205  if (!isPredicated(*I) && (isUncondBranchOpcode(I->getOpcode()) ||
206  isJumpOpcode(I->getOpcode()) || I->isReturn())) {
207  // Forget any previous condition branch information - it no longer
208  // applies.
209  Cond.clear();
210  FBB = nullptr;
211 
212  // If we can modify the function, delete everything below this
213  // unconditional branch.
214  if (AllowModify) {
215  MachineBasicBlock::iterator DI = std::next(I);
216  while (DI != MBB.end()) {
217  MachineInstr &InstToDelete = *DI;
218  ++DI;
219  InstToDelete.eraseFromParent();
220  }
221  }
222  }
223 
224  if (CantAnalyze)
225  return true;
226 
227  if (I == MBB.begin())
228  return false;
229 
230  --I;
231  }
232 
233  // We made it past the terminators without bailing out - we must have
234  // analyzed this branch successfully.
235  return false;
236 }
237 
239  int *BytesRemoved) const {
240  assert(!BytesRemoved && "Code size not handled");
242  if (I == MBB.end())
243  return 0;
244 
245  if (!isUncondBranchOpcode(I->getOpcode()) &&
246  !isCondBranchOpcode(I->getOpcode()))
247  return 0;
248 
249  // Remove the branch.
250  I->eraseFromParent();
251 
252  I = MBB.end();
253 
254  if (I == MBB.begin())
255  return 1;
256  --I;
257  if (!isCondBranchOpcode(I->getOpcode()))
258  return 1;
259 
260  // Remove the branch.
261  I->eraseFromParent();
262  return 2;
263 }
264 
267  const DebugLoc &dl, unsigned DestReg,
268  unsigned SrcReg, bool KillSrc) const {
269  assert(ARC::GPR32RegClass.contains(SrcReg) &&
270  "Only GPR32 src copy supported.");
271  assert(ARC::GPR32RegClass.contains(DestReg) &&
272  "Only GPR32 dest copy supported.");
273  BuildMI(MBB, I, dl, get(ARC::MOV_rr), DestReg)
274  .addReg(SrcReg, getKillRegState(KillSrc));
275 }
276 
279  unsigned SrcReg, bool isKill,
280  int FrameIndex,
281  const TargetRegisterClass *RC,
282  const TargetRegisterInfo *TRI) const {
283  DebugLoc dl = MBB.findDebugLoc(I);
284  MachineFunction &MF = *MBB.getParent();
285  MachineFrameInfo &MFI = MF.getFrameInfo();
286  unsigned Align = MFI.getObjectAlignment(FrameIndex);
287 
289  MachinePointerInfo::getFixedStack(MF, FrameIndex),
291 
292  assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
293  assert(TRI->getSpillSize(*RC) == 4 &&
294  "Only support 4-byte stores to stack now.");
295  assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
296  "Only support GPR32 stores to stack now.");
297  DEBUG(dbgs() << "Created store reg=" << PrintReg(SrcReg, TRI)
298  << " to FrameIndex=" << FrameIndex << "\n");
299  BuildMI(MBB, I, dl, get(ARC::ST_rs9))
300  .addReg(SrcReg, getKillRegState(isKill))
301  .addFrameIndex(FrameIndex)
302  .addImm(0)
303  .addMemOperand(MMO);
304 }
305 
308  unsigned DestReg, int FrameIndex,
309  const TargetRegisterClass *RC,
310  const TargetRegisterInfo *TRI) const {
311  DebugLoc dl = MBB.findDebugLoc(I);
312  MachineFunction &MF = *MBB.getParent();
313  MachineFrameInfo &MFI = MF.getFrameInfo();
314  unsigned Align = MFI.getObjectAlignment(FrameIndex);
316  MachinePointerInfo::getFixedStack(MF, FrameIndex),
317  MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), Align);
318 
319  assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
320  assert(TRI->getSpillSize(*RC) == 4 &&
321  "Only support 4-byte loads from stack now.");
322  assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
323  "Only support GPR32 stores to stack now.");
324  DEBUG(dbgs() << "Created load reg=" << PrintReg(DestReg, TRI)
325  << " from FrameIndex=" << FrameIndex << "\n");
326  BuildMI(MBB, I, dl, get(ARC::LD_rs9))
327  .addReg(DestReg, RegState::Define)
328  .addFrameIndex(FrameIndex)
329  .addImm(0)
330  .addMemOperand(MMO);
331 }
332 
333 /// Return the inverse opcode of the specified Branch instruction.
335  SmallVectorImpl<MachineOperand> &Cond) const {
336  assert((Cond.size() == 3) && "Invalid ARC branch condition!");
337  Cond[2].setImm(GetOppositeBranchCondition((ARCCC::CondCode)Cond[2].getImm()));
338  return false;
339 }
340 
344  uint64_t Value) const {
345  DebugLoc dl = MBB.findDebugLoc(MI);
346  if (isInt<12>(Value)) {
347  return BuildMI(MBB, MI, dl, get(ARC::MOV_rs12), Reg)
348  .addImm(Value)
349  .getInstr();
350  }
351  llvm_unreachable("Need Arc long immediate instructions.");
352 }
353 
355  MachineBasicBlock *TBB,
356  MachineBasicBlock *FBB,
358  const DebugLoc &dl, int *BytesAdded) const {
359  assert(!BytesAdded && "Code size not handled.");
360 
361  // Shouldn't be a fall through.
362  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
363  assert((Cond.size() == 3 || Cond.size() == 0) &&
364  "ARC branch conditions have two components!");
365 
366  if (Cond.empty()) {
367  BuildMI(&MBB, dl, get(ARC::BR)).addMBB(TBB);
368  return 1;
369  }
370  int BccOpc = Cond[1].isImm() ? ARC::BRcc_ru6_p : ARC::BRcc_rr_p;
371  MachineInstrBuilder MIB = BuildMI(&MBB, dl, get(BccOpc));
372  MIB.addMBB(TBB);
373  for (unsigned i = 0; i < 3; i++) {
374  MIB.add(Cond[i]);
375  }
376 
377  // One-way conditional branch.
378  if (!FBB) {
379  return 1;
380  }
381 
382  // Two-way conditional branch.
383  BuildMI(&MBB, dl, get(ARC::BR)).addMBB(FBB);
384  return 2;
385 }
386 
388  if (MI.getOpcode() == TargetOpcode::INLINEASM) {
389  const MachineFunction *MF = MI.getParent()->getParent();
390  const char *AsmStr = MI.getOperand(0).getSymbolName();
391  return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
392  }
393  return MI.getDesc().getSize();
394 }
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:290
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:634
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:287
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)
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
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:596
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:139
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:59
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:295
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...