LLVM  3.7.0
MipsInstrInfo.cpp
Go to the documentation of this file.
1 //===-- MipsInstrInfo.cpp - Mips Instruction Information ------------------===//
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 Mips implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsInstrInfo.h"
16 #include "MipsAnalyzeImmediate.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsSubtarget.h"
19 #include "llvm/ADT/STLExtras.h"
24 
25 using namespace llvm;
26 
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "MipsGenInstrInfo.inc"
29 
30 // Pin the vtable to this file.
31 void MipsInstrInfo::anchor() {}
32 
33 MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr)
34  : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
35  Subtarget(STI), UncondBrOpc(UncondBr) {}
36 
38  if (STI.inMips16Mode())
39  return llvm::createMips16InstrInfo(STI);
40 
41  return llvm::createMipsSEInstrInfo(STI);
42 }
43 
45  return op.isImm() && op.getImm() == 0;
46 }
47 
48 /// insertNoop - If data hazard condition is found insert the target nop
49 /// instruction.
50 void MipsInstrInfo::
52 {
53  DebugLoc DL;
54  BuildMI(MBB, MI, DL, get(Mips::NOP));
55 }
56 
58  unsigned Flag) const {
59  MachineFunction &MF = *MBB.getParent();
60  MachineFrameInfo &MFI = *MF.getFrameInfo();
61  unsigned Align = MFI.getObjectAlignment(FI);
62 
64  MFI.getObjectSize(FI), Align);
65 }
66 
67 //===----------------------------------------------------------------------===//
68 // Branch Analysis
69 //===----------------------------------------------------------------------===//
70 
71 void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
72  MachineBasicBlock *&BB,
73  SmallVectorImpl<MachineOperand> &Cond) const {
74  assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch");
75  int NumOp = Inst->getNumExplicitOperands();
76 
77  // for both int and fp branches, the last explicit operand is the
78  // MBB.
79  BB = Inst->getOperand(NumOp-1).getMBB();
81 
82  for (int i=0; i<NumOp-1; i++)
83  Cond.push_back(Inst->getOperand(i));
84 }
85 
87  MachineBasicBlock *&TBB,
88  MachineBasicBlock *&FBB,
90  bool AllowModify) const {
91  SmallVector<MachineInstr*, 2> BranchInstrs;
92  BranchType BT = AnalyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);
93 
94  return (BT == BT_None) || (BT == BT_Indirect);
95 }
96 
97 void
98 MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
99  DebugLoc DL, ArrayRef<MachineOperand> Cond) const {
100  unsigned Opc = Cond[0].getImm();
101  const MCInstrDesc &MCID = get(Opc);
102  MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);
103 
104  for (unsigned i = 1; i < Cond.size(); ++i) {
105  if (Cond[i].isReg())
106  MIB.addReg(Cond[i].getReg());
107  else if (Cond[i].isImm())
108  MIB.addImm(Cond[i].getImm());
109  else
110  assert(true && "Cannot copy operand");
111  }
112  MIB.addMBB(TBB);
113 }
114 
117  ArrayRef<MachineOperand> Cond, DebugLoc DL) const {
118  // Shouldn't be a fall through.
119  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
120 
121  // # of condition operands:
122  // Unconditional branches: 0
123  // Floating point branches: 1 (opc)
124  // Int BranchZero: 2 (opc, reg)
125  // Int Branch: 3 (opc, reg0, reg1)
126  assert((Cond.size() <= 3) &&
127  "# of Mips branch conditions must be <= 3!");
128 
129  // Two-way Conditional branch.
130  if (FBB) {
131  BuildCondBr(MBB, TBB, DL, Cond);
132  BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(FBB);
133  return 2;
134  }
135 
136  // One way branch.
137  // Unconditional branch.
138  if (Cond.empty())
139  BuildMI(&MBB, DL, get(UncondBrOpc)).addMBB(TBB);
140  else // Conditional branch.
141  BuildCondBr(MBB, TBB, DL, Cond);
142  return 1;
143 }
144 
146  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
148  unsigned removed;
149 
150  // Skip all the debug instructions.
151  while (I != REnd && I->isDebugValue())
152  ++I;
153 
154  FirstBr = I;
155 
156  // Up to 2 branches are removed.
157  // Note that indirect branches are not removed.
158  for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
159  if (!getAnalyzableBrOpc(I->getOpcode()))
160  break;
161 
162  MBB.erase(I.base(), FirstBr.base());
163 
164  return removed;
165 }
166 
167 /// ReverseBranchCondition - Return the inverse opcode of the
168 /// specified Branch instruction.
170  SmallVectorImpl<MachineOperand> &Cond) const {
171  assert( (Cond.size() && Cond.size() <= 3) &&
172  "Invalid Mips branch condition!");
173  Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
174  return false;
175 }
176 
179  SmallVectorImpl<MachineOperand> &Cond, bool AllowModify,
180  SmallVectorImpl<MachineInstr *> &BranchInstrs) const {
181 
182  MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
183 
184  // Skip all the debug instructions.
185  while (I != REnd && I->isDebugValue())
186  ++I;
187 
188  if (I == REnd || !isUnpredicatedTerminator(&*I)) {
189  // This block ends with no branches (it just falls through to its succ).
190  // Leave TBB/FBB null.
191  TBB = FBB = nullptr;
192  return BT_NoBranch;
193  }
194 
195  MachineInstr *LastInst = &*I;
196  unsigned LastOpc = LastInst->getOpcode();
197  BranchInstrs.push_back(LastInst);
198 
199  // Not an analyzable branch (e.g., indirect jump).
200  if (!getAnalyzableBrOpc(LastOpc))
201  return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;
202 
203  // Get the second to last instruction in the block.
204  unsigned SecondLastOpc = 0;
205  MachineInstr *SecondLastInst = nullptr;
206 
207  if (++I != REnd) {
208  SecondLastInst = &*I;
209  SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
210 
211  // Not an analyzable branch (must be an indirect jump).
212  if (isUnpredicatedTerminator(SecondLastInst) && !SecondLastOpc)
213  return BT_None;
214  }
215 
216  // If there is only one terminator instruction, process it.
217  if (!SecondLastOpc) {
218  // Unconditional branch.
219  if (LastOpc == UncondBrOpc) {
220  TBB = LastInst->getOperand(0).getMBB();
221  return BT_Uncond;
222  }
223 
224  // Conditional branch
225  AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
226  return BT_Cond;
227  }
228 
229  // If we reached here, there are two branches.
230  // If there are three terminators, we don't know what sort of block this is.
231  if (++I != REnd && isUnpredicatedTerminator(&*I))
232  return BT_None;
233 
234  BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
235 
236  // If second to last instruction is an unconditional branch,
237  // analyze it and remove the last instruction.
238  if (SecondLastOpc == UncondBrOpc) {
239  // Return if the last instruction cannot be removed.
240  if (!AllowModify)
241  return BT_None;
242 
243  TBB = SecondLastInst->getOperand(0).getMBB();
244  LastInst->eraseFromParent();
245  BranchInstrs.pop_back();
246  return BT_Uncond;
247  }
248 
249  // Conditional branch followed by an unconditional branch.
250  // The last one must be unconditional.
251  if (LastOpc != UncondBrOpc)
252  return BT_None;
253 
254  AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
255  FBB = LastInst->getOperand(0).getMBB();
256 
257  return BT_CondUncond;
258 }
259 
260 /// Return the number of bytes of code the specified instruction may be.
262  switch (MI->getOpcode()) {
263  default:
264  return MI->getDesc().getSize();
265  case TargetOpcode::INLINEASM: { // Inline Asm: Variable size.
266  const MachineFunction *MF = MI->getParent()->getParent();
267  const char *AsmStr = MI->getOperand(0).getSymbolName();
268  return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
269  }
270  case Mips::CONSTPOOL_ENTRY:
271  // If this machine instr is a constant pool entry, its size is recorded as
272  // operand #2.
273  return MI->getOperand(2).getImm();
274  }
275 }
276 
281  MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
282 
283  for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J)
284  MIB.addOperand(I->getOperand(J));
285 
286  MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end());
287  return MIB;
288 }
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isZeroImm(const MachineOperand &op) const
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, DebugLoc DL) const override
MachineBasicBlock * getMBB() const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:138
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:264
const char * getSymbolName() const
A debug info location.
Definition: DebugLoc.h:34
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
#define op(i)
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert nop instruction when hazard condition is found.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, unsigned f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
getMachineMemOperand - Allocate a new MachineMemOperand.
static MachinePointerInfo getFixedStack(int FI, int64_t offset=0)
getFixedStack - Return a MachinePointerInfo record that refers to the the specified FrameIndex...
bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Branch Analysis.
MachineMemOperand - A description of a memory reference used in the backend.
MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:31
int64_t getImm() const
reverse_iterator rend()
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:134
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:97
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:120
bundle_iterator< MachineInstr, instr_iterator > iterator
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
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:532
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
Definition: MachineInstr.h:433
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ReverseBranchCondition - Return the inverse opcode of the specified Branch instruction.
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:129
bool inMips16Mode() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
unsigned RemoveBranch(MachineBasicBlock &MBB) const override
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:481
Representation of each machine instruction.
Definition: MachineInstr.h:51
static MachineOperand CreateImm(int64_t Val)
#define I(x, y, z)
Definition: MD5.cpp:54
const MipsInstrInfo * createMipsSEInstrInfo(const MipsSubtarget &STI)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
std::reverse_iterator< iterator > reverse_iterator
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
unsigned GetInstSizeInBytes(const MachineInstr *MI) const
Return the number of bytes of code the specified instruction may be.
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, unsigned Flag) const
static const MipsInstrInfo * create(MipsSubtarget &STI)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc, MachineBasicBlock::iterator I) const
Create an instruction which has the same operands and memory operands as MI but has a new opcode...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.