Skip to content

Commit ab302cd

Browse files
committed
AArch64: Use TTI branch functions in branch relaxation
The main change is to return the code size from InsertBranch/RemoveBranch. Patch mostly by Tim Northover git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281505 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b4dbf03 commit ab302cd

36 files changed

+287
-247
lines changed

include/llvm/Target/TargetInstrInfo.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -525,15 +525,18 @@ class TargetInstrInfo : public MCInstrInfo {
525525
/// Remove the branching code at the end of the specific MBB.
526526
/// This is only invoked in cases where AnalyzeBranch returns success. It
527527
/// returns the number of instructions that were removed.
528-
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
528+
/// If \p BytesRemoved is non-null, report the change in code size from the
529+
/// removed instructions.
530+
virtual unsigned RemoveBranch(MachineBasicBlock &MBB,
531+
int *BytesRemoved = nullptr) const {
529532
llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!");
530533
}
531534

532-
/// Insert branch code into the end of the specified MachineBasicBlock.
533-
/// The operands to this method are the same as those
534-
/// returned by AnalyzeBranch. This is only invoked in cases where
535-
/// AnalyzeBranch returns success. It returns the number of instructions
536-
/// inserted.
535+
/// Insert branch code into the end of the specified MachineBasicBlock. The
536+
/// operands to this method are the same as those returned by AnalyzeBranch.
537+
/// This is only invoked in cases where AnalyzeBranch returns success. It
538+
/// returns the number of instructions inserted. If \p BytesAdded is non-null,
539+
/// report the change in code size from the added instructions.
537540
///
538541
/// It is also invoked by tail merging to add unconditional branches in
539542
/// cases where AnalyzeBranch doesn't apply because there was no original
@@ -545,10 +548,19 @@ class TargetInstrInfo : public MCInstrInfo {
545548
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
546549
MachineBasicBlock *FBB,
547550
ArrayRef<MachineOperand> Cond,
548-
const DebugLoc &DL) const {
551+
const DebugLoc &DL,
552+
int *BytesAdded = nullptr) const {
549553
llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!");
550554
}
551555

556+
unsigned insertUnconditionalBranch(MachineBasicBlock &MBB,
557+
MachineBasicBlock *DestBB,
558+
const DebugLoc &DL,
559+
int *BytesAdded = nullptr) const {
560+
return InsertBranch(MBB, DestBB, nullptr,
561+
ArrayRef<MachineOperand>(), DL, BytesAdded);
562+
}
563+
552564
/// Analyze the loop code, return true if it cannot be understoo. Upon
553565
/// success, this function returns false and returns information about the
554566
/// induction variable and compare instruction used at the end.

lib/Target/AArch64/AArch64BranchRelaxation.cpp

Lines changed: 53 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,6 @@ class AArch64BranchRelaxation : public MachineFunctionPass {
7474
void adjustBlockOffsets(MachineBasicBlock &MBB);
7575
bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const;
7676

77-
unsigned insertInvertedConditionalBranch(MachineBasicBlock &SrcBB,
78-
MachineBasicBlock::iterator InsPt,
79-
const DebugLoc &DL,
80-
const MachineInstr &OldBr,
81-
MachineBasicBlock &NewDestBB) const;
82-
unsigned insertUnconditionalBranch(MachineBasicBlock &MBB,
83-
MachineBasicBlock &NewDestBB,
84-
const DebugLoc &DL) const;
85-
8677
bool fixupConditionalBranch(MachineInstr &MI);
8778
void computeBlockSize(const MachineBasicBlock &MBB);
8879
unsigned getInstrOffset(const MachineInstr &MI) const;
@@ -130,22 +121,6 @@ void AArch64BranchRelaxation::dumpBBs() {
130121
}
131122
}
132123

133-
// FIXME: This is a less precise version of MachineBasicBlock::canFallThrough?
134-
135-
/// \returns true if the specified basic block can fallthrough
136-
/// into the block immediately after it.
137-
static bool hasFallthrough(const MachineBasicBlock &MBB) {
138-
// Get the next machine basic block in the function.
139-
MachineFunction::const_iterator MBBI(MBB);
140-
141-
// Can't fall off end of function.
142-
auto NextBB = std::next(MBBI);
143-
if (NextBB == MBB.getParent()->end())
144-
return false;
145-
146-
return MBB.isSuccessor(&*NextBB);
147-
}
148-
149124
/// scanFunction - Do the initial scan of the function, building up
150125
/// information about each block.
151126
void AArch64BranchRelaxation::scanFunction() {
@@ -228,7 +203,7 @@ AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) {
228203
// Note the new unconditional branch is not being recorded.
229204
// There doesn't seem to be meaningful DebugInfo available; this doesn't
230205
// correspond to anything in the source.
231-
insertUnconditionalBranch(*OrigBB, *NewBB, DebugLoc());
206+
TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc());
232207

233208
// Insert an entry into BlockInfo to align it properly with the block numbers.
234209
BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
@@ -293,91 +268,18 @@ static MachineBasicBlock *getDestBlock(const MachineInstr &MI) {
293268
}
294269
}
295270

296-
static unsigned getOppositeConditionOpcode(unsigned Opc) {
297-
switch (Opc) {
298-
default:
299-
llvm_unreachable("unexpected opcode!");
300-
case AArch64::TBNZW: return AArch64::TBZW;
301-
case AArch64::TBNZX: return AArch64::TBZX;
302-
case AArch64::TBZW: return AArch64::TBNZW;
303-
case AArch64::TBZX: return AArch64::TBNZX;
304-
case AArch64::CBNZW: return AArch64::CBZW;
305-
case AArch64::CBNZX: return AArch64::CBZX;
306-
case AArch64::CBZW: return AArch64::CBNZW;
307-
case AArch64::CBZX: return AArch64::CBNZX;
308-
case AArch64::Bcc: return AArch64::Bcc; // Condition is an operand for Bcc.
309-
}
310-
}
311-
312-
static inline void invertBccCondition(MachineInstr &MI) {
313-
assert(MI.getOpcode() == AArch64::Bcc && "Unexpected opcode!");
314-
MachineOperand &CCOp = MI.getOperand(0);
315-
316-
AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(CCOp.getImm());
317-
CCOp.setImm(AArch64CC::getInvertedCondCode(CC));
318-
}
319-
320-
/// Insert a conditional branch at the end of \p MBB to \p NewDestBB, using the
321-
/// inverse condition of branch \p OldBr.
322-
/// \returns The number of bytes added to the block.
323-
unsigned AArch64BranchRelaxation::insertInvertedConditionalBranch(
324-
MachineBasicBlock &SrcMBB,
325-
MachineBasicBlock::iterator InsPt,
326-
const DebugLoc &DL,
327-
const MachineInstr &OldBr,
328-
MachineBasicBlock &NewDestBB) const {
329-
unsigned OppositeCondOpc = getOppositeConditionOpcode(OldBr.getOpcode());
330-
331-
MachineInstrBuilder MIB =
332-
BuildMI(SrcMBB, InsPt, DL, TII->get(OppositeCondOpc))
333-
.addOperand(OldBr.getOperand(0));
334-
335-
unsigned Opc = OldBr.getOpcode();
336-
337-
if (Opc == AArch64::TBZW || Opc == AArch64::TBNZW ||
338-
Opc == AArch64::TBZX || Opc == AArch64::TBNZX)
339-
MIB.addOperand(OldBr.getOperand(1));
340-
341-
if (OldBr.getOpcode() == AArch64::Bcc)
342-
invertBccCondition(*MIB);
343-
344-
MIB.addMBB(&NewDestBB);
345-
346-
return TII->getInstSizeInBytes(*MIB);
347-
}
348-
349-
/// Insert an unconditional branch at the end of \p MBB to \p DestBB.
350-
/// \returns the number of bytes emitted.
351-
unsigned AArch64BranchRelaxation::insertUnconditionalBranch(
352-
MachineBasicBlock &MBB,
353-
MachineBasicBlock &DestBB,
354-
const DebugLoc &DL) const {
355-
MachineInstr *MI = BuildMI(&MBB, DL, TII->get(AArch64::B))
356-
.addMBB(&DestBB);
357-
358-
return TII->getInstSizeInBytes(*MI);
359-
}
360-
361-
static void changeBranchDestBlock(MachineInstr &MI,
362-
MachineBasicBlock &NewDestBB) {
363-
unsigned OpNum = 0;
364-
unsigned Opc = MI.getOpcode();
365-
366-
if (Opc != AArch64::B) {
367-
OpNum = (Opc == AArch64::TBZW ||
368-
Opc == AArch64::TBNZW ||
369-
Opc == AArch64::TBZX ||
370-
Opc == AArch64::TBNZX) ? 2 : 1;
371-
}
372-
373-
MI.getOperand(OpNum).setMBB(&NewDestBB);
374-
}
375-
376271
/// fixupConditionalBranch - Fix up a conditional branch whose destination is
377272
/// too far away to fit in its displacement field. It is converted to an inverse
378273
/// conditional branch + an unconditional branch to the destination.
379274
bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
380-
MachineBasicBlock *DestBB = getDestBlock(MI);
275+
DebugLoc DL = MI.getDebugLoc();
276+
MachineBasicBlock *MBB = MI.getParent();
277+
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
278+
SmallVector<MachineOperand, 4> Cond;
279+
280+
bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond);
281+
assert(!Fail && "branches to be relaxed must be analyzable");
282+
(void)Fail;
381283

382284
// Add an unconditional branch to the destination and invert the branch
383285
// condition to jump over it:
@@ -387,80 +289,64 @@ bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
387289
// b L1
388290
// L2:
389291

390-
// If the branch is at the end of its MBB and that has a fall-through block,
391-
// direct the updated conditional branch to the fall-through block. Otherwise,
392-
// split the MBB before the next instruction.
393-
MachineBasicBlock *MBB = MI.getParent();
394-
MachineInstr *BMI = &MBB->back();
395-
bool NeedSplit = (BMI != &MI) || !hasFallthrough(*MBB);
396-
397-
if (BMI != &MI) {
398-
if (std::next(MachineBasicBlock::iterator(MI)) ==
399-
std::prev(MBB->getLastNonDebugInstr()) &&
400-
BMI->isUnconditionalBranch()) {
401-
// Last MI in the BB is an unconditional branch. We can simply invert the
402-
// condition and swap destinations:
403-
// beq L1
404-
// b L2
405-
// =>
406-
// bne L2
407-
// b L1
408-
MachineBasicBlock *NewDest = getDestBlock(*BMI);
409-
if (isBlockInRange(MI, *NewDest)) {
410-
DEBUG(dbgs() << " Invert condition and swap its destination with "
411-
<< *BMI);
412-
changeBranchDestBlock(*BMI, *DestBB);
413-
414-
int NewSize =
415-
insertInvertedConditionalBranch(*MBB, MI.getIterator(),
416-
MI.getDebugLoc(), MI, *NewDest);
417-
int OldSize = TII->getInstSizeInBytes(MI);
418-
BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize);
419-
MI.eraseFromParent();
420-
return true;
421-
}
422-
}
423-
}
292+
if (FBB && isBlockInRange(MI, *FBB)) {
293+
// Last MI in the BB is an unconditional branch. We can simply invert the
294+
// condition and swap destinations:
295+
// beq L1
296+
// b L2
297+
// =>
298+
// bne L2
299+
// b L1
300+
DEBUG(dbgs() << " Invert condition and swap "
301+
"its destination with " << MBB->back());
302+
303+
TII->ReverseBranchCondition(Cond);
304+
int OldSize = 0, NewSize = 0;
305+
TII->RemoveBranch(*MBB, &OldSize);
306+
TII->InsertBranch(*MBB, FBB, TBB, Cond, DL, &NewSize);
307+
308+
BlockInfo[MBB->getNumber()].Size += (NewSize - OldSize);
309+
return true;
310+
} else if (FBB) {
311+
// We need to split the basic block here to obtain two long-range
312+
// unconditional branches.
313+
auto &NewBB = *MF->CreateMachineBasicBlock(MBB->getBasicBlock());
314+
MF->insert(++MBB->getIterator(), &NewBB);
315+
316+
// Insert an entry into BlockInfo to align it properly with the block
317+
// numbers.
318+
BlockInfo.insert(BlockInfo.begin() + NewBB.getNumber(), BasicBlockInfo());
424319

425-
if (NeedSplit) {
426-
// Analyze the branch so we know how to update the successor lists.
427-
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
428-
SmallVector<MachineOperand, 2> Cond;
429-
bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond, false);
430-
assert(!Fail && "branches to relax should be analyzable");
431-
(void)Fail;
432-
433-
MachineBasicBlock *NewBB = splitBlockBeforeInstr(MI);
434-
// No need for the branch to the next block. We're adding an unconditional
435-
// branch to the destination.
436-
int delta = TII->getInstSizeInBytes(MBB->back());
437-
BlockInfo[MBB->getNumber()].Size -= delta;
438-
MBB->back().eraseFromParent();
439-
// BlockInfo[SplitBB].Offset is wrong temporarily, fixed below
320+
unsigned &NewBBSize = BlockInfo[NewBB.getNumber()].Size;
321+
int NewBrSize;
322+
TII->insertUnconditionalBranch(NewBB, FBB, DL, &NewBrSize);
323+
NewBBSize += NewBrSize;
440324

441325
// Update the successor lists according to the transformation to follow.
442326
// Do it here since if there's no split, no update is needed.
443-
MBB->replaceSuccessor(FBB, NewBB);
444-
NewBB->addSuccessor(FBB);
327+
MBB->replaceSuccessor(FBB, &NewBB);
328+
NewBB.addSuccessor(FBB);
445329
}
446330

331+
// We now have an appropriate fall-through block in place (either naturally or
332+
// just created), so we can invert the condition.
447333
MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
448334

449-
DEBUG(dbgs() << " Insert B to BB#" << DestBB->getNumber()
335+
DEBUG(dbgs() << " Insert B to BB#" << TBB->getNumber()
450336
<< ", invert condition and change dest. to BB#"
451337
<< NextBB.getNumber() << '\n');
452338

453339
unsigned &MBBSize = BlockInfo[MBB->getNumber()].Size;
454340

455341
// Insert a new conditional branch and a new unconditional branch.
456-
MBBSize += insertInvertedConditionalBranch(*MBB, MBB->end(),
457-
MI.getDebugLoc(), MI, NextBB);
458-
459-
MBBSize += insertUnconditionalBranch(*MBB, *DestBB, MI.getDebugLoc());
460-
461-
// Remove the old conditional branch. It may or may not still be in MBB.
462-
MBBSize -= TII->getInstSizeInBytes(MI);
463-
MI.eraseFromParent();
342+
int RemovedSize = 0;
343+
TII->ReverseBranchCondition(Cond);
344+
TII->RemoveBranch(*MBB, &RemovedSize);
345+
MBBSize -= RemovedSize;
346+
347+
int AddedSize = 0;
348+
TII->InsertBranch(*MBB, &NextBB, TBB, Cond, DL, &AddedSize);
349+
MBBSize += AddedSize;
464350

465351
// Finally, keep the block offsets up to date.
466352
adjustBlockOffsets(*MBB);

lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ bool AArch64InstrInfo::ReverseBranchCondition(
298298
return false;
299299
}
300300

301-
unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
301+
unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB,
302+
int *BytesRemoved) const {
302303
MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
303304
if (I == MBB.end())
304305
return 0;
@@ -312,14 +313,23 @@ unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
312313

313314
I = MBB.end();
314315

315-
if (I == MBB.begin())
316+
if (I == MBB.begin()) {
317+
if (BytesRemoved)
318+
*BytesRemoved = 4;
316319
return 1;
320+
}
317321
--I;
318-
if (!isCondBranchOpcode(I->getOpcode()))
322+
if (!isCondBranchOpcode(I->getOpcode())) {
323+
if (BytesRemoved)
324+
*BytesRemoved = 4;
319325
return 1;
326+
}
320327

321328
// Remove the branch.
322329
I->eraseFromParent();
330+
if (BytesRemoved)
331+
*BytesRemoved = 8;
332+
323333
return 2;
324334
}
325335

@@ -344,7 +354,8 @@ unsigned AArch64InstrInfo::InsertBranch(MachineBasicBlock &MBB,
344354
MachineBasicBlock *TBB,
345355
MachineBasicBlock *FBB,
346356
ArrayRef<MachineOperand> Cond,
347-
const DebugLoc &DL) const {
357+
const DebugLoc &DL,
358+
int *BytesAdded) const {
348359
// Shouldn't be a fall through.
349360
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
350361

@@ -353,12 +364,20 @@ unsigned AArch64InstrInfo::InsertBranch(MachineBasicBlock &MBB,
353364
BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB);
354365
else
355366
instantiateCondBranch(MBB, DL, TBB, Cond);
367+
368+
if (BytesAdded)
369+
*BytesAdded = 4;
370+
356371
return 1;
357372
}
358373

359374
// Two-way conditional branch.
360375
instantiateCondBranch(MBB, DL, TBB, Cond);
361376
BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB);
377+
378+
if (BytesAdded)
379+
*BytesAdded = 8;
380+
362381
return 2;
363382
}
364383

0 commit comments

Comments
 (0)