1618c555bSEugene Zelenko //===- BranchRelaxation.cpp -----------------------------------------------===//
236919a4fSMatt Arsenault //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
636919a4fSMatt Arsenault //
736919a4fSMatt Arsenault //===----------------------------------------------------------------------===//
836919a4fSMatt Arsenault
936919a4fSMatt Arsenault #include "llvm/ADT/SmallVector.h"
1036919a4fSMatt Arsenault #include "llvm/ADT/Statistic.h"
1118198305SMatthias Braun #include "llvm/CodeGen/LivePhysRegs.h"
12618c555bSEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h"
13618c555bSEugene Zelenko #include "llvm/CodeGen/MachineFunction.h"
1436919a4fSMatt Arsenault #include "llvm/CodeGen/MachineFunctionPass.h"
15618c555bSEugene Zelenko #include "llvm/CodeGen/MachineInstr.h"
166bc43d86SMatt Arsenault #include "llvm/CodeGen/RegisterScavenging.h"
173f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
18b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
19b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h"
20432a3883SNico Weber #include "llvm/Config/llvm-config.h"
21618c555bSEugene Zelenko #include "llvm/IR/DebugLoc.h"
2205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
23618c555bSEugene Zelenko #include "llvm/Pass.h"
24618c555bSEugene Zelenko #include "llvm/Support/Compiler.h"
2536919a4fSMatt Arsenault #include "llvm/Support/Debug.h"
2636919a4fSMatt Arsenault #include "llvm/Support/Format.h"
2736919a4fSMatt Arsenault #include "llvm/Support/raw_ostream.h"
28618c555bSEugene Zelenko #include <cassert>
29618c555bSEugene Zelenko #include <cstdint>
30618c555bSEugene Zelenko #include <iterator>
31618c555bSEugene Zelenko #include <memory>
3236919a4fSMatt Arsenault
3336919a4fSMatt Arsenault using namespace llvm;
3436919a4fSMatt Arsenault
3536919a4fSMatt Arsenault #define DEBUG_TYPE "branch-relaxation"
3636919a4fSMatt Arsenault
3736919a4fSMatt Arsenault STATISTIC(NumSplit, "Number of basic blocks split");
3836919a4fSMatt Arsenault STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed");
396bc43d86SMatt Arsenault STATISTIC(NumUnconditionalRelaxed, "Number of unconditional branches relaxed");
4036919a4fSMatt Arsenault
4136919a4fSMatt Arsenault #define BRANCH_RELAX_NAME "Branch relaxation pass"
4236919a4fSMatt Arsenault
4336919a4fSMatt Arsenault namespace {
44618c555bSEugene Zelenko
4536919a4fSMatt Arsenault class BranchRelaxation : public MachineFunctionPass {
4636919a4fSMatt Arsenault /// BasicBlockInfo - Information about the offset and size of a single
4736919a4fSMatt Arsenault /// basic block.
4836919a4fSMatt Arsenault struct BasicBlockInfo {
4936919a4fSMatt Arsenault /// Offset - Distance from the beginning of the function to the beginning
5036919a4fSMatt Arsenault /// of this basic block.
5136919a4fSMatt Arsenault ///
5236919a4fSMatt Arsenault /// The offset is always aligned as required by the basic block.
53618c555bSEugene Zelenko unsigned Offset = 0;
5436919a4fSMatt Arsenault
5536919a4fSMatt Arsenault /// Size - Size of the basic block in bytes. If the block contains
5636919a4fSMatt Arsenault /// inline assembly, this is a worst case estimate.
5736919a4fSMatt Arsenault ///
5836919a4fSMatt Arsenault /// The size does not include any alignment padding whether from the
5936919a4fSMatt Arsenault /// beginning of the block, or from an aligned jump table at the end.
60618c555bSEugene Zelenko unsigned Size = 0;
6136919a4fSMatt Arsenault
62618c555bSEugene Zelenko BasicBlockInfo() = default;
6336919a4fSMatt Arsenault
64ef5bba01SMatt Arsenault /// Compute the offset immediately following this block. \p MBB is the next
65ef5bba01SMatt Arsenault /// block.
postOffset__anonb12d89e90111::BranchRelaxation::BasicBlockInfo66ef5bba01SMatt Arsenault unsigned postOffset(const MachineBasicBlock &MBB) const {
6748904e94SGuillaume Chatelet const unsigned PO = Offset + Size;
6818f805a7SGuillaume Chatelet const Align Alignment = MBB.getAlignment();
6918f805a7SGuillaume Chatelet const Align ParentAlign = MBB.getParent()->getAlignment();
7018f805a7SGuillaume Chatelet if (Alignment <= ParentAlign)
71886d2c2cSFangrui Song return alignTo(PO, Alignment);
72ef5bba01SMatt Arsenault
73ef5bba01SMatt Arsenault // The alignment of this MBB is larger than the function's alignment, so we
74ef5bba01SMatt Arsenault // can't tell whether or not it will insert nops. Assume that it will.
75886d2c2cSFangrui Song return alignTo(PO, Alignment) + Alignment.value() - ParentAlign.value();
7636919a4fSMatt Arsenault }
7736919a4fSMatt Arsenault };
7836919a4fSMatt Arsenault
7936919a4fSMatt Arsenault SmallVector<BasicBlockInfo, 16> BlockInfo;
806bc43d86SMatt Arsenault std::unique_ptr<RegScavenger> RS;
8118198305SMatthias Braun LivePhysRegs LiveRegs;
8236919a4fSMatt Arsenault
8336919a4fSMatt Arsenault MachineFunction *MF;
8418198305SMatthias Braun const TargetRegisterInfo *TRI;
8536919a4fSMatt Arsenault const TargetInstrInfo *TII;
8636919a4fSMatt Arsenault
8736919a4fSMatt Arsenault bool relaxBranchInstructions();
8836919a4fSMatt Arsenault void scanFunction();
896bc43d86SMatt Arsenault
906bc43d86SMatt Arsenault MachineBasicBlock *createNewBlockAfter(MachineBasicBlock &BB);
916bc43d86SMatt Arsenault
9244deb791SMatt Arsenault MachineBasicBlock *splitBlockBeforeInstr(MachineInstr &MI,
9344deb791SMatt Arsenault MachineBasicBlock *DestBB);
94cb0bab86SFangrui Song void adjustBlockOffsets(MachineBasicBlock &Start);
9536919a4fSMatt Arsenault bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const;
9636919a4fSMatt Arsenault
9736919a4fSMatt Arsenault bool fixupConditionalBranch(MachineInstr &MI);
986bc43d86SMatt Arsenault bool fixupUnconditionalBranch(MachineInstr &MI);
9936919a4fSMatt Arsenault uint64_t computeBlockSize(const MachineBasicBlock &MBB) const;
10036919a4fSMatt Arsenault unsigned getInstrOffset(const MachineInstr &MI) const;
10136919a4fSMatt Arsenault void dumpBBs();
10236919a4fSMatt Arsenault void verify();
10336919a4fSMatt Arsenault
10436919a4fSMatt Arsenault public:
10536919a4fSMatt Arsenault static char ID;
106618c555bSEugene Zelenko
BranchRelaxation()10736919a4fSMatt Arsenault BranchRelaxation() : MachineFunctionPass(ID) {}
10836919a4fSMatt Arsenault
10936919a4fSMatt Arsenault bool runOnMachineFunction(MachineFunction &MF) override;
11036919a4fSMatt Arsenault
getPassName() const111618c555bSEugene Zelenko StringRef getPassName() const override { return BRANCH_RELAX_NAME; }
11236919a4fSMatt Arsenault };
11336919a4fSMatt Arsenault
114618c555bSEugene Zelenko } // end anonymous namespace
11536919a4fSMatt Arsenault
11636919a4fSMatt Arsenault char BranchRelaxation::ID = 0;
117618c555bSEugene Zelenko
11836919a4fSMatt Arsenault char &llvm::BranchRelaxationPassID = BranchRelaxation::ID;
11936919a4fSMatt Arsenault
INITIALIZE_PASS(BranchRelaxation,DEBUG_TYPE,BRANCH_RELAX_NAME,false,false)12036919a4fSMatt Arsenault INITIALIZE_PASS(BranchRelaxation, DEBUG_TYPE, BRANCH_RELAX_NAME, false, false)
12136919a4fSMatt Arsenault
12236919a4fSMatt Arsenault /// verify - check BBOffsets, BBSizes, alignment of islands
12336919a4fSMatt Arsenault void BranchRelaxation::verify() {
12436919a4fSMatt Arsenault #ifndef NDEBUG
12536919a4fSMatt Arsenault unsigned PrevNum = MF->begin()->getNumber();
12636919a4fSMatt Arsenault for (MachineBasicBlock &MBB : *MF) {
127d4c4671aSGuillaume Chatelet const unsigned Num = MBB.getNumber();
128ef5bba01SMatt Arsenault assert(!Num || BlockInfo[PrevNum].postOffset(MBB) <= BlockInfo[Num].Offset);
12944deb791SMatt Arsenault assert(BlockInfo[Num].Size == computeBlockSize(MBB));
13036919a4fSMatt Arsenault PrevNum = Num;
13136919a4fSMatt Arsenault }
13236919a4fSMatt Arsenault #endif
13336919a4fSMatt Arsenault }
13436919a4fSMatt Arsenault
135615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
13636919a4fSMatt Arsenault /// print block size and offset information - debugging
dumpBBs()1378c209aa8SMatthias Braun LLVM_DUMP_METHOD void BranchRelaxation::dumpBBs() {
13836919a4fSMatt Arsenault for (auto &MBB : *MF) {
13936919a4fSMatt Arsenault const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()];
140187c63f1SEvgeniy Stepanov dbgs() << format("%%bb.%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset)
14136919a4fSMatt Arsenault << format("size=%#x\n", BBI.Size);
14236919a4fSMatt Arsenault }
14336919a4fSMatt Arsenault }
1448c209aa8SMatthias Braun #endif
14536919a4fSMatt Arsenault
14636919a4fSMatt Arsenault /// scanFunction - Do the initial scan of the function, building up
14736919a4fSMatt Arsenault /// information about each block.
scanFunction()14836919a4fSMatt Arsenault void BranchRelaxation::scanFunction() {
14936919a4fSMatt Arsenault BlockInfo.clear();
15036919a4fSMatt Arsenault BlockInfo.resize(MF->getNumBlockIDs());
15136919a4fSMatt Arsenault
15236919a4fSMatt Arsenault // First thing, compute the size of all basic blocks, and see if the function
15336919a4fSMatt Arsenault // has any inline assembly in it. If so, we have to be conservative about
15436919a4fSMatt Arsenault // alignment assumptions, as we don't know for sure the size of any
15536919a4fSMatt Arsenault // instructions in the inline assembly.
15636919a4fSMatt Arsenault for (MachineBasicBlock &MBB : *MF)
15736919a4fSMatt Arsenault BlockInfo[MBB.getNumber()].Size = computeBlockSize(MBB);
15836919a4fSMatt Arsenault
15936919a4fSMatt Arsenault // Compute block offsets and known bits.
16036919a4fSMatt Arsenault adjustBlockOffsets(*MF->begin());
16136919a4fSMatt Arsenault }
16236919a4fSMatt Arsenault
16336919a4fSMatt Arsenault /// computeBlockSize - Compute the size for MBB.
computeBlockSize(const MachineBasicBlock & MBB) const16436919a4fSMatt Arsenault uint64_t BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) const {
16536919a4fSMatt Arsenault uint64_t Size = 0;
16636919a4fSMatt Arsenault for (const MachineInstr &MI : MBB)
16736919a4fSMatt Arsenault Size += TII->getInstSizeInBytes(MI);
16836919a4fSMatt Arsenault return Size;
16936919a4fSMatt Arsenault }
17036919a4fSMatt Arsenault
17136919a4fSMatt Arsenault /// getInstrOffset - Return the current offset of the specified machine
17236919a4fSMatt Arsenault /// instruction from the start of the function. This offset changes as stuff is
17336919a4fSMatt Arsenault /// moved around inside the function.
getInstrOffset(const MachineInstr & MI) const17436919a4fSMatt Arsenault unsigned BranchRelaxation::getInstrOffset(const MachineInstr &MI) const {
17536919a4fSMatt Arsenault const MachineBasicBlock *MBB = MI.getParent();
17636919a4fSMatt Arsenault
17736919a4fSMatt Arsenault // The offset is composed of two things: the sum of the sizes of all MBB's
17836919a4fSMatt Arsenault // before this instruction's block, and the offset from the start of the block
17936919a4fSMatt Arsenault // it is in.
18036919a4fSMatt Arsenault unsigned Offset = BlockInfo[MBB->getNumber()].Offset;
18136919a4fSMatt Arsenault
18236919a4fSMatt Arsenault // Sum instructions before MI in MBB.
18336919a4fSMatt Arsenault for (MachineBasicBlock::const_iterator I = MBB->begin(); &*I != &MI; ++I) {
18436919a4fSMatt Arsenault assert(I != MBB->end() && "Didn't find MI in its own basic block?");
18536919a4fSMatt Arsenault Offset += TII->getInstSizeInBytes(*I);
18636919a4fSMatt Arsenault }
18736919a4fSMatt Arsenault
18836919a4fSMatt Arsenault return Offset;
18936919a4fSMatt Arsenault }
19036919a4fSMatt Arsenault
adjustBlockOffsets(MachineBasicBlock & Start)19136919a4fSMatt Arsenault void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) {
19236919a4fSMatt Arsenault unsigned PrevNum = Start.getNumber();
193886d2c2cSFangrui Song for (auto &MBB :
194886d2c2cSFangrui Song make_range(std::next(MachineFunction::iterator(Start)), MF->end())) {
19536919a4fSMatt Arsenault unsigned Num = MBB.getNumber();
19636919a4fSMatt Arsenault // Get the offset and known bits at the end of the layout predecessor.
19736919a4fSMatt Arsenault // Include the alignment of the current block.
198ef5bba01SMatt Arsenault BlockInfo[Num].Offset = BlockInfo[PrevNum].postOffset(MBB);
199ef5bba01SMatt Arsenault
20036919a4fSMatt Arsenault PrevNum = Num;
20136919a4fSMatt Arsenault }
20236919a4fSMatt Arsenault }
20336919a4fSMatt Arsenault
2046bc43d86SMatt Arsenault /// Insert a new empty basic block and insert it after \BB
createNewBlockAfter(MachineBasicBlock & BB)2056bc43d86SMatt Arsenault MachineBasicBlock *BranchRelaxation::createNewBlockAfter(MachineBasicBlock &BB) {
2066bc43d86SMatt Arsenault // Create a new MBB for the code after the OrigBB.
2076bc43d86SMatt Arsenault MachineBasicBlock *NewBB =
2086bc43d86SMatt Arsenault MF->CreateMachineBasicBlock(BB.getBasicBlock());
2096bc43d86SMatt Arsenault MF->insert(++BB.getIterator(), NewBB);
2106bc43d86SMatt Arsenault
2116bc43d86SMatt Arsenault // Insert an entry into BlockInfo to align it properly with the block numbers.
2126bc43d86SMatt Arsenault BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
2136bc43d86SMatt Arsenault
2146bc43d86SMatt Arsenault return NewBB;
2156bc43d86SMatt Arsenault }
2166bc43d86SMatt Arsenault
21736919a4fSMatt Arsenault /// Split the basic block containing MI into two blocks, which are joined by
21836919a4fSMatt Arsenault /// an unconditional branch. Update data structures and renumber blocks to
21936919a4fSMatt Arsenault /// account for this change and returns the newly created block.
splitBlockBeforeInstr(MachineInstr & MI,MachineBasicBlock * DestBB)22044deb791SMatt Arsenault MachineBasicBlock *BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI,
22144deb791SMatt Arsenault MachineBasicBlock *DestBB) {
22236919a4fSMatt Arsenault MachineBasicBlock *OrigBB = MI.getParent();
22336919a4fSMatt Arsenault
22436919a4fSMatt Arsenault // Create a new MBB for the code after the OrigBB.
22536919a4fSMatt Arsenault MachineBasicBlock *NewBB =
22636919a4fSMatt Arsenault MF->CreateMachineBasicBlock(OrigBB->getBasicBlock());
22736919a4fSMatt Arsenault MF->insert(++OrigBB->getIterator(), NewBB);
22836919a4fSMatt Arsenault
22936919a4fSMatt Arsenault // Splice the instructions starting with MI over to NewBB.
23036919a4fSMatt Arsenault NewBB->splice(NewBB->end(), OrigBB, MI.getIterator(), OrigBB->end());
23136919a4fSMatt Arsenault
23236919a4fSMatt Arsenault // Add an unconditional branch from OrigBB to NewBB.
23336919a4fSMatt Arsenault // Note the new unconditional branch is not being recorded.
23436919a4fSMatt Arsenault // There doesn't seem to be meaningful DebugInfo available; this doesn't
23536919a4fSMatt Arsenault // correspond to anything in the source.
23636919a4fSMatt Arsenault TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc());
23736919a4fSMatt Arsenault
23836919a4fSMatt Arsenault // Insert an entry into BlockInfo to align it properly with the block numbers.
23936919a4fSMatt Arsenault BlockInfo.insert(BlockInfo.begin() + NewBB->getNumber(), BasicBlockInfo());
24036919a4fSMatt Arsenault
24144deb791SMatt Arsenault NewBB->transferSuccessors(OrigBB);
24244deb791SMatt Arsenault OrigBB->addSuccessor(NewBB);
24344deb791SMatt Arsenault OrigBB->addSuccessor(DestBB);
24444deb791SMatt Arsenault
24544deb791SMatt Arsenault // Cleanup potential unconditional branch to successor block.
24644deb791SMatt Arsenault // Note that updateTerminator may change the size of the blocks.
2471978309dSJames Y Knight OrigBB->updateTerminator(NewBB);
24844deb791SMatt Arsenault
24936919a4fSMatt Arsenault // Figure out how large the OrigBB is. As the first half of the original
25036919a4fSMatt Arsenault // block, it cannot contain a tablejump. The size includes
25136919a4fSMatt Arsenault // the new jump we added. (It should be possible to do this without
25236919a4fSMatt Arsenault // recounting everything, but it's very confusing, and this is rarely
25336919a4fSMatt Arsenault // executed.)
25436919a4fSMatt Arsenault BlockInfo[OrigBB->getNumber()].Size = computeBlockSize(*OrigBB);
25536919a4fSMatt Arsenault
25636919a4fSMatt Arsenault // Figure out how large the NewMBB is. As the second half of the original
25736919a4fSMatt Arsenault // block, it may contain a tablejump.
25836919a4fSMatt Arsenault BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB);
25936919a4fSMatt Arsenault
26036919a4fSMatt Arsenault // All BBOffsets following these blocks must be modified.
26136919a4fSMatt Arsenault adjustBlockOffsets(*OrigBB);
26236919a4fSMatt Arsenault
26318198305SMatthias Braun // Need to fix live-in lists if we track liveness.
26418198305SMatthias Braun if (TRI->trackLivenessAfterRegAlloc(*MF))
265c9056b83SMatthias Braun computeAndAddLiveIns(LiveRegs, *NewBB);
26618198305SMatthias Braun
26736919a4fSMatt Arsenault ++NumSplit;
26836919a4fSMatt Arsenault
26936919a4fSMatt Arsenault return NewBB;
27036919a4fSMatt Arsenault }
27136919a4fSMatt Arsenault
27236919a4fSMatt Arsenault /// isBlockInRange - Returns true if the distance between specific MI and
27336919a4fSMatt Arsenault /// specific BB can fit in MI's displacement field.
isBlockInRange(const MachineInstr & MI,const MachineBasicBlock & DestBB) const27436919a4fSMatt Arsenault bool BranchRelaxation::isBlockInRange(
27536919a4fSMatt Arsenault const MachineInstr &MI, const MachineBasicBlock &DestBB) const {
27636919a4fSMatt Arsenault int64_t BrOffset = getInstrOffset(MI);
27736919a4fSMatt Arsenault int64_t DestOffset = BlockInfo[DestBB.getNumber()].Offset;
27836919a4fSMatt Arsenault
27936919a4fSMatt Arsenault if (TII->isBranchOffsetInRange(MI.getOpcode(), DestOffset - BrOffset))
28036919a4fSMatt Arsenault return true;
28136919a4fSMatt Arsenault
282d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Out of range branch to destination "
28325528d6dSFrancis Visoiu Mistrih << printMBBReference(DestBB) << " from "
284d34e60caSNicola Zaghen << printMBBReference(*MI.getParent()) << " to "
285d34e60caSNicola Zaghen << DestOffset << " offset " << DestOffset - BrOffset << '\t'
286d34e60caSNicola Zaghen << MI);
28736919a4fSMatt Arsenault
28836919a4fSMatt Arsenault return false;
28936919a4fSMatt Arsenault }
29036919a4fSMatt Arsenault
29136919a4fSMatt Arsenault /// fixupConditionalBranch - Fix up a conditional branch whose destination is
29236919a4fSMatt Arsenault /// too far away to fit in its displacement field. It is converted to an inverse
29336919a4fSMatt Arsenault /// conditional branch + an unconditional branch to the destination.
fixupConditionalBranch(MachineInstr & MI)29436919a4fSMatt Arsenault bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) {
295bbddf21fSChandler Carruth DebugLoc DL = MI.getDebugLoc();
29636919a4fSMatt Arsenault MachineBasicBlock *MBB = MI.getParent();
29736919a4fSMatt Arsenault MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
298b8f2978bSElena Demikhovsky MachineBasicBlock *NewBB = nullptr;
29936919a4fSMatt Arsenault SmallVector<MachineOperand, 4> Cond;
30036919a4fSMatt Arsenault
301b8f2978bSElena Demikhovsky auto insertUncondBranch = [&](MachineBasicBlock *MBB,
302b8f2978bSElena Demikhovsky MachineBasicBlock *DestBB) {
303b8f2978bSElena Demikhovsky unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
304b8f2978bSElena Demikhovsky int NewBrSize = 0;
305b8f2978bSElena Demikhovsky TII->insertUnconditionalBranch(*MBB, DestBB, DL, &NewBrSize);
306b8f2978bSElena Demikhovsky BBSize += NewBrSize;
307b8f2978bSElena Demikhovsky };
308b8f2978bSElena Demikhovsky auto insertBranch = [&](MachineBasicBlock *MBB, MachineBasicBlock *TBB,
309b8f2978bSElena Demikhovsky MachineBasicBlock *FBB,
310b8f2978bSElena Demikhovsky SmallVectorImpl<MachineOperand>& Cond) {
311b8f2978bSElena Demikhovsky unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
312b8f2978bSElena Demikhovsky int NewBrSize = 0;
313b8f2978bSElena Demikhovsky TII->insertBranch(*MBB, TBB, FBB, Cond, DL, &NewBrSize);
314b8f2978bSElena Demikhovsky BBSize += NewBrSize;
315b8f2978bSElena Demikhovsky };
316b8f2978bSElena Demikhovsky auto removeBranch = [&](MachineBasicBlock *MBB) {
317b8f2978bSElena Demikhovsky unsigned &BBSize = BlockInfo[MBB->getNumber()].Size;
318b8f2978bSElena Demikhovsky int RemovedSize = 0;
319b8f2978bSElena Demikhovsky TII->removeBranch(*MBB, &RemovedSize);
320b8f2978bSElena Demikhovsky BBSize -= RemovedSize;
321b8f2978bSElena Demikhovsky };
322b8f2978bSElena Demikhovsky
323b8f2978bSElena Demikhovsky auto finalizeBlockChanges = [&](MachineBasicBlock *MBB,
324b8f2978bSElena Demikhovsky MachineBasicBlock *NewBB) {
325b8f2978bSElena Demikhovsky // Keep the block offsets up to date.
326b8f2978bSElena Demikhovsky adjustBlockOffsets(*MBB);
327b8f2978bSElena Demikhovsky
328b8f2978bSElena Demikhovsky // Need to fix live-in lists if we track liveness.
329b8f2978bSElena Demikhovsky if (NewBB && TRI->trackLivenessAfterRegAlloc(*MF))
330b8f2978bSElena Demikhovsky computeAndAddLiveIns(LiveRegs, *NewBB);
331b8f2978bSElena Demikhovsky };
332b8f2978bSElena Demikhovsky
33336919a4fSMatt Arsenault bool Fail = TII->analyzeBranch(*MBB, TBB, FBB, Cond);
33436919a4fSMatt Arsenault assert(!Fail && "branches to be relaxed must be analyzable");
33536919a4fSMatt Arsenault (void)Fail;
33636919a4fSMatt Arsenault
33736919a4fSMatt Arsenault // Add an unconditional branch to the destination and invert the branch
33836919a4fSMatt Arsenault // condition to jump over it:
33936919a4fSMatt Arsenault // tbz L1
34036919a4fSMatt Arsenault // =>
34136919a4fSMatt Arsenault // tbnz L2
34236919a4fSMatt Arsenault // b L1
34336919a4fSMatt Arsenault // L2:
34436919a4fSMatt Arsenault
345b8f2978bSElena Demikhovsky bool ReversedCond = !TII->reverseBranchCondition(Cond);
346b8f2978bSElena Demikhovsky if (ReversedCond) {
34736919a4fSMatt Arsenault if (FBB && isBlockInRange(MI, *FBB)) {
34836919a4fSMatt Arsenault // Last MI in the BB is an unconditional branch. We can simply invert the
34936919a4fSMatt Arsenault // condition and swap destinations:
35036919a4fSMatt Arsenault // beq L1
35136919a4fSMatt Arsenault // b L2
35236919a4fSMatt Arsenault // =>
35336919a4fSMatt Arsenault // bne L2
35436919a4fSMatt Arsenault // b L1
355d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Invert condition and swap "
356d34e60caSNicola Zaghen "its destination with "
357d34e60caSNicola Zaghen << MBB->back());
35836919a4fSMatt Arsenault
359b8f2978bSElena Demikhovsky removeBranch(MBB);
360b8f2978bSElena Demikhovsky insertBranch(MBB, FBB, TBB, Cond);
361b8f2978bSElena Demikhovsky finalizeBlockChanges(MBB, nullptr);
36236919a4fSMatt Arsenault return true;
363b8f2978bSElena Demikhovsky }
364b8f2978bSElena Demikhovsky if (FBB) {
36536919a4fSMatt Arsenault // We need to split the basic block here to obtain two long-range
36636919a4fSMatt Arsenault // unconditional branches.
367b8f2978bSElena Demikhovsky NewBB = createNewBlockAfter(*MBB);
36836919a4fSMatt Arsenault
369b8f2978bSElena Demikhovsky insertUncondBranch(NewBB, FBB);
370b8f2978bSElena Demikhovsky // Update the succesor lists according to the transformation to follow.
37136919a4fSMatt Arsenault // Do it here since if there's no split, no update is needed.
372b8f2978bSElena Demikhovsky MBB->replaceSuccessor(FBB, NewBB);
373b8f2978bSElena Demikhovsky NewBB->addSuccessor(FBB);
37436919a4fSMatt Arsenault }
37536919a4fSMatt Arsenault
37636919a4fSMatt Arsenault // We now have an appropriate fall-through block in place (either naturally or
377b8f2978bSElena Demikhovsky // just created), so we can use the inverted the condition.
37836919a4fSMatt Arsenault MachineBasicBlock &NextBB = *std::next(MachineFunction::iterator(MBB));
37936919a4fSMatt Arsenault
380d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Insert B to " << printMBBReference(*TBB)
38125528d6dSFrancis Visoiu Mistrih << ", invert condition and change dest. to "
38225528d6dSFrancis Visoiu Mistrih << printMBBReference(NextBB) << '\n');
38336919a4fSMatt Arsenault
384b8f2978bSElena Demikhovsky removeBranch(MBB);
38536919a4fSMatt Arsenault // Insert a new conditional branch and a new unconditional branch.
386b8f2978bSElena Demikhovsky insertBranch(MBB, &NextBB, TBB, Cond);
38736919a4fSMatt Arsenault
388b8f2978bSElena Demikhovsky finalizeBlockChanges(MBB, NewBB);
389b8f2978bSElena Demikhovsky return true;
390b8f2978bSElena Demikhovsky }
391b8f2978bSElena Demikhovsky // Branch cond can't be inverted.
392b8f2978bSElena Demikhovsky // In this case we always add a block after the MBB.
393d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " The branch condition can't be inverted. "
394b8f2978bSElena Demikhovsky << " Insert a new BB after " << MBB->back());
39536919a4fSMatt Arsenault
396b8f2978bSElena Demikhovsky if (!FBB)
397b8f2978bSElena Demikhovsky FBB = &(*std::next(MachineFunction::iterator(MBB)));
398b8f2978bSElena Demikhovsky
399b8f2978bSElena Demikhovsky // This is the block with cond. branch and the distance to TBB is too long.
400b8f2978bSElena Demikhovsky // beq L1
401b8f2978bSElena Demikhovsky // L2:
402b8f2978bSElena Demikhovsky
403b8f2978bSElena Demikhovsky // We do the following transformation:
404b8f2978bSElena Demikhovsky // beq NewBB
405b8f2978bSElena Demikhovsky // b L2
406b8f2978bSElena Demikhovsky // NewBB:
407b8f2978bSElena Demikhovsky // b L1
408b8f2978bSElena Demikhovsky // L2:
409b8f2978bSElena Demikhovsky
410b8f2978bSElena Demikhovsky NewBB = createNewBlockAfter(*MBB);
411b8f2978bSElena Demikhovsky insertUncondBranch(NewBB, TBB);
412b8f2978bSElena Demikhovsky
413d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Insert cond B to the new BB "
414d34e60caSNicola Zaghen << printMBBReference(*NewBB)
415b8f2978bSElena Demikhovsky << " Keep the exiting condition.\n"
416b8f2978bSElena Demikhovsky << " Insert B to " << printMBBReference(*FBB) << ".\n"
417b8f2978bSElena Demikhovsky << " In the new BB: Insert B to "
418b8f2978bSElena Demikhovsky << printMBBReference(*TBB) << ".\n");
419b8f2978bSElena Demikhovsky
420b8f2978bSElena Demikhovsky // Update the successor lists according to the transformation to follow.
421b8f2978bSElena Demikhovsky MBB->replaceSuccessor(TBB, NewBB);
422b8f2978bSElena Demikhovsky NewBB->addSuccessor(TBB);
423b8f2978bSElena Demikhovsky
424b8f2978bSElena Demikhovsky // Replace branch in the current (MBB) block.
425b8f2978bSElena Demikhovsky removeBranch(MBB);
426b8f2978bSElena Demikhovsky insertBranch(MBB, NewBB, FBB, Cond);
427b8f2978bSElena Demikhovsky
428b8f2978bSElena Demikhovsky finalizeBlockChanges(MBB, NewBB);
42936919a4fSMatt Arsenault return true;
43036919a4fSMatt Arsenault }
43136919a4fSMatt Arsenault
fixupUnconditionalBranch(MachineInstr & MI)4326bc43d86SMatt Arsenault bool BranchRelaxation::fixupUnconditionalBranch(MachineInstr &MI) {
4336bc43d86SMatt Arsenault MachineBasicBlock *MBB = MI.getParent();
4346bc43d86SMatt Arsenault
4356bc43d86SMatt Arsenault unsigned OldBrSize = TII->getInstSizeInBytes(MI);
4366bc43d86SMatt Arsenault MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI);
4376bc43d86SMatt Arsenault
4386bc43d86SMatt Arsenault int64_t DestOffset = BlockInfo[DestBB->getNumber()].Offset;
4396bc43d86SMatt Arsenault int64_t SrcOffset = getInstrOffset(MI);
4406bc43d86SMatt Arsenault
4416bc43d86SMatt Arsenault assert(!TII->isBranchOffsetInRange(MI.getOpcode(), DestOffset - SrcOffset));
4426bc43d86SMatt Arsenault
4436bc43d86SMatt Arsenault BlockInfo[MBB->getNumber()].Size -= OldBrSize;
4446bc43d86SMatt Arsenault
4456bc43d86SMatt Arsenault MachineBasicBlock *BranchBB = MBB;
4466bc43d86SMatt Arsenault
4476bc43d86SMatt Arsenault // If this was an expanded conditional branch, there is already a single
4486bc43d86SMatt Arsenault // unconditional branch in a block.
4496bc43d86SMatt Arsenault if (!MBB->empty()) {
4506bc43d86SMatt Arsenault BranchBB = createNewBlockAfter(*MBB);
4516bc43d86SMatt Arsenault
4526bc43d86SMatt Arsenault // Add live outs.
4536bc43d86SMatt Arsenault for (const MachineBasicBlock *Succ : MBB->successors()) {
4546bc43d86SMatt Arsenault for (const MachineBasicBlock::RegisterMaskPair &LiveIn : Succ->liveins())
4556bc43d86SMatt Arsenault BranchBB->addLiveIn(LiveIn);
4566bc43d86SMatt Arsenault }
4576bc43d86SMatt Arsenault
458691efe03SMatt Arsenault BranchBB->sortUniqueLiveIns();
4596bc43d86SMatt Arsenault BranchBB->addSuccessor(DestBB);
4606bc43d86SMatt Arsenault MBB->replaceSuccessor(DestBB, BranchBB);
4616bc43d86SMatt Arsenault }
4626bc43d86SMatt Arsenault
463bbddf21fSChandler Carruth DebugLoc DL = MI.getDebugLoc();
4646bc43d86SMatt Arsenault MI.eraseFromParent();
4656bc43d86SMatt Arsenault
466e6a4ba3aSMichael Liao // Create the optional restore block and, initially, place it at the end of
467e6a4ba3aSMichael Liao // function. That block will be placed later if it's used; otherwise, it will
468e6a4ba3aSMichael Liao // be erased.
469e6a4ba3aSMichael Liao MachineBasicBlock *RestoreBB = createNewBlockAfter(MF->back());
470e6a4ba3aSMichael Liao
471e6a4ba3aSMichael Liao TII->insertIndirectBranch(*BranchBB, *DestBB, *RestoreBB, DL,
472e6a4ba3aSMichael Liao DestOffset - SrcOffset, RS.get());
473e6a4ba3aSMichael Liao
474e6a4ba3aSMichael Liao BlockInfo[BranchBB->getNumber()].Size = computeBlockSize(*BranchBB);
4756bc43d86SMatt Arsenault adjustBlockOffsets(*MBB);
476e6a4ba3aSMichael Liao
477e6a4ba3aSMichael Liao // If RestoreBB is required, try to place just before DestBB.
478e6a4ba3aSMichael Liao if (!RestoreBB->empty()) {
479e6a4ba3aSMichael Liao // TODO: For multiple far branches to the same destination, there are
480e6a4ba3aSMichael Liao // chances that some restore blocks could be shared if they clobber the
481e6a4ba3aSMichael Liao // same registers and share the same restore sequence. So far, those
482e6a4ba3aSMichael Liao // restore blocks are just duplicated for each far branch.
483e6a4ba3aSMichael Liao assert(!DestBB->isEntryBlock());
484e6a4ba3aSMichael Liao MachineBasicBlock *PrevBB = &*std::prev(DestBB->getIterator());
485e6a4ba3aSMichael Liao if (auto *FT = PrevBB->getFallThrough()) {
486e6a4ba3aSMichael Liao assert(FT == DestBB);
487af2ae2cfSMichael Liao TII->insertUnconditionalBranch(*PrevBB, FT, DebugLoc());
488e6a4ba3aSMichael Liao // Recalculate the block size.
489e6a4ba3aSMichael Liao BlockInfo[PrevBB->getNumber()].Size = computeBlockSize(*PrevBB);
490e6a4ba3aSMichael Liao }
491e6a4ba3aSMichael Liao // Now, RestoreBB could be placed directly before DestBB.
492e6a4ba3aSMichael Liao MF->splice(DestBB->getIterator(), RestoreBB->getIterator());
493e6a4ba3aSMichael Liao // Update successors and predecessors.
494e6a4ba3aSMichael Liao RestoreBB->addSuccessor(DestBB);
495e6a4ba3aSMichael Liao BranchBB->replaceSuccessor(DestBB, RestoreBB);
496e6a4ba3aSMichael Liao if (TRI->trackLivenessAfterRegAlloc(*MF))
497e6a4ba3aSMichael Liao computeAndAddLiveIns(LiveRegs, *RestoreBB);
498e6a4ba3aSMichael Liao // Compute the restore block size.
499e6a4ba3aSMichael Liao BlockInfo[RestoreBB->getNumber()].Size = computeBlockSize(*RestoreBB);
500e6a4ba3aSMichael Liao // Update the offset starting from the previous block.
501e6a4ba3aSMichael Liao adjustBlockOffsets(*PrevBB);
502e6a4ba3aSMichael Liao } else {
503e6a4ba3aSMichael Liao // Remove restore block if it's not required.
504e6a4ba3aSMichael Liao MF->erase(RestoreBB);
505e6a4ba3aSMichael Liao }
506e6a4ba3aSMichael Liao
5076bc43d86SMatt Arsenault return true;
5086bc43d86SMatt Arsenault }
5096bc43d86SMatt Arsenault
relaxBranchInstructions()51036919a4fSMatt Arsenault bool BranchRelaxation::relaxBranchInstructions() {
51136919a4fSMatt Arsenault bool Changed = false;
5126bc43d86SMatt Arsenault
51336919a4fSMatt Arsenault // Relaxing branches involves creating new basic blocks, so re-eval
51436919a4fSMatt Arsenault // end() for termination.
515*d5b73a70SKazu Hirata for (MachineBasicBlock &MBB : *MF) {
51618198305SMatthias Braun // Empty block?
51718198305SMatthias Braun MachineBasicBlock::iterator Last = MBB.getLastNonDebugInstr();
51818198305SMatthias Braun if (Last == MBB.end())
519cb578f84SMatt Arsenault continue;
520cb578f84SMatt Arsenault
521cb578f84SMatt Arsenault // Expand the unconditional branch first if necessary. If there is a
522cb578f84SMatt Arsenault // conditional branch, this will end up changing the branch destination of
523cb578f84SMatt Arsenault // it to be over the newly inserted indirect branch block, which may avoid
524cb578f84SMatt Arsenault // the need to try expanding the conditional branch first, saving an extra
525cb578f84SMatt Arsenault // jump.
526cb578f84SMatt Arsenault if (Last->isUnconditionalBranch()) {
527cb578f84SMatt Arsenault // Unconditional branch destination might be unanalyzable, assume these
528cb578f84SMatt Arsenault // are OK.
529cb578f84SMatt Arsenault if (MachineBasicBlock *DestBB = TII->getBranchDestBlock(*Last)) {
530cb578f84SMatt Arsenault if (!isBlockInRange(*Last, *DestBB)) {
531cb578f84SMatt Arsenault fixupUnconditionalBranch(*Last);
532cb578f84SMatt Arsenault ++NumUnconditionalRelaxed;
533cb578f84SMatt Arsenault Changed = true;
534cb578f84SMatt Arsenault }
535cb578f84SMatt Arsenault }
536cb578f84SMatt Arsenault }
537cb578f84SMatt Arsenault
538cb578f84SMatt Arsenault // Loop over the conditional branches.
53936919a4fSMatt Arsenault MachineBasicBlock::iterator Next;
54036919a4fSMatt Arsenault for (MachineBasicBlock::iterator J = MBB.getFirstTerminator();
54136919a4fSMatt Arsenault J != MBB.end(); J = Next) {
54236919a4fSMatt Arsenault Next = std::next(J);
54336919a4fSMatt Arsenault MachineInstr &MI = *J;
54436919a4fSMatt Arsenault
545b04c181eSPhilip Reames if (!MI.isConditionalBranch())
546b04c181eSPhilip Reames continue;
547b04c181eSPhilip Reames
548b04c181eSPhilip Reames if (MI.getOpcode() == TargetOpcode::FAULTING_OP)
549b04c181eSPhilip Reames // FAULTING_OP's destination is not encoded in the instruction stream
550b04c181eSPhilip Reames // and thus never needs relaxed.
551b04c181eSPhilip Reames continue;
552b04c181eSPhilip Reames
55336919a4fSMatt Arsenault MachineBasicBlock *DestBB = TII->getBranchDestBlock(MI);
55436919a4fSMatt Arsenault if (!isBlockInRange(MI, *DestBB)) {
55536919a4fSMatt Arsenault if (Next != MBB.end() && Next->isConditionalBranch()) {
55636919a4fSMatt Arsenault // If there are multiple conditional branches, this isn't an
55736919a4fSMatt Arsenault // analyzable block. Split later terminators into a new block so
55836919a4fSMatt Arsenault // each one will be analyzable.
55936919a4fSMatt Arsenault
56044deb791SMatt Arsenault splitBlockBeforeInstr(*Next, DestBB);
56136919a4fSMatt Arsenault } else {
56236919a4fSMatt Arsenault fixupConditionalBranch(MI);
56336919a4fSMatt Arsenault ++NumConditionalRelaxed;
56436919a4fSMatt Arsenault }
56536919a4fSMatt Arsenault
56636919a4fSMatt Arsenault Changed = true;
56736919a4fSMatt Arsenault
56836919a4fSMatt Arsenault // This may have modified all of the terminators, so start over.
56936919a4fSMatt Arsenault Next = MBB.getFirstTerminator();
57036919a4fSMatt Arsenault }
57136919a4fSMatt Arsenault }
57236919a4fSMatt Arsenault }
57336919a4fSMatt Arsenault
57436919a4fSMatt Arsenault return Changed;
57536919a4fSMatt Arsenault }
57636919a4fSMatt Arsenault
runOnMachineFunction(MachineFunction & mf)57736919a4fSMatt Arsenault bool BranchRelaxation::runOnMachineFunction(MachineFunction &mf) {
57836919a4fSMatt Arsenault MF = &mf;
57936919a4fSMatt Arsenault
580d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "***** BranchRelaxation *****\n");
58136919a4fSMatt Arsenault
5826bc43d86SMatt Arsenault const TargetSubtargetInfo &ST = MF->getSubtarget();
5836bc43d86SMatt Arsenault TII = ST.getInstrInfo();
5846bc43d86SMatt Arsenault
58518198305SMatthias Braun TRI = ST.getRegisterInfo();
5866bc43d86SMatt Arsenault if (TRI->trackLivenessAfterRegAlloc(*MF))
5876bc43d86SMatt Arsenault RS.reset(new RegScavenger());
58836919a4fSMatt Arsenault
58936919a4fSMatt Arsenault // Renumber all of the machine basic blocks in the function, guaranteeing that
59036919a4fSMatt Arsenault // the numbers agree with the position of the block in the function.
59136919a4fSMatt Arsenault MF->RenumberBlocks();
59236919a4fSMatt Arsenault
59336919a4fSMatt Arsenault // Do the initial scan of the function, building up information about the
59436919a4fSMatt Arsenault // sizes of each block.
59536919a4fSMatt Arsenault scanFunction();
59636919a4fSMatt Arsenault
597d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Basic blocks before relaxation\n"; dumpBBs(););
59836919a4fSMatt Arsenault
59936919a4fSMatt Arsenault bool MadeChange = false;
60036919a4fSMatt Arsenault while (relaxBranchInstructions())
60136919a4fSMatt Arsenault MadeChange = true;
60236919a4fSMatt Arsenault
60336919a4fSMatt Arsenault // After a while, this might be made debug-only, but it is not expensive.
60436919a4fSMatt Arsenault verify();
60536919a4fSMatt Arsenault
606d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " Basic blocks after relaxation\n\n"; dumpBBs());
60736919a4fSMatt Arsenault
60836919a4fSMatt Arsenault BlockInfo.clear();
60936919a4fSMatt Arsenault
61036919a4fSMatt Arsenault return MadeChange;
61136919a4fSMatt Arsenault }
612