@@ -74,15 +74,6 @@ class AArch64BranchRelaxation : public MachineFunctionPass {
74
74
void adjustBlockOffsets (MachineBasicBlock &MBB);
75
75
bool isBlockInRange (const MachineInstr &MI, const MachineBasicBlock &BB) const ;
76
76
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
-
86
77
bool fixupConditionalBranch (MachineInstr &MI);
87
78
void computeBlockSize (const MachineBasicBlock &MBB);
88
79
unsigned getInstrOffset (const MachineInstr &MI) const ;
@@ -130,22 +121,6 @@ void AArch64BranchRelaxation::dumpBBs() {
130
121
}
131
122
}
132
123
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
-
149
124
// / scanFunction - Do the initial scan of the function, building up
150
125
// / information about each block.
151
126
void AArch64BranchRelaxation::scanFunction () {
@@ -228,7 +203,7 @@ AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) {
228
203
// Note the new unconditional branch is not being recorded.
229
204
// There doesn't seem to be meaningful DebugInfo available; this doesn't
230
205
// correspond to anything in the source.
231
- insertUnconditionalBranch (*OrigBB, * NewBB, DebugLoc ());
206
+ TII-> insertUnconditionalBranch (*OrigBB, NewBB, DebugLoc ());
232
207
233
208
// Insert an entry into BlockInfo to align it properly with the block numbers.
234
209
BlockInfo.insert (BlockInfo.begin () + NewBB->getNumber (), BasicBlockInfo ());
@@ -293,91 +268,18 @@ static MachineBasicBlock *getDestBlock(const MachineInstr &MI) {
293
268
}
294
269
}
295
270
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
-
376
271
// / fixupConditionalBranch - Fix up a conditional branch whose destination is
377
272
// / too far away to fit in its displacement field. It is converted to an inverse
378
273
// / conditional branch + an unconditional branch to the destination.
379
274
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;
381
283
382
284
// Add an unconditional branch to the destination and invert the branch
383
285
// condition to jump over it:
@@ -387,80 +289,64 @@ bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
387
289
// b L1
388
290
// L2:
389
291
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 ());
424
319
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;
440
324
441
325
// Update the successor lists according to the transformation to follow.
442
326
// 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);
445
329
}
446
330
331
+ // We now have an appropriate fall-through block in place (either naturally or
332
+ // just created), so we can invert the condition.
447
333
MachineBasicBlock &NextBB = *std::next (MachineFunction::iterator (MBB));
448
334
449
- DEBUG (dbgs () << " Insert B to BB#" << DestBB ->getNumber ()
335
+ DEBUG (dbgs () << " Insert B to BB#" << TBB ->getNumber ()
450
336
<< " , invert condition and change dest. to BB#"
451
337
<< NextBB.getNumber () << ' \n ' );
452
338
453
339
unsigned &MBBSize = BlockInfo[MBB->getNumber ()].Size ;
454
340
455
341
// 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 ;
464
350
465
351
// Finally, keep the block offsets up to date.
466
352
adjustBlockOffsets (*MBB);
0 commit comments