25#define DEBUG_TYPE "hexagon_cfg"
39 StringRef getPassName()
const override {
return "Hexagon CFG Optimizer"; }
49char HexagonCFGOptimizer::ID = 0;
53 case Hexagon::J2_jumpt:
54 case Hexagon::J2_jumptpt:
55 case Hexagon::J2_jumpf:
56 case Hexagon::J2_jumpfpt:
57 case Hexagon::J2_jumptnew:
58 case Hexagon::J2_jumpfnew:
59 case Hexagon::J2_jumptnewpt:
60 case Hexagon::J2_jumpfnewpt:
67 return (
Opc == Hexagon::J2_jump);
70void HexagonCFGOptimizer::InvertAndChangeJumpTarget(
72 const TargetInstrInfo *
TII =
73 MI.getParent()->getParent()->getSubtarget().getInstrInfo();
75 switch (
MI.getOpcode()) {
76 case Hexagon::J2_jumpt:
77 NewOpcode = Hexagon::J2_jumpf;
79 case Hexagon::J2_jumpf:
80 NewOpcode = Hexagon::J2_jumpt;
82 case Hexagon::J2_jumptnewpt:
83 NewOpcode = Hexagon::J2_jumpfnewpt;
85 case Hexagon::J2_jumpfnewpt:
86 NewOpcode = Hexagon::J2_jumptnewpt;
92 MI.setDesc(
TII->get(NewOpcode));
93 MI.getOperand(1).setMBB(NewTarget);
96bool HexagonCFGOptimizer::isOnFallThroughPath(MachineBasicBlock *
MBB) {
100 if (
PB->isLayoutSuccessor(
MBB) &&
PB->canFallThrough())
105bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
110 for (MachineBasicBlock &
MBB : Fn) {
114 MachineInstr &
MI = *MII;
115 int Opc =
MI.getOpcode();
146 MachineBasicBlock* FirstSucc = *
SI;
147 MachineBasicBlock* SecondSucc = *(++
SI);
148 MachineBasicBlock* LayoutSucc =
nullptr;
149 MachineBasicBlock* JumpAroundTarget =
nullptr;
152 LayoutSucc = FirstSucc;
153 JumpAroundTarget = SecondSucc;
155 LayoutSucc = SecondSucc;
156 JumpAroundTarget = FirstSucc;
163 MachineBasicBlock* CondBranchTarget =
nullptr;
164 if (
MI.getOpcode() == Hexagon::J2_jumpt ||
165 MI.getOpcode() == Hexagon::J2_jumpf) {
166 CondBranchTarget =
MI.getOperand(1).getMBB();
169 if (!LayoutSucc || (CondBranchTarget != JumpAroundTarget)) {
173 if ((NumSuccs == 2) && LayoutSucc && (LayoutSucc->
pred_size() == 1)) {
175 if ((LayoutSucc->
size() == 1) &&
177 assert(JumpAroundTarget &&
"jump target is needed to process second basic block");
178 MachineBasicBlock* UncondTarget =
182 bool case2 = JumpAroundTarget->
isSuccessor(UncondTarget) &&
183 !JumpAroundTarget->
empty() &&
188 if (case1 || case2) {
189 InvertAndChangeJumpTarget(
MI, UncondTarget);
198 if (case2 && !case1) {
202 if (!isOnFallThroughPath(UncondTarget))
203 UncondTarget->
moveAfter(JumpAroundTarget);
209 std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn(
211 std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn(
214 for (
const auto &OrigLI : OrigLiveIn)
216 for (
const auto &NewLI : NewLiveIn)
235 return new HexagonCFGOptimizer();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool IsConditionalBranch(int Opc)
static bool IsUnconditionalJump(int Opc)
const HexagonInstrInfo * TII
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
FunctionPass class - This class is used to implement most global optimizations.
unsigned pred_size() const
livein_iterator livein_end() const
LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
LLVM_ABI bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
succ_iterator succ_begin()
LLVM_ABI void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI livein_iterator livein_begin() const
unsigned succ_size() const
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineBasicBlock * getMBB() const
Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createHexagonCFGOptimizer()