003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/Hexagon
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
Hexagon
/
📁
..
📁
AsmParser
📄
BitTracker.cpp
(35.36 KB)
📄
BitTracker.h
(17.25 KB)
📁
Disassembler
📄
Hexagon.h
(1004 B)
📄
Hexagon.td
(17.33 KB)
📄
HexagonArch.h
(1.2 KB)
📄
HexagonAsmPrinter.cpp
(26.65 KB)
📄
HexagonAsmPrinter.h
(2.03 KB)
📄
HexagonBitSimplify.cpp
(107.45 KB)
📄
HexagonBitTracker.cpp
(39.88 KB)
📄
HexagonBitTracker.h
(2.5 KB)
📄
HexagonBlockRanges.cpp
(15.85 KB)
📄
HexagonBlockRanges.h
(6.97 KB)
📄
HexagonBranchRelaxation.cpp
(7.78 KB)
📄
HexagonCFGOptimizer.cpp
(8.4 KB)
📄
HexagonCallingConv.td
(4.46 KB)
📄
HexagonCommonGEP.cpp
(41.47 KB)
📄
HexagonConstExtenders.cpp
(70.64 KB)
📄
HexagonConstPropagation.cpp
(97.75 KB)
📄
HexagonCopyToCombine.cpp
(32.2 KB)
📄
HexagonDepArch.h
(2.04 KB)
📄
HexagonDepArch.td
(1.87 KB)
📄
HexagonDepDecoders.inc
(2.55 KB)
📄
HexagonDepIICHVX.td
(113.05 KB)
📄
HexagonDepIICScalar.td
(224.12 KB)
📄
HexagonDepITypes.h
(1.51 KB)
📄
HexagonDepITypes.td
(1.91 KB)
📄
HexagonDepInstrFormats.td
(91.89 KB)
📄
HexagonDepInstrInfo.td
(1021.44 KB)
📄
HexagonDepMapAsm2Intrin.td
(255.17 KB)
📄
HexagonDepMappings.td
(64.27 KB)
📄
HexagonDepMask.h
(51.94 KB)
📄
HexagonDepOperands.td
(12.12 KB)
📄
HexagonDepTimingClasses.h
(4.69 KB)
📄
HexagonEarlyIfConv.cpp
(37.36 KB)
📄
HexagonExpandCondsets.cpp
(48.55 KB)
📄
HexagonFixupHwLoops.cpp
(6.54 KB)
📄
HexagonFrameLowering.cpp
(97.16 KB)
📄
HexagonFrameLowering.h
(7.85 KB)
📄
HexagonGenExtract.cpp
(8.61 KB)
📄
HexagonGenInsert.cpp
(53.24 KB)
📄
HexagonGenMux.cpp
(12.71 KB)
📄
HexagonGenPredicate.cpp
(16.25 KB)
📄
HexagonHardwareLoops.cpp
(70.32 KB)
📄
HexagonHazardRecognizer.cpp
(5.85 KB)
📄
HexagonHazardRecognizer.h
(3.58 KB)
📄
HexagonIICHVX.td
(1.21 KB)
📄
HexagonIICScalar.td
(1.34 KB)
📄
HexagonISelDAGToDAG.cpp
(78.63 KB)
📄
HexagonISelDAGToDAG.h
(5.88 KB)
📄
HexagonISelDAGToDAGHVX.cpp
(68.26 KB)
📄
HexagonISelLowering.cpp
(134.65 KB)
📄
HexagonISelLowering.h
(22.5 KB)
📄
HexagonISelLoweringHVX.cpp
(70.57 KB)
📄
HexagonInstrFormats.td
(12.04 KB)
📄
HexagonInstrFormatsV60.td
(1.03 KB)
📄
HexagonInstrFormatsV65.td
(1.54 KB)
📄
HexagonInstrInfo.cpp
(161.08 KB)
📄
HexagonInstrInfo.h
(25.31 KB)
📄
HexagonIntrinsics.td
(19.21 KB)
📄
HexagonIntrinsicsV5.td
(16.8 KB)
📄
HexagonIntrinsicsV60.td
(28.9 KB)
📄
HexagonLoopIdiomRecognition.cpp
(79.16 KB)
📄
HexagonMCInstLower.cpp
(6.25 KB)
📄
HexagonMachineFunctionInfo.cpp
(507 B)
📄
HexagonMachineFunctionInfo.h
(3.32 KB)
📄
HexagonMachineScheduler.cpp
(34.25 KB)
📄
HexagonMachineScheduler.h
(8.66 KB)
📄
HexagonMapAsm2IntrinV62.gen.td
(8.71 KB)
📄
HexagonMapAsm2IntrinV65.gen.td
(12.43 KB)
📄
HexagonNewValueJump.cpp
(25.57 KB)
📄
HexagonOperands.td
(1.62 KB)
📄
HexagonOptAddrMode.cpp
(29.37 KB)
📄
HexagonOptimizeSZextends.cpp
(4.74 KB)
📄
HexagonPatterns.td
(142.35 KB)
📄
HexagonPatternsHVX.td
(22.06 KB)
📄
HexagonPatternsV65.td
(2.96 KB)
📄
HexagonPeephole.cpp
(10.18 KB)
📄
HexagonPseudo.td
(21.62 KB)
📄
HexagonRDFOpt.cpp
(9.94 KB)
📄
HexagonRegisterInfo.cpp
(12.03 KB)
📄
HexagonRegisterInfo.h
(2.88 KB)
📄
HexagonRegisterInfo.td
(20.42 KB)
📄
HexagonSchedule.td
(2.33 KB)
📄
HexagonScheduleV5.td
(1.73 KB)
📄
HexagonScheduleV55.td
(1.81 KB)
📄
HexagonScheduleV60.td
(4.31 KB)
📄
HexagonScheduleV62.td
(1.53 KB)
📄
HexagonScheduleV65.td
(1.57 KB)
📄
HexagonScheduleV66.td
(1.57 KB)
📄
HexagonScheduleV67.td
(1.57 KB)
📄
HexagonScheduleV67T.td
(2.51 KB)
📄
HexagonSelectionDAGInfo.cpp
(2.35 KB)
📄
HexagonSelectionDAGInfo.h
(1.24 KB)
📄
HexagonSplitConst32AndConst64.cpp
(4.15 KB)
📄
HexagonSplitDouble.cpp
(37.86 KB)
📄
HexagonStoreWidening.cpp
(20.47 KB)
📄
HexagonSubtarget.cpp
(20.97 KB)
📄
HexagonSubtarget.h
(10.59 KB)
📄
HexagonTargetMachine.cpp
(16 KB)
📄
HexagonTargetMachine.h
(1.77 KB)
📄
HexagonTargetObjectFile.cpp
(16.8 KB)
📄
HexagonTargetObjectFile.h
(2.17 KB)
📄
HexagonTargetStreamer.h
(1.2 KB)
📄
HexagonTargetTransformInfo.cpp
(13.11 KB)
📄
HexagonTargetTransformInfo.h
(6.27 KB)
📄
HexagonVExtract.cpp
(6.64 KB)
📄
HexagonVLIWPacketizer.cpp
(67.01 KB)
📄
HexagonVLIWPacketizer.h
(6.09 KB)
📄
HexagonVectorLoopCarriedReuse.cpp
(23.99 KB)
📄
HexagonVectorPrint.cpp
(7.06 KB)
📁
MCTargetDesc
📄
RDFCopy.cpp
(6.37 KB)
📄
RDFCopy.h
(1.69 KB)
📄
RDFDeadCode.cpp
(7.5 KB)
📄
RDFDeadCode.h
(2.33 KB)
📁
TargetInfo
Editing: HexagonCFGOptimizer.cpp
//===- HexagonCFGOptimizer.cpp - CFG optimizations ------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "Hexagon.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> #include <vector> using namespace llvm; #define DEBUG_TYPE "hexagon_cfg" namespace llvm { FunctionPass *createHexagonCFGOptimizer(); void initializeHexagonCFGOptimizerPass(PassRegistry&); } // end namespace llvm namespace { class HexagonCFGOptimizer : public MachineFunctionPass { private: void InvertAndChangeJumpTarget(MachineInstr &, MachineBasicBlock *); bool isOnFallThroughPath(MachineBasicBlock *MBB); public: static char ID; HexagonCFGOptimizer() : MachineFunctionPass(ID) { initializeHexagonCFGOptimizerPass(*PassRegistry::getPassRegistry()); } StringRef getPassName() const override { return "Hexagon CFG Optimizer"; } bool runOnMachineFunction(MachineFunction &Fn) override; MachineFunctionProperties getRequiredProperties() const override { return MachineFunctionProperties().set( MachineFunctionProperties::Property::NoVRegs); } }; } // end anonymous namespace char HexagonCFGOptimizer::ID = 0; static bool IsConditionalBranch(int Opc) { switch (Opc) { case Hexagon::J2_jumpt: case Hexagon::J2_jumptpt: case Hexagon::J2_jumpf: case Hexagon::J2_jumpfpt: case Hexagon::J2_jumptnew: case Hexagon::J2_jumpfnew: case Hexagon::J2_jumptnewpt: case Hexagon::J2_jumpfnewpt: return true; } return false; } static bool IsUnconditionalJump(int Opc) { return (Opc == Hexagon::J2_jump); } void HexagonCFGOptimizer::InvertAndChangeJumpTarget( MachineInstr &MI, MachineBasicBlock *NewTarget) { const TargetInstrInfo *TII = MI.getParent()->getParent()->getSubtarget().getInstrInfo(); int NewOpcode = 0; switch (MI.getOpcode()) { case Hexagon::J2_jumpt: NewOpcode = Hexagon::J2_jumpf; break; case Hexagon::J2_jumpf: NewOpcode = Hexagon::J2_jumpt; break; case Hexagon::J2_jumptnewpt: NewOpcode = Hexagon::J2_jumpfnewpt; break; case Hexagon::J2_jumpfnewpt: NewOpcode = Hexagon::J2_jumptnewpt; break; default: llvm_unreachable("Cannot handle this case"); } MI.setDesc(TII->get(NewOpcode)); MI.getOperand(1).setMBB(NewTarget); } bool HexagonCFGOptimizer::isOnFallThroughPath(MachineBasicBlock *MBB) { if (MBB->canFallThrough()) return true; for (MachineBasicBlock *PB : MBB->predecessors()) if (PB->isLayoutSuccessor(MBB) && PB->canFallThrough()) return true; return false; } bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) { if (skipFunction(Fn.getFunction())) return false; // Loop over all of the basic blocks. for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); MBBb != MBBe; ++MBBb) { MachineBasicBlock *MBB = &*MBBb; // Traverse the basic block. MachineBasicBlock::iterator MII = MBB->getFirstTerminator(); if (MII != MBB->end()) { MachineInstr &MI = *MII; int Opc = MI.getOpcode(); if (IsConditionalBranch(Opc)) { // (Case 1) Transform the code if the following condition occurs: // BB1: if (p0) jump BB3 // ...falls-through to BB2 ... // BB2: jump BB4 // ...next block in layout is BB3... // BB3: ... // // Transform this to: // BB1: if (!p0) jump BB4 // Remove BB2 // BB3: ... // // (Case 2) A variation occurs when BB3 contains a JMP to BB4: // BB1: if (p0) jump BB3 // ...falls-through to BB2 ... // BB2: jump BB4 // ...other basic blocks ... // BB4: // ...not a fall-thru // BB3: ... // jump BB4 // // Transform this to: // BB1: if (!p0) jump BB4 // Remove BB2 // BB3: ... // BB4: ... unsigned NumSuccs = MBB->succ_size(); MachineBasicBlock::succ_iterator SI = MBB->succ_begin(); MachineBasicBlock* FirstSucc = *SI; MachineBasicBlock* SecondSucc = *(++SI); MachineBasicBlock* LayoutSucc = nullptr; MachineBasicBlock* JumpAroundTarget = nullptr; if (MBB->isLayoutSuccessor(FirstSucc)) { LayoutSucc = FirstSucc; JumpAroundTarget = SecondSucc; } else if (MBB->isLayoutSuccessor(SecondSucc)) { LayoutSucc = SecondSucc; JumpAroundTarget = FirstSucc; } else { // Odd case...cannot handle. } // The target of the unconditional branch must be JumpAroundTarget. // TODO: If not, we should not invert the unconditional branch. MachineBasicBlock* CondBranchTarget = nullptr; if (MI.getOpcode() == Hexagon::J2_jumpt || MI.getOpcode() == Hexagon::J2_jumpf) { CondBranchTarget = MI.getOperand(1).getMBB(); } if (!LayoutSucc || (CondBranchTarget != JumpAroundTarget)) { continue; } if ((NumSuccs == 2) && LayoutSucc && (LayoutSucc->pred_size() == 1)) { // Ensure that BB2 has one instruction -- an unconditional jump. if ((LayoutSucc->size() == 1) && IsUnconditionalJump(LayoutSucc->front().getOpcode())) { assert(JumpAroundTarget && "jump target is needed to process second basic block"); MachineBasicBlock* UncondTarget = LayoutSucc->front().getOperand(0).getMBB(); // Check if the layout successor of BB2 is BB3. bool case1 = LayoutSucc->isLayoutSuccessor(JumpAroundTarget); bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) && !JumpAroundTarget->empty() && IsUnconditionalJump(JumpAroundTarget->back().getOpcode()) && JumpAroundTarget->pred_size() == 1 && JumpAroundTarget->succ_size() == 1; if (case1 || case2) { InvertAndChangeJumpTarget(MI, UncondTarget); MBB->replaceSuccessor(JumpAroundTarget, UncondTarget); // Remove the unconditional branch in LayoutSucc. LayoutSucc->erase(LayoutSucc->begin()); LayoutSucc->replaceSuccessor(UncondTarget, JumpAroundTarget); // This code performs the conversion for case 2, which moves // the block to the fall-thru case (BB3 in the code above). if (case2 && !case1) { JumpAroundTarget->moveAfter(LayoutSucc); // only move a block if it doesn't have a fall-thru. otherwise // the CFG will be incorrect. if (!isOnFallThroughPath(UncondTarget)) UncondTarget->moveAfter(JumpAroundTarget); } // Correct live-in information. Is used by post-RA scheduler // The live-in to LayoutSucc is now all values live-in to // JumpAroundTarget. std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn( LayoutSucc->livein_begin(), LayoutSucc->livein_end()); std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn( JumpAroundTarget->livein_begin(), JumpAroundTarget->livein_end()); for (const auto &OrigLI : OrigLiveIn) LayoutSucc->removeLiveIn(OrigLI.PhysReg); for (const auto &NewLI : NewLiveIn) LayoutSucc->addLiveIn(NewLI); } } } } } } return true; } //===----------------------------------------------------------------------===// // Public Constructor Functions //===----------------------------------------------------------------------===// INITIALIZE_PASS(HexagonCFGOptimizer, "hexagon-cfg", "Hexagon CFG Optimizer", false, false) FunctionPass *llvm::createHexagonCFGOptimizer() { return new HexagonCFGOptimizer(); }
Upload File
Create Folder