LLVM: lib/Target/Hexagon/HexagonCFGOptimizer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
20#include
21#include
22
23using namespace llvm;
24
25#define DEBUG_TYPE "hexagon_cfg"
26
27namespace {
28
30private:
33
34public:
35 static char ID;
36
38
39 StringRef getPassName() const override { return "Hexagon CFG Optimizer"; }
41
44 }
45};
46
47}
48
49char HexagonCFGOptimizer::ID = 0;
50
52 switch (Opc) {
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:
61 return true;
62 }
63 return false;
64}
65
67 return (Opc == Hexagon::J2_jump);
68}
69
70void HexagonCFGOptimizer::InvertAndChangeJumpTarget(
72 const TargetInstrInfo *TII =
73 MI.getParent()->getParent()->getSubtarget().getInstrInfo();
74 int NewOpcode = 0;
75 switch (MI.getOpcode()) {
76 case Hexagon::J2_jumpt:
77 NewOpcode = Hexagon::J2_jumpf;
78 break;
79 case Hexagon::J2_jumpf:
80 NewOpcode = Hexagon::J2_jumpt;
81 break;
82 case Hexagon::J2_jumptnewpt:
83 NewOpcode = Hexagon::J2_jumpfnewpt;
84 break;
85 case Hexagon::J2_jumpfnewpt:
86 NewOpcode = Hexagon::J2_jumptnewpt;
87 break;
88 default:
90 }
91
92 MI.setDesc(TII->get(NewOpcode));
93 MI.getOperand(1).setMBB(NewTarget);
94}
95
96bool HexagonCFGOptimizer::isOnFallThroughPath(MachineBasicBlock *MBB) {
98 return true;
100 if (PB->isLayoutSuccessor(MBB) && PB->canFallThrough())
101 return true;
102 return false;
103}
104
105bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
107 return false;
108
109
110 for (MachineBasicBlock &MBB : Fn) {
111
114 MachineInstr &MI = *MII;
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
146 MachineBasicBlock* FirstSucc = *SI;
147 MachineBasicBlock* SecondSucc = *(++SI);
148 MachineBasicBlock* LayoutSucc = nullptr;
149 MachineBasicBlock* JumpAroundTarget = nullptr;
150
152 LayoutSucc = FirstSucc;
153 JumpAroundTarget = SecondSucc;
155 LayoutSucc = SecondSucc;
156 JumpAroundTarget = FirstSucc;
157 } else {
158
159 }
160
161
162
163 MachineBasicBlock* CondBranchTarget = nullptr;
164 if (MI.getOpcode() == Hexagon::J2_jumpt ||
165 MI.getOpcode() == Hexagon::J2_jumpf) {
166 CondBranchTarget = MI.getOperand(1).getMBB();
167 }
168
169 if (!LayoutSucc || (CondBranchTarget != JumpAroundTarget)) {
170 continue;
171 }
172
173 if ((NumSuccs == 2) && LayoutSucc && (LayoutSucc->pred_size() == 1)) {
174
175 if ((LayoutSucc->size() == 1) &&
177 assert(JumpAroundTarget && "jump target is needed to process second basic block");
178 MachineBasicBlock* UncondTarget =
180
182 bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) &&
183 !JumpAroundTarget->empty() &&
185 JumpAroundTarget->pred_size() == 1 &&
186 JumpAroundTarget->succ_size() == 1;
187
188 if (case1 || case2) {
189 InvertAndChangeJumpTarget(MI, UncondTarget);
191
192
193 LayoutSucc->erase(LayoutSucc->begin());
194 LayoutSucc->replaceSuccessor(UncondTarget, JumpAroundTarget);
195
196
197
198 if (case2 && !case1) {
199 JumpAroundTarget->moveAfter(LayoutSucc);
200
201
202 if (!isOnFallThroughPath(UncondTarget))
203 UncondTarget->moveAfter(JumpAroundTarget);
204 }
205
206
207
208
209 std::vectorMachineBasicBlock::RegisterMaskPair OrigLiveIn(
211 std::vectorMachineBasicBlock::RegisterMaskPair NewLiveIn(
214 for (const auto &OrigLI : OrigLiveIn)
216 for (const auto &NewLI : NewLiveIn)
218 }
219 }
220 }
221 }
222 }
223 }
224 return true;
225}
226
227
228
229
230
231INITIALIZE_PASS(HexagonCFGOptimizer, "hexagon-cfg", "Hexagon CFG Optimizer",
232 false, false)
233
235 return new HexagonCFGOptimizer();
236}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static bool IsConditionalBranch(int Opc)
Definition HexagonCFGOptimizer.cpp:51
static bool IsUnconditionalJump(int Opc)
Definition HexagonCFGOptimizer.cpp:66
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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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
StringRef - Represent a constant reference to a string, i.e.
#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()