25#define DEBUG_TYPE "hexagon_cfg"
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(
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);
100 if (
PB->isLayoutSuccessor(
MBB) &&
PB->canFallThrough())
115 int Opc =
MI.getOpcode();
152 LayoutSucc = FirstSucc;
153 JumpAroundTarget = SecondSucc;
155 LayoutSucc = SecondSucc;
156 JumpAroundTarget = FirstSucc;
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");
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()
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
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
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createHexagonCFGOptimizer()