llvm.org GIT mirror llvm / 86050dc
Allow ARM if-converter to be run after post allocation scheduling. - This fixed a number of bugs in if-converter, tail merging, and post-allocation scheduler. If-converter now runs branch folding / tail merging first to maximize if-conversion opportunities. - Also changed the t2IT instruction slightly. It now defines the ITSTATE register which is read by instructions in the IT block. - Added Thumb2 specific hazard recognizer to ensure the scheduler doesn't change the instruction ordering in the IT block (since IT mask has been finalized). It also ensures no other instructions can be scheduled between instructions in the IT block. This is not yet enabled. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106344 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 10 years ago
18 changed file(s) with 303 addition(s) and 83 deletion(s). Raw diff Collapse all Expand all
320320 assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
321321 return 0;
322322 }
323
324 /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
325 /// after it, replacing it with an unconditional branch to NewDest. This is
326 /// used by the tail merging pass.
327 virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
328 MachineBasicBlock *NewDest) const = 0;
323329
324330 /// copyRegToReg - Emit instructions to copy between a pair of registers. It
325331 /// returns false if the target does not how to copy between the specified
561567 return true;
562568 }
563569
570 /// isSchedulingBoundary - Test if the given instruction should be
571 /// considered a scheduling boundary. This primarily includes labels and
572 /// terminators.
573 virtual bool isSchedulingBoundary(const MachineInstr *MI,
574 const MachineBasicBlock *MBB,
575 const MachineFunction &MF) const = 0;
576
564577 /// GetInstSize - Returns the size of the specified Instruction.
565578 ///
566579 virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
594607 TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
595608 : TargetInstrInfo(desc, NumOpcodes) {}
596609 public:
610 virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
611 MachineBasicBlock *NewDest) const;
597612 virtual MachineInstr *commuteInstruction(MachineInstr *MI,
598613 bool NewMI = false) const;
599614 virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
609624 MachineFunction &MF) const;
610625 virtual bool produceSameValue(const MachineInstr *MI0,
611626 const MachineInstr *MI1) const;
627 virtual bool isSchedulingBoundary(const MachineInstr *MI,
628 const MachineBasicBlock *MBB,
629 const MachineFunction &MF) const;
612630 virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
613631
614632 virtual ScheduleHazardRecognizer *
357357 }
358358
359359 /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything
360 /// after it, replacing it with an unconditional branch to NewDest. This
361 /// returns true if OldInst's block is modified, false if NewDest is modified.
360 /// after it, replacing it with an unconditional branch to NewDest.
362361 void BranchFolder::ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
363362 MachineBasicBlock *NewDest) {
364 MachineBasicBlock *OldBB = OldInst->getParent();
365
366 // Remove all the old successors of OldBB from the CFG.
367 while (!OldBB->succ_empty())
368 OldBB->removeSuccessor(OldBB->succ_begin());
369
370 // Remove all the dead instructions from the end of OldBB.
371 OldBB->erase(OldInst, OldBB->end());
372
373 // If OldBB isn't immediately before OldBB, insert a branch to it.
374 if (++MachineFunction::iterator(OldBB) != MachineFunction::iterator(NewDest))
375 TII->InsertBranch(*OldBB, NewDest, 0, SmallVector(),
376 OldInst->getDebugLoc());
377 OldBB->addSuccessor(NewDest);
363 TII->ReplaceTailWithBranchTo(OldInst, NewDest);
378364 ++NumTailMerge;
379365 }
380366
233233 TII = MF.getTarget().getInstrInfo();
234234 TRI = MF.getTarget().getRegisterInfo();
235235 if (!TII) return false;
236
237 // Tail merge tend to expose more if-conversion opportunities.
238 BranchFolder BF(true);
239 bool BFChange = BF.OptimizeFunction(MF, TII,
240 MF.getTarget().getRegisterInfo(),
241 getAnalysisIfAvailable());
236242
237243 DEBUG(dbgs() << "\nIfcvt: function (" << ++FnNum << ") \'"
238244 << MF.getFunction()->getName() << "\'");
375381 getAnalysisIfAvailable());
376382 }
377383
384 MadeChange |= BFChange;
378385 return MadeChange;
379386 }
380387
389389 report("MBB exits via unconditional fall-through but its successor "
390390 "differs from its CFG successor!", MBB);
391391 }
392 if (!MBB->empty() && MBB->back().getDesc().isBarrier()) {
392 if (!MBB->empty() && MBB->back().getDesc().isBarrier() &&
393 !TII->isPredicated(&MBB->back())) {
393394 report("MBB exits via unconditional fall-through but ends with a "
394395 "barrier instruction!", MBB);
395396 }
7878 namespace {
7979 class PostRAScheduler : public MachineFunctionPass {
8080 AliasAnalysis *AA;
81 const TargetInstrInfo *TII;
8182 CodeGenOpt::Level OptLevel;
8283
8384 public:
180181 };
181182 }
182183
183 /// isSchedulingBoundary - Test if the given instruction should be
184 /// considered a scheduling boundary. This primarily includes labels
185 /// and terminators.
186 ///
187 static bool isSchedulingBoundary(const MachineInstr *MI,
188 const MachineFunction &MF) {
189 // Terminators and labels can't be scheduled around.
190 if (MI->getDesc().isTerminator() || MI->isLabel())
191 return true;
192
193 // Don't attempt to schedule around any instruction that defines
194 // a stack-oriented pointer, as it's unlikely to be profitable. This
195 // saves compile time, because it doesn't require every single
196 // stack slot reference to depend on the instruction that does the
197 // modification.
198 const TargetLowering &TLI = *MF.getTarget().getTargetLowering();
199 if (MI->definesRegister(TLI.getStackPointerRegisterToSaveRestore()))
200 return true;
201
202 return false;
203 }
204
205184 bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
206185 AA = &getAnalysis();
186 TII = Fn.getTarget().getInstrInfo();
207187
208188 // Check for explicit enable/disable of post-ra scheduling.
209189 TargetSubtarget::AntiDepBreakMode AntiDepMode = TargetSubtarget::ANTIDEP_NONE;
264244 MachineBasicBlock::iterator Current = MBB->end();
265245 unsigned Count = MBB->size(), CurrentCount = Count;
266246 for (MachineBasicBlock::iterator I = Current; I != MBB->begin(); ) {
267 MachineInstr *MI = prior(I);
268 if (isSchedulingBoundary(MI, Fn)) {
247 MachineInstr *MI = llvm::prior(I);
248 if (TII->isSchedulingBoundary(MI, MBB, Fn)) {
269249 Scheduler.Run(MBB, I, Current, CurrentCount);
270250 Scheduler.EmitSchedule();
271251 Current = MI;
1212 //===----------------------------------------------------------------------===//
1313
1414 #include "llvm/Target/TargetInstrInfo.h"
15 #include "llvm/Target/TargetLowering.h"
1516 #include "llvm/Target/TargetMachine.h"
1617 #include "llvm/Target/TargetRegisterInfo.h"
1718 #include "llvm/ADT/SmallVector.h"
2526 #include "llvm/Support/ErrorHandling.h"
2627 #include "llvm/Support/raw_ostream.h"
2728 using namespace llvm;
29
30 void
31 TargetInstrInfoImpl::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
32 MachineBasicBlock *NewDest) const {
33 MachineBasicBlock *MBB = Tail->getParent();
34
35 // Remove all the old successors of MBB from the CFG.
36 while (!MBB->succ_empty())
37 MBB->removeSuccessor(MBB->succ_begin());
38
39 // Remove all the dead instructions from the end of MBB.
40 MBB->erase(Tail, MBB->end());
41
42 // If MBB isn't immediately before MBB, insert a branch to it.
43 if (++MachineFunction::iterator(MBB) != MachineFunction::iterator(NewDest))
44 InsertBranch(*MBB, NewDest, 0, SmallVector(),
45 Tail->getDebugLoc());
46 MBB->addSuccessor(NewDest);
47 }
2848
2949 // commuteInstruction - The default implementation of this method just exchanges
3050 // the two operands returned by findCommutedOpIndices.
315335 return true;
316336 }
317337
338 /// isSchedulingBoundary - Test if the given instruction should be
339 /// considered a scheduling boundary. This primarily includes labels
340 /// and terminators.
341 bool TargetInstrInfoImpl::isSchedulingBoundary(const MachineInstr *MI,
342 const MachineBasicBlock *MBB,
343 const MachineFunction &MF) const{
344 // Terminators and labels can't be scheduled around.
345 if (MI->getDesc().isTerminator() || MI->isLabel())
346 return true;
347
348 // Don't attempt to schedule around any instruction that defines
349 // a stack-oriented pointer, as it's unlikely to be profitable. This
350 // saves compile time, because it doesn't require every single
351 // stack slot reference to depend on the instruction that does the
352 // modification.
353 const TargetLowering &TLI = *MF.getTarget().getTargetLowering();
354 if (MI->definesRegister(TLI.getStackPointerRegisterToSaveRestore()))
355 return true;
356
357 return false;
358 }
359
318360 // Default implementation of CreateTargetPostRAHazardRecognizer.
319361 ScheduleHazardRecognizer *TargetInstrInfoImpl::
320362 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
13051305 return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
13061306 }
13071307
1308 bool ARMBaseInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
1309 const MachineBasicBlock *MBB,
1310 const MachineFunction &MF) const {
1311 // Terminators and labels can't be scheduled around.
1312 if (MI->getDesc().isTerminator() || MI->isLabel())
1313 return true;
1314
1315 // Treat the start of the IT block as a scheduling boundary, but schedule
1316 // t2IT along with all instructions following it.
1317 // FIXME: This is a big hammer. But the alternative is to add all potential
1318 // true and anti dependencies to IT block instructions as implicit operands
1319 // to the t2IT instruction. The added compile time and complexity does not
1320 // seem worth it.
1321 MachineBasicBlock::const_iterator I = MI;
1322 if (++I != MBB->end() && I->getOpcode() == ARM::t2IT)
1323 return true;
1324
1325 // Don't attempt to schedule around any instruction that defines
1326 // a stack-oriented pointer, as it's unlikely to be profitable. This
1327 // saves compile time, because it doesn't require every single
1328 // stack slot reference to depend on the instruction that does the
1329 // modification.
1330 if (MI->definesRegister(ARM::SP))
1331 return true;
1332
1333 return false;
1334 }
1335
13081336 /// getInstrPredicate - If instruction is predicated, returns its predicate
13091337 /// condition, otherwise returns AL. It also returns the condition code
13101338 /// register by reference.
318318
319319 virtual bool produceSameValue(const MachineInstr *MI0,
320320 const MachineInstr *MI1) const;
321
322 virtual bool isSchedulingBoundary(const MachineInstr *MI,
323 const MachineBasicBlock *MBB,
324 const MachineFunction &MF) const;
321325 };
322326
323327 static inline
25272527
25282528
25292529 // IT block
2530 let Defs = [ITSTATE] in
25302531 def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
25312532 AddrModeNone, Size2Bytes, IIC_iALUx,
25322533 "it$mask\t$cc", "", []> {
8686
8787 /// VarArgsFrameIndex - FrameIndex for start of varargs area.
8888 int VarArgsFrameIndex;
89
90 /// HasITBlocks - True if IT blocks have been inserted.
91 bool HasITBlocks;
8992
9093 public:
9194 ARMFunctionInfo() :
9699 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
97100 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
98101 GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
99 JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0) {}
102 JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
103 HasITBlocks(false) {}
100104
101105 explicit ARMFunctionInfo(MachineFunction &MF) :
102106 isThumb(MF.getTarget().getSubtarget().isThumb()),
107111 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
108112 GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
109113 SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()),
110 JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0) {}
114 JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
115 HasITBlocks(false) {}
111116
112117 bool isThumbFunction() const { return isThumb; }
113118 bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
228233
229234 int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
230235 void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
236
237 bool hasITBlocks() const { return HasITBlocks; }
238 void setHasITBlocks(bool h) { HasITBlocks = h; }
231239 };
232240 } // End llvm namespace
233241
196196 }
197197
198198 // Current Program Status Register.
199 def CPSR : ARMReg<0, "cpsr">;
200
201 def FPSCR : ARMReg<1, "fpscr">;
199 def CPSR : ARMReg<0, "cpsr">;
200 def FPSCR : ARMReg<1, "fpscr">;
201 def ITSTATE : ARMReg<2, "itstate">;
202202
203203 // Register classes.
204204 //
556556
557557 // Condition code registers.
558558 def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]>;
559
130130 PM.add(createARMExpandPseudoPass());
131131
132132 if (EarlyIfConvert && OptLevel != CodeGenOpt::None) {
133 if (!Subtarget.isThumb1Only())
133 if (!Subtarget.isThumb1Only())
134134 PM.add(createIfConverterPass());
135 if (Subtarget.isThumb2())
136 PM.add(createThumb2ITBlockPass());
135137 }
136138
137139 return true;
145147 }
146148
147149 if (Subtarget.isThumb2()) {
148 PM.add(createThumb2ITBlockPass());
150 if (!EarlyIfConvert)
151 PM.add(createThumb2ITBlockPass());
149152 PM.add(createThumb2SizeReductionPass());
150153 }
151154
3030 MachineFunctionPass(&ID), PreRegAlloc(PreRA) {}
3131
3232 const Thumb2InstrInfo *TII;
33 const TargetRegisterInfo *TRI;
3334 ARMFunctionInfo *AFI;
3435
3536 virtual bool runOnMachineFunction(MachineFunction &Fn);
5152 SmallVector &LastUses);
5253 bool InsertITBlock(MachineInstr *First, MachineInstr *Last);
5354 bool InsertITBlocks(MachineBasicBlock &MBB);
55 bool MoveCopyOutOfITBlock(MachineInstr *MI,
56 ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
57 SmallSet &Defs,
58 SmallSet &Uses);
5459 bool InsertITInstructions(MachineBasicBlock &MBB);
5560 };
5661 char Thumb2ITBlockPass::ID = 0;
248253 return Modified;
249254 }
250255
251 static void TrackDefUses(MachineInstr *MI, SmallSet &Defs,
252 SmallSet &Uses) {
256 /// TrackDefUses - Tracking what registers are being defined and used by
257 /// instructions in the IT block. This also tracks "dependencies", i.e. uses
258 /// in the IT block that are defined before the IT instruction.
259 static void TrackDefUses(MachineInstr *MI,
260 SmallSet &Defs,
261 SmallSet &Uses,
262 const TargetRegisterInfo *TRI) {
263 SmallVector LocalDefs;
264 SmallVector LocalUses;
265
253266 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
254267 MachineOperand &MO = MI->getOperand(i);
255268 if (!MO.isReg())
256269 continue;
257270 unsigned Reg = MO.getReg();
258 if (!Reg)
271 if (!Reg || Reg == ARM::ITSTATE || Reg == ARM::SP)
259272 continue;
260 if (MO.isDef())
261 Defs.insert(Reg);
273 if (MO.isUse())
274 LocalUses.push_back(Reg);
262275 else
263 Uses.insert(Reg);
264 }
276 LocalDefs.push_back(Reg);
277 }
278
279 for (unsigned i = 0, e = LocalUses.size(); i != e; ++i) {
280 unsigned Reg = LocalUses[i];
281 Uses.insert(Reg);
282 for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
283 *Subreg; ++Subreg)
284 Uses.insert(*Subreg);
285 }
286
287 for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
288 unsigned Reg = LocalDefs[i];
289 Defs.insert(Reg);
290 for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
291 *Subreg; ++Subreg)
292 Defs.insert(*Subreg);
293 if (Reg == ARM::CPSR)
294 continue;
295 }
296 }
297
298 bool
299 Thumb2ITBlockPass::MoveCopyOutOfITBlock(MachineInstr *MI,
300 ARMCC::CondCodes CC, ARMCC::CondCodes OCC,
301 SmallSet &Defs,
302 SmallSet &Uses) {
303 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
304 if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
305 assert(SrcSubIdx == 0 && DstSubIdx == 0 &&
306 "Sub-register indices still around?");
307 // llvm models select's as two-address instructions. That means a copy
308 // is inserted before a t2MOVccr, etc. If the copy is scheduled in
309 // between selects we would end up creating multiple IT blocks.
310
311 // First check if it's safe to move it.
312 if (Uses.count(DstReg) || Defs.count(SrcReg))
313 return false;
314
315 // Then peek at the next instruction to see if it's predicated on CC or OCC.
316 // If not, then there is nothing to be gained by moving the copy.
317 MachineBasicBlock::iterator I = MI; ++I;
318 MachineBasicBlock::iterator E = MI->getParent()->end();
319 while (I != E && I->isDebugValue())
320 ++I;
321 unsigned NPredReg = 0;
322 ARMCC::CondCodes NCC = getPredicate(I, NPredReg);
323 if (NCC == CC || NCC == OCC)
324 return true;
325 }
326 return false;
265327 }
266328
267329 bool Thumb2ITBlockPass::InsertITInstructions(MachineBasicBlock &MBB) {
282344
283345 Defs.clear();
284346 Uses.clear();
285 TrackDefUses(MI, Defs, Uses);
347 TrackDefUses(MI, Defs, Uses, TRI);
286348
287349 // Insert an IT instruction.
288350 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT))
289351 .addImm(CC);
352
353 // Add implicit use of ITSTATE to IT block instructions.
354 MI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
355 true/*isImp*/, false/*isKill*/));
356
357 MachineInstr *LastITMI = MI;
290358 MachineBasicBlock::iterator InsertPos = MIB;
291359 ++MBBI;
292360
293 // Finalize IT mask.
361 // Form IT block.
294362 ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC);
295363 unsigned Mask = 0, Pos = 3;
296364 // Branches, including tricky ones like LDM_RET, need to end an IT
305373
306374 unsigned NPredReg = 0;
307375 ARMCC::CondCodes NCC = getPredicate(NMI, NPredReg);
308 if (NCC == CC || NCC == OCC)
376 if (NCC == CC || NCC == OCC) {
309377 Mask |= (NCC & 1) << Pos;
310 else {
311 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
378 // Add implicit use of ITSTATE.
379 NMI->addOperand(MachineOperand::CreateReg(ARM::ITSTATE, false/*ifDef*/,
380 true/*isImp*/, false/*isKill*/));
381 LastITMI = NMI;
382 } else {
312383 if (NCC == ARMCC::AL &&
313 TII->isMoveInstr(*NMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
314 assert(SrcSubIdx == 0 && DstSubIdx == 0 &&
315 "Sub-register indices still around?");
316 // llvm models select's as two-address instructions. That means a copy
317 // is inserted before a t2MOVccr, etc. If the copy is scheduled in
318 // between selects we would end up creating multiple IT blocks.
319 if (!Uses.count(DstReg) && !Defs.count(SrcReg)) {
320 --MBBI;
321 MBB.remove(NMI);
322 MBB.insert(InsertPos, NMI);
323 ++NumMovedInsts;
324 continue;
325 }
384 MoveCopyOutOfITBlock(NMI, CC, OCC, Defs, Uses)) {
385 --MBBI;
386 MBB.remove(NMI);
387 MBB.insert(InsertPos, NMI);
388 ++NumMovedInsts;
389 continue;
326390 }
327391 break;
328392 }
329 TrackDefUses(NMI, Defs, Uses);
393 TrackDefUses(NMI, Defs, Uses, TRI);
330394 --Pos;
331395 }
332396
397 // Finalize IT mask.
333398 Mask |= (1 << Pos);
334399 // Tag along (firstcond[0] << 4) with the mask.
335400 Mask |= (CC & 1) << 4;
336401 MIB.addImm(Mask);
402
403 // Last instruction in IT block kills ITSTATE.
404 LastITMI->findRegisterUseOperand(ARM::ITSTATE)->setIsKill();
405
337406 Modified = true;
338407 ++NumITs;
339408 }
345414 const TargetMachine &TM = Fn.getTarget();
346415 AFI = Fn.getInfo();
347416 TII = static_cast(TM.getInstrInfo());
417 TRI = TM.getRegisterInfo();
348418
349419 if (!AFI->isThumbFunction())
350420 return false;
359429 Modified |= InsertITInstructions(MBB);
360430 }
361431
432 if (Modified && !PreRegAlloc)
433 AFI->setHasITBlocks(true);
434
362435 return Modified;
363436 }
364437
1616 #include "ARMAddressingModes.h"
1717 #include "ARMGenInstrInfo.inc"
1818 #include "ARMMachineFunctionInfo.h"
19 #include "Thumb2HazardRecognizer.h"
20 #include "Thumb2InstrInfo.h"
1921 #include "llvm/CodeGen/MachineFrameInfo.h"
2022 #include "llvm/CodeGen/MachineInstrBuilder.h"
2123 #include "llvm/CodeGen/MachineMemOperand.h"
2224 #include "llvm/CodeGen/PseudoSourceValue.h"
2325 #include "llvm/ADT/SmallVector.h"
24 #include "Thumb2InstrInfo.h"
2526
2627 using namespace llvm;
2728
3233 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
3334 // FIXME
3435 return 0;
36 }
37
38 void
39 Thumb2InstrInfo::ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
40 MachineBasicBlock *NewDest) const {
41 MachineBasicBlock *MBB = Tail->getParent();
42 ARMFunctionInfo *AFI = MBB->getParent()->getInfo();
43 if (!AFI->hasITBlocks()) {
44 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest);
45 return;
46 }
47
48 // If the first instruction of Tail is predicated, we may have to update
49 // the IT instruction.
50 unsigned PredReg = 0;
51 ARMCC::CondCodes CC = llvm::getInstrPredicate(Tail, PredReg);
52 MachineBasicBlock::iterator MBBI = Tail;
53 if (CC != ARMCC::AL)
54 // Expecting at least the t2IT instruction before it.
55 --MBBI;
56
57 // Actually replace the tail.
58 TargetInstrInfoImpl::ReplaceTailWithBranchTo(Tail, NewDest);
59
60 // Fix up IT.
61 if (CC != ARMCC::AL) {
62 MachineBasicBlock::iterator E = MBB->begin();
63 unsigned Count = 4; // At most 4 instructions in an IT block.
64 while (Count && MBBI != E) {
65 if (MBBI->isDebugValue()) {
66 --MBBI;
67 continue;
68 }
69 if (MBBI->getOpcode() == ARM::t2IT) {
70 unsigned Mask = MBBI->getOperand(1).getImm();
71 if (Count == 4)
72 MBBI->eraseFromParent();
73 else {
74 unsigned MaskOn = 1 << Count;
75 unsigned MaskOff = ~(MaskOn - 1);
76 MBBI->getOperand(1).setImm((Mask & MaskOff) | MaskOn);
77 }
78 return;
79 }
80 --MBBI;
81 --Count;
82 }
83
84 // Ctrl flow can reach here if branch folding is run before IT block
85 // formation pass.
86 }
3587 }
3688
3789 bool
113165 }
114166
115167 ARMBaseInstrInfo::loadRegFromStackSlot(MBB, I, DestReg, FI, RC, TRI);
168 }
169
170 ScheduleHazardRecognizer *Thumb2InstrInfo::
171 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const {
172 return (ScheduleHazardRecognizer *)new Thumb2HazardRecognizer(II);
116173 }
117174
118175 void llvm::emitT2RegPlusImmediate(MachineBasicBlock &MBB,
1919 #include "Thumb2RegisterInfo.h"
2020
2121 namespace llvm {
22 class ARMSubtarget;
22 class ARMSubtarget;
23 class ScheduleHazardRecognizer;
2324
2425 class Thumb2InstrInfo : public ARMBaseInstrInfo {
2526 Thumb2RegisterInfo RI;
2930 // Return the non-pre/post incrementing version of 'Opc'. Return 0
3031 // if there is not such an opcode.
3132 unsigned getUnindexedOpcode(unsigned Opc) const;
33
34 void ReplaceTailWithBranchTo(MachineBasicBlock::iterator Tail,
35 MachineBasicBlock *NewDest) const;
3236
3337 bool copyRegToReg(MachineBasicBlock &MBB,
3438 MachineBasicBlock::iterator I,
5963 /// always be able to get register info as well (through this method).
6064 ///
6165 const Thumb2RegisterInfo &getRegisterInfo() const { return RI; }
66
67 ScheduleHazardRecognizer *
68 CreateTargetPostRAHazardRecognizer(const InstrItineraryData &II) const;
6269 };
6370 }
6471
None ; RUN: llc < %s -march=arm > %t
1 ; RUN: grep bxlt %t | count 1
2 ; RUN: grep bxgt %t | count 1
3 ; RUN: not grep bxge %t
4 ; RUN: not grep bxle %t
0 ; RUN: llc < %s -march=arm | FileCheck %s
51
62 define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) {
3 ; CHECK: t1:
4 ; CHECK: bxlt lr
75 %tmp2 = icmp sgt i32 %c, 10
86 %tmp5 = icmp slt i32 %d, 4
97 %tmp8 = or i1 %tmp5, %tmp2
2018 }
2119
2220 define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) {
21 ; CHECK: t2:
22 ; CHECK: bxgt lr
23 ; CHECK: cmp
24 ; CHECK: addge
25 ; CHECK: subge
26 ; CHECK-NOT: bxge lr
27 ; CHECK: bx lr
2328 %tmp2 = icmp sgt i32 %c, 10
2429 %tmp5 = icmp slt i32 %d, 4
2530 %tmp8 = and i1 %tmp5, %tmp2
2020
2121 bb9: ; preds = %bb7
2222 ; CHECK: cmp r0, #0
23 ; CHECK-NEXT: cmp r0, #0
23 ; CHECK: cmp r0, #0
2424 ; CHECK-NEXT: cbnz
2525 %0 = tail call double @floor(double %b) nounwind readnone ; [#uses=0]
2626 br label %bb11
3131 ; CHECK: it eq
3232 ; CHECK: cmpeq
3333 ; CHECK: bne
34 ; CHECK: cmp
3435 ; CHECK: itt eq
3536 ; CHECK: moveq
3637 ; CHECK: popeq