LLVM  4.0.0
HexagonCFGOptimizer.cpp
Go to the documentation of this file.
1 //===-- HexagonCFGOptimizer.cpp - CFG optimizations -----------------------===//
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Hexagon.h"
11 #include "HexagonSubtarget.h"
12 #include "HexagonTargetMachine.h"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/Support/Debug.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "hexagon_cfg"
28 
29 namespace llvm {
32 }
33 
34 
35 namespace {
36 
37 class HexagonCFGOptimizer : public MachineFunctionPass {
38 
39 private:
40  void InvertAndChangeJumpTarget(MachineInstr &, MachineBasicBlock *);
41 
42 public:
43  static char ID;
44  HexagonCFGOptimizer() : MachineFunctionPass(ID) {
46  }
47 
48  StringRef getPassName() const override { return "Hexagon CFG Optimizer"; }
49  bool runOnMachineFunction(MachineFunction &Fn) override;
50  MachineFunctionProperties getRequiredProperties() const override {
53  }
54 };
55 
56 
58 
59 static bool IsConditionalBranch(int Opc) {
60  switch (Opc) {
61  case Hexagon::J2_jumpt:
62  case Hexagon::J2_jumptpt:
63  case Hexagon::J2_jumpf:
64  case Hexagon::J2_jumpfpt:
65  case Hexagon::J2_jumptnew:
66  case Hexagon::J2_jumpfnew:
67  case Hexagon::J2_jumptnewpt:
68  case Hexagon::J2_jumpfnewpt:
69  return true;
70  }
71  return false;
72 }
73 
74 
75 static bool IsUnconditionalJump(int Opc) {
76  return (Opc == Hexagon::J2_jump);
77 }
78 
79 void HexagonCFGOptimizer::InvertAndChangeJumpTarget(
80  MachineInstr &MI, MachineBasicBlock *NewTarget) {
81  const TargetInstrInfo *TII =
83  int NewOpcode = 0;
84  switch (MI.getOpcode()) {
85  case Hexagon::J2_jumpt:
86  NewOpcode = Hexagon::J2_jumpf;
87  break;
88 
89  case Hexagon::J2_jumpf:
90  NewOpcode = Hexagon::J2_jumpt;
91  break;
92 
93  case Hexagon::J2_jumptnewpt:
94  NewOpcode = Hexagon::J2_jumpfnewpt;
95  break;
96 
97  case Hexagon::J2_jumpfnewpt:
98  NewOpcode = Hexagon::J2_jumptnewpt;
99  break;
100 
101  default:
102  llvm_unreachable("Cannot handle this case");
103  }
104 
105  MI.setDesc(TII->get(NewOpcode));
106  MI.getOperand(1).setMBB(NewTarget);
107 }
108 
109 
110 bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
111  if (skipFunction(*Fn.getFunction()))
112  return false;
113 
114  // Loop over all of the basic blocks.
115  for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
116  MBBb != MBBe; ++MBBb) {
117  MachineBasicBlock *MBB = &*MBBb;
118 
119  // Traverse the basic block.
121  if (MII != MBB->end()) {
122  MachineInstr &MI = *MII;
123  int Opc = MI.getOpcode();
124  if (IsConditionalBranch(Opc)) {
125 
126  //
127  // (Case 1) Transform the code if the following condition occurs:
128  // BB1: if (p0) jump BB3
129  // ...falls-through to BB2 ...
130  // BB2: jump BB4
131  // ...next block in layout is BB3...
132  // BB3: ...
133  //
134  // Transform this to:
135  // BB1: if (!p0) jump BB4
136  // Remove BB2
137  // BB3: ...
138  //
139  // (Case 2) A variation occurs when BB3 contains a JMP to BB4:
140  // BB1: if (p0) jump BB3
141  // ...falls-through to BB2 ...
142  // BB2: jump BB4
143  // ...other basic blocks ...
144  // BB4:
145  // ...not a fall-thru
146  // BB3: ...
147  // jump BB4
148  //
149  // Transform this to:
150  // BB1: if (!p0) jump BB4
151  // Remove BB2
152  // BB3: ...
153  // BB4: ...
154  //
155  unsigned NumSuccs = MBB->succ_size();
157  MachineBasicBlock* FirstSucc = *SI;
158  MachineBasicBlock* SecondSucc = *(++SI);
159  MachineBasicBlock* LayoutSucc = nullptr;
160  MachineBasicBlock* JumpAroundTarget = nullptr;
161 
162  if (MBB->isLayoutSuccessor(FirstSucc)) {
163  LayoutSucc = FirstSucc;
164  JumpAroundTarget = SecondSucc;
165  } else if (MBB->isLayoutSuccessor(SecondSucc)) {
166  LayoutSucc = SecondSucc;
167  JumpAroundTarget = FirstSucc;
168  } else {
169  // Odd case...cannot handle.
170  }
171 
172  // The target of the unconditional branch must be JumpAroundTarget.
173  // TODO: If not, we should not invert the unconditional branch.
174  MachineBasicBlock* CondBranchTarget = nullptr;
175  if (MI.getOpcode() == Hexagon::J2_jumpt ||
176  MI.getOpcode() == Hexagon::J2_jumpf) {
177  CondBranchTarget = MI.getOperand(1).getMBB();
178  }
179 
180  if (!LayoutSucc || (CondBranchTarget != JumpAroundTarget)) {
181  continue;
182  }
183 
184  if ((NumSuccs == 2) && LayoutSucc && (LayoutSucc->pred_size() == 1)) {
185 
186  // Ensure that BB2 has one instruction -- an unconditional jump.
187  if ((LayoutSucc->size() == 1) &&
188  IsUnconditionalJump(LayoutSucc->front().getOpcode())) {
189  assert(JumpAroundTarget && "jump target is needed to process second basic block");
190  MachineBasicBlock* UncondTarget =
191  LayoutSucc->front().getOperand(0).getMBB();
192  // Check if the layout successor of BB2 is BB3.
193  bool case1 = LayoutSucc->isLayoutSuccessor(JumpAroundTarget);
194  bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) &&
195  JumpAroundTarget->size() >= 1 &&
196  IsUnconditionalJump(JumpAroundTarget->back().getOpcode()) &&
197  JumpAroundTarget->pred_size() == 1 &&
198  JumpAroundTarget->succ_size() == 1;
199 
200  if (case1 || case2) {
201  InvertAndChangeJumpTarget(MI, UncondTarget);
202  MBB->replaceSuccessor(JumpAroundTarget, UncondTarget);
203 
204  // Remove the unconditional branch in LayoutSucc.
205  LayoutSucc->erase(LayoutSucc->begin());
206  LayoutSucc->replaceSuccessor(UncondTarget, JumpAroundTarget);
207 
208  // This code performs the conversion for case 2, which moves
209  // the block to the fall-thru case (BB3 in the code above).
210  if (case2 && !case1) {
211  JumpAroundTarget->moveAfter(LayoutSucc);
212  // only move a block if it doesn't have a fall-thru. otherwise
213  // the CFG will be incorrect.
214  if (!UncondTarget->canFallThrough()) {
215  UncondTarget->moveAfter(JumpAroundTarget);
216  }
217  }
218 
219  //
220  // Correct live-in information. Is used by post-RA scheduler
221  // The live-in to LayoutSucc is now all values live-in to
222  // JumpAroundTarget.
223  //
224  std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn(
225  LayoutSucc->livein_begin(), LayoutSucc->livein_end());
226  std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn(
227  JumpAroundTarget->livein_begin(),
228  JumpAroundTarget->livein_end());
229  for (const auto &OrigLI : OrigLiveIn)
230  LayoutSucc->removeLiveIn(OrigLI.PhysReg);
231  for (const auto &NewLI : NewLiveIn)
232  LayoutSucc->addLiveIn(NewLI);
233  }
234  }
235  }
236  }
237  }
238  }
239  return true;
240 }
241 }
242 
243 
244 //===----------------------------------------------------------------------===//
245 // Public Constructor Functions
246 //===----------------------------------------------------------------------===//
247 
248 INITIALIZE_PASS(HexagonCFGOptimizer, "hexagon-cfg", "Hexagon CFG Optimizer",
249  false, false)
250 
252  return new HexagonCFGOptimizer();
253 }
unsigned succ_size() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MachineBasicBlock * getMBB() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void moveAfter(MachineBasicBlock *NewBefore)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
std::vector< MachineBasicBlock * >::iterator succ_iterator
MachineBasicBlock * MBB
bool canFallThrough()
Return true if the block can implicitly transfer control to the block after it by falling off the end...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:273
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:131
TargetInstrInfo - Interface to description of machine instruction set.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
livein_iterator livein_begin() const
livein_iterator livein_end() const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
void setMBB(MachineBasicBlock *MBB)
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
Definition: MachineInstr.h:52
INITIALIZE_PASS(HexagonCFGOptimizer,"hexagon-cfg","Hexagon CFG Optimizer", false, false) FunctionPass *llvm
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
void initializeHexagonCFGOptimizerPass(PassRegistry &)
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
unsigned pred_size() const
Properties which a MachineFunction may have at a given point in time.
FunctionPass * createHexagonCFGOptimizer()