diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index 94e3c32c92b4..7dc7d416ed09 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -181,6 +181,10 @@ namespace llvm { /// branches. extern char &BranchFolderPassID; + /// BranchRelaxation - This pass replaces branches that need to jump further + /// than is supported by a branch instruction. + extern char &BranchRelaxationPassID; + /// MachineFunctionPrinterPass - This pass prints out MachineInstr's. extern char &MachineFunctionPrinterPassID; diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 11ed422ab8dd..604d2a58f8f0 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -79,6 +79,7 @@ void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&); void initializeBoundsCheckingPass(PassRegistry&); void initializeBranchFolderPassPass(PassRegistry&); void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry&); +void initializeBranchRelaxationPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&); void initializeCFGPrinterLegacyPassPass(PassRegistry&); diff --git a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp b/llvm/lib/CodeGen/BranchRelaxation.cpp similarity index 85% rename from llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp rename to llvm/lib/CodeGen/BranchRelaxation.cpp index 6042b0a96247..f1383064b79c 100644 --- a/llvm/lib/Target/AArch64/AArch64BranchRelaxation.cpp +++ b/llvm/lib/CodeGen/BranchRelaxation.cpp @@ -1,4 +1,4 @@ -//===-- AArch64BranchRelaxation.cpp - AArch64 branch relaxation -----------===// +//===-- BranchRelaxation.cpp ----------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,32 +7,27 @@ // //===----------------------------------------------------------------------===// -#include "AArch64.h" -#include "AArch64InstrInfo.h" -#include "AArch64MachineFunctionInfo.h" -#include "AArch64Subtarget.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; -#define DEBUG_TYPE "aarch64-branch-relax" +#define DEBUG_TYPE "branch-relaxation" STATISTIC(NumSplit, "Number of basic blocks split"); STATISTIC(NumConditionalRelaxed, "Number of conditional branches relaxed"); -namespace llvm { -void initializeAArch64BranchRelaxationPass(PassRegistry &); -} - -#define AARCH64_BR_RELAX_NAME "AArch64 branch relaxation pass" +#define BRANCH_RELAX_NAME "Branch relaxation pass" namespace { -class AArch64BranchRelaxation : public MachineFunctionPass { +class BranchRelaxation : public MachineFunctionPass { /// BasicBlockInfo - Information about the offset and size of a single /// basic block. struct BasicBlockInfo { @@ -64,7 +59,7 @@ class AArch64BranchRelaxation : public MachineFunctionPass { SmallVector BlockInfo; MachineFunction *MF; - const AArch64InstrInfo *TII; + const TargetInstrInfo *TII; bool relaxBranchInstructions(); void scanFunction(); @@ -73,29 +68,31 @@ class AArch64BranchRelaxation : public MachineFunctionPass { bool isBlockInRange(const MachineInstr &MI, const MachineBasicBlock &BB) const; bool fixupConditionalBranch(MachineInstr &MI); - void computeBlockSize(const MachineBasicBlock &MBB); + uint64_t computeBlockSize(const MachineBasicBlock &MBB) const; unsigned getInstrOffset(const MachineInstr &MI) const; void dumpBBs(); void verify(); public: static char ID; - AArch64BranchRelaxation() : MachineFunctionPass(ID) { - initializeAArch64BranchRelaxationPass(*PassRegistry::getPassRegistry()); - } + BranchRelaxation() : MachineFunctionPass(ID) { } bool runOnMachineFunction(MachineFunction &MF) override; - StringRef getPassName() const override { return AARCH64_BR_RELAX_NAME; } + StringRef getPassName() const override { + return BRANCH_RELAX_NAME; + } }; -char AArch64BranchRelaxation::ID = 0; + } -INITIALIZE_PASS(AArch64BranchRelaxation, "aarch64-branch-relax", - AARCH64_BR_RELAX_NAME, false, false) +char BranchRelaxation::ID = 0; +char &llvm::BranchRelaxationPassID = BranchRelaxation::ID; + +INITIALIZE_PASS(BranchRelaxation, DEBUG_TYPE, BRANCH_RELAX_NAME, false, false) /// verify - check BBOffsets, BBSizes, alignment of islands -void AArch64BranchRelaxation::verify() { +void BranchRelaxation::verify() { #ifndef NDEBUG unsigned PrevNum = MF->begin()->getNumber(); for (MachineBasicBlock &MBB : *MF) { @@ -109,7 +106,7 @@ void AArch64BranchRelaxation::verify() { } /// print block size and offset information - debugging -void AArch64BranchRelaxation::dumpBBs() { +void BranchRelaxation::dumpBBs() { for (auto &MBB : *MF) { const BasicBlockInfo &BBI = BlockInfo[MBB.getNumber()]; dbgs() << format("BB#%u\toffset=%08x\t", MBB.getNumber(), BBI.Offset) @@ -119,7 +116,7 @@ void AArch64BranchRelaxation::dumpBBs() { /// scanFunction - Do the initial scan of the function, building up /// information about each block. -void AArch64BranchRelaxation::scanFunction() { +void BranchRelaxation::scanFunction() { BlockInfo.clear(); BlockInfo.resize(MF->getNumBlockIDs()); @@ -128,25 +125,24 @@ void AArch64BranchRelaxation::scanFunction() { // alignment assumptions, as we don't know for sure the size of any // instructions in the inline assembly. for (MachineBasicBlock &MBB : *MF) - computeBlockSize(MBB); + BlockInfo[MBB.getNumber()].Size = computeBlockSize(MBB); // Compute block offsets and known bits. adjustBlockOffsets(*MF->begin()); } /// computeBlockSize - Compute the size for MBB. -/// This function updates BlockInfo directly. -void AArch64BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) { - unsigned Size = 0; +uint64_t BranchRelaxation::computeBlockSize(const MachineBasicBlock &MBB) const { + uint64_t Size = 0; for (const MachineInstr &MI : MBB) Size += TII->getInstSizeInBytes(MI); - BlockInfo[MBB.getNumber()].Size = Size; + return Size; } /// getInstrOffset - Return the current offset of the specified machine /// instruction from the start of the function. This offset changes as stuff is /// moved around inside the function. -unsigned AArch64BranchRelaxation::getInstrOffset(const MachineInstr &MI) const { +unsigned BranchRelaxation::getInstrOffset(const MachineInstr &MI) const { const MachineBasicBlock *MBB = MI.getParent(); // The offset is composed of two things: the sum of the sizes of all MBB's @@ -163,7 +159,7 @@ unsigned AArch64BranchRelaxation::getInstrOffset(const MachineInstr &MI) const { return Offset; } -void AArch64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) { +void BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) { unsigned PrevNum = Start.getNumber(); for (auto &MBB : make_range(MachineFunction::iterator(Start), MF->end())) { unsigned Num = MBB.getNumber(); @@ -183,8 +179,7 @@ void AArch64BranchRelaxation::adjustBlockOffsets(MachineBasicBlock &Start) { /// NOTE: Successor list of the original BB is out of date after this function, /// and must be updated by the caller! Other transforms follow using this /// utility function, so no point updating now rather than waiting. -MachineBasicBlock * -AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) { +MachineBasicBlock *BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) { MachineBasicBlock *OrigBB = MI.getParent(); // Create a new MBB for the code after the OrigBB. @@ -209,11 +204,11 @@ AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) { // the new jump we added. (It should be possible to do this without // recounting everything, but it's very confusing, and this is rarely // executed.) - computeBlockSize(*OrigBB); + BlockInfo[OrigBB->getNumber()].Size = computeBlockSize(*OrigBB); - // Figure out how large the NewMBB is. As the second half of the original + // Figure out how large the NewMBB is. As the second half of the original // block, it may contain a tablejump. - computeBlockSize(*NewBB); + BlockInfo[NewBB->getNumber()].Size = computeBlockSize(*NewBB); // All BBOffsets following these blocks must be modified. adjustBlockOffsets(*OrigBB); @@ -225,7 +220,7 @@ AArch64BranchRelaxation::splitBlockBeforeInstr(MachineInstr &MI) { /// isBlockInRange - Returns true if the distance between specific MI and /// specific BB can fit in MI's displacement field. -bool AArch64BranchRelaxation::isBlockInRange( +bool BranchRelaxation::isBlockInRange( const MachineInstr &MI, const MachineBasicBlock &DestBB) const { int64_t BrOffset = getInstrOffset(MI); int64_t DestOffset = BlockInfo[DestBB.getNumber()].Offset; @@ -247,7 +242,7 @@ bool AArch64BranchRelaxation::isBlockInRange( /// fixupConditionalBranch - Fix up a conditional branch whose destination is /// too far away to fit in its displacement field. It is converted to an inverse /// conditional branch + an unconditional branch to the destination. -bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) { +bool BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) { DebugLoc DL = MI.getDebugLoc(); MachineBasicBlock *MBB = MI.getParent(); MachineBasicBlock *TBB = nullptr, *FBB = nullptr; @@ -329,7 +324,7 @@ bool AArch64BranchRelaxation::fixupConditionalBranch(MachineInstr &MI) { return true; } -bool AArch64BranchRelaxation::relaxBranchInstructions() { +bool BranchRelaxation::relaxBranchInstructions() { bool Changed = false; // Relaxing branches involves creating new basic blocks, so re-eval // end() for termination. @@ -339,6 +334,7 @@ bool AArch64BranchRelaxation::relaxBranchInstructions() { if (J == MBB.end()) continue; + MachineBasicBlock::iterator Next; for (MachineBasicBlock::iterator J = MBB.getFirstTerminator(); J != MBB.end(); J = Next) { @@ -371,7 +367,6 @@ bool AArch64BranchRelaxation::relaxBranchInstructions() { // This may have modified all of the terminators, so start over. Next = MBB.getFirstTerminator(); } - } } } @@ -379,12 +374,12 @@ bool AArch64BranchRelaxation::relaxBranchInstructions() { return Changed; } -bool AArch64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) { +bool BranchRelaxation::runOnMachineFunction(MachineFunction &mf) { MF = &mf; - DEBUG(dbgs() << "***** AArch64BranchRelaxation *****\n"); + DEBUG(dbgs() << "***** BranchRelaxation *****\n"); - TII = MF->getSubtarget().getInstrInfo(); + TII = MF->getSubtarget().getInstrInfo(); // Renumber all of the machine basic blocks in the function, guaranteeing that // the numbers agree with the position of the block in the function. @@ -409,8 +404,3 @@ bool AArch64BranchRelaxation::runOnMachineFunction(MachineFunction &mf) { return MadeChange; } - -/// Returns an instance of the AArch64 Branch Relaxation pass. -FunctionPass *llvm::createAArch64BranchRelaxation() { - return new AArch64BranchRelaxation(); -} diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index ed86e6e544a9..4cc8290cacfb 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -5,6 +5,7 @@ add_llvm_library(LLVMCodeGen AtomicExpandPass.cpp BasicTargetTransformInfo.cpp BranchFolding.cpp + BranchRelaxation.cpp BuiltinGCs.cpp CalcSpillWeights.cpp CallingConvLower.cpp diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp index 59f52ba7954e..a1592d71a6bf 100644 --- a/llvm/lib/CodeGen/CodeGen.cpp +++ b/llvm/lib/CodeGen/CodeGen.cpp @@ -22,6 +22,7 @@ using namespace llvm; void llvm::initializeCodeGen(PassRegistry &Registry) { initializeAtomicExpandPass(Registry); initializeBranchFolderPassPass(Registry); + initializeBranchRelaxationPass(Registry); initializeCodeGenPreparePass(Registry); initializeCountingFunctionInserterPass(Registry); initializeDeadMachineInstructionElimPass(Registry); diff --git a/llvm/lib/Target/AArch64/AArch64.h b/llvm/lib/Target/AArch64/AArch64.h index 9bc800e5f968..bf80e662f82a 100644 --- a/llvm/lib/Target/AArch64/AArch64.h +++ b/llvm/lib/Target/AArch64/AArch64.h @@ -30,7 +30,6 @@ FunctionPass *createAArch64DeadRegisterDefinitions(); FunctionPass *createAArch64RedundantCopyEliminationPass(); FunctionPass *createAArch64ConditionalCompares(); FunctionPass *createAArch64AdvSIMDScalar(); -FunctionPass *createAArch64BranchRelaxation(); FunctionPass *createAArch64ISelDag(AArch64TargetMachine &TM, CodeGenOpt::Level OptLevel); FunctionPass *createAArch64StorePairSuppressPass(); @@ -50,7 +49,6 @@ void initializeAArch64A53Fix835769Pass(PassRegistry&); void initializeAArch64A57FPLoadBalancingPass(PassRegistry&); void initializeAArch64AddressTypePromotionPass(PassRegistry&); void initializeAArch64AdvSIMDScalarPass(PassRegistry&); -void initializeAArch64BranchRelaxationPass(PassRegistry&); void initializeAArch64CollectLOHPass(PassRegistry&); void initializeAArch64ConditionalComparesPass(PassRegistry&); void initializeAArch64ConditionOptimizerPass(PassRegistry&); diff --git a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp index 52ccc78fb624..d98a9339f3d2 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetMachine.cpp @@ -135,7 +135,6 @@ extern "C" void LLVMInitializeAArch64Target() { initializeAArch64A57FPLoadBalancingPass(*PR); initializeAArch64AddressTypePromotionPass(*PR); initializeAArch64AdvSIMDScalarPass(*PR); - initializeAArch64BranchRelaxationPass(*PR); initializeAArch64CollectLOHPass(*PR); initializeAArch64ConditionalComparesPass(*PR); initializeAArch64ConditionOptimizerPass(*PR); @@ -463,7 +462,8 @@ void AArch64PassConfig::addPreEmitPass() { // Relax conditional branch instructions if they're otherwise out of // range of their destination. if (BranchRelaxation) - addPass(createAArch64BranchRelaxation()); + addPass(&BranchRelaxationPassID); + if (TM->getOptLevel() != CodeGenOpt::None && EnableCollectLOH && TM->getTargetTriple().isOSBinFormatMachO()) addPass(createAArch64CollectLOHPass()); diff --git a/llvm/lib/Target/AArch64/CMakeLists.txt b/llvm/lib/Target/AArch64/CMakeLists.txt index 89cfaa763a09..acd4ab129494 100644 --- a/llvm/lib/Target/AArch64/CMakeLists.txt +++ b/llvm/lib/Target/AArch64/CMakeLists.txt @@ -38,7 +38,6 @@ add_llvm_target(AArch64CodeGen AArch64AddressTypePromotion.cpp AArch64AdvSIMDScalarPass.cpp AArch64AsmPrinter.cpp - AArch64BranchRelaxation.cpp AArch64CleanupLocalDynamicTLSPass.cpp AArch64CollectLOH.cpp AArch64ConditionalCompares.cpp diff --git a/llvm/test/CodeGen/MIR/AArch64/inst-size-patchpoint.mir b/llvm/test/CodeGen/MIR/AArch64/inst-size-patchpoint.mir index e9d05cd2e1c6..f14fc3ece72a 100644 --- a/llvm/test/CodeGen/MIR/AArch64/inst-size-patchpoint.mir +++ b/llvm/test/CodeGen/MIR/AArch64/inst-size-patchpoint.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=aarch64-unknown -run-pass aarch64-branch-relax -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s --- | ; ModuleID = '/tmp/test.ll' source_filename = "test.ll" diff --git a/llvm/test/CodeGen/MIR/AArch64/inst-size-stackmap.mir b/llvm/test/CodeGen/MIR/AArch64/inst-size-stackmap.mir index a3faed719a40..3c542e261177 100644 --- a/llvm/test/CodeGen/MIR/AArch64/inst-size-stackmap.mir +++ b/llvm/test/CodeGen/MIR/AArch64/inst-size-stackmap.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=aarch64-unknown -run-pass aarch64-branch-relax -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s --- | ; ModuleID = 'test.ll' source_filename = "test.ll" diff --git a/llvm/test/CodeGen/MIR/AArch64/inst-size-tlsdesc-callseq.mir b/llvm/test/CodeGen/MIR/AArch64/inst-size-tlsdesc-callseq.mir index 7e7b318009a5..261747c62764 100644 --- a/llvm/test/CodeGen/MIR/AArch64/inst-size-tlsdesc-callseq.mir +++ b/llvm/test/CodeGen/MIR/AArch64/inst-size-tlsdesc-callseq.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=aarch64-unknown -run-pass aarch64-branch-relax -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s +# RUN: llc -mtriple=aarch64-unknown -run-pass branch-relaxation -aarch64-tbz-offset-bits=4 %s -o - | FileCheck %s --- | ; ModuleID = 'test.ll' source_filename = "test.ll"