diff options
author | Perry MacMurray <pmacmurr@quicinc.com> | 2024-04-26 22:08:45 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-26 22:08:45 -0500 |
commit | cb508a0032eb2d11391214864f408261158361bf (patch) | |
tree | ab0d2148013e19d9dec9084216847130d980be2f | |
parent | 315dc4bbc730a3c672967c27587088cfe9752fe6 (diff) |
[Hexagon] Add Hexagon Copy Hoisting pass (#89313)
Adds the HexagonCopyHoisting pass, which moves a common copy instruction
into a basic block if it is present in all successor basic blocks.
---------
Co-authored-by: Jyotsna Verma <jverma@quicinc.com>
-rw-r--r-- | llvm/lib/Target/Hexagon/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp | 272 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp | 187 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/hexagon-copy-hoisting.mir | 53 |
4 files changed, 428 insertions, 85 deletions
diff --git a/llvm/lib/Target/Hexagon/CMakeLists.txt b/llvm/lib/Target/Hexagon/CMakeLists.txt index cdc062eee72b..9e4ca08aea40 100644 --- a/llvm/lib/Target/Hexagon/CMakeLists.txt +++ b/llvm/lib/Target/Hexagon/CMakeLists.txt @@ -26,6 +26,7 @@ add_llvm_target(HexagonCodeGen HexagonCommonGEP.cpp HexagonConstExtenders.cpp HexagonConstPropagation.cpp + HexagonCopyHoisting.cpp HexagonCopyToCombine.cpp HexagonEarlyIfConv.cpp HexagonExpandCondsets.cpp diff --git a/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp b/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp new file mode 100644 index 000000000000..97917270601b --- /dev/null +++ b/llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp @@ -0,0 +1,272 @@ +//===--------- HexagonCopyHoisting.cpp - Hexagon Copy Hoisting ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// The purpose of this pass is to move the copy instructions that are +// present in all the successor of a basic block (BB) to the end of BB. +//===----------------------------------------------------------------------===// + +#include "HexagonTargetMachine.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervals.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "CopyHoist" + +using namespace llvm; + +static cl::opt<std::string> CPHoistFn("cphoistfn", cl::Hidden, cl::desc(""), + cl::init("")); + +namespace llvm { +void initializeHexagonCopyHoistingPass(PassRegistry &Registry); +FunctionPass *createHexagonCopyHoisting(); +} // namespace llvm + +namespace { + +class HexagonCopyHoisting : public MachineFunctionPass { + +public: + static char ID; + HexagonCopyHoisting() : MachineFunctionPass(ID), MFN(nullptr), MRI(nullptr) { + initializeHexagonCopyHoistingPass(*PassRegistry::getPassRegistry()); + } + + StringRef getPassName() const override { return "Hexagon Copy Hoisting"; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<SlotIndexes>(); + AU.addRequired<LiveIntervals>(); + AU.addPreserved<SlotIndexes>(); + AU.addPreserved<LiveIntervals>(); + AU.addRequired<MachineDominatorTree>(); + AU.addPreserved<MachineDominatorTree>(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + bool runOnMachineFunction(MachineFunction &Fn) override; + void collectCopyInst(); + void addMItoCopyList(MachineInstr *MI); + bool analyzeCopy(MachineBasicBlock *BB); + bool isSafetoMove(MachineInstr *CandMI); + void moveCopyInstr(MachineBasicBlock *DestBB, + std::pair<Register, Register> Key, MachineInstr *MI); + + MachineFunction *MFN; + MachineRegisterInfo *MRI; + std::vector<DenseMap<std::pair<Register, Register>, MachineInstr *>> + CopyMIList; +}; + +} // namespace + +char HexagonCopyHoisting::ID = 0; + +namespace llvm { +char &HexagonCopyHoistingID = HexagonCopyHoisting::ID; +} // namespace llvm + +bool HexagonCopyHoisting::runOnMachineFunction(MachineFunction &Fn) { + + if ((CPHoistFn != "") && (CPHoistFn != Fn.getFunction().getName())) + return false; + + MFN = &Fn; + MRI = &Fn.getRegInfo(); + + LLVM_DEBUG(dbgs() << "\nCopy Hoisting:" << "\'" << Fn.getName() << "\'\n"); + + CopyMIList.clear(); + CopyMIList.resize(Fn.getNumBlockIDs()); + + // Traverse through all basic blocks and collect copy instructions. + collectCopyInst(); + + // Traverse through the basic blocks again and move the COPY instructions + // that are present in all the successors of BB to BB. + bool Changed = false; + for (MachineBasicBlock *BB : post_order(&Fn)) { + if (!BB->empty()) { + if (BB->pred_size() != 1) + continue; + auto &BBCopyInst = CopyMIList[BB->getNumber()]; + if (BBCopyInst.size() > 0) + Changed |= analyzeCopy(*BB->pred_begin()); + } + } + // Re-compute liveness + if (Changed) { + LiveIntervals &LIS = getAnalysis<LiveIntervals>(); + SlotIndexes *SI = LIS.getSlotIndexes(); + SI->releaseMemory(); + SI->runOnMachineFunction(Fn); + LIS.releaseMemory(); + LIS.runOnMachineFunction(Fn); + } + return Changed; +} + +//===----------------------------------------------------------------------===// +// Save all COPY instructions for each basic block in CopyMIList vector. +//===----------------------------------------------------------------------===// +void HexagonCopyHoisting::collectCopyInst() { + for (MachineBasicBlock &BB : *MFN) { +#ifndef NDEBUG + auto &BBCopyInst = CopyMIList[BB.getNumber()]; + LLVM_DEBUG(dbgs() << "Visiting BB#" << BB.getNumber() << ":\n"); +#endif + + for (MachineInstr &MI : BB) { + if (MI.getOpcode() == TargetOpcode::COPY) + addMItoCopyList(&MI); + } + LLVM_DEBUG(dbgs() << "\tNumber of copies: " << BBCopyInst.size() << "\n"); + } +} + +void HexagonCopyHoisting::addMItoCopyList(MachineInstr *MI) { + unsigned BBNum = MI->getParent()->getNumber(); + auto &BBCopyInst = CopyMIList[BBNum]; + Register DstReg = MI->getOperand(0).getReg(); + Register SrcReg = MI->getOperand(1).getReg(); + + if (!Register::isVirtualRegister(DstReg) || + !Register::isVirtualRegister(SrcReg) || + MRI->getRegClass(DstReg) != &Hexagon::IntRegsRegClass || + MRI->getRegClass(SrcReg) != &Hexagon::IntRegsRegClass) + return; + + BBCopyInst.insert(std::pair(std::pair(SrcReg, DstReg), MI)); +#ifndef NDEBUG + LLVM_DEBUG(dbgs() << "\tAdding Copy Instr to the list: " << MI << "\n"); + for (auto II : BBCopyInst) { + MachineInstr *TempMI = II.getSecond(); + LLVM_DEBUG(dbgs() << "\tIn the list: " << TempMI << "\n"); + } +#endif +} + +//===----------------------------------------------------------------------===// +// Look at the COPY instructions of all the successors of BB. If the same +// instruction is present in every successor and can be safely moved, +// pull it into BB. +//===----------------------------------------------------------------------===// +bool HexagonCopyHoisting::analyzeCopy(MachineBasicBlock *BB) { + + bool Changed = false; + if (BB->succ_size() < 2) + return false; + + for (MachineBasicBlock *SB : BB->successors()) { + if (SB->pred_size() != 1 || SB->isEHPad() || SB->hasAddressTaken()) + return false; + } + + MachineBasicBlock *SBB1 = *BB->succ_begin(); + auto &BBCopyInst1 = CopyMIList[SBB1->getNumber()]; + + for (auto II : BBCopyInst1) { + std::pair<Register, Register> Key = II.getFirst(); + MachineInstr *MI = II.getSecond(); + bool IsSafetoMove = true; + for (MachineBasicBlock *SuccBB : BB->successors()) { + auto &SuccBBCopyInst = CopyMIList[SuccBB->getNumber()]; + if (!SuccBBCopyInst.count(Key)) { + // Same copy not present in this successor + IsSafetoMove = false; + break; + } + // If present, make sure that it's safe to pull this copy instruction + // into the predecessor. + MachineInstr *SuccMI = SuccBBCopyInst[Key]; + if (!isSafetoMove(SuccMI)) { + IsSafetoMove = false; + break; + } + } + // If we have come this far, this copy instruction can be safely + // moved to the predecessor basic block. + if (IsSafetoMove) { + LLVM_DEBUG(dbgs() << "\t\t Moving instr to BB#" << BB->getNumber() << ": " + << MI << "\n"); + moveCopyInstr(BB, Key, MI); + // Add my into BB copyMI list. + Changed = true; + } + } + +#ifndef NDEBUG + auto &BBCopyInst = CopyMIList[BB->getNumber()]; + for (auto II : BBCopyInst) { + MachineInstr *TempMI = II.getSecond(); + LLVM_DEBUG(dbgs() << "\tIn the list: " << TempMI << "\n"); + } +#endif + return Changed; +} + +bool HexagonCopyHoisting::isSafetoMove(MachineInstr *CandMI) { + // Make sure that it's safe to move this 'copy' instruction to the predecessor + // basic block. + assert(CandMI->getOperand(0).isReg() && CandMI->getOperand(1).isReg()); + Register DefR = CandMI->getOperand(0).getReg(); + Register UseR = CandMI->getOperand(1).getReg(); + + MachineBasicBlock *BB = CandMI->getParent(); + // There should not be a def/use of DefR between the start of BB and CandMI. + MachineBasicBlock::iterator MII, MIE; + for (MII = BB->begin(), MIE = CandMI; MII != MIE; ++MII) { + MachineInstr *OtherMI = &*MII; + for (const MachineOperand &Mo : OtherMI->operands()) + if (Mo.isReg() && Mo.getReg() == DefR) + return false; + } + // There should not be a def of UseR between the start of BB and CandMI. + for (MII = BB->begin(), MIE = CandMI; MII != MIE; ++MII) { + MachineInstr *OtherMI = &*MII; + for (const MachineOperand &Mo : OtherMI->operands()) + if (Mo.isReg() && Mo.isDef() && Mo.getReg() == UseR) + return false; + } + return true; +} + +void HexagonCopyHoisting::moveCopyInstr(MachineBasicBlock *DestBB, + std::pair<Register, Register> Key, + MachineInstr *MI) { + MachineBasicBlock::iterator FirstTI = DestBB->getFirstTerminator(); + assert(FirstTI != DestBB->end()); + + DestBB->splice(FirstTI, MI->getParent(), MI); + + addMItoCopyList(MI); + for (auto I = ++(DestBB->succ_begin()), E = DestBB->succ_end(); I != E; ++I) { + MachineBasicBlock *SuccBB = *I; + auto &BBCopyInst = CopyMIList[SuccBB->getNumber()]; + MachineInstr *SuccMI = BBCopyInst[Key]; + SuccMI->eraseFromParent(); + BBCopyInst.erase(Key); + } +} + +//===----------------------------------------------------------------------===// +// Public Constructor Functions +//===----------------------------------------------------------------------===// + +INITIALIZE_PASS(HexagonCopyHoisting, "hexagon-move-phicopy", + "Hexagon move phi copy", false, false) + +FunctionPass *llvm::createHexagonCopyHoisting() { + return new HexagonCopyHoisting(); +} diff --git a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp index e64d7e52a9aa..3a792ecfd03d 100644 --- a/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -43,8 +43,9 @@ cl::opt<unsigned> RDFFuncBlockLimit( "rdf-bb-limit", cl::Hidden, cl::init(1000), cl::desc("Basic block limit for a function for RDF optimizations")); -static cl::opt<bool> DisableHardwareLoops("disable-hexagon-hwloops", - cl::Hidden, cl::desc("Disable Hardware Loops for Hexagon target")); +static cl::opt<bool> + DisableHardwareLoops("disable-hexagon-hwloops", cl::Hidden, + cl::desc("Disable Hardware Loops for Hexagon target")); static cl::opt<bool> DisableAModeOpt("disable-hexagon-amodeopt", cl::Hidden, @@ -58,8 +59,9 @@ static cl::opt<bool> DisableHCP("disable-hcp", cl::Hidden, cl::desc("Disable Hexagon constant propagation")); -static cl::opt<bool> DisableStoreWidening("disable-store-widen", - cl::Hidden, cl::init(false), cl::desc("Disable store widening")); +static cl::opt<bool> DisableStoreWidening("disable-store-widen", cl::Hidden, + cl::init(false), + cl::desc("Disable store widening")); static cl::opt<bool> EnableExpandCondsets("hexagon-expand-condsets", cl::init(true), cl::Hidden, @@ -72,42 +74,53 @@ static cl::opt<bool> EnableTfrCleanup("hexagon-tfr-cleanup", cl::init(true), static cl::opt<bool> EnableEarlyIf("hexagon-eif", cl::init(true), cl::Hidden, cl::desc("Enable early if-conversion")); -static cl::opt<bool> EnableGenInsert("hexagon-insert", cl::init(true), - cl::Hidden, cl::desc("Generate \"insert\" instructions")); +static cl::opt<bool> EnableCopyHoist("hexagon-copy-hoist", cl::init(true), + cl::Hidden, cl::ZeroOrMore, + cl::desc("Enable Hexagon copy hoisting")); + +static cl::opt<bool> + EnableGenInsert("hexagon-insert", cl::init(true), cl::Hidden, + cl::desc("Generate \"insert\" instructions")); static cl::opt<bool> EnableCommGEP("hexagon-commgep", cl::init(true), cl::Hidden, cl::desc("Enable commoning of GEP instructions")); -static cl::opt<bool> EnableGenExtract("hexagon-extract", cl::init(true), - cl::Hidden, cl::desc("Generate \"extract\" instructions")); +static cl::opt<bool> + EnableGenExtract("hexagon-extract", cl::init(true), cl::Hidden, + cl::desc("Generate \"extract\" instructions")); -static cl::opt<bool> EnableGenMux("hexagon-mux", cl::init(true), cl::Hidden, - cl::desc("Enable converting conditional transfers into MUX instructions")); +static cl::opt<bool> EnableGenMux( + "hexagon-mux", cl::init(true), cl::Hidden, + cl::desc("Enable converting conditional transfers into MUX instructions")); -static cl::opt<bool> EnableGenPred("hexagon-gen-pred", cl::init(true), - cl::Hidden, cl::desc("Enable conversion of arithmetic operations to " - "predicate instructions")); +static cl::opt<bool> + EnableGenPred("hexagon-gen-pred", cl::init(true), cl::Hidden, + cl::desc("Enable conversion of arithmetic operations to " + "predicate instructions")); static cl::opt<bool> EnableLoopPrefetch("hexagon-loop-prefetch", cl::Hidden, cl::desc("Enable loop data prefetch on Hexagon")); -static cl::opt<bool> DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, - cl::desc("Disable splitting double registers")); +static cl::opt<bool> + DisableHSDR("disable-hsdr", cl::init(false), cl::Hidden, + cl::desc("Disable splitting double registers")); static cl::opt<bool> EnableGenMemAbs("hexagon-mem-abs", cl::init(true), cl::Hidden, cl::desc("Generate absolute set instructions")); static cl::opt<bool> EnableBitSimplify("hexagon-bit", cl::init(true), - cl::Hidden, cl::desc("Bit simplification")); + cl::Hidden, + cl::desc("Bit simplification")); static cl::opt<bool> EnableLoopResched("hexagon-loop-resched", cl::init(true), - cl::Hidden, cl::desc("Loop rescheduling")); + cl::Hidden, + cl::desc("Loop rescheduling")); -static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), - cl::Hidden, cl::desc("Disable backend optimizations")); +static cl::opt<bool> HexagonNoOpt("hexagon-noopt", cl::init(false), cl::Hidden, + cl::desc("Disable backend optimizations")); static cl::opt<bool> EnableVectorPrint("enable-hexagon-vector-print", cl::Hidden, @@ -148,69 +161,72 @@ static ScheduleDAGInstrs *createVLIWMachineSched(MachineSchedContext *C) { } static MachineSchedRegistry -SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", - createVLIWMachineSched); + SchedCustomRegistry("hexagon", "Run Hexagon's custom scheduler", + createVLIWMachineSched); namespace llvm { - extern char &HexagonExpandCondsetsID; - extern char &HexagonTfrCleanupID; - void initializeHexagonBitSimplifyPass(PassRegistry&); - void initializeHexagonConstExtendersPass(PassRegistry&); - void initializeHexagonConstPropagationPass(PassRegistry&); - void initializeHexagonCopyToCombinePass(PassRegistry&); - void initializeHexagonEarlyIfConversionPass(PassRegistry&); - void initializeHexagonExpandCondsetsPass(PassRegistry&); - void initializeHexagonGenMemAbsolutePass(PassRegistry &); - void initializeHexagonGenMuxPass(PassRegistry&); - void initializeHexagonHardwareLoopsPass(PassRegistry&); - void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &); - void initializeHexagonLoopAlignPass(PassRegistry &); - void initializeHexagonNewValueJumpPass(PassRegistry&); - void initializeHexagonOptAddrModePass(PassRegistry&); - void initializeHexagonPacketizerPass(PassRegistry&); - void initializeHexagonRDFOptPass(PassRegistry&); - void initializeHexagonSplitDoubleRegsPass(PassRegistry&); - void initializeHexagonTfrCleanupPass(PassRegistry &); - void initializeHexagonVExtractPass(PassRegistry &); - void initializeHexagonVectorCombineLegacyPass(PassRegistry&); - void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &); - Pass *createHexagonLoopIdiomPass(); - Pass *createHexagonVectorLoopCarriedReuseLegacyPass(); - - FunctionPass *createHexagonBitSimplify(); - FunctionPass *createHexagonBranchRelaxation(); - FunctionPass *createHexagonCallFrameInformation(); - FunctionPass *createHexagonCFGOptimizer(); - FunctionPass *createHexagonCommonGEP(); - FunctionPass *createHexagonConstExtenders(); - FunctionPass *createHexagonConstPropagationPass(); - FunctionPass *createHexagonCopyToCombine(); - FunctionPass *createHexagonEarlyIfConversion(); - FunctionPass *createHexagonFixupHwLoops(); - FunctionPass *createHexagonGenExtract(); - FunctionPass *createHexagonGenInsert(); - FunctionPass *createHexagonGenMemAbsolute(); - FunctionPass *createHexagonGenMux(); - FunctionPass *createHexagonGenPredicate(); - FunctionPass *createHexagonHardwareLoops(); - FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, - CodeGenOptLevel OptLevel); - FunctionPass *createHexagonLoopAlign(); - FunctionPass *createHexagonLoopRescheduling(); - FunctionPass *createHexagonNewValueJump(); - FunctionPass *createHexagonOptAddrMode(); - FunctionPass *createHexagonOptimizeSZextends(); - FunctionPass *createHexagonPacketizer(bool Minimal); - FunctionPass *createHexagonPeephole(); - FunctionPass *createHexagonRDFOpt(); - FunctionPass *createHexagonSplitConst32AndConst64(); - FunctionPass *createHexagonSplitDoubleRegs(); - FunctionPass *createHexagonStoreWidening(); - FunctionPass *createHexagonTfrCleanup(); - FunctionPass *createHexagonVectorCombineLegacyPass(); - FunctionPass *createHexagonVectorPrint(); - FunctionPass *createHexagonVExtract(); -} // end namespace llvm; +extern char &HexagonCopyHoistingID; +extern char &HexagonExpandCondsetsID; +extern char &HexagonTfrCleanupID; +void initializeHexagonBitSimplifyPass(PassRegistry &); +void initializeHexagonCopyHoistingPass(PassRegistry &); +void initializeHexagonConstExtendersPass(PassRegistry &); +void initializeHexagonConstPropagationPass(PassRegistry &); +void initializeHexagonCopyToCombinePass(PassRegistry &); +void initializeHexagonEarlyIfConversionPass(PassRegistry &); +void initializeHexagonExpandCondsetsPass(PassRegistry &); +void initializeHexagonGenMemAbsolutePass(PassRegistry &); +void initializeHexagonGenMuxPass(PassRegistry &); +void initializeHexagonHardwareLoopsPass(PassRegistry &); +void initializeHexagonLoopIdiomRecognizeLegacyPassPass(PassRegistry &); +void initializeHexagonLoopAlignPass(PassRegistry &); +void initializeHexagonNewValueJumpPass(PassRegistry &); +void initializeHexagonOptAddrModePass(PassRegistry &); +void initializeHexagonPacketizerPass(PassRegistry &); +void initializeHexagonRDFOptPass(PassRegistry &); +void initializeHexagonSplitDoubleRegsPass(PassRegistry &); +void initializeHexagonTfrCleanupPass(PassRegistry &); +void initializeHexagonVExtractPass(PassRegistry &); +void initializeHexagonVectorCombineLegacyPass(PassRegistry &); +void initializeHexagonVectorLoopCarriedReuseLegacyPassPass(PassRegistry &); +Pass *createHexagonLoopIdiomPass(); +Pass *createHexagonVectorLoopCarriedReuseLegacyPass(); + +FunctionPass *createHexagonBitSimplify(); +FunctionPass *createHexagonBranchRelaxation(); +FunctionPass *createHexagonCallFrameInformation(); +FunctionPass *createHexagonCFGOptimizer(); +FunctionPass *createHexagonCommonGEP(); +FunctionPass *createHexagonConstExtenders(); +FunctionPass *createHexagonConstPropagationPass(); +FunctionPass *createHexagonCopyHoisting(); +FunctionPass *createHexagonCopyToCombine(); +FunctionPass *createHexagonEarlyIfConversion(); +FunctionPass *createHexagonFixupHwLoops(); +FunctionPass *createHexagonGenExtract(); +FunctionPass *createHexagonGenInsert(); +FunctionPass *createHexagonGenMemAbsolute(); +FunctionPass *createHexagonGenMux(); +FunctionPass *createHexagonGenPredicate(); +FunctionPass *createHexagonHardwareLoops(); +FunctionPass *createHexagonISelDag(HexagonTargetMachine &TM, + CodeGenOptLevel OptLevel); +FunctionPass *createHexagonLoopAlign(); +FunctionPass *createHexagonLoopRescheduling(); +FunctionPass *createHexagonNewValueJump(); +FunctionPass *createHexagonOptAddrMode(); +FunctionPass *createHexagonOptimizeSZextends(); +FunctionPass *createHexagonPacketizer(bool Minimal); +FunctionPass *createHexagonPeephole(); +FunctionPass *createHexagonRDFOpt(); +FunctionPass *createHexagonSplitConst32AndConst64(); +FunctionPass *createHexagonSplitDoubleRegs(); +FunctionPass *createHexagonStoreWidening(); +FunctionPass *createHexagonTfrCleanup(); +FunctionPass *createHexagonVectorCombineLegacyPass(); +FunctionPass *createHexagonVectorPrint(); +FunctionPass *createHexagonVExtract(); +} // namespace llvm static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) { return RM.value_or(Reloc::Static); @@ -260,6 +276,7 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, (HexagonNoOpt ? CodeGenOptLevel::None : OL)), TLOF(std::make_unique<HexagonTargetObjectFile>()), Subtarget(Triple(TT), CPU, FS, *this) { + initializeHexagonCopyHoistingPass(*PassRegistry::getPassRegistry()); initializeHexagonExpandCondsetsPass(*PassRegistry::getPassRegistry()); initializeHexagonLoopAlignPass(*PassRegistry::getPassRegistry()); initializeHexagonTfrCleanupPass(*PassRegistry::getPassRegistry()); @@ -269,10 +286,8 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, const Triple &TT, const HexagonSubtarget * HexagonTargetMachine::getSubtargetImpl(const Function &F) const { AttributeList FnAttrs = F.getAttributes(); - Attribute CPUAttr = - FnAttrs.getFnAttr("target-cpu"); - Attribute FSAttr = - FnAttrs.getFnAttr("target-features"); + Attribute CPUAttr = FnAttrs.getFnAttr("target-cpu"); + Attribute FSAttr = FnAttrs.getFnAttr("target-features"); std::string CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; @@ -331,7 +346,7 @@ namespace { class HexagonPassConfig : public TargetPassConfig { public: HexagonPassConfig(HexagonTargetMachine &TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) {} HexagonTargetMachine &getHexagonTargetMachine() const { return getTM<HexagonTargetMachine>(); @@ -433,6 +448,8 @@ void HexagonPassConfig::addPreRegAlloc() { addPass(createHexagonConstExtenders()); if (EnableExpandCondsets) insertPass(&RegisterCoalescerID, &HexagonExpandCondsetsID); + if (EnableCopyHoist) + insertPass(&RegisterCoalescerID, &HexagonCopyHoistingID); if (EnableTfrCleanup) insertPass(&VirtRegRewriterID, &HexagonTfrCleanupID); if (!DisableStoreWidening) diff --git a/llvm/test/CodeGen/Hexagon/hexagon-copy-hoisting.mir b/llvm/test/CodeGen/Hexagon/hexagon-copy-hoisting.mir new file mode 100644 index 000000000000..0836cac7f913 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/hexagon-copy-hoisting.mir @@ -0,0 +1,53 @@ +# RUN: llc -march=hexagon -run-pass hexagon-move-phicopy -o - %s | FileCheck %s + +# CHECK-COUNT-1: %4:intregs = COPY %1 + +# CHECK: bb.1 +# CHECK-NOT: %4:intregs = COPY %1 + +# CHECK: bb.2 +# CHECK-NOT: %4:intregs = COPY %1 +# CHECK: %5:intregs = COPY %0 + +--- +name: f0 +tracksRegLiveness: true +registers: + - { id: 0, class: intregs, preferred-register: '' } + - { id: 1, class: intregs, preferred-register: '' } + - { id: 2, class: predregs, preferred-register: '' } + - { id: 3, class: predregs, preferred-register: '' } + - { id: 4, class: intregs, preferred-register: '' } + - { id: 5, class: intregs, preferred-register: '' } +liveins: + - { reg: '$r0', virtual-reg: '%0' } + - { reg: '$r1', virtual-reg: '%1' } +stack: + - { id: 0, offset: 0, size: 4, alignment: 8 } +body: | + bb.0: + successors: %bb.1, %bb.2 + liveins: $r0, $r1 + + %1:intregs = COPY $r1 + %0:intregs = COPY $r0 + %2:predregs = C2_cmpgt %0, %1 + %3:predregs = C2_not %2 + J2_jumpt %3, %bb.2, implicit-def dead $pc + J2_jump %bb.1, implicit-def dead $pc + + bb.1: + successors: %bb.0 + + %4:intregs = COPY %1 + $r1 = COPY %4 + J2_jump %bb.0, implicit-def dead $pc + + bb.2: + successors: %bb.0 + + %4:intregs = COPY %1 + %5:intregs = COPY %0 + $r1 = COPY %4 + J2_jump %bb.0, implicit-def dead $pc +... |