1*9880d681SAndroid Build Coastguard Worker //===-- HexagonHardwareLoops.cpp - Identify and generate hardware loops ---===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This pass identifies loops where we can generate the Hexagon hardware
11*9880d681SAndroid Build Coastguard Worker // loop instruction. The hardware loop can perform loop branches with a
12*9880d681SAndroid Build Coastguard Worker // zero-cycle overhead.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // The pattern that defines the induction variable can changed depending on
15*9880d681SAndroid Build Coastguard Worker // prior optimizations. For example, the IndVarSimplify phase run by 'opt'
16*9880d681SAndroid Build Coastguard Worker // normalizes induction variables, and the Loop Strength Reduction pass
17*9880d681SAndroid Build Coastguard Worker // run by 'llc' may also make changes to the induction variable.
18*9880d681SAndroid Build Coastguard Worker // The pattern detected by this phase is due to running Strength Reduction.
19*9880d681SAndroid Build Coastguard Worker //
20*9880d681SAndroid Build Coastguard Worker // Criteria for hardware loops:
21*9880d681SAndroid Build Coastguard Worker // - Countable loops (w/ ind. var for a trip count)
22*9880d681SAndroid Build Coastguard Worker // - Assumes loops are normalized by IndVarSimplify
23*9880d681SAndroid Build Coastguard Worker // - Try inner-most loops first
24*9880d681SAndroid Build Coastguard Worker // - No function calls in loops.
25*9880d681SAndroid Build Coastguard Worker //
26*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallSet.h"
29*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
30*9880d681SAndroid Build Coastguard Worker #include "HexagonSubtarget.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/PassSupport.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
43*9880d681SAndroid Build Coastguard Worker #include <algorithm>
44*9880d681SAndroid Build Coastguard Worker #include <vector>
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker using namespace llvm;
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hwloops"
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
51*9880d681SAndroid Build Coastguard Worker static cl::opt<int> HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1));
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker // Option to create preheader only for a specific function.
54*9880d681SAndroid Build Coastguard Worker static cl::opt<std::string> PHFn("hexagon-hwloop-phfn", cl::Hidden,
55*9880d681SAndroid Build Coastguard Worker cl::init(""));
56*9880d681SAndroid Build Coastguard Worker #endif
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker // Option to create a preheader if one doesn't exist.
59*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> HWCreatePreheader("hexagon-hwloop-preheader",
60*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::init(true),
61*9880d681SAndroid Build Coastguard Worker cl::desc("Add a preheader to a hardware loop if one doesn't exist"));
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker STATISTIC(NumHWLoops, "Number of loops converted to hardware loops");
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker namespace llvm {
66*9880d681SAndroid Build Coastguard Worker FunctionPass *createHexagonHardwareLoops();
67*9880d681SAndroid Build Coastguard Worker void initializeHexagonHardwareLoopsPass(PassRegistry&);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker namespace {
71*9880d681SAndroid Build Coastguard Worker class CountValue;
72*9880d681SAndroid Build Coastguard Worker struct HexagonHardwareLoops : public MachineFunctionPass {
73*9880d681SAndroid Build Coastguard Worker MachineLoopInfo *MLI;
74*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo *MRI;
75*9880d681SAndroid Build Coastguard Worker MachineDominatorTree *MDT;
76*9880d681SAndroid Build Coastguard Worker const HexagonInstrInfo *TII;
77*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
78*9880d681SAndroid Build Coastguard Worker static int Counter;
79*9880d681SAndroid Build Coastguard Worker #endif
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker public:
82*9880d681SAndroid Build Coastguard Worker static char ID;
83*9880d681SAndroid Build Coastguard Worker
HexagonHardwareLoops__anon375e1b3c0111::HexagonHardwareLoops84*9880d681SAndroid Build Coastguard Worker HexagonHardwareLoops() : MachineFunctionPass(ID) {
85*9880d681SAndroid Build Coastguard Worker initializeHexagonHardwareLoopsPass(*PassRegistry::getPassRegistry());
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
89*9880d681SAndroid Build Coastguard Worker
getPassName__anon375e1b3c0111::HexagonHardwareLoops90*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override { return "Hexagon Hardware Loops"; }
91*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage__anon375e1b3c0111::HexagonHardwareLoops92*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
93*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineDominatorTree>();
94*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineLoopInfo>();
95*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker private:
99*9880d681SAndroid Build Coastguard Worker typedef std::map<unsigned, MachineInstr *> LoopFeederMap;
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker /// Kinds of comparisons in the compare instructions.
102*9880d681SAndroid Build Coastguard Worker struct Comparison {
103*9880d681SAndroid Build Coastguard Worker enum Kind {
104*9880d681SAndroid Build Coastguard Worker EQ = 0x01,
105*9880d681SAndroid Build Coastguard Worker NE = 0x02,
106*9880d681SAndroid Build Coastguard Worker L = 0x04,
107*9880d681SAndroid Build Coastguard Worker G = 0x08,
108*9880d681SAndroid Build Coastguard Worker U = 0x40,
109*9880d681SAndroid Build Coastguard Worker LTs = L,
110*9880d681SAndroid Build Coastguard Worker LEs = L | EQ,
111*9880d681SAndroid Build Coastguard Worker GTs = G,
112*9880d681SAndroid Build Coastguard Worker GEs = G | EQ,
113*9880d681SAndroid Build Coastguard Worker LTu = L | U,
114*9880d681SAndroid Build Coastguard Worker LEu = L | EQ | U,
115*9880d681SAndroid Build Coastguard Worker GTu = G | U,
116*9880d681SAndroid Build Coastguard Worker GEu = G | EQ | U
117*9880d681SAndroid Build Coastguard Worker };
118*9880d681SAndroid Build Coastguard Worker
getSwappedComparison__anon375e1b3c0111::HexagonHardwareLoops::Comparison119*9880d681SAndroid Build Coastguard Worker static Kind getSwappedComparison(Kind Cmp) {
120*9880d681SAndroid Build Coastguard Worker assert ((!((Cmp & L) && (Cmp & G))) && "Malformed comparison operator");
121*9880d681SAndroid Build Coastguard Worker if ((Cmp & L) || (Cmp & G))
122*9880d681SAndroid Build Coastguard Worker return (Kind)(Cmp ^ (L|G));
123*9880d681SAndroid Build Coastguard Worker return Cmp;
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker
getNegatedComparison__anon375e1b3c0111::HexagonHardwareLoops::Comparison126*9880d681SAndroid Build Coastguard Worker static Kind getNegatedComparison(Kind Cmp) {
127*9880d681SAndroid Build Coastguard Worker if ((Cmp & L) || (Cmp & G))
128*9880d681SAndroid Build Coastguard Worker return (Kind)((Cmp ^ (L | G)) ^ EQ);
129*9880d681SAndroid Build Coastguard Worker if ((Cmp & NE) || (Cmp & EQ))
130*9880d681SAndroid Build Coastguard Worker return (Kind)(Cmp ^ (EQ | NE));
131*9880d681SAndroid Build Coastguard Worker return (Kind)0;
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker
isSigned__anon375e1b3c0111::HexagonHardwareLoops::Comparison134*9880d681SAndroid Build Coastguard Worker static bool isSigned(Kind Cmp) {
135*9880d681SAndroid Build Coastguard Worker return (Cmp & (L | G) && !(Cmp & U));
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
isUnsigned__anon375e1b3c0111::HexagonHardwareLoops::Comparison138*9880d681SAndroid Build Coastguard Worker static bool isUnsigned(Kind Cmp) {
139*9880d681SAndroid Build Coastguard Worker return (Cmp & U);
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker };
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker /// \brief Find the register that contains the loop controlling
145*9880d681SAndroid Build Coastguard Worker /// induction variable.
146*9880d681SAndroid Build Coastguard Worker /// If successful, it will return true and set the \p Reg, \p IVBump
147*9880d681SAndroid Build Coastguard Worker /// and \p IVOp arguments. Otherwise it will return false.
148*9880d681SAndroid Build Coastguard Worker /// The returned induction register is the register R that follows the
149*9880d681SAndroid Build Coastguard Worker /// following induction pattern:
150*9880d681SAndroid Build Coastguard Worker /// loop:
151*9880d681SAndroid Build Coastguard Worker /// R = phi ..., [ R.next, LatchBlock ]
152*9880d681SAndroid Build Coastguard Worker /// R.next = R + #bump
153*9880d681SAndroid Build Coastguard Worker /// if (R.next < #N) goto loop
154*9880d681SAndroid Build Coastguard Worker /// IVBump is the immediate value added to R, and IVOp is the instruction
155*9880d681SAndroid Build Coastguard Worker /// "R.next = R + #bump".
156*9880d681SAndroid Build Coastguard Worker bool findInductionRegister(MachineLoop *L, unsigned &Reg,
157*9880d681SAndroid Build Coastguard Worker int64_t &IVBump, MachineInstr *&IVOp) const;
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker /// \brief Return the comparison kind for the specified opcode.
160*9880d681SAndroid Build Coastguard Worker Comparison::Kind getComparisonKind(unsigned CondOpc,
161*9880d681SAndroid Build Coastguard Worker MachineOperand *InitialValue,
162*9880d681SAndroid Build Coastguard Worker const MachineOperand *Endvalue,
163*9880d681SAndroid Build Coastguard Worker int64_t IVBump) const;
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker /// \brief Analyze the statements in a loop to determine if the loop
166*9880d681SAndroid Build Coastguard Worker /// has a computable trip count and, if so, return a value that represents
167*9880d681SAndroid Build Coastguard Worker /// the trip count expression.
168*9880d681SAndroid Build Coastguard Worker CountValue *getLoopTripCount(MachineLoop *L,
169*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &OldInsts);
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker /// \brief Return the expression that represents the number of times
172*9880d681SAndroid Build Coastguard Worker /// a loop iterates. The function takes the operands that represent the
173*9880d681SAndroid Build Coastguard Worker /// loop start value, loop end value, and induction value. Based upon
174*9880d681SAndroid Build Coastguard Worker /// these operands, the function attempts to compute the trip count.
175*9880d681SAndroid Build Coastguard Worker /// If the trip count is not directly available (as an immediate value,
176*9880d681SAndroid Build Coastguard Worker /// or a register), the function will attempt to insert computation of it
177*9880d681SAndroid Build Coastguard Worker /// to the loop's preheader.
178*9880d681SAndroid Build Coastguard Worker CountValue *computeCount(MachineLoop *Loop, const MachineOperand *Start,
179*9880d681SAndroid Build Coastguard Worker const MachineOperand *End, unsigned IVReg,
180*9880d681SAndroid Build Coastguard Worker int64_t IVBump, Comparison::Kind Cmp) const;
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the instruction is not valid within a hardware
183*9880d681SAndroid Build Coastguard Worker /// loop.
184*9880d681SAndroid Build Coastguard Worker bool isInvalidLoopOperation(const MachineInstr *MI,
185*9880d681SAndroid Build Coastguard Worker bool IsInnerHWLoop) const;
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the loop contains an instruction that inhibits
188*9880d681SAndroid Build Coastguard Worker /// using the hardware loop.
189*9880d681SAndroid Build Coastguard Worker bool containsInvalidInstruction(MachineLoop *L, bool IsInnerHWLoop) const;
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker /// \brief Given a loop, check if we can convert it to a hardware loop.
192*9880d681SAndroid Build Coastguard Worker /// If so, then perform the conversion and return true.
193*9880d681SAndroid Build Coastguard Worker bool convertToHardwareLoop(MachineLoop *L, bool &L0used, bool &L1used);
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the instruction is now dead.
196*9880d681SAndroid Build Coastguard Worker bool isDead(const MachineInstr *MI,
197*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &DeadPhis) const;
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker /// \brief Remove the instruction if it is now dead.
200*9880d681SAndroid Build Coastguard Worker void removeIfDead(MachineInstr *MI);
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker /// \brief Make sure that the "bump" instruction executes before the
203*9880d681SAndroid Build Coastguard Worker /// compare. We need that for the IV fixup, so that the compare
204*9880d681SAndroid Build Coastguard Worker /// instruction would not use a bumped value that has not yet been
205*9880d681SAndroid Build Coastguard Worker /// defined. If the instructions are out of order, try to reorder them.
206*9880d681SAndroid Build Coastguard Worker bool orderBumpCompare(MachineInstr *BumpI, MachineInstr *CmpI);
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker /// \brief Return true if MO and MI pair is visited only once. If visited
209*9880d681SAndroid Build Coastguard Worker /// more than once, this indicates there is recursion. In such a case,
210*9880d681SAndroid Build Coastguard Worker /// return false.
211*9880d681SAndroid Build Coastguard Worker bool isLoopFeeder(MachineLoop *L, MachineBasicBlock *A, MachineInstr *MI,
212*9880d681SAndroid Build Coastguard Worker const MachineOperand *MO,
213*9880d681SAndroid Build Coastguard Worker LoopFeederMap &LoopFeederPhi) const;
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the Phi may generate a value that may underflow,
216*9880d681SAndroid Build Coastguard Worker /// or may wrap.
217*9880d681SAndroid Build Coastguard Worker bool phiMayWrapOrUnderflow(MachineInstr *Phi, const MachineOperand *EndVal,
218*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB, MachineLoop *L,
219*9880d681SAndroid Build Coastguard Worker LoopFeederMap &LoopFeederPhi) const;
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the induction variable may underflow an unsigned
222*9880d681SAndroid Build Coastguard Worker /// value in the first iteration.
223*9880d681SAndroid Build Coastguard Worker bool loopCountMayWrapOrUnderFlow(const MachineOperand *InitVal,
224*9880d681SAndroid Build Coastguard Worker const MachineOperand *EndVal,
225*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB, MachineLoop *L,
226*9880d681SAndroid Build Coastguard Worker LoopFeederMap &LoopFeederPhi) const;
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker /// \brief Check if the given operand has a compile-time known constant
229*9880d681SAndroid Build Coastguard Worker /// value. Return true if yes, and false otherwise. When returning true, set
230*9880d681SAndroid Build Coastguard Worker /// Val to the corresponding constant value.
231*9880d681SAndroid Build Coastguard Worker bool checkForImmediate(const MachineOperand &MO, int64_t &Val) const;
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker /// \brief Check if the operand has a compile-time known constant value.
isImmediate__anon375e1b3c0111::HexagonHardwareLoops234*9880d681SAndroid Build Coastguard Worker bool isImmediate(const MachineOperand &MO) const {
235*9880d681SAndroid Build Coastguard Worker int64_t V;
236*9880d681SAndroid Build Coastguard Worker return checkForImmediate(MO, V);
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Worker /// \brief Return the immediate for the specified operand.
getImmediate__anon375e1b3c0111::HexagonHardwareLoops240*9880d681SAndroid Build Coastguard Worker int64_t getImmediate(const MachineOperand &MO) const {
241*9880d681SAndroid Build Coastguard Worker int64_t V;
242*9880d681SAndroid Build Coastguard Worker if (!checkForImmediate(MO, V))
243*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid operand");
244*9880d681SAndroid Build Coastguard Worker return V;
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker /// \brief Reset the given machine operand to now refer to a new immediate
248*9880d681SAndroid Build Coastguard Worker /// value. Assumes that the operand was already referencing an immediate
249*9880d681SAndroid Build Coastguard Worker /// value, either directly, or via a register.
250*9880d681SAndroid Build Coastguard Worker void setImmediate(MachineOperand &MO, int64_t Val);
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker /// \brief Fix the data flow of the induction varible.
253*9880d681SAndroid Build Coastguard Worker /// The desired flow is: phi ---> bump -+-> comparison-in-latch.
254*9880d681SAndroid Build Coastguard Worker /// |
255*9880d681SAndroid Build Coastguard Worker /// +-> back to phi
256*9880d681SAndroid Build Coastguard Worker /// where "bump" is the increment of the induction variable:
257*9880d681SAndroid Build Coastguard Worker /// iv = iv + #const.
258*9880d681SAndroid Build Coastguard Worker /// Due to some prior code transformations, the actual flow may look
259*9880d681SAndroid Build Coastguard Worker /// like this:
260*9880d681SAndroid Build Coastguard Worker /// phi -+-> bump ---> back to phi
261*9880d681SAndroid Build Coastguard Worker /// |
262*9880d681SAndroid Build Coastguard Worker /// +-> comparison-in-latch (against upper_bound-bump),
263*9880d681SAndroid Build Coastguard Worker /// i.e. the comparison that controls the loop execution may be using
264*9880d681SAndroid Build Coastguard Worker /// the value of the induction variable from before the increment.
265*9880d681SAndroid Build Coastguard Worker ///
266*9880d681SAndroid Build Coastguard Worker /// Return true if the loop's flow is the desired one (i.e. it's
267*9880d681SAndroid Build Coastguard Worker /// either been fixed, or no fixing was necessary).
268*9880d681SAndroid Build Coastguard Worker /// Otherwise, return false. This can happen if the induction variable
269*9880d681SAndroid Build Coastguard Worker /// couldn't be identified, or if the value in the latch's comparison
270*9880d681SAndroid Build Coastguard Worker /// cannot be adjusted to reflect the post-bump value.
271*9880d681SAndroid Build Coastguard Worker bool fixupInductionVariable(MachineLoop *L);
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker /// \brief Given a loop, if it does not have a preheader, create one.
274*9880d681SAndroid Build Coastguard Worker /// Return the block that is the preheader.
275*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *createPreheaderForLoop(MachineLoop *L);
276*9880d681SAndroid Build Coastguard Worker };
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker char HexagonHardwareLoops::ID = 0;
279*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
280*9880d681SAndroid Build Coastguard Worker int HexagonHardwareLoops::Counter = 0;
281*9880d681SAndroid Build Coastguard Worker #endif
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker /// \brief Abstraction for a trip count of a loop. A smaller version
284*9880d681SAndroid Build Coastguard Worker /// of the MachineOperand class without the concerns of changing the
285*9880d681SAndroid Build Coastguard Worker /// operand representation.
286*9880d681SAndroid Build Coastguard Worker class CountValue {
287*9880d681SAndroid Build Coastguard Worker public:
288*9880d681SAndroid Build Coastguard Worker enum CountValueType {
289*9880d681SAndroid Build Coastguard Worker CV_Register,
290*9880d681SAndroid Build Coastguard Worker CV_Immediate
291*9880d681SAndroid Build Coastguard Worker };
292*9880d681SAndroid Build Coastguard Worker private:
293*9880d681SAndroid Build Coastguard Worker CountValueType Kind;
294*9880d681SAndroid Build Coastguard Worker union Values {
295*9880d681SAndroid Build Coastguard Worker struct {
296*9880d681SAndroid Build Coastguard Worker unsigned Reg;
297*9880d681SAndroid Build Coastguard Worker unsigned Sub;
298*9880d681SAndroid Build Coastguard Worker } R;
299*9880d681SAndroid Build Coastguard Worker unsigned ImmVal;
300*9880d681SAndroid Build Coastguard Worker } Contents;
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker public:
CountValue(CountValueType t,unsigned v,unsigned u=0)303*9880d681SAndroid Build Coastguard Worker explicit CountValue(CountValueType t, unsigned v, unsigned u = 0) {
304*9880d681SAndroid Build Coastguard Worker Kind = t;
305*9880d681SAndroid Build Coastguard Worker if (Kind == CV_Register) {
306*9880d681SAndroid Build Coastguard Worker Contents.R.Reg = v;
307*9880d681SAndroid Build Coastguard Worker Contents.R.Sub = u;
308*9880d681SAndroid Build Coastguard Worker } else {
309*9880d681SAndroid Build Coastguard Worker Contents.ImmVal = v;
310*9880d681SAndroid Build Coastguard Worker }
311*9880d681SAndroid Build Coastguard Worker }
isReg() const312*9880d681SAndroid Build Coastguard Worker bool isReg() const { return Kind == CV_Register; }
isImm() const313*9880d681SAndroid Build Coastguard Worker bool isImm() const { return Kind == CV_Immediate; }
314*9880d681SAndroid Build Coastguard Worker
getReg() const315*9880d681SAndroid Build Coastguard Worker unsigned getReg() const {
316*9880d681SAndroid Build Coastguard Worker assert(isReg() && "Wrong CountValue accessor");
317*9880d681SAndroid Build Coastguard Worker return Contents.R.Reg;
318*9880d681SAndroid Build Coastguard Worker }
getSubReg() const319*9880d681SAndroid Build Coastguard Worker unsigned getSubReg() const {
320*9880d681SAndroid Build Coastguard Worker assert(isReg() && "Wrong CountValue accessor");
321*9880d681SAndroid Build Coastguard Worker return Contents.R.Sub;
322*9880d681SAndroid Build Coastguard Worker }
getImm() const323*9880d681SAndroid Build Coastguard Worker unsigned getImm() const {
324*9880d681SAndroid Build Coastguard Worker assert(isImm() && "Wrong CountValue accessor");
325*9880d681SAndroid Build Coastguard Worker return Contents.ImmVal;
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker
print(raw_ostream & OS,const TargetRegisterInfo * TRI=nullptr) const328*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const {
329*9880d681SAndroid Build Coastguard Worker if (isReg()) { OS << PrintReg(Contents.R.Reg, TRI, Contents.R.Sub); }
330*9880d681SAndroid Build Coastguard Worker if (isImm()) { OS << Contents.ImmVal; }
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker };
333*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(HexagonHardwareLoops, "hwloops",
337*9880d681SAndroid Build Coastguard Worker "Hexagon Hardware Loops", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)338*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
339*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
340*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(HexagonHardwareLoops, "hwloops",
341*9880d681SAndroid Build Coastguard Worker "Hexagon Hardware Loops", false, false)
342*9880d681SAndroid Build Coastguard Worker
343*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createHexagonHardwareLoops() {
344*9880d681SAndroid Build Coastguard Worker return new HexagonHardwareLoops();
345*9880d681SAndroid Build Coastguard Worker }
346*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)347*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) {
348*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "********* Hexagon Hardware Loops *********\n");
349*9880d681SAndroid Build Coastguard Worker if (skipFunction(*MF.getFunction()))
350*9880d681SAndroid Build Coastguard Worker return false;
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker bool Changed = false;
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker MLI = &getAnalysis<MachineLoopInfo>();
355*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
356*9880d681SAndroid Build Coastguard Worker MDT = &getAnalysis<MachineDominatorTree>();
357*9880d681SAndroid Build Coastguard Worker TII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker for (auto &L : *MLI)
360*9880d681SAndroid Build Coastguard Worker if (!L->getParentLoop()) {
361*9880d681SAndroid Build Coastguard Worker bool L0Used = false;
362*9880d681SAndroid Build Coastguard Worker bool L1Used = false;
363*9880d681SAndroid Build Coastguard Worker Changed |= convertToHardwareLoop(L, L0Used, L1Used);
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker return Changed;
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker /// \brief Return the latch block if it's one of the exiting blocks. Otherwise,
370*9880d681SAndroid Build Coastguard Worker /// return the exiting block. Return 'null' when multiple exiting blocks are
371*9880d681SAndroid Build Coastguard Worker /// present.
getExitingBlock(MachineLoop * L)372*9880d681SAndroid Build Coastguard Worker static MachineBasicBlock* getExitingBlock(MachineLoop *L) {
373*9880d681SAndroid Build Coastguard Worker if (MachineBasicBlock *Latch = L->getLoopLatch()) {
374*9880d681SAndroid Build Coastguard Worker if (L->isLoopExiting(Latch))
375*9880d681SAndroid Build Coastguard Worker return Latch;
376*9880d681SAndroid Build Coastguard Worker else
377*9880d681SAndroid Build Coastguard Worker return L->getExitingBlock();
378*9880d681SAndroid Build Coastguard Worker }
379*9880d681SAndroid Build Coastguard Worker return nullptr;
380*9880d681SAndroid Build Coastguard Worker }
381*9880d681SAndroid Build Coastguard Worker
findInductionRegister(MachineLoop * L,unsigned & Reg,int64_t & IVBump,MachineInstr * & IVOp) const382*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L,
383*9880d681SAndroid Build Coastguard Worker unsigned &Reg,
384*9880d681SAndroid Build Coastguard Worker int64_t &IVBump,
385*9880d681SAndroid Build Coastguard Worker MachineInstr *&IVOp
386*9880d681SAndroid Build Coastguard Worker ) const {
387*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Header = L->getHeader();
388*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Preheader = L->getLoopPreheader();
389*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Latch = L->getLoopLatch();
390*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ExitingBlock = getExitingBlock(L);
391*9880d681SAndroid Build Coastguard Worker if (!Header || !Preheader || !Latch || !ExitingBlock)
392*9880d681SAndroid Build Coastguard Worker return false;
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker // This pair represents an induction register together with an immediate
395*9880d681SAndroid Build Coastguard Worker // value that will be added to it in each loop iteration.
396*9880d681SAndroid Build Coastguard Worker typedef std::pair<unsigned,int64_t> RegisterBump;
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker // Mapping: R.next -> (R, bump), where R, R.next and bump are derived
399*9880d681SAndroid Build Coastguard Worker // from an induction operation
400*9880d681SAndroid Build Coastguard Worker // R.next = R + bump
401*9880d681SAndroid Build Coastguard Worker // where bump is an immediate value.
402*9880d681SAndroid Build Coastguard Worker typedef std::map<unsigned,RegisterBump> InductionMap;
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker InductionMap IndMap;
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::instr_iterator instr_iterator;
407*9880d681SAndroid Build Coastguard Worker for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
408*9880d681SAndroid Build Coastguard Worker I != E && I->isPHI(); ++I) {
409*9880d681SAndroid Build Coastguard Worker MachineInstr *Phi = &*I;
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker // Have a PHI instruction. Get the operand that corresponds to the
412*9880d681SAndroid Build Coastguard Worker // latch block, and see if is a result of an addition of form "reg+imm",
413*9880d681SAndroid Build Coastguard Worker // where the "reg" is defined by the PHI node we are looking at.
414*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = Phi->getNumOperands(); i < n; i += 2) {
415*9880d681SAndroid Build Coastguard Worker if (Phi->getOperand(i+1).getMBB() != Latch)
416*9880d681SAndroid Build Coastguard Worker continue;
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker unsigned PhiOpReg = Phi->getOperand(i).getReg();
419*9880d681SAndroid Build Coastguard Worker MachineInstr *DI = MRI->getVRegDef(PhiOpReg);
420*9880d681SAndroid Build Coastguard Worker unsigned UpdOpc = DI->getOpcode();
421*9880d681SAndroid Build Coastguard Worker bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Worker if (isAdd) {
424*9880d681SAndroid Build Coastguard Worker // If the register operand to the add is the PHI we're looking at, this
425*9880d681SAndroid Build Coastguard Worker // meets the induction pattern.
426*9880d681SAndroid Build Coastguard Worker unsigned IndReg = DI->getOperand(1).getReg();
427*9880d681SAndroid Build Coastguard Worker MachineOperand &Opnd2 = DI->getOperand(2);
428*9880d681SAndroid Build Coastguard Worker int64_t V;
429*9880d681SAndroid Build Coastguard Worker if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
430*9880d681SAndroid Build Coastguard Worker unsigned UpdReg = DI->getOperand(0).getReg();
431*9880d681SAndroid Build Coastguard Worker IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
432*9880d681SAndroid Build Coastguard Worker }
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker } // for (i)
435*9880d681SAndroid Build Coastguard Worker } // for (instr)
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> Cond;
438*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TB = nullptr, *FB = nullptr;
439*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false);
440*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed)
441*9880d681SAndroid Build Coastguard Worker return false;
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker unsigned PredR, PredPos, PredRegFlags;
444*9880d681SAndroid Build Coastguard Worker if (!TII->getPredReg(Cond, PredR, PredPos, PredRegFlags))
445*9880d681SAndroid Build Coastguard Worker return false;
446*9880d681SAndroid Build Coastguard Worker
447*9880d681SAndroid Build Coastguard Worker MachineInstr *PredI = MRI->getVRegDef(PredR);
448*9880d681SAndroid Build Coastguard Worker if (!PredI->isCompare())
449*9880d681SAndroid Build Coastguard Worker return false;
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker unsigned CmpReg1 = 0, CmpReg2 = 0;
452*9880d681SAndroid Build Coastguard Worker int CmpImm = 0, CmpMask = 0;
453*9880d681SAndroid Build Coastguard Worker bool CmpAnalyzed =
454*9880d681SAndroid Build Coastguard Worker TII->analyzeCompare(*PredI, CmpReg1, CmpReg2, CmpMask, CmpImm);
455*9880d681SAndroid Build Coastguard Worker // Fail if the compare was not analyzed, or it's not comparing a register
456*9880d681SAndroid Build Coastguard Worker // with an immediate value. Not checking the mask here, since we handle
457*9880d681SAndroid Build Coastguard Worker // the individual compare opcodes (including A4_cmpb*) later on.
458*9880d681SAndroid Build Coastguard Worker if (!CmpAnalyzed)
459*9880d681SAndroid Build Coastguard Worker return false;
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker // Exactly one of the input registers to the comparison should be among
462*9880d681SAndroid Build Coastguard Worker // the induction registers.
463*9880d681SAndroid Build Coastguard Worker InductionMap::iterator IndMapEnd = IndMap.end();
464*9880d681SAndroid Build Coastguard Worker InductionMap::iterator F = IndMapEnd;
465*9880d681SAndroid Build Coastguard Worker if (CmpReg1 != 0) {
466*9880d681SAndroid Build Coastguard Worker InductionMap::iterator F1 = IndMap.find(CmpReg1);
467*9880d681SAndroid Build Coastguard Worker if (F1 != IndMapEnd)
468*9880d681SAndroid Build Coastguard Worker F = F1;
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker if (CmpReg2 != 0) {
471*9880d681SAndroid Build Coastguard Worker InductionMap::iterator F2 = IndMap.find(CmpReg2);
472*9880d681SAndroid Build Coastguard Worker if (F2 != IndMapEnd) {
473*9880d681SAndroid Build Coastguard Worker if (F != IndMapEnd)
474*9880d681SAndroid Build Coastguard Worker return false;
475*9880d681SAndroid Build Coastguard Worker F = F2;
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker }
478*9880d681SAndroid Build Coastguard Worker if (F == IndMapEnd)
479*9880d681SAndroid Build Coastguard Worker return false;
480*9880d681SAndroid Build Coastguard Worker
481*9880d681SAndroid Build Coastguard Worker Reg = F->second.first;
482*9880d681SAndroid Build Coastguard Worker IVBump = F->second.second;
483*9880d681SAndroid Build Coastguard Worker IVOp = MRI->getVRegDef(F->first);
484*9880d681SAndroid Build Coastguard Worker return true;
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker // Return the comparison kind for the specified opcode.
488*9880d681SAndroid Build Coastguard Worker HexagonHardwareLoops::Comparison::Kind
getComparisonKind(unsigned CondOpc,MachineOperand * InitialValue,const MachineOperand * EndValue,int64_t IVBump) const489*9880d681SAndroid Build Coastguard Worker HexagonHardwareLoops::getComparisonKind(unsigned CondOpc,
490*9880d681SAndroid Build Coastguard Worker MachineOperand *InitialValue,
491*9880d681SAndroid Build Coastguard Worker const MachineOperand *EndValue,
492*9880d681SAndroid Build Coastguard Worker int64_t IVBump) const {
493*9880d681SAndroid Build Coastguard Worker Comparison::Kind Cmp = (Comparison::Kind)0;
494*9880d681SAndroid Build Coastguard Worker switch (CondOpc) {
495*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpeqi:
496*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpeq:
497*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpeqp:
498*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::EQ;
499*9880d681SAndroid Build Coastguard Worker break;
500*9880d681SAndroid Build Coastguard Worker case Hexagon::C4_cmpneq:
501*9880d681SAndroid Build Coastguard Worker case Hexagon::C4_cmpneqi:
502*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::NE;
503*9880d681SAndroid Build Coastguard Worker break;
504*9880d681SAndroid Build Coastguard Worker case Hexagon::C4_cmplte:
505*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::LEs;
506*9880d681SAndroid Build Coastguard Worker break;
507*9880d681SAndroid Build Coastguard Worker case Hexagon::C4_cmplteu:
508*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::LEu;
509*9880d681SAndroid Build Coastguard Worker break;
510*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgtui:
511*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgtu:
512*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgtup:
513*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::GTu;
514*9880d681SAndroid Build Coastguard Worker break;
515*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgti:
516*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgt:
517*9880d681SAndroid Build Coastguard Worker case Hexagon::C2_cmpgtp:
518*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::GTs;
519*9880d681SAndroid Build Coastguard Worker break;
520*9880d681SAndroid Build Coastguard Worker default:
521*9880d681SAndroid Build Coastguard Worker return (Comparison::Kind)0;
522*9880d681SAndroid Build Coastguard Worker }
523*9880d681SAndroid Build Coastguard Worker return Cmp;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker /// \brief Analyze the statements in a loop to determine if the loop has
527*9880d681SAndroid Build Coastguard Worker /// a computable trip count and, if so, return a value that represents
528*9880d681SAndroid Build Coastguard Worker /// the trip count expression.
529*9880d681SAndroid Build Coastguard Worker ///
530*9880d681SAndroid Build Coastguard Worker /// This function iterates over the phi nodes in the loop to check for
531*9880d681SAndroid Build Coastguard Worker /// induction variable patterns that are used in the calculation for
532*9880d681SAndroid Build Coastguard Worker /// the number of time the loop is executed.
getLoopTripCount(MachineLoop * L,SmallVectorImpl<MachineInstr * > & OldInsts)533*9880d681SAndroid Build Coastguard Worker CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
534*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &OldInsts) {
535*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TopMBB = L->getTopBlock();
536*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::pred_iterator PI = TopMBB->pred_begin();
537*9880d681SAndroid Build Coastguard Worker assert(PI != TopMBB->pred_end() &&
538*9880d681SAndroid Build Coastguard Worker "Loop must have more than one incoming edge!");
539*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Backedge = *PI++;
540*9880d681SAndroid Build Coastguard Worker if (PI == TopMBB->pred_end()) // dead loop?
541*9880d681SAndroid Build Coastguard Worker return nullptr;
542*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Incoming = *PI++;
543*9880d681SAndroid Build Coastguard Worker if (PI != TopMBB->pred_end()) // multiple backedges?
544*9880d681SAndroid Build Coastguard Worker return nullptr;
545*9880d681SAndroid Build Coastguard Worker
546*9880d681SAndroid Build Coastguard Worker // Make sure there is one incoming and one backedge and determine which
547*9880d681SAndroid Build Coastguard Worker // is which.
548*9880d681SAndroid Build Coastguard Worker if (L->contains(Incoming)) {
549*9880d681SAndroid Build Coastguard Worker if (L->contains(Backedge))
550*9880d681SAndroid Build Coastguard Worker return nullptr;
551*9880d681SAndroid Build Coastguard Worker std::swap(Incoming, Backedge);
552*9880d681SAndroid Build Coastguard Worker } else if (!L->contains(Backedge))
553*9880d681SAndroid Build Coastguard Worker return nullptr;
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker // Look for the cmp instruction to determine if we can get a useful trip
556*9880d681SAndroid Build Coastguard Worker // count. The trip count can be either a register or an immediate. The
557*9880d681SAndroid Build Coastguard Worker // location of the value depends upon the type (reg or imm).
558*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ExitingBlock = getExitingBlock(L);
559*9880d681SAndroid Build Coastguard Worker if (!ExitingBlock)
560*9880d681SAndroid Build Coastguard Worker return nullptr;
561*9880d681SAndroid Build Coastguard Worker
562*9880d681SAndroid Build Coastguard Worker unsigned IVReg = 0;
563*9880d681SAndroid Build Coastguard Worker int64_t IVBump = 0;
564*9880d681SAndroid Build Coastguard Worker MachineInstr *IVOp;
565*9880d681SAndroid Build Coastguard Worker bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
566*9880d681SAndroid Build Coastguard Worker if (!FoundIV)
567*9880d681SAndroid Build Coastguard Worker return nullptr;
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Preheader = L->getLoopPreheader();
570*9880d681SAndroid Build Coastguard Worker
571*9880d681SAndroid Build Coastguard Worker MachineOperand *InitialValue = nullptr;
572*9880d681SAndroid Build Coastguard Worker MachineInstr *IV_Phi = MRI->getVRegDef(IVReg);
573*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Latch = L->getLoopLatch();
574*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = IV_Phi->getNumOperands(); i < n; i += 2) {
575*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = IV_Phi->getOperand(i+1).getMBB();
576*9880d681SAndroid Build Coastguard Worker if (MBB == Preheader)
577*9880d681SAndroid Build Coastguard Worker InitialValue = &IV_Phi->getOperand(i);
578*9880d681SAndroid Build Coastguard Worker else if (MBB == Latch)
579*9880d681SAndroid Build Coastguard Worker IVReg = IV_Phi->getOperand(i).getReg(); // Want IV reg after bump.
580*9880d681SAndroid Build Coastguard Worker }
581*9880d681SAndroid Build Coastguard Worker if (!InitialValue)
582*9880d681SAndroid Build Coastguard Worker return nullptr;
583*9880d681SAndroid Build Coastguard Worker
584*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> Cond;
585*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TB = nullptr, *FB = nullptr;
586*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false);
587*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed)
588*9880d681SAndroid Build Coastguard Worker return nullptr;
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Header = L->getHeader();
591*9880d681SAndroid Build Coastguard Worker // TB must be non-null. If FB is also non-null, one of them must be
592*9880d681SAndroid Build Coastguard Worker // the header. Otherwise, branch to TB could be exiting the loop, and
593*9880d681SAndroid Build Coastguard Worker // the fall through can go to the header.
594*9880d681SAndroid Build Coastguard Worker assert (TB && "Exit block without a branch?");
595*9880d681SAndroid Build Coastguard Worker if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
596*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *LTB = 0, *LFB = 0;
597*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> LCond;
598*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
599*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed)
600*9880d681SAndroid Build Coastguard Worker return nullptr;
601*9880d681SAndroid Build Coastguard Worker if (TB == Latch)
602*9880d681SAndroid Build Coastguard Worker TB = (LTB == Header) ? LTB : LFB;
603*9880d681SAndroid Build Coastguard Worker else
604*9880d681SAndroid Build Coastguard Worker FB = (LTB == Header) ? LTB: LFB;
605*9880d681SAndroid Build Coastguard Worker }
606*9880d681SAndroid Build Coastguard Worker assert ((!FB || TB == Header || FB == Header) && "Branches not to header?");
607*9880d681SAndroid Build Coastguard Worker if (!TB || (FB && TB != Header && FB != Header))
608*9880d681SAndroid Build Coastguard Worker return nullptr;
609*9880d681SAndroid Build Coastguard Worker
610*9880d681SAndroid Build Coastguard Worker // Branches of form "if (!P) ..." cause HexagonInstrInfo::AnalyzeBranch
611*9880d681SAndroid Build Coastguard Worker // to put imm(0), followed by P in the vector Cond.
612*9880d681SAndroid Build Coastguard Worker // If TB is not the header, it means that the "not-taken" path must lead
613*9880d681SAndroid Build Coastguard Worker // to the header.
614*9880d681SAndroid Build Coastguard Worker bool Negated = TII->predOpcodeHasNot(Cond) ^ (TB != Header);
615*9880d681SAndroid Build Coastguard Worker unsigned PredReg, PredPos, PredRegFlags;
616*9880d681SAndroid Build Coastguard Worker if (!TII->getPredReg(Cond, PredReg, PredPos, PredRegFlags))
617*9880d681SAndroid Build Coastguard Worker return nullptr;
618*9880d681SAndroid Build Coastguard Worker MachineInstr *CondI = MRI->getVRegDef(PredReg);
619*9880d681SAndroid Build Coastguard Worker unsigned CondOpc = CondI->getOpcode();
620*9880d681SAndroid Build Coastguard Worker
621*9880d681SAndroid Build Coastguard Worker unsigned CmpReg1 = 0, CmpReg2 = 0;
622*9880d681SAndroid Build Coastguard Worker int Mask = 0, ImmValue = 0;
623*9880d681SAndroid Build Coastguard Worker bool AnalyzedCmp =
624*9880d681SAndroid Build Coastguard Worker TII->analyzeCompare(*CondI, CmpReg1, CmpReg2, Mask, ImmValue);
625*9880d681SAndroid Build Coastguard Worker if (!AnalyzedCmp)
626*9880d681SAndroid Build Coastguard Worker return nullptr;
627*9880d681SAndroid Build Coastguard Worker
628*9880d681SAndroid Build Coastguard Worker // The comparison operator type determines how we compute the loop
629*9880d681SAndroid Build Coastguard Worker // trip count.
630*9880d681SAndroid Build Coastguard Worker OldInsts.push_back(CondI);
631*9880d681SAndroid Build Coastguard Worker OldInsts.push_back(IVOp);
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Worker // Sadly, the following code gets information based on the position
634*9880d681SAndroid Build Coastguard Worker // of the operands in the compare instruction. This has to be done
635*9880d681SAndroid Build Coastguard Worker // this way, because the comparisons check for a specific relationship
636*9880d681SAndroid Build Coastguard Worker // between the operands (e.g. is-less-than), rather than to find out
637*9880d681SAndroid Build Coastguard Worker // what relationship the operands are in (as on PPC).
638*9880d681SAndroid Build Coastguard Worker Comparison::Kind Cmp;
639*9880d681SAndroid Build Coastguard Worker bool isSwapped = false;
640*9880d681SAndroid Build Coastguard Worker const MachineOperand &Op1 = CondI->getOperand(1);
641*9880d681SAndroid Build Coastguard Worker const MachineOperand &Op2 = CondI->getOperand(2);
642*9880d681SAndroid Build Coastguard Worker const MachineOperand *EndValue = nullptr;
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Worker if (Op1.isReg()) {
645*9880d681SAndroid Build Coastguard Worker if (Op2.isImm() || Op1.getReg() == IVReg)
646*9880d681SAndroid Build Coastguard Worker EndValue = &Op2;
647*9880d681SAndroid Build Coastguard Worker else {
648*9880d681SAndroid Build Coastguard Worker EndValue = &Op1;
649*9880d681SAndroid Build Coastguard Worker isSwapped = true;
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker }
652*9880d681SAndroid Build Coastguard Worker
653*9880d681SAndroid Build Coastguard Worker if (!EndValue)
654*9880d681SAndroid Build Coastguard Worker return nullptr;
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
657*9880d681SAndroid Build Coastguard Worker if (!Cmp)
658*9880d681SAndroid Build Coastguard Worker return nullptr;
659*9880d681SAndroid Build Coastguard Worker if (Negated)
660*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::getNegatedComparison(Cmp);
661*9880d681SAndroid Build Coastguard Worker if (isSwapped)
662*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::getSwappedComparison(Cmp);
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker if (InitialValue->isReg()) {
665*9880d681SAndroid Build Coastguard Worker unsigned R = InitialValue->getReg();
666*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
667*9880d681SAndroid Build Coastguard Worker if (!MDT->properlyDominates(DefBB, Header))
668*9880d681SAndroid Build Coastguard Worker return nullptr;
669*9880d681SAndroid Build Coastguard Worker OldInsts.push_back(MRI->getVRegDef(R));
670*9880d681SAndroid Build Coastguard Worker }
671*9880d681SAndroid Build Coastguard Worker if (EndValue->isReg()) {
672*9880d681SAndroid Build Coastguard Worker unsigned R = EndValue->getReg();
673*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent();
674*9880d681SAndroid Build Coastguard Worker if (!MDT->properlyDominates(DefBB, Header))
675*9880d681SAndroid Build Coastguard Worker return nullptr;
676*9880d681SAndroid Build Coastguard Worker OldInsts.push_back(MRI->getVRegDef(R));
677*9880d681SAndroid Build Coastguard Worker }
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker /// \brief Helper function that returns the expression that represents the
683*9880d681SAndroid Build Coastguard Worker /// number of times a loop iterates. The function takes the operands that
684*9880d681SAndroid Build Coastguard Worker /// represent the loop start value, loop end value, and induction value.
685*9880d681SAndroid Build Coastguard Worker /// Based upon these operands, the function attempts to compute the trip count.
computeCount(MachineLoop * Loop,const MachineOperand * Start,const MachineOperand * End,unsigned IVReg,int64_t IVBump,Comparison::Kind Cmp) const686*9880d681SAndroid Build Coastguard Worker CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
687*9880d681SAndroid Build Coastguard Worker const MachineOperand *Start,
688*9880d681SAndroid Build Coastguard Worker const MachineOperand *End,
689*9880d681SAndroid Build Coastguard Worker unsigned IVReg,
690*9880d681SAndroid Build Coastguard Worker int64_t IVBump,
691*9880d681SAndroid Build Coastguard Worker Comparison::Kind Cmp) const {
692*9880d681SAndroid Build Coastguard Worker // Cannot handle comparison EQ, i.e. while (A == B).
693*9880d681SAndroid Build Coastguard Worker if (Cmp == Comparison::EQ)
694*9880d681SAndroid Build Coastguard Worker return nullptr;
695*9880d681SAndroid Build Coastguard Worker
696*9880d681SAndroid Build Coastguard Worker // Check if either the start or end values are an assignment of an immediate.
697*9880d681SAndroid Build Coastguard Worker // If so, use the immediate value rather than the register.
698*9880d681SAndroid Build Coastguard Worker if (Start->isReg()) {
699*9880d681SAndroid Build Coastguard Worker const MachineInstr *StartValInstr = MRI->getVRegDef(Start->getReg());
700*9880d681SAndroid Build Coastguard Worker if (StartValInstr && (StartValInstr->getOpcode() == Hexagon::A2_tfrsi ||
701*9880d681SAndroid Build Coastguard Worker StartValInstr->getOpcode() == Hexagon::A2_tfrpi))
702*9880d681SAndroid Build Coastguard Worker Start = &StartValInstr->getOperand(1);
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker if (End->isReg()) {
705*9880d681SAndroid Build Coastguard Worker const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
706*9880d681SAndroid Build Coastguard Worker if (EndValInstr && (EndValInstr->getOpcode() == Hexagon::A2_tfrsi ||
707*9880d681SAndroid Build Coastguard Worker EndValInstr->getOpcode() == Hexagon::A2_tfrpi))
708*9880d681SAndroid Build Coastguard Worker End = &EndValInstr->getOperand(1);
709*9880d681SAndroid Build Coastguard Worker }
710*9880d681SAndroid Build Coastguard Worker
711*9880d681SAndroid Build Coastguard Worker if (!Start->isReg() && !Start->isImm())
712*9880d681SAndroid Build Coastguard Worker return nullptr;
713*9880d681SAndroid Build Coastguard Worker if (!End->isReg() && !End->isImm())
714*9880d681SAndroid Build Coastguard Worker return nullptr;
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker bool CmpLess = Cmp & Comparison::L;
717*9880d681SAndroid Build Coastguard Worker bool CmpGreater = Cmp & Comparison::G;
718*9880d681SAndroid Build Coastguard Worker bool CmpHasEqual = Cmp & Comparison::EQ;
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker // Avoid certain wrap-arounds. This doesn't detect all wrap-arounds.
721*9880d681SAndroid Build Coastguard Worker if (CmpLess && IVBump < 0)
722*9880d681SAndroid Build Coastguard Worker // Loop going while iv is "less" with the iv value going down. Must wrap.
723*9880d681SAndroid Build Coastguard Worker return nullptr;
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker if (CmpGreater && IVBump > 0)
726*9880d681SAndroid Build Coastguard Worker // Loop going while iv is "greater" with the iv value going up. Must wrap.
727*9880d681SAndroid Build Coastguard Worker return nullptr;
728*9880d681SAndroid Build Coastguard Worker
729*9880d681SAndroid Build Coastguard Worker // Phis that may feed into the loop.
730*9880d681SAndroid Build Coastguard Worker LoopFeederMap LoopFeederPhi;
731*9880d681SAndroid Build Coastguard Worker
732*9880d681SAndroid Build Coastguard Worker // Check if the initial value may be zero and can be decremented in the first
733*9880d681SAndroid Build Coastguard Worker // iteration. If the value is zero, the endloop instruction will not decrement
734*9880d681SAndroid Build Coastguard Worker // the loop counter, so we shouldn't generate a hardware loop in this case.
735*9880d681SAndroid Build Coastguard Worker if (loopCountMayWrapOrUnderFlow(Start, End, Loop->getLoopPreheader(), Loop,
736*9880d681SAndroid Build Coastguard Worker LoopFeederPhi))
737*9880d681SAndroid Build Coastguard Worker return nullptr;
738*9880d681SAndroid Build Coastguard Worker
739*9880d681SAndroid Build Coastguard Worker if (Start->isImm() && End->isImm()) {
740*9880d681SAndroid Build Coastguard Worker // Both, start and end are immediates.
741*9880d681SAndroid Build Coastguard Worker int64_t StartV = Start->getImm();
742*9880d681SAndroid Build Coastguard Worker int64_t EndV = End->getImm();
743*9880d681SAndroid Build Coastguard Worker int64_t Dist = EndV - StartV;
744*9880d681SAndroid Build Coastguard Worker if (Dist == 0)
745*9880d681SAndroid Build Coastguard Worker return nullptr;
746*9880d681SAndroid Build Coastguard Worker
747*9880d681SAndroid Build Coastguard Worker bool Exact = (Dist % IVBump) == 0;
748*9880d681SAndroid Build Coastguard Worker
749*9880d681SAndroid Build Coastguard Worker if (Cmp == Comparison::NE) {
750*9880d681SAndroid Build Coastguard Worker if (!Exact)
751*9880d681SAndroid Build Coastguard Worker return nullptr;
752*9880d681SAndroid Build Coastguard Worker if ((Dist < 0) ^ (IVBump < 0))
753*9880d681SAndroid Build Coastguard Worker return nullptr;
754*9880d681SAndroid Build Coastguard Worker }
755*9880d681SAndroid Build Coastguard Worker
756*9880d681SAndroid Build Coastguard Worker // For comparisons that include the final value (i.e. include equality
757*9880d681SAndroid Build Coastguard Worker // with the final value), we need to increase the distance by 1.
758*9880d681SAndroid Build Coastguard Worker if (CmpHasEqual)
759*9880d681SAndroid Build Coastguard Worker Dist = Dist > 0 ? Dist+1 : Dist-1;
760*9880d681SAndroid Build Coastguard Worker
761*9880d681SAndroid Build Coastguard Worker // For the loop to iterate, CmpLess should imply Dist > 0. Similarly,
762*9880d681SAndroid Build Coastguard Worker // CmpGreater should imply Dist < 0. These conditions could actually
763*9880d681SAndroid Build Coastguard Worker // fail, for example, in unreachable code (which may still appear to be
764*9880d681SAndroid Build Coastguard Worker // reachable in the CFG).
765*9880d681SAndroid Build Coastguard Worker if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
766*9880d681SAndroid Build Coastguard Worker return nullptr;
767*9880d681SAndroid Build Coastguard Worker
768*9880d681SAndroid Build Coastguard Worker // "Normalized" distance, i.e. with the bump set to +-1.
769*9880d681SAndroid Build Coastguard Worker int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
770*9880d681SAndroid Build Coastguard Worker : (-Dist + (-IVBump - 1)) / (-IVBump);
771*9880d681SAndroid Build Coastguard Worker assert (Dist1 > 0 && "Fishy thing. Both operands have the same sign.");
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker uint64_t Count = Dist1;
774*9880d681SAndroid Build Coastguard Worker
775*9880d681SAndroid Build Coastguard Worker if (Count > 0xFFFFFFFFULL)
776*9880d681SAndroid Build Coastguard Worker return nullptr;
777*9880d681SAndroid Build Coastguard Worker
778*9880d681SAndroid Build Coastguard Worker return new CountValue(CountValue::CV_Immediate, Count);
779*9880d681SAndroid Build Coastguard Worker }
780*9880d681SAndroid Build Coastguard Worker
781*9880d681SAndroid Build Coastguard Worker // A general case: Start and End are some values, but the actual
782*9880d681SAndroid Build Coastguard Worker // iteration count may not be available. If it is not, insert
783*9880d681SAndroid Build Coastguard Worker // a computation of it into the preheader.
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker // If the induction variable bump is not a power of 2, quit.
786*9880d681SAndroid Build Coastguard Worker // Othwerise we'd need a general integer division.
787*9880d681SAndroid Build Coastguard Worker if (!isPowerOf2_64(std::abs(IVBump)))
788*9880d681SAndroid Build Coastguard Worker return nullptr;
789*9880d681SAndroid Build Coastguard Worker
790*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PH = Loop->getLoopPreheader();
791*9880d681SAndroid Build Coastguard Worker assert (PH && "Should have a preheader by now");
792*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPos = PH->getFirstTerminator();
793*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
794*9880d681SAndroid Build Coastguard Worker if (InsertPos != PH->end())
795*9880d681SAndroid Build Coastguard Worker DL = InsertPos->getDebugLoc();
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker // If Start is an immediate and End is a register, the trip count
798*9880d681SAndroid Build Coastguard Worker // will be "reg - imm". Hexagon's "subtract immediate" instruction
799*9880d681SAndroid Build Coastguard Worker // is actually "reg + -imm".
800*9880d681SAndroid Build Coastguard Worker
801*9880d681SAndroid Build Coastguard Worker // If the loop IV is going downwards, i.e. if the bump is negative,
802*9880d681SAndroid Build Coastguard Worker // then the iteration count (computed as End-Start) will need to be
803*9880d681SAndroid Build Coastguard Worker // negated. To avoid the negation, just swap Start and End.
804*9880d681SAndroid Build Coastguard Worker if (IVBump < 0) {
805*9880d681SAndroid Build Coastguard Worker std::swap(Start, End);
806*9880d681SAndroid Build Coastguard Worker IVBump = -IVBump;
807*9880d681SAndroid Build Coastguard Worker }
808*9880d681SAndroid Build Coastguard Worker // Cmp may now have a wrong direction, e.g. LEs may now be GEs.
809*9880d681SAndroid Build Coastguard Worker // Signedness, and "including equality" are preserved.
810*9880d681SAndroid Build Coastguard Worker
811*9880d681SAndroid Build Coastguard Worker bool RegToImm = Start->isReg() && End->isImm(); // for (reg..imm)
812*9880d681SAndroid Build Coastguard Worker bool RegToReg = Start->isReg() && End->isReg(); // for (reg..reg)
813*9880d681SAndroid Build Coastguard Worker
814*9880d681SAndroid Build Coastguard Worker int64_t StartV = 0, EndV = 0;
815*9880d681SAndroid Build Coastguard Worker if (Start->isImm())
816*9880d681SAndroid Build Coastguard Worker StartV = Start->getImm();
817*9880d681SAndroid Build Coastguard Worker if (End->isImm())
818*9880d681SAndroid Build Coastguard Worker EndV = End->getImm();
819*9880d681SAndroid Build Coastguard Worker
820*9880d681SAndroid Build Coastguard Worker int64_t AdjV = 0;
821*9880d681SAndroid Build Coastguard Worker // To compute the iteration count, we would need this computation:
822*9880d681SAndroid Build Coastguard Worker // Count = (End - Start + (IVBump-1)) / IVBump
823*9880d681SAndroid Build Coastguard Worker // or, when CmpHasEqual:
824*9880d681SAndroid Build Coastguard Worker // Count = (End - Start + (IVBump-1)+1) / IVBump
825*9880d681SAndroid Build Coastguard Worker // The "IVBump-1" part is the adjustment (AdjV). We can avoid
826*9880d681SAndroid Build Coastguard Worker // generating an instruction specifically to add it if we can adjust
827*9880d681SAndroid Build Coastguard Worker // the immediate values for Start or End.
828*9880d681SAndroid Build Coastguard Worker
829*9880d681SAndroid Build Coastguard Worker if (CmpHasEqual) {
830*9880d681SAndroid Build Coastguard Worker // Need to add 1 to the total iteration count.
831*9880d681SAndroid Build Coastguard Worker if (Start->isImm())
832*9880d681SAndroid Build Coastguard Worker StartV--;
833*9880d681SAndroid Build Coastguard Worker else if (End->isImm())
834*9880d681SAndroid Build Coastguard Worker EndV++;
835*9880d681SAndroid Build Coastguard Worker else
836*9880d681SAndroid Build Coastguard Worker AdjV += 1;
837*9880d681SAndroid Build Coastguard Worker }
838*9880d681SAndroid Build Coastguard Worker
839*9880d681SAndroid Build Coastguard Worker if (Cmp != Comparison::NE) {
840*9880d681SAndroid Build Coastguard Worker if (Start->isImm())
841*9880d681SAndroid Build Coastguard Worker StartV -= (IVBump-1);
842*9880d681SAndroid Build Coastguard Worker else if (End->isImm())
843*9880d681SAndroid Build Coastguard Worker EndV += (IVBump-1);
844*9880d681SAndroid Build Coastguard Worker else
845*9880d681SAndroid Build Coastguard Worker AdjV += (IVBump-1);
846*9880d681SAndroid Build Coastguard Worker }
847*9880d681SAndroid Build Coastguard Worker
848*9880d681SAndroid Build Coastguard Worker unsigned R = 0, SR = 0;
849*9880d681SAndroid Build Coastguard Worker if (Start->isReg()) {
850*9880d681SAndroid Build Coastguard Worker R = Start->getReg();
851*9880d681SAndroid Build Coastguard Worker SR = Start->getSubReg();
852*9880d681SAndroid Build Coastguard Worker } else {
853*9880d681SAndroid Build Coastguard Worker R = End->getReg();
854*9880d681SAndroid Build Coastguard Worker SR = End->getSubReg();
855*9880d681SAndroid Build Coastguard Worker }
856*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = MRI->getRegClass(R);
857*9880d681SAndroid Build Coastguard Worker // Hardware loops cannot handle 64-bit registers. If it's a double
858*9880d681SAndroid Build Coastguard Worker // register, it has to have a subregister.
859*9880d681SAndroid Build Coastguard Worker if (!SR && RC == &Hexagon::DoubleRegsRegClass)
860*9880d681SAndroid Build Coastguard Worker return nullptr;
861*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *IntRC = &Hexagon::IntRegsRegClass;
862*9880d681SAndroid Build Coastguard Worker
863*9880d681SAndroid Build Coastguard Worker // Compute DistR (register with the distance between Start and End).
864*9880d681SAndroid Build Coastguard Worker unsigned DistR, DistSR;
865*9880d681SAndroid Build Coastguard Worker
866*9880d681SAndroid Build Coastguard Worker // Avoid special case, where the start value is an imm(0).
867*9880d681SAndroid Build Coastguard Worker if (Start->isImm() && StartV == 0) {
868*9880d681SAndroid Build Coastguard Worker DistR = End->getReg();
869*9880d681SAndroid Build Coastguard Worker DistSR = End->getSubReg();
870*9880d681SAndroid Build Coastguard Worker } else {
871*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
872*9880d681SAndroid Build Coastguard Worker (RegToImm ? TII->get(Hexagon::A2_subri) :
873*9880d681SAndroid Build Coastguard Worker TII->get(Hexagon::A2_addi));
874*9880d681SAndroid Build Coastguard Worker if (RegToReg || RegToImm) {
875*9880d681SAndroid Build Coastguard Worker unsigned SubR = MRI->createVirtualRegister(IntRC);
876*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder SubIB =
877*9880d681SAndroid Build Coastguard Worker BuildMI(*PH, InsertPos, DL, SubD, SubR);
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker if (RegToReg)
880*9880d681SAndroid Build Coastguard Worker SubIB.addReg(End->getReg(), 0, End->getSubReg())
881*9880d681SAndroid Build Coastguard Worker .addReg(Start->getReg(), 0, Start->getSubReg());
882*9880d681SAndroid Build Coastguard Worker else
883*9880d681SAndroid Build Coastguard Worker SubIB.addImm(EndV)
884*9880d681SAndroid Build Coastguard Worker .addReg(Start->getReg(), 0, Start->getSubReg());
885*9880d681SAndroid Build Coastguard Worker DistR = SubR;
886*9880d681SAndroid Build Coastguard Worker } else {
887*9880d681SAndroid Build Coastguard Worker // If the loop has been unrolled, we should use the original loop count
888*9880d681SAndroid Build Coastguard Worker // instead of recalculating the value. This will avoid additional
889*9880d681SAndroid Build Coastguard Worker // 'Add' instruction.
890*9880d681SAndroid Build Coastguard Worker const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
891*9880d681SAndroid Build Coastguard Worker if (EndValInstr->getOpcode() == Hexagon::A2_addi &&
892*9880d681SAndroid Build Coastguard Worker EndValInstr->getOperand(2).getImm() == StartV) {
893*9880d681SAndroid Build Coastguard Worker DistR = EndValInstr->getOperand(1).getReg();
894*9880d681SAndroid Build Coastguard Worker } else {
895*9880d681SAndroid Build Coastguard Worker unsigned SubR = MRI->createVirtualRegister(IntRC);
896*9880d681SAndroid Build Coastguard Worker MachineInstrBuilder SubIB =
897*9880d681SAndroid Build Coastguard Worker BuildMI(*PH, InsertPos, DL, SubD, SubR);
898*9880d681SAndroid Build Coastguard Worker SubIB.addReg(End->getReg(), 0, End->getSubReg())
899*9880d681SAndroid Build Coastguard Worker .addImm(-StartV);
900*9880d681SAndroid Build Coastguard Worker DistR = SubR;
901*9880d681SAndroid Build Coastguard Worker }
902*9880d681SAndroid Build Coastguard Worker }
903*9880d681SAndroid Build Coastguard Worker DistSR = 0;
904*9880d681SAndroid Build Coastguard Worker }
905*9880d681SAndroid Build Coastguard Worker
906*9880d681SAndroid Build Coastguard Worker // From DistR, compute AdjR (register with the adjusted distance).
907*9880d681SAndroid Build Coastguard Worker unsigned AdjR, AdjSR;
908*9880d681SAndroid Build Coastguard Worker
909*9880d681SAndroid Build Coastguard Worker if (AdjV == 0) {
910*9880d681SAndroid Build Coastguard Worker AdjR = DistR;
911*9880d681SAndroid Build Coastguard Worker AdjSR = DistSR;
912*9880d681SAndroid Build Coastguard Worker } else {
913*9880d681SAndroid Build Coastguard Worker // Generate CountR = ADD DistR, AdjVal
914*9880d681SAndroid Build Coastguard Worker unsigned AddR = MRI->createVirtualRegister(IntRC);
915*9880d681SAndroid Build Coastguard Worker MCInstrDesc const &AddD = TII->get(Hexagon::A2_addi);
916*9880d681SAndroid Build Coastguard Worker BuildMI(*PH, InsertPos, DL, AddD, AddR)
917*9880d681SAndroid Build Coastguard Worker .addReg(DistR, 0, DistSR)
918*9880d681SAndroid Build Coastguard Worker .addImm(AdjV);
919*9880d681SAndroid Build Coastguard Worker
920*9880d681SAndroid Build Coastguard Worker AdjR = AddR;
921*9880d681SAndroid Build Coastguard Worker AdjSR = 0;
922*9880d681SAndroid Build Coastguard Worker }
923*9880d681SAndroid Build Coastguard Worker
924*9880d681SAndroid Build Coastguard Worker // From AdjR, compute CountR (register with the final count).
925*9880d681SAndroid Build Coastguard Worker unsigned CountR, CountSR;
926*9880d681SAndroid Build Coastguard Worker
927*9880d681SAndroid Build Coastguard Worker if (IVBump == 1) {
928*9880d681SAndroid Build Coastguard Worker CountR = AdjR;
929*9880d681SAndroid Build Coastguard Worker CountSR = AdjSR;
930*9880d681SAndroid Build Coastguard Worker } else {
931*9880d681SAndroid Build Coastguard Worker // The IV bump is a power of two. Log_2(IV bump) is the shift amount.
932*9880d681SAndroid Build Coastguard Worker unsigned Shift = Log2_32(IVBump);
933*9880d681SAndroid Build Coastguard Worker
934*9880d681SAndroid Build Coastguard Worker // Generate NormR = LSR DistR, Shift.
935*9880d681SAndroid Build Coastguard Worker unsigned LsrR = MRI->createVirtualRegister(IntRC);
936*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
937*9880d681SAndroid Build Coastguard Worker BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
938*9880d681SAndroid Build Coastguard Worker .addReg(AdjR, 0, AdjSR)
939*9880d681SAndroid Build Coastguard Worker .addImm(Shift);
940*9880d681SAndroid Build Coastguard Worker
941*9880d681SAndroid Build Coastguard Worker CountR = LsrR;
942*9880d681SAndroid Build Coastguard Worker CountSR = 0;
943*9880d681SAndroid Build Coastguard Worker }
944*9880d681SAndroid Build Coastguard Worker
945*9880d681SAndroid Build Coastguard Worker return new CountValue(CountValue::CV_Register, CountR, CountSR);
946*9880d681SAndroid Build Coastguard Worker }
947*9880d681SAndroid Build Coastguard Worker
948*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the operation is invalid within hardware loop.
isInvalidLoopOperation(const MachineInstr * MI,bool IsInnerHWLoop) const949*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI,
950*9880d681SAndroid Build Coastguard Worker bool IsInnerHWLoop) const {
951*9880d681SAndroid Build Coastguard Worker
952*9880d681SAndroid Build Coastguard Worker // Call is not allowed because the callee may use a hardware loop except for
953*9880d681SAndroid Build Coastguard Worker // the case when the call never returns.
954*9880d681SAndroid Build Coastguard Worker if (MI->getDesc().isCall() && MI->getOpcode() != Hexagon::CALLv3nr)
955*9880d681SAndroid Build Coastguard Worker return true;
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker // Check if the instruction defines a hardware loop register.
958*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
959*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = MI->getOperand(i);
960*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || !MO.isDef())
961*9880d681SAndroid Build Coastguard Worker continue;
962*9880d681SAndroid Build Coastguard Worker unsigned R = MO.getReg();
963*9880d681SAndroid Build Coastguard Worker if (IsInnerHWLoop && (R == Hexagon::LC0 || R == Hexagon::SA0 ||
964*9880d681SAndroid Build Coastguard Worker R == Hexagon::LC1 || R == Hexagon::SA1))
965*9880d681SAndroid Build Coastguard Worker return true;
966*9880d681SAndroid Build Coastguard Worker if (!IsInnerHWLoop && (R == Hexagon::LC1 || R == Hexagon::SA1))
967*9880d681SAndroid Build Coastguard Worker return true;
968*9880d681SAndroid Build Coastguard Worker }
969*9880d681SAndroid Build Coastguard Worker return false;
970*9880d681SAndroid Build Coastguard Worker }
971*9880d681SAndroid Build Coastguard Worker
972*9880d681SAndroid Build Coastguard Worker /// \brief Return true if the loop contains an instruction that inhibits
973*9880d681SAndroid Build Coastguard Worker /// the use of the hardware loop instruction.
containsInvalidInstruction(MachineLoop * L,bool IsInnerHWLoop) const974*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L,
975*9880d681SAndroid Build Coastguard Worker bool IsInnerHWLoop) const {
976*9880d681SAndroid Build Coastguard Worker const std::vector<MachineBasicBlock *> &Blocks = L->getBlocks();
977*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nhw_loop head, BB#" << Blocks[0]->getNumber(););
978*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Blocks.size(); i != e; ++i) {
979*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = Blocks[i];
980*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator
981*9880d681SAndroid Build Coastguard Worker MII = MBB->begin(), E = MBB->end(); MII != E; ++MII) {
982*9880d681SAndroid Build Coastguard Worker const MachineInstr *MI = &*MII;
983*9880d681SAndroid Build Coastguard Worker if (isInvalidLoopOperation(MI, IsInnerHWLoop)) {
984*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs()<< "\nCannot convert to hw_loop due to:"; MI->dump(););
985*9880d681SAndroid Build Coastguard Worker return true;
986*9880d681SAndroid Build Coastguard Worker }
987*9880d681SAndroid Build Coastguard Worker }
988*9880d681SAndroid Build Coastguard Worker }
989*9880d681SAndroid Build Coastguard Worker return false;
990*9880d681SAndroid Build Coastguard Worker }
991*9880d681SAndroid Build Coastguard Worker
992*9880d681SAndroid Build Coastguard Worker /// \brief Returns true if the instruction is dead. This was essentially
993*9880d681SAndroid Build Coastguard Worker /// copied from DeadMachineInstructionElim::isDead, but with special cases
994*9880d681SAndroid Build Coastguard Worker /// for inline asm, physical registers and instructions with side effects
995*9880d681SAndroid Build Coastguard Worker /// removed.
isDead(const MachineInstr * MI,SmallVectorImpl<MachineInstr * > & DeadPhis) const996*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::isDead(const MachineInstr *MI,
997*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<MachineInstr *> &DeadPhis) const {
998*9880d681SAndroid Build Coastguard Worker // Examine each operand.
999*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1000*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = MI->getOperand(i);
1001*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || !MO.isDef())
1002*9880d681SAndroid Build Coastguard Worker continue;
1003*9880d681SAndroid Build Coastguard Worker
1004*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
1005*9880d681SAndroid Build Coastguard Worker if (MRI->use_nodbg_empty(Reg))
1006*9880d681SAndroid Build Coastguard Worker continue;
1007*9880d681SAndroid Build Coastguard Worker
1008*9880d681SAndroid Build Coastguard Worker typedef MachineRegisterInfo::use_nodbg_iterator use_nodbg_iterator;
1009*9880d681SAndroid Build Coastguard Worker
1010*9880d681SAndroid Build Coastguard Worker // This instruction has users, but if the only user is the phi node for the
1011*9880d681SAndroid Build Coastguard Worker // parent block, and the only use of that phi node is this instruction, then
1012*9880d681SAndroid Build Coastguard Worker // this instruction is dead: both it (and the phi node) can be removed.
1013*9880d681SAndroid Build Coastguard Worker use_nodbg_iterator I = MRI->use_nodbg_begin(Reg);
1014*9880d681SAndroid Build Coastguard Worker use_nodbg_iterator End = MRI->use_nodbg_end();
1015*9880d681SAndroid Build Coastguard Worker if (std::next(I) != End || !I->getParent()->isPHI())
1016*9880d681SAndroid Build Coastguard Worker return false;
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker MachineInstr *OnePhi = I->getParent();
1019*9880d681SAndroid Build Coastguard Worker for (unsigned j = 0, f = OnePhi->getNumOperands(); j != f; ++j) {
1020*9880d681SAndroid Build Coastguard Worker const MachineOperand &OPO = OnePhi->getOperand(j);
1021*9880d681SAndroid Build Coastguard Worker if (!OPO.isReg() || !OPO.isDef())
1022*9880d681SAndroid Build Coastguard Worker continue;
1023*9880d681SAndroid Build Coastguard Worker
1024*9880d681SAndroid Build Coastguard Worker unsigned OPReg = OPO.getReg();
1025*9880d681SAndroid Build Coastguard Worker use_nodbg_iterator nextJ;
1026*9880d681SAndroid Build Coastguard Worker for (use_nodbg_iterator J = MRI->use_nodbg_begin(OPReg);
1027*9880d681SAndroid Build Coastguard Worker J != End; J = nextJ) {
1028*9880d681SAndroid Build Coastguard Worker nextJ = std::next(J);
1029*9880d681SAndroid Build Coastguard Worker MachineOperand &Use = *J;
1030*9880d681SAndroid Build Coastguard Worker MachineInstr *UseMI = Use.getParent();
1031*9880d681SAndroid Build Coastguard Worker
1032*9880d681SAndroid Build Coastguard Worker // If the phi node has a user that is not MI, bail.
1033*9880d681SAndroid Build Coastguard Worker if (MI != UseMI)
1034*9880d681SAndroid Build Coastguard Worker return false;
1035*9880d681SAndroid Build Coastguard Worker }
1036*9880d681SAndroid Build Coastguard Worker }
1037*9880d681SAndroid Build Coastguard Worker DeadPhis.push_back(OnePhi);
1038*9880d681SAndroid Build Coastguard Worker }
1039*9880d681SAndroid Build Coastguard Worker
1040*9880d681SAndroid Build Coastguard Worker // If there are no defs with uses, the instruction is dead.
1041*9880d681SAndroid Build Coastguard Worker return true;
1042*9880d681SAndroid Build Coastguard Worker }
1043*9880d681SAndroid Build Coastguard Worker
removeIfDead(MachineInstr * MI)1044*9880d681SAndroid Build Coastguard Worker void HexagonHardwareLoops::removeIfDead(MachineInstr *MI) {
1045*9880d681SAndroid Build Coastguard Worker // This procedure was essentially copied from DeadMachineInstructionElim.
1046*9880d681SAndroid Build Coastguard Worker
1047*9880d681SAndroid Build Coastguard Worker SmallVector<MachineInstr*, 1> DeadPhis;
1048*9880d681SAndroid Build Coastguard Worker if (isDead(MI, DeadPhis)) {
1049*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "HW looping will remove: " << *MI);
1050*9880d681SAndroid Build Coastguard Worker
1051*9880d681SAndroid Build Coastguard Worker // It is possible that some DBG_VALUE instructions refer to this
1052*9880d681SAndroid Build Coastguard Worker // instruction. Examine each def operand for such references;
1053*9880d681SAndroid Build Coastguard Worker // if found, mark the DBG_VALUE as undef (but don't delete it).
1054*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1055*9880d681SAndroid Build Coastguard Worker const MachineOperand &MO = MI->getOperand(i);
1056*9880d681SAndroid Build Coastguard Worker if (!MO.isReg() || !MO.isDef())
1057*9880d681SAndroid Build Coastguard Worker continue;
1058*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
1059*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo::use_iterator nextI;
1060*9880d681SAndroid Build Coastguard Worker for (MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg),
1061*9880d681SAndroid Build Coastguard Worker E = MRI->use_end(); I != E; I = nextI) {
1062*9880d681SAndroid Build Coastguard Worker nextI = std::next(I); // I is invalidated by the setReg
1063*9880d681SAndroid Build Coastguard Worker MachineOperand &Use = *I;
1064*9880d681SAndroid Build Coastguard Worker MachineInstr *UseMI = I->getParent();
1065*9880d681SAndroid Build Coastguard Worker if (UseMI == MI)
1066*9880d681SAndroid Build Coastguard Worker continue;
1067*9880d681SAndroid Build Coastguard Worker if (Use.isDebug())
1068*9880d681SAndroid Build Coastguard Worker UseMI->getOperand(0).setReg(0U);
1069*9880d681SAndroid Build Coastguard Worker }
1070*9880d681SAndroid Build Coastguard Worker }
1071*9880d681SAndroid Build Coastguard Worker
1072*9880d681SAndroid Build Coastguard Worker MI->eraseFromParent();
1073*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < DeadPhis.size(); ++i)
1074*9880d681SAndroid Build Coastguard Worker DeadPhis[i]->eraseFromParent();
1075*9880d681SAndroid Build Coastguard Worker }
1076*9880d681SAndroid Build Coastguard Worker }
1077*9880d681SAndroid Build Coastguard Worker
1078*9880d681SAndroid Build Coastguard Worker /// \brief Check if the loop is a candidate for converting to a hardware
1079*9880d681SAndroid Build Coastguard Worker /// loop. If so, then perform the transformation.
1080*9880d681SAndroid Build Coastguard Worker ///
1081*9880d681SAndroid Build Coastguard Worker /// This function works on innermost loops first. A loop can be converted
1082*9880d681SAndroid Build Coastguard Worker /// if it is a counting loop; either a register value or an immediate.
1083*9880d681SAndroid Build Coastguard Worker ///
1084*9880d681SAndroid Build Coastguard Worker /// The code makes several assumptions about the representation of the loop
1085*9880d681SAndroid Build Coastguard Worker /// in llvm.
convertToHardwareLoop(MachineLoop * L,bool & RecL0used,bool & RecL1used)1086*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L,
1087*9880d681SAndroid Build Coastguard Worker bool &RecL0used,
1088*9880d681SAndroid Build Coastguard Worker bool &RecL1used) {
1089*9880d681SAndroid Build Coastguard Worker // This is just for sanity.
1090*9880d681SAndroid Build Coastguard Worker assert(L->getHeader() && "Loop without a header?");
1091*9880d681SAndroid Build Coastguard Worker
1092*9880d681SAndroid Build Coastguard Worker bool Changed = false;
1093*9880d681SAndroid Build Coastguard Worker bool L0Used = false;
1094*9880d681SAndroid Build Coastguard Worker bool L1Used = false;
1095*9880d681SAndroid Build Coastguard Worker
1096*9880d681SAndroid Build Coastguard Worker // Process nested loops first.
1097*9880d681SAndroid Build Coastguard Worker for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I) {
1098*9880d681SAndroid Build Coastguard Worker Changed |= convertToHardwareLoop(*I, RecL0used, RecL1used);
1099*9880d681SAndroid Build Coastguard Worker L0Used |= RecL0used;
1100*9880d681SAndroid Build Coastguard Worker L1Used |= RecL1used;
1101*9880d681SAndroid Build Coastguard Worker }
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker // If a nested loop has been converted, then we can't convert this loop.
1104*9880d681SAndroid Build Coastguard Worker if (Changed && L0Used && L1Used)
1105*9880d681SAndroid Build Coastguard Worker return Changed;
1106*9880d681SAndroid Build Coastguard Worker
1107*9880d681SAndroid Build Coastguard Worker unsigned LOOP_i;
1108*9880d681SAndroid Build Coastguard Worker unsigned LOOP_r;
1109*9880d681SAndroid Build Coastguard Worker unsigned ENDLOOP;
1110*9880d681SAndroid Build Coastguard Worker
1111*9880d681SAndroid Build Coastguard Worker // Flag used to track loopN instruction:
1112*9880d681SAndroid Build Coastguard Worker // 1 - Hardware loop is being generated for the inner most loop.
1113*9880d681SAndroid Build Coastguard Worker // 0 - Hardware loop is being generated for the outer loop.
1114*9880d681SAndroid Build Coastguard Worker unsigned IsInnerHWLoop = 1;
1115*9880d681SAndroid Build Coastguard Worker
1116*9880d681SAndroid Build Coastguard Worker if (L0Used) {
1117*9880d681SAndroid Build Coastguard Worker LOOP_i = Hexagon::J2_loop1i;
1118*9880d681SAndroid Build Coastguard Worker LOOP_r = Hexagon::J2_loop1r;
1119*9880d681SAndroid Build Coastguard Worker ENDLOOP = Hexagon::ENDLOOP1;
1120*9880d681SAndroid Build Coastguard Worker IsInnerHWLoop = 0;
1121*9880d681SAndroid Build Coastguard Worker } else {
1122*9880d681SAndroid Build Coastguard Worker LOOP_i = Hexagon::J2_loop0i;
1123*9880d681SAndroid Build Coastguard Worker LOOP_r = Hexagon::J2_loop0r;
1124*9880d681SAndroid Build Coastguard Worker ENDLOOP = Hexagon::ENDLOOP0;
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker
1127*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
1128*9880d681SAndroid Build Coastguard Worker // Stop trying after reaching the limit (if any).
1129*9880d681SAndroid Build Coastguard Worker int Limit = HWLoopLimit;
1130*9880d681SAndroid Build Coastguard Worker if (Limit >= 0) {
1131*9880d681SAndroid Build Coastguard Worker if (Counter >= HWLoopLimit)
1132*9880d681SAndroid Build Coastguard Worker return false;
1133*9880d681SAndroid Build Coastguard Worker Counter++;
1134*9880d681SAndroid Build Coastguard Worker }
1135*9880d681SAndroid Build Coastguard Worker #endif
1136*9880d681SAndroid Build Coastguard Worker
1137*9880d681SAndroid Build Coastguard Worker // Does the loop contain any invalid instructions?
1138*9880d681SAndroid Build Coastguard Worker if (containsInvalidInstruction(L, IsInnerHWLoop))
1139*9880d681SAndroid Build Coastguard Worker return false;
1140*9880d681SAndroid Build Coastguard Worker
1141*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *LastMBB = getExitingBlock(L);
1142*9880d681SAndroid Build Coastguard Worker // Don't generate hw loop if the loop has more than one exit.
1143*9880d681SAndroid Build Coastguard Worker if (!LastMBB)
1144*9880d681SAndroid Build Coastguard Worker return false;
1145*9880d681SAndroid Build Coastguard Worker
1146*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator LastI = LastMBB->getFirstTerminator();
1147*9880d681SAndroid Build Coastguard Worker if (LastI == LastMBB->end())
1148*9880d681SAndroid Build Coastguard Worker return false;
1149*9880d681SAndroid Build Coastguard Worker
1150*9880d681SAndroid Build Coastguard Worker // Is the induction variable bump feeding the latch condition?
1151*9880d681SAndroid Build Coastguard Worker if (!fixupInductionVariable(L))
1152*9880d681SAndroid Build Coastguard Worker return false;
1153*9880d681SAndroid Build Coastguard Worker
1154*9880d681SAndroid Build Coastguard Worker // Ensure the loop has a preheader: the loop instruction will be
1155*9880d681SAndroid Build Coastguard Worker // placed there.
1156*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Preheader = L->getLoopPreheader();
1157*9880d681SAndroid Build Coastguard Worker if (!Preheader) {
1158*9880d681SAndroid Build Coastguard Worker Preheader = createPreheaderForLoop(L);
1159*9880d681SAndroid Build Coastguard Worker if (!Preheader)
1160*9880d681SAndroid Build Coastguard Worker return false;
1161*9880d681SAndroid Build Coastguard Worker }
1162*9880d681SAndroid Build Coastguard Worker
1163*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPos = Preheader->getFirstTerminator();
1164*9880d681SAndroid Build Coastguard Worker
1165*9880d681SAndroid Build Coastguard Worker SmallVector<MachineInstr*, 2> OldInsts;
1166*9880d681SAndroid Build Coastguard Worker // Are we able to determine the trip count for the loop?
1167*9880d681SAndroid Build Coastguard Worker CountValue *TripCount = getLoopTripCount(L, OldInsts);
1168*9880d681SAndroid Build Coastguard Worker if (!TripCount)
1169*9880d681SAndroid Build Coastguard Worker return false;
1170*9880d681SAndroid Build Coastguard Worker
1171*9880d681SAndroid Build Coastguard Worker // Is the trip count available in the preheader?
1172*9880d681SAndroid Build Coastguard Worker if (TripCount->isReg()) {
1173*9880d681SAndroid Build Coastguard Worker // There will be a use of the register inserted into the preheader,
1174*9880d681SAndroid Build Coastguard Worker // so make sure that the register is actually defined at that point.
1175*9880d681SAndroid Build Coastguard Worker MachineInstr *TCDef = MRI->getVRegDef(TripCount->getReg());
1176*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BBDef = TCDef->getParent();
1177*9880d681SAndroid Build Coastguard Worker if (!MDT->dominates(BBDef, Preheader))
1178*9880d681SAndroid Build Coastguard Worker return false;
1179*9880d681SAndroid Build Coastguard Worker }
1180*9880d681SAndroid Build Coastguard Worker
1181*9880d681SAndroid Build Coastguard Worker // Determine the loop start.
1182*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TopBlock = L->getTopBlock();
1183*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ExitingBlock = getExitingBlock(L);
1184*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *LoopStart = 0;
1185*9880d681SAndroid Build Coastguard Worker if (ExitingBlock != L->getLoopLatch()) {
1186*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TB = 0, *FB = 0;
1187*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 2> Cond;
1188*9880d681SAndroid Build Coastguard Worker
1189*9880d681SAndroid Build Coastguard Worker if (TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false))
1190*9880d681SAndroid Build Coastguard Worker return false;
1191*9880d681SAndroid Build Coastguard Worker
1192*9880d681SAndroid Build Coastguard Worker if (L->contains(TB))
1193*9880d681SAndroid Build Coastguard Worker LoopStart = TB;
1194*9880d681SAndroid Build Coastguard Worker else if (L->contains(FB))
1195*9880d681SAndroid Build Coastguard Worker LoopStart = FB;
1196*9880d681SAndroid Build Coastguard Worker else
1197*9880d681SAndroid Build Coastguard Worker return false;
1198*9880d681SAndroid Build Coastguard Worker }
1199*9880d681SAndroid Build Coastguard Worker else
1200*9880d681SAndroid Build Coastguard Worker LoopStart = TopBlock;
1201*9880d681SAndroid Build Coastguard Worker
1202*9880d681SAndroid Build Coastguard Worker // Convert the loop to a hardware loop.
1203*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Change to hardware loop at "; L->dump());
1204*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
1205*9880d681SAndroid Build Coastguard Worker if (InsertPos != Preheader->end())
1206*9880d681SAndroid Build Coastguard Worker DL = InsertPos->getDebugLoc();
1207*9880d681SAndroid Build Coastguard Worker
1208*9880d681SAndroid Build Coastguard Worker if (TripCount->isReg()) {
1209*9880d681SAndroid Build Coastguard Worker // Create a copy of the loop count register.
1210*9880d681SAndroid Build Coastguard Worker unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1211*9880d681SAndroid Build Coastguard Worker BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg)
1212*9880d681SAndroid Build Coastguard Worker .addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1213*9880d681SAndroid Build Coastguard Worker // Add the Loop instruction to the beginning of the loop.
1214*9880d681SAndroid Build Coastguard Worker BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r)).addMBB(LoopStart)
1215*9880d681SAndroid Build Coastguard Worker .addReg(CountReg);
1216*9880d681SAndroid Build Coastguard Worker } else {
1217*9880d681SAndroid Build Coastguard Worker assert(TripCount->isImm() && "Expecting immediate value for trip count");
1218*9880d681SAndroid Build Coastguard Worker // Add the Loop immediate instruction to the beginning of the loop,
1219*9880d681SAndroid Build Coastguard Worker // if the immediate fits in the instructions. Otherwise, we need to
1220*9880d681SAndroid Build Coastguard Worker // create a new virtual register.
1221*9880d681SAndroid Build Coastguard Worker int64_t CountImm = TripCount->getImm();
1222*9880d681SAndroid Build Coastguard Worker if (!TII->isValidOffset(LOOP_i, CountImm)) {
1223*9880d681SAndroid Build Coastguard Worker unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1224*9880d681SAndroid Build Coastguard Worker BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
1225*9880d681SAndroid Build Coastguard Worker .addImm(CountImm);
1226*9880d681SAndroid Build Coastguard Worker BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r))
1227*9880d681SAndroid Build Coastguard Worker .addMBB(LoopStart).addReg(CountReg);
1228*9880d681SAndroid Build Coastguard Worker } else
1229*9880d681SAndroid Build Coastguard Worker BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_i))
1230*9880d681SAndroid Build Coastguard Worker .addMBB(LoopStart).addImm(CountImm);
1231*9880d681SAndroid Build Coastguard Worker }
1232*9880d681SAndroid Build Coastguard Worker
1233*9880d681SAndroid Build Coastguard Worker // Make sure the loop start always has a reference in the CFG. We need
1234*9880d681SAndroid Build Coastguard Worker // to create a BlockAddress operand to get this mechanism to work both the
1235*9880d681SAndroid Build Coastguard Worker // MachineBasicBlock and BasicBlock objects need the flag set.
1236*9880d681SAndroid Build Coastguard Worker LoopStart->setHasAddressTaken();
1237*9880d681SAndroid Build Coastguard Worker // This line is needed to set the hasAddressTaken flag on the BasicBlock
1238*9880d681SAndroid Build Coastguard Worker // object.
1239*9880d681SAndroid Build Coastguard Worker BlockAddress::get(const_cast<BasicBlock *>(LoopStart->getBasicBlock()));
1240*9880d681SAndroid Build Coastguard Worker
1241*9880d681SAndroid Build Coastguard Worker // Replace the loop branch with an endloop instruction.
1242*9880d681SAndroid Build Coastguard Worker DebugLoc LastIDL = LastI->getDebugLoc();
1243*9880d681SAndroid Build Coastguard Worker BuildMI(*LastMBB, LastI, LastIDL, TII->get(ENDLOOP)).addMBB(LoopStart);
1244*9880d681SAndroid Build Coastguard Worker
1245*9880d681SAndroid Build Coastguard Worker // The loop ends with either:
1246*9880d681SAndroid Build Coastguard Worker // - a conditional branch followed by an unconditional branch, or
1247*9880d681SAndroid Build Coastguard Worker // - a conditional branch to the loop start.
1248*9880d681SAndroid Build Coastguard Worker if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1249*9880d681SAndroid Build Coastguard Worker LastI->getOpcode() == Hexagon::J2_jumpf) {
1250*9880d681SAndroid Build Coastguard Worker // Delete one and change/add an uncond. branch to out of the loop.
1251*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
1252*9880d681SAndroid Build Coastguard Worker LastI = LastMBB->erase(LastI);
1253*9880d681SAndroid Build Coastguard Worker if (!L->contains(BranchTarget)) {
1254*9880d681SAndroid Build Coastguard Worker if (LastI != LastMBB->end())
1255*9880d681SAndroid Build Coastguard Worker LastI = LastMBB->erase(LastI);
1256*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 0> Cond;
1257*9880d681SAndroid Build Coastguard Worker TII->InsertBranch(*LastMBB, BranchTarget, nullptr, Cond, LastIDL);
1258*9880d681SAndroid Build Coastguard Worker }
1259*9880d681SAndroid Build Coastguard Worker } else {
1260*9880d681SAndroid Build Coastguard Worker // Conditional branch to loop start; just delete it.
1261*9880d681SAndroid Build Coastguard Worker LastMBB->erase(LastI);
1262*9880d681SAndroid Build Coastguard Worker }
1263*9880d681SAndroid Build Coastguard Worker delete TripCount;
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker // The induction operation and the comparison may now be
1266*9880d681SAndroid Build Coastguard Worker // unneeded. If these are unneeded, then remove them.
1267*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < OldInsts.size(); ++i)
1268*9880d681SAndroid Build Coastguard Worker removeIfDead(OldInsts[i]);
1269*9880d681SAndroid Build Coastguard Worker
1270*9880d681SAndroid Build Coastguard Worker ++NumHWLoops;
1271*9880d681SAndroid Build Coastguard Worker
1272*9880d681SAndroid Build Coastguard Worker // Set RecL1used and RecL0used only after hardware loop has been
1273*9880d681SAndroid Build Coastguard Worker // successfully generated. Doing it earlier can cause wrong loop instruction
1274*9880d681SAndroid Build Coastguard Worker // to be used.
1275*9880d681SAndroid Build Coastguard Worker if (L0Used) // Loop0 was already used. So, the correct loop must be loop1.
1276*9880d681SAndroid Build Coastguard Worker RecL1used = true;
1277*9880d681SAndroid Build Coastguard Worker else
1278*9880d681SAndroid Build Coastguard Worker RecL0used = true;
1279*9880d681SAndroid Build Coastguard Worker
1280*9880d681SAndroid Build Coastguard Worker return true;
1281*9880d681SAndroid Build Coastguard Worker }
1282*9880d681SAndroid Build Coastguard Worker
orderBumpCompare(MachineInstr * BumpI,MachineInstr * CmpI)1283*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::orderBumpCompare(MachineInstr *BumpI,
1284*9880d681SAndroid Build Coastguard Worker MachineInstr *CmpI) {
1285*9880d681SAndroid Build Coastguard Worker assert (BumpI != CmpI && "Bump and compare in the same instruction?");
1286*9880d681SAndroid Build Coastguard Worker
1287*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB = BumpI->getParent();
1288*9880d681SAndroid Build Coastguard Worker if (CmpI->getParent() != BB)
1289*9880d681SAndroid Build Coastguard Worker return false;
1290*9880d681SAndroid Build Coastguard Worker
1291*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::instr_iterator instr_iterator;
1292*9880d681SAndroid Build Coastguard Worker // Check if things are in order to begin with.
1293*9880d681SAndroid Build Coastguard Worker for (instr_iterator I(BumpI), E = BB->instr_end(); I != E; ++I)
1294*9880d681SAndroid Build Coastguard Worker if (&*I == CmpI)
1295*9880d681SAndroid Build Coastguard Worker return true;
1296*9880d681SAndroid Build Coastguard Worker
1297*9880d681SAndroid Build Coastguard Worker // Out of order.
1298*9880d681SAndroid Build Coastguard Worker unsigned PredR = CmpI->getOperand(0).getReg();
1299*9880d681SAndroid Build Coastguard Worker bool FoundBump = false;
1300*9880d681SAndroid Build Coastguard Worker instr_iterator CmpIt = CmpI->getIterator(), NextIt = std::next(CmpIt);
1301*9880d681SAndroid Build Coastguard Worker for (instr_iterator I = NextIt, E = BB->instr_end(); I != E; ++I) {
1302*9880d681SAndroid Build Coastguard Worker MachineInstr *In = &*I;
1303*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, n = In->getNumOperands(); i < n; ++i) {
1304*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = In->getOperand(i);
1305*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && MO.isUse()) {
1306*9880d681SAndroid Build Coastguard Worker if (MO.getReg() == PredR) // Found an intervening use of PredR.
1307*9880d681SAndroid Build Coastguard Worker return false;
1308*9880d681SAndroid Build Coastguard Worker }
1309*9880d681SAndroid Build Coastguard Worker }
1310*9880d681SAndroid Build Coastguard Worker
1311*9880d681SAndroid Build Coastguard Worker if (In == BumpI) {
1312*9880d681SAndroid Build Coastguard Worker BB->splice(++BumpI->getIterator(), BB, CmpI->getIterator());
1313*9880d681SAndroid Build Coastguard Worker FoundBump = true;
1314*9880d681SAndroid Build Coastguard Worker break;
1315*9880d681SAndroid Build Coastguard Worker }
1316*9880d681SAndroid Build Coastguard Worker }
1317*9880d681SAndroid Build Coastguard Worker assert (FoundBump && "Cannot determine instruction order");
1318*9880d681SAndroid Build Coastguard Worker return FoundBump;
1319*9880d681SAndroid Build Coastguard Worker }
1320*9880d681SAndroid Build Coastguard Worker
1321*9880d681SAndroid Build Coastguard Worker /// This function is required to break recursion. Visiting phis in a loop may
1322*9880d681SAndroid Build Coastguard Worker /// result in recursion during compilation. We break the recursion by making
1323*9880d681SAndroid Build Coastguard Worker /// sure that we visit a MachineOperand and its definition in a
1324*9880d681SAndroid Build Coastguard Worker /// MachineInstruction only once. If we attempt to visit more than once, then
1325*9880d681SAndroid Build Coastguard Worker /// there is recursion, and will return false.
isLoopFeeder(MachineLoop * L,MachineBasicBlock * A,MachineInstr * MI,const MachineOperand * MO,LoopFeederMap & LoopFeederPhi) const1326*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::isLoopFeeder(MachineLoop *L, MachineBasicBlock *A,
1327*9880d681SAndroid Build Coastguard Worker MachineInstr *MI,
1328*9880d681SAndroid Build Coastguard Worker const MachineOperand *MO,
1329*9880d681SAndroid Build Coastguard Worker LoopFeederMap &LoopFeederPhi) const {
1330*9880d681SAndroid Build Coastguard Worker if (LoopFeederPhi.find(MO->getReg()) == LoopFeederPhi.end()) {
1331*9880d681SAndroid Build Coastguard Worker const std::vector<MachineBasicBlock *> &Blocks = L->getBlocks();
1332*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nhw_loop head, BB#" << Blocks[0]->getNumber(););
1333*9880d681SAndroid Build Coastguard Worker // Ignore all BBs that form Loop.
1334*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Blocks.size(); i != e; ++i) {
1335*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = Blocks[i];
1336*9880d681SAndroid Build Coastguard Worker if (A == MBB)
1337*9880d681SAndroid Build Coastguard Worker return false;
1338*9880d681SAndroid Build Coastguard Worker }
1339*9880d681SAndroid Build Coastguard Worker MachineInstr *Def = MRI->getVRegDef(MO->getReg());
1340*9880d681SAndroid Build Coastguard Worker LoopFeederPhi.insert(std::make_pair(MO->getReg(), Def));
1341*9880d681SAndroid Build Coastguard Worker return true;
1342*9880d681SAndroid Build Coastguard Worker } else
1343*9880d681SAndroid Build Coastguard Worker // Already visited node.
1344*9880d681SAndroid Build Coastguard Worker return false;
1345*9880d681SAndroid Build Coastguard Worker }
1346*9880d681SAndroid Build Coastguard Worker
1347*9880d681SAndroid Build Coastguard Worker /// Return true if a Phi may generate a value that can underflow.
1348*9880d681SAndroid Build Coastguard Worker /// This function calls loopCountMayWrapOrUnderFlow for each Phi operand.
phiMayWrapOrUnderflow(MachineInstr * Phi,const MachineOperand * EndVal,MachineBasicBlock * MBB,MachineLoop * L,LoopFeederMap & LoopFeederPhi) const1349*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1350*9880d681SAndroid Build Coastguard Worker MachineInstr *Phi, const MachineOperand *EndVal, MachineBasicBlock *MBB,
1351*9880d681SAndroid Build Coastguard Worker MachineLoop *L, LoopFeederMap &LoopFeederPhi) const {
1352*9880d681SAndroid Build Coastguard Worker assert(Phi->isPHI() && "Expecting a Phi.");
1353*9880d681SAndroid Build Coastguard Worker // Walk through each Phi, and its used operands. Make sure that
1354*9880d681SAndroid Build Coastguard Worker // if there is recursion in Phi, we won't generate hardware loops.
1355*9880d681SAndroid Build Coastguard Worker for (int i = 1, n = Phi->getNumOperands(); i < n; i += 2)
1356*9880d681SAndroid Build Coastguard Worker if (isLoopFeeder(L, MBB, Phi, &(Phi->getOperand(i)), LoopFeederPhi))
1357*9880d681SAndroid Build Coastguard Worker if (loopCountMayWrapOrUnderFlow(&(Phi->getOperand(i)), EndVal,
1358*9880d681SAndroid Build Coastguard Worker Phi->getParent(), L, LoopFeederPhi))
1359*9880d681SAndroid Build Coastguard Worker return true;
1360*9880d681SAndroid Build Coastguard Worker return false;
1361*9880d681SAndroid Build Coastguard Worker }
1362*9880d681SAndroid Build Coastguard Worker
1363*9880d681SAndroid Build Coastguard Worker /// Return true if the induction variable can underflow in the first iteration.
1364*9880d681SAndroid Build Coastguard Worker /// An example, is an initial unsigned value that is 0 and is decrement in the
1365*9880d681SAndroid Build Coastguard Worker /// first itertion of a do-while loop. In this case, we cannot generate a
1366*9880d681SAndroid Build Coastguard Worker /// hardware loop because the endloop instruction does not decrement the loop
1367*9880d681SAndroid Build Coastguard Worker /// counter if it is <= 1. We only need to perform this analysis if the
1368*9880d681SAndroid Build Coastguard Worker /// initial value is a register.
1369*9880d681SAndroid Build Coastguard Worker ///
1370*9880d681SAndroid Build Coastguard Worker /// This function assumes the initial value may underfow unless proven
1371*9880d681SAndroid Build Coastguard Worker /// otherwise. If the type is signed, then we don't care because signed
1372*9880d681SAndroid Build Coastguard Worker /// underflow is undefined. We attempt to prove the initial value is not
1373*9880d681SAndroid Build Coastguard Worker /// zero by perfoming a crude analysis of the loop counter. This function
1374*9880d681SAndroid Build Coastguard Worker /// checks if the initial value is used in any comparison prior to the loop
1375*9880d681SAndroid Build Coastguard Worker /// and, if so, assumes the comparison is a range check. This is inexact,
1376*9880d681SAndroid Build Coastguard Worker /// but will catch the simple cases.
loopCountMayWrapOrUnderFlow(const MachineOperand * InitVal,const MachineOperand * EndVal,MachineBasicBlock * MBB,MachineLoop * L,LoopFeederMap & LoopFeederPhi) const1377*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1378*9880d681SAndroid Build Coastguard Worker const MachineOperand *InitVal, const MachineOperand *EndVal,
1379*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB, MachineLoop *L,
1380*9880d681SAndroid Build Coastguard Worker LoopFeederMap &LoopFeederPhi) const {
1381*9880d681SAndroid Build Coastguard Worker // Only check register values since they are unknown.
1382*9880d681SAndroid Build Coastguard Worker if (!InitVal->isReg())
1383*9880d681SAndroid Build Coastguard Worker return false;
1384*9880d681SAndroid Build Coastguard Worker
1385*9880d681SAndroid Build Coastguard Worker if (!EndVal->isImm())
1386*9880d681SAndroid Build Coastguard Worker return false;
1387*9880d681SAndroid Build Coastguard Worker
1388*9880d681SAndroid Build Coastguard Worker // A register value that is assigned an immediate is a known value, and it
1389*9880d681SAndroid Build Coastguard Worker // won't underflow in the first iteration.
1390*9880d681SAndroid Build Coastguard Worker int64_t Imm;
1391*9880d681SAndroid Build Coastguard Worker if (checkForImmediate(*InitVal, Imm))
1392*9880d681SAndroid Build Coastguard Worker return (EndVal->getImm() == Imm);
1393*9880d681SAndroid Build Coastguard Worker
1394*9880d681SAndroid Build Coastguard Worker unsigned Reg = InitVal->getReg();
1395*9880d681SAndroid Build Coastguard Worker
1396*9880d681SAndroid Build Coastguard Worker // We don't know the value of a physical register.
1397*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(Reg))
1398*9880d681SAndroid Build Coastguard Worker return true;
1399*9880d681SAndroid Build Coastguard Worker
1400*9880d681SAndroid Build Coastguard Worker MachineInstr *Def = MRI->getVRegDef(Reg);
1401*9880d681SAndroid Build Coastguard Worker if (!Def)
1402*9880d681SAndroid Build Coastguard Worker return true;
1403*9880d681SAndroid Build Coastguard Worker
1404*9880d681SAndroid Build Coastguard Worker // If the initial value is a Phi or copy and the operands may not underflow,
1405*9880d681SAndroid Build Coastguard Worker // then the definition cannot be underflow either.
1406*9880d681SAndroid Build Coastguard Worker if (Def->isPHI() && !phiMayWrapOrUnderflow(Def, EndVal, Def->getParent(),
1407*9880d681SAndroid Build Coastguard Worker L, LoopFeederPhi))
1408*9880d681SAndroid Build Coastguard Worker return false;
1409*9880d681SAndroid Build Coastguard Worker if (Def->isCopy() && !loopCountMayWrapOrUnderFlow(&(Def->getOperand(1)),
1410*9880d681SAndroid Build Coastguard Worker EndVal, Def->getParent(),
1411*9880d681SAndroid Build Coastguard Worker L, LoopFeederPhi))
1412*9880d681SAndroid Build Coastguard Worker return false;
1413*9880d681SAndroid Build Coastguard Worker
1414*9880d681SAndroid Build Coastguard Worker // Iterate over the uses of the initial value. If the initial value is used
1415*9880d681SAndroid Build Coastguard Worker // in a compare, then we assume this is a range check that ensures the loop
1416*9880d681SAndroid Build Coastguard Worker // doesn't underflow. This is not an exact test and should be improved.
1417*9880d681SAndroid Build Coastguard Worker for (MachineRegisterInfo::use_instr_nodbg_iterator I = MRI->use_instr_nodbg_begin(Reg),
1418*9880d681SAndroid Build Coastguard Worker E = MRI->use_instr_nodbg_end(); I != E; ++I) {
1419*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
1420*9880d681SAndroid Build Coastguard Worker unsigned CmpReg1 = 0, CmpReg2 = 0;
1421*9880d681SAndroid Build Coastguard Worker int CmpMask = 0, CmpValue = 0;
1422*9880d681SAndroid Build Coastguard Worker
1423*9880d681SAndroid Build Coastguard Worker if (!TII->analyzeCompare(*MI, CmpReg1, CmpReg2, CmpMask, CmpValue))
1424*9880d681SAndroid Build Coastguard Worker continue;
1425*9880d681SAndroid Build Coastguard Worker
1426*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TBB = 0, *FBB = 0;
1427*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 2> Cond;
1428*9880d681SAndroid Build Coastguard Worker if (TII->analyzeBranch(*MI->getParent(), TBB, FBB, Cond, false))
1429*9880d681SAndroid Build Coastguard Worker continue;
1430*9880d681SAndroid Build Coastguard Worker
1431*9880d681SAndroid Build Coastguard Worker Comparison::Kind Cmp = getComparisonKind(MI->getOpcode(), 0, 0, 0);
1432*9880d681SAndroid Build Coastguard Worker if (Cmp == 0)
1433*9880d681SAndroid Build Coastguard Worker continue;
1434*9880d681SAndroid Build Coastguard Worker if (TII->predOpcodeHasNot(Cond) ^ (TBB != MBB))
1435*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::getNegatedComparison(Cmp);
1436*9880d681SAndroid Build Coastguard Worker if (CmpReg2 != 0 && CmpReg2 == Reg)
1437*9880d681SAndroid Build Coastguard Worker Cmp = Comparison::getSwappedComparison(Cmp);
1438*9880d681SAndroid Build Coastguard Worker
1439*9880d681SAndroid Build Coastguard Worker // Signed underflow is undefined.
1440*9880d681SAndroid Build Coastguard Worker if (Comparison::isSigned(Cmp))
1441*9880d681SAndroid Build Coastguard Worker return false;
1442*9880d681SAndroid Build Coastguard Worker
1443*9880d681SAndroid Build Coastguard Worker // Check if there is a comparison of the initial value. If the initial value
1444*9880d681SAndroid Build Coastguard Worker // is greater than or not equal to another value, then assume this is a
1445*9880d681SAndroid Build Coastguard Worker // range check.
1446*9880d681SAndroid Build Coastguard Worker if ((Cmp & Comparison::G) || Cmp == Comparison::NE)
1447*9880d681SAndroid Build Coastguard Worker return false;
1448*9880d681SAndroid Build Coastguard Worker }
1449*9880d681SAndroid Build Coastguard Worker
1450*9880d681SAndroid Build Coastguard Worker // OK - this is a hack that needs to be improved. We really need to analyze
1451*9880d681SAndroid Build Coastguard Worker // the instructions performed on the initial value. This works on the simplest
1452*9880d681SAndroid Build Coastguard Worker // cases only.
1453*9880d681SAndroid Build Coastguard Worker if (!Def->isCopy() && !Def->isPHI())
1454*9880d681SAndroid Build Coastguard Worker return false;
1455*9880d681SAndroid Build Coastguard Worker
1456*9880d681SAndroid Build Coastguard Worker return true;
1457*9880d681SAndroid Build Coastguard Worker }
1458*9880d681SAndroid Build Coastguard Worker
checkForImmediate(const MachineOperand & MO,int64_t & Val) const1459*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO,
1460*9880d681SAndroid Build Coastguard Worker int64_t &Val) const {
1461*9880d681SAndroid Build Coastguard Worker if (MO.isImm()) {
1462*9880d681SAndroid Build Coastguard Worker Val = MO.getImm();
1463*9880d681SAndroid Build Coastguard Worker return true;
1464*9880d681SAndroid Build Coastguard Worker }
1465*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
1466*9880d681SAndroid Build Coastguard Worker return false;
1467*9880d681SAndroid Build Coastguard Worker
1468*9880d681SAndroid Build Coastguard Worker // MO is a register. Check whether it is defined as an immediate value,
1469*9880d681SAndroid Build Coastguard Worker // and if so, get the value of it in TV. That value will then need to be
1470*9880d681SAndroid Build Coastguard Worker // processed to handle potential subregisters in MO.
1471*9880d681SAndroid Build Coastguard Worker int64_t TV;
1472*9880d681SAndroid Build Coastguard Worker
1473*9880d681SAndroid Build Coastguard Worker unsigned R = MO.getReg();
1474*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isVirtualRegister(R))
1475*9880d681SAndroid Build Coastguard Worker return false;
1476*9880d681SAndroid Build Coastguard Worker MachineInstr *DI = MRI->getVRegDef(R);
1477*9880d681SAndroid Build Coastguard Worker unsigned DOpc = DI->getOpcode();
1478*9880d681SAndroid Build Coastguard Worker switch (DOpc) {
1479*9880d681SAndroid Build Coastguard Worker case TargetOpcode::COPY:
1480*9880d681SAndroid Build Coastguard Worker case Hexagon::A2_tfrsi:
1481*9880d681SAndroid Build Coastguard Worker case Hexagon::A2_tfrpi:
1482*9880d681SAndroid Build Coastguard Worker case Hexagon::CONST32_Int_Real:
1483*9880d681SAndroid Build Coastguard Worker case Hexagon::CONST64_Int_Real: {
1484*9880d681SAndroid Build Coastguard Worker // Call recursively to avoid an extra check whether operand(1) is
1485*9880d681SAndroid Build Coastguard Worker // indeed an immediate (it could be a global address, for example),
1486*9880d681SAndroid Build Coastguard Worker // plus we can handle COPY at the same time.
1487*9880d681SAndroid Build Coastguard Worker if (!checkForImmediate(DI->getOperand(1), TV))
1488*9880d681SAndroid Build Coastguard Worker return false;
1489*9880d681SAndroid Build Coastguard Worker break;
1490*9880d681SAndroid Build Coastguard Worker }
1491*9880d681SAndroid Build Coastguard Worker case Hexagon::A2_combineii:
1492*9880d681SAndroid Build Coastguard Worker case Hexagon::A4_combineir:
1493*9880d681SAndroid Build Coastguard Worker case Hexagon::A4_combineii:
1494*9880d681SAndroid Build Coastguard Worker case Hexagon::A4_combineri:
1495*9880d681SAndroid Build Coastguard Worker case Hexagon::A2_combinew: {
1496*9880d681SAndroid Build Coastguard Worker const MachineOperand &S1 = DI->getOperand(1);
1497*9880d681SAndroid Build Coastguard Worker const MachineOperand &S2 = DI->getOperand(2);
1498*9880d681SAndroid Build Coastguard Worker int64_t V1, V2;
1499*9880d681SAndroid Build Coastguard Worker if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1500*9880d681SAndroid Build Coastguard Worker return false;
1501*9880d681SAndroid Build Coastguard Worker TV = V2 | (V1 << 32);
1502*9880d681SAndroid Build Coastguard Worker break;
1503*9880d681SAndroid Build Coastguard Worker }
1504*9880d681SAndroid Build Coastguard Worker case TargetOpcode::REG_SEQUENCE: {
1505*9880d681SAndroid Build Coastguard Worker const MachineOperand &S1 = DI->getOperand(1);
1506*9880d681SAndroid Build Coastguard Worker const MachineOperand &S3 = DI->getOperand(3);
1507*9880d681SAndroid Build Coastguard Worker int64_t V1, V3;
1508*9880d681SAndroid Build Coastguard Worker if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1509*9880d681SAndroid Build Coastguard Worker return false;
1510*9880d681SAndroid Build Coastguard Worker unsigned Sub2 = DI->getOperand(2).getImm();
1511*9880d681SAndroid Build Coastguard Worker unsigned Sub4 = DI->getOperand(4).getImm();
1512*9880d681SAndroid Build Coastguard Worker if (Sub2 == Hexagon::subreg_loreg && Sub4 == Hexagon::subreg_hireg)
1513*9880d681SAndroid Build Coastguard Worker TV = V1 | (V3 << 32);
1514*9880d681SAndroid Build Coastguard Worker else if (Sub2 == Hexagon::subreg_hireg && Sub4 == Hexagon::subreg_loreg)
1515*9880d681SAndroid Build Coastguard Worker TV = V3 | (V1 << 32);
1516*9880d681SAndroid Build Coastguard Worker else
1517*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected form of REG_SEQUENCE");
1518*9880d681SAndroid Build Coastguard Worker break;
1519*9880d681SAndroid Build Coastguard Worker }
1520*9880d681SAndroid Build Coastguard Worker
1521*9880d681SAndroid Build Coastguard Worker default:
1522*9880d681SAndroid Build Coastguard Worker return false;
1523*9880d681SAndroid Build Coastguard Worker }
1524*9880d681SAndroid Build Coastguard Worker
1525*9880d681SAndroid Build Coastguard Worker // By now, we should have successfuly obtained the immediate value defining
1526*9880d681SAndroid Build Coastguard Worker // the register referenced in MO. Handle a potential use of a subregister.
1527*9880d681SAndroid Build Coastguard Worker switch (MO.getSubReg()) {
1528*9880d681SAndroid Build Coastguard Worker case Hexagon::subreg_loreg:
1529*9880d681SAndroid Build Coastguard Worker Val = TV & 0xFFFFFFFFULL;
1530*9880d681SAndroid Build Coastguard Worker break;
1531*9880d681SAndroid Build Coastguard Worker case Hexagon::subreg_hireg:
1532*9880d681SAndroid Build Coastguard Worker Val = (TV >> 32) & 0xFFFFFFFFULL;
1533*9880d681SAndroid Build Coastguard Worker break;
1534*9880d681SAndroid Build Coastguard Worker default:
1535*9880d681SAndroid Build Coastguard Worker Val = TV;
1536*9880d681SAndroid Build Coastguard Worker break;
1537*9880d681SAndroid Build Coastguard Worker }
1538*9880d681SAndroid Build Coastguard Worker return true;
1539*9880d681SAndroid Build Coastguard Worker }
1540*9880d681SAndroid Build Coastguard Worker
setImmediate(MachineOperand & MO,int64_t Val)1541*9880d681SAndroid Build Coastguard Worker void HexagonHardwareLoops::setImmediate(MachineOperand &MO, int64_t Val) {
1542*9880d681SAndroid Build Coastguard Worker if (MO.isImm()) {
1543*9880d681SAndroid Build Coastguard Worker MO.setImm(Val);
1544*9880d681SAndroid Build Coastguard Worker return;
1545*9880d681SAndroid Build Coastguard Worker }
1546*9880d681SAndroid Build Coastguard Worker
1547*9880d681SAndroid Build Coastguard Worker assert(MO.isReg());
1548*9880d681SAndroid Build Coastguard Worker unsigned R = MO.getReg();
1549*9880d681SAndroid Build Coastguard Worker MachineInstr *DI = MRI->getVRegDef(R);
1550*9880d681SAndroid Build Coastguard Worker
1551*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = MRI->getRegClass(R);
1552*9880d681SAndroid Build Coastguard Worker unsigned NewR = MRI->createVirtualRegister(RC);
1553*9880d681SAndroid Build Coastguard Worker MachineBasicBlock &B = *DI->getParent();
1554*9880d681SAndroid Build Coastguard Worker DebugLoc DL = DI->getDebugLoc();
1555*9880d681SAndroid Build Coastguard Worker BuildMI(B, DI, DL, TII->get(DI->getOpcode()), NewR).addImm(Val);
1556*9880d681SAndroid Build Coastguard Worker MO.setReg(NewR);
1557*9880d681SAndroid Build Coastguard Worker }
1558*9880d681SAndroid Build Coastguard Worker
isImmValidForOpcode(unsigned CmpOpc,int64_t Imm)1559*9880d681SAndroid Build Coastguard Worker static bool isImmValidForOpcode(unsigned CmpOpc, int64_t Imm) {
1560*9880d681SAndroid Build Coastguard Worker // These two instructions are not extendable.
1561*9880d681SAndroid Build Coastguard Worker if (CmpOpc == Hexagon::A4_cmpbeqi)
1562*9880d681SAndroid Build Coastguard Worker return isUInt<8>(Imm);
1563*9880d681SAndroid Build Coastguard Worker if (CmpOpc == Hexagon::A4_cmpbgti)
1564*9880d681SAndroid Build Coastguard Worker return isInt<8>(Imm);
1565*9880d681SAndroid Build Coastguard Worker // The rest of the comparison-with-immediate instructions are extendable.
1566*9880d681SAndroid Build Coastguard Worker return true;
1567*9880d681SAndroid Build Coastguard Worker }
1568*9880d681SAndroid Build Coastguard Worker
fixupInductionVariable(MachineLoop * L)1569*9880d681SAndroid Build Coastguard Worker bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) {
1570*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Header = L->getHeader();
1571*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Latch = L->getLoopLatch();
1572*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ExitingBlock = getExitingBlock(L);
1573*9880d681SAndroid Build Coastguard Worker
1574*9880d681SAndroid Build Coastguard Worker if (!(Header && Latch && ExitingBlock))
1575*9880d681SAndroid Build Coastguard Worker return false;
1576*9880d681SAndroid Build Coastguard Worker
1577*9880d681SAndroid Build Coastguard Worker // These data structures follow the same concept as the corresponding
1578*9880d681SAndroid Build Coastguard Worker // ones in findInductionRegister (where some comments are).
1579*9880d681SAndroid Build Coastguard Worker typedef std::pair<unsigned,int64_t> RegisterBump;
1580*9880d681SAndroid Build Coastguard Worker typedef std::pair<unsigned,RegisterBump> RegisterInduction;
1581*9880d681SAndroid Build Coastguard Worker typedef std::set<RegisterInduction> RegisterInductionSet;
1582*9880d681SAndroid Build Coastguard Worker
1583*9880d681SAndroid Build Coastguard Worker // Register candidates for induction variables, with their associated bumps.
1584*9880d681SAndroid Build Coastguard Worker RegisterInductionSet IndRegs;
1585*9880d681SAndroid Build Coastguard Worker
1586*9880d681SAndroid Build Coastguard Worker // Look for induction patterns:
1587*9880d681SAndroid Build Coastguard Worker // vreg1 = PHI ..., [ latch, vreg2 ]
1588*9880d681SAndroid Build Coastguard Worker // vreg2 = ADD vreg1, imm
1589*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::instr_iterator instr_iterator;
1590*9880d681SAndroid Build Coastguard Worker for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1591*9880d681SAndroid Build Coastguard Worker I != E && I->isPHI(); ++I) {
1592*9880d681SAndroid Build Coastguard Worker MachineInstr *Phi = &*I;
1593*9880d681SAndroid Build Coastguard Worker
1594*9880d681SAndroid Build Coastguard Worker // Have a PHI instruction.
1595*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = Phi->getNumOperands(); i < n; i += 2) {
1596*9880d681SAndroid Build Coastguard Worker if (Phi->getOperand(i+1).getMBB() != Latch)
1597*9880d681SAndroid Build Coastguard Worker continue;
1598*9880d681SAndroid Build Coastguard Worker
1599*9880d681SAndroid Build Coastguard Worker unsigned PhiReg = Phi->getOperand(i).getReg();
1600*9880d681SAndroid Build Coastguard Worker MachineInstr *DI = MRI->getVRegDef(PhiReg);
1601*9880d681SAndroid Build Coastguard Worker unsigned UpdOpc = DI->getOpcode();
1602*9880d681SAndroid Build Coastguard Worker bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
1603*9880d681SAndroid Build Coastguard Worker
1604*9880d681SAndroid Build Coastguard Worker if (isAdd) {
1605*9880d681SAndroid Build Coastguard Worker // If the register operand to the add/sub is the PHI we are looking
1606*9880d681SAndroid Build Coastguard Worker // at, this meets the induction pattern.
1607*9880d681SAndroid Build Coastguard Worker unsigned IndReg = DI->getOperand(1).getReg();
1608*9880d681SAndroid Build Coastguard Worker MachineOperand &Opnd2 = DI->getOperand(2);
1609*9880d681SAndroid Build Coastguard Worker int64_t V;
1610*9880d681SAndroid Build Coastguard Worker if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1611*9880d681SAndroid Build Coastguard Worker unsigned UpdReg = DI->getOperand(0).getReg();
1612*9880d681SAndroid Build Coastguard Worker IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1613*9880d681SAndroid Build Coastguard Worker }
1614*9880d681SAndroid Build Coastguard Worker }
1615*9880d681SAndroid Build Coastguard Worker } // for (i)
1616*9880d681SAndroid Build Coastguard Worker } // for (instr)
1617*9880d681SAndroid Build Coastguard Worker
1618*9880d681SAndroid Build Coastguard Worker if (IndRegs.empty())
1619*9880d681SAndroid Build Coastguard Worker return false;
1620*9880d681SAndroid Build Coastguard Worker
1621*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TB = nullptr, *FB = nullptr;
1622*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> Cond;
1623*9880d681SAndroid Build Coastguard Worker // AnalyzeBranch returns true if it fails to analyze branch.
1624*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false);
1625*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed || Cond.empty())
1626*9880d681SAndroid Build Coastguard Worker return false;
1627*9880d681SAndroid Build Coastguard Worker
1628*9880d681SAndroid Build Coastguard Worker if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1629*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *LTB = 0, *LFB = 0;
1630*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> LCond;
1631*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false);
1632*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed)
1633*9880d681SAndroid Build Coastguard Worker return false;
1634*9880d681SAndroid Build Coastguard Worker
1635*9880d681SAndroid Build Coastguard Worker // Since latch is not the exiting block, the latch branch should be an
1636*9880d681SAndroid Build Coastguard Worker // unconditional branch to the loop header.
1637*9880d681SAndroid Build Coastguard Worker if (TB == Latch)
1638*9880d681SAndroid Build Coastguard Worker TB = (LTB == Header) ? LTB : LFB;
1639*9880d681SAndroid Build Coastguard Worker else
1640*9880d681SAndroid Build Coastguard Worker FB = (LTB == Header) ? LTB : LFB;
1641*9880d681SAndroid Build Coastguard Worker }
1642*9880d681SAndroid Build Coastguard Worker if (TB != Header) {
1643*9880d681SAndroid Build Coastguard Worker if (FB != Header) {
1644*9880d681SAndroid Build Coastguard Worker // The latch/exit block does not go back to the header.
1645*9880d681SAndroid Build Coastguard Worker return false;
1646*9880d681SAndroid Build Coastguard Worker }
1647*9880d681SAndroid Build Coastguard Worker // FB is the header (i.e., uncond. jump to branch header)
1648*9880d681SAndroid Build Coastguard Worker // In this case, the LoopBody -> TB should not be a back edge otherwise
1649*9880d681SAndroid Build Coastguard Worker // it could result in an infinite loop after conversion to hw_loop.
1650*9880d681SAndroid Build Coastguard Worker // This case can happen when the Latch has two jumps like this:
1651*9880d681SAndroid Build Coastguard Worker // Jmp_c OuterLoopHeader <-- TB
1652*9880d681SAndroid Build Coastguard Worker // Jmp InnerLoopHeader <-- FB
1653*9880d681SAndroid Build Coastguard Worker if (MDT->dominates(TB, FB))
1654*9880d681SAndroid Build Coastguard Worker return false;
1655*9880d681SAndroid Build Coastguard Worker }
1656*9880d681SAndroid Build Coastguard Worker
1657*9880d681SAndroid Build Coastguard Worker // Expecting a predicate register as a condition. It won't be a hardware
1658*9880d681SAndroid Build Coastguard Worker // predicate register at this point yet, just a vreg.
1659*9880d681SAndroid Build Coastguard Worker // HexagonInstrInfo::AnalyzeBranch for negated branches inserts imm(0)
1660*9880d681SAndroid Build Coastguard Worker // into Cond, followed by the predicate register. For non-negated branches
1661*9880d681SAndroid Build Coastguard Worker // it's just the register.
1662*9880d681SAndroid Build Coastguard Worker unsigned CSz = Cond.size();
1663*9880d681SAndroid Build Coastguard Worker if (CSz != 1 && CSz != 2)
1664*9880d681SAndroid Build Coastguard Worker return false;
1665*9880d681SAndroid Build Coastguard Worker
1666*9880d681SAndroid Build Coastguard Worker if (!Cond[CSz-1].isReg())
1667*9880d681SAndroid Build Coastguard Worker return false;
1668*9880d681SAndroid Build Coastguard Worker
1669*9880d681SAndroid Build Coastguard Worker unsigned P = Cond[CSz-1].getReg();
1670*9880d681SAndroid Build Coastguard Worker MachineInstr *PredDef = MRI->getVRegDef(P);
1671*9880d681SAndroid Build Coastguard Worker
1672*9880d681SAndroid Build Coastguard Worker if (!PredDef->isCompare())
1673*9880d681SAndroid Build Coastguard Worker return false;
1674*9880d681SAndroid Build Coastguard Worker
1675*9880d681SAndroid Build Coastguard Worker SmallSet<unsigned,2> CmpRegs;
1676*9880d681SAndroid Build Coastguard Worker MachineOperand *CmpImmOp = nullptr;
1677*9880d681SAndroid Build Coastguard Worker
1678*9880d681SAndroid Build Coastguard Worker // Go over all operands to the compare and look for immediate and register
1679*9880d681SAndroid Build Coastguard Worker // operands. Assume that if the compare has a single register use and a
1680*9880d681SAndroid Build Coastguard Worker // single immediate operand, then the register is being compared with the
1681*9880d681SAndroid Build Coastguard Worker // immediate value.
1682*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, n = PredDef->getNumOperands(); i < n; ++i) {
1683*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = PredDef->getOperand(i);
1684*9880d681SAndroid Build Coastguard Worker if (MO.isReg()) {
1685*9880d681SAndroid Build Coastguard Worker // Skip all implicit references. In one case there was:
1686*9880d681SAndroid Build Coastguard Worker // %vreg140<def> = FCMPUGT32_rr %vreg138, %vreg139, %USR<imp-use>
1687*9880d681SAndroid Build Coastguard Worker if (MO.isImplicit())
1688*9880d681SAndroid Build Coastguard Worker continue;
1689*9880d681SAndroid Build Coastguard Worker if (MO.isUse()) {
1690*9880d681SAndroid Build Coastguard Worker if (!isImmediate(MO)) {
1691*9880d681SAndroid Build Coastguard Worker CmpRegs.insert(MO.getReg());
1692*9880d681SAndroid Build Coastguard Worker continue;
1693*9880d681SAndroid Build Coastguard Worker }
1694*9880d681SAndroid Build Coastguard Worker // Consider the register to be the "immediate" operand.
1695*9880d681SAndroid Build Coastguard Worker if (CmpImmOp)
1696*9880d681SAndroid Build Coastguard Worker return false;
1697*9880d681SAndroid Build Coastguard Worker CmpImmOp = &MO;
1698*9880d681SAndroid Build Coastguard Worker }
1699*9880d681SAndroid Build Coastguard Worker } else if (MO.isImm()) {
1700*9880d681SAndroid Build Coastguard Worker if (CmpImmOp) // A second immediate argument? Confusing. Bail out.
1701*9880d681SAndroid Build Coastguard Worker return false;
1702*9880d681SAndroid Build Coastguard Worker CmpImmOp = &MO;
1703*9880d681SAndroid Build Coastguard Worker }
1704*9880d681SAndroid Build Coastguard Worker }
1705*9880d681SAndroid Build Coastguard Worker
1706*9880d681SAndroid Build Coastguard Worker if (CmpRegs.empty())
1707*9880d681SAndroid Build Coastguard Worker return false;
1708*9880d681SAndroid Build Coastguard Worker
1709*9880d681SAndroid Build Coastguard Worker // Check if the compared register follows the order we want. Fix if needed.
1710*9880d681SAndroid Build Coastguard Worker for (RegisterInductionSet::iterator I = IndRegs.begin(), E = IndRegs.end();
1711*9880d681SAndroid Build Coastguard Worker I != E; ++I) {
1712*9880d681SAndroid Build Coastguard Worker // This is a success. If the register used in the comparison is one that
1713*9880d681SAndroid Build Coastguard Worker // we have identified as a bumped (updated) induction register, there is
1714*9880d681SAndroid Build Coastguard Worker // nothing to do.
1715*9880d681SAndroid Build Coastguard Worker if (CmpRegs.count(I->first))
1716*9880d681SAndroid Build Coastguard Worker return true;
1717*9880d681SAndroid Build Coastguard Worker
1718*9880d681SAndroid Build Coastguard Worker // Otherwise, if the register being compared comes out of a PHI node,
1719*9880d681SAndroid Build Coastguard Worker // and has been recognized as following the induction pattern, and is
1720*9880d681SAndroid Build Coastguard Worker // compared against an immediate, we can fix it.
1721*9880d681SAndroid Build Coastguard Worker const RegisterBump &RB = I->second;
1722*9880d681SAndroid Build Coastguard Worker if (CmpRegs.count(RB.first)) {
1723*9880d681SAndroid Build Coastguard Worker if (!CmpImmOp) {
1724*9880d681SAndroid Build Coastguard Worker // If both operands to the compare instruction are registers, see if
1725*9880d681SAndroid Build Coastguard Worker // it can be changed to use induction register as one of the operands.
1726*9880d681SAndroid Build Coastguard Worker MachineInstr *IndI = nullptr;
1727*9880d681SAndroid Build Coastguard Worker MachineInstr *nonIndI = nullptr;
1728*9880d681SAndroid Build Coastguard Worker MachineOperand *IndMO = nullptr;
1729*9880d681SAndroid Build Coastguard Worker MachineOperand *nonIndMO = nullptr;
1730*9880d681SAndroid Build Coastguard Worker
1731*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = PredDef->getNumOperands(); i < n; ++i) {
1732*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = PredDef->getOperand(i);
1733*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && MO.getReg() == RB.first) {
1734*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\n DefMI(" << i << ") = "
1735*9880d681SAndroid Build Coastguard Worker << *(MRI->getVRegDef(I->first)));
1736*9880d681SAndroid Build Coastguard Worker if (IndI)
1737*9880d681SAndroid Build Coastguard Worker return false;
1738*9880d681SAndroid Build Coastguard Worker
1739*9880d681SAndroid Build Coastguard Worker IndI = MRI->getVRegDef(I->first);
1740*9880d681SAndroid Build Coastguard Worker IndMO = &MO;
1741*9880d681SAndroid Build Coastguard Worker } else if (MO.isReg()) {
1742*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\n DefMI(" << i << ") = "
1743*9880d681SAndroid Build Coastguard Worker << *(MRI->getVRegDef(MO.getReg())));
1744*9880d681SAndroid Build Coastguard Worker if (nonIndI)
1745*9880d681SAndroid Build Coastguard Worker return false;
1746*9880d681SAndroid Build Coastguard Worker
1747*9880d681SAndroid Build Coastguard Worker nonIndI = MRI->getVRegDef(MO.getReg());
1748*9880d681SAndroid Build Coastguard Worker nonIndMO = &MO;
1749*9880d681SAndroid Build Coastguard Worker }
1750*9880d681SAndroid Build Coastguard Worker }
1751*9880d681SAndroid Build Coastguard Worker if (IndI && nonIndI &&
1752*9880d681SAndroid Build Coastguard Worker nonIndI->getOpcode() == Hexagon::A2_addi &&
1753*9880d681SAndroid Build Coastguard Worker nonIndI->getOperand(2).isImm() &&
1754*9880d681SAndroid Build Coastguard Worker nonIndI->getOperand(2).getImm() == - RB.second) {
1755*9880d681SAndroid Build Coastguard Worker bool Order = orderBumpCompare(IndI, PredDef);
1756*9880d681SAndroid Build Coastguard Worker if (Order) {
1757*9880d681SAndroid Build Coastguard Worker IndMO->setReg(I->first);
1758*9880d681SAndroid Build Coastguard Worker nonIndMO->setReg(nonIndI->getOperand(1).getReg());
1759*9880d681SAndroid Build Coastguard Worker return true;
1760*9880d681SAndroid Build Coastguard Worker }
1761*9880d681SAndroid Build Coastguard Worker }
1762*9880d681SAndroid Build Coastguard Worker return false;
1763*9880d681SAndroid Build Coastguard Worker }
1764*9880d681SAndroid Build Coastguard Worker
1765*9880d681SAndroid Build Coastguard Worker // It is not valid to do this transformation on an unsigned comparison
1766*9880d681SAndroid Build Coastguard Worker // because it may underflow.
1767*9880d681SAndroid Build Coastguard Worker Comparison::Kind Cmp = getComparisonKind(PredDef->getOpcode(), 0, 0, 0);
1768*9880d681SAndroid Build Coastguard Worker if (!Cmp || Comparison::isUnsigned(Cmp))
1769*9880d681SAndroid Build Coastguard Worker return false;
1770*9880d681SAndroid Build Coastguard Worker
1771*9880d681SAndroid Build Coastguard Worker // If the register is being compared against an immediate, try changing
1772*9880d681SAndroid Build Coastguard Worker // the compare instruction to use induction register and adjust the
1773*9880d681SAndroid Build Coastguard Worker // immediate operand.
1774*9880d681SAndroid Build Coastguard Worker int64_t CmpImm = getImmediate(*CmpImmOp);
1775*9880d681SAndroid Build Coastguard Worker int64_t V = RB.second;
1776*9880d681SAndroid Build Coastguard Worker // Handle Overflow (64-bit).
1777*9880d681SAndroid Build Coastguard Worker if (((V > 0) && (CmpImm > INT64_MAX - V)) ||
1778*9880d681SAndroid Build Coastguard Worker ((V < 0) && (CmpImm < INT64_MIN - V)))
1779*9880d681SAndroid Build Coastguard Worker return false;
1780*9880d681SAndroid Build Coastguard Worker CmpImm += V;
1781*9880d681SAndroid Build Coastguard Worker // Most comparisons of register against an immediate value allow
1782*9880d681SAndroid Build Coastguard Worker // the immediate to be constant-extended. There are some exceptions
1783*9880d681SAndroid Build Coastguard Worker // though. Make sure the new combination will work.
1784*9880d681SAndroid Build Coastguard Worker if (CmpImmOp->isImm())
1785*9880d681SAndroid Build Coastguard Worker if (!isImmValidForOpcode(PredDef->getOpcode(), CmpImm))
1786*9880d681SAndroid Build Coastguard Worker return false;
1787*9880d681SAndroid Build Coastguard Worker
1788*9880d681SAndroid Build Coastguard Worker // Make sure that the compare happens after the bump. Otherwise,
1789*9880d681SAndroid Build Coastguard Worker // after the fixup, the compare would use a yet-undefined register.
1790*9880d681SAndroid Build Coastguard Worker MachineInstr *BumpI = MRI->getVRegDef(I->first);
1791*9880d681SAndroid Build Coastguard Worker bool Order = orderBumpCompare(BumpI, PredDef);
1792*9880d681SAndroid Build Coastguard Worker if (!Order)
1793*9880d681SAndroid Build Coastguard Worker return false;
1794*9880d681SAndroid Build Coastguard Worker
1795*9880d681SAndroid Build Coastguard Worker // Finally, fix the compare instruction.
1796*9880d681SAndroid Build Coastguard Worker setImmediate(*CmpImmOp, CmpImm);
1797*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, n = PredDef->getNumOperands(); i < n; ++i) {
1798*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = PredDef->getOperand(i);
1799*9880d681SAndroid Build Coastguard Worker if (MO.isReg() && MO.getReg() == RB.first) {
1800*9880d681SAndroid Build Coastguard Worker MO.setReg(I->first);
1801*9880d681SAndroid Build Coastguard Worker return true;
1802*9880d681SAndroid Build Coastguard Worker }
1803*9880d681SAndroid Build Coastguard Worker }
1804*9880d681SAndroid Build Coastguard Worker }
1805*9880d681SAndroid Build Coastguard Worker }
1806*9880d681SAndroid Build Coastguard Worker
1807*9880d681SAndroid Build Coastguard Worker return false;
1808*9880d681SAndroid Build Coastguard Worker }
1809*9880d681SAndroid Build Coastguard Worker
1810*9880d681SAndroid Build Coastguard Worker /// \brief Create a preheader for a given loop.
createPreheaderForLoop(MachineLoop * L)1811*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop(
1812*9880d681SAndroid Build Coastguard Worker MachineLoop *L) {
1813*9880d681SAndroid Build Coastguard Worker if (MachineBasicBlock *TmpPH = L->getLoopPreheader())
1814*9880d681SAndroid Build Coastguard Worker return TmpPH;
1815*9880d681SAndroid Build Coastguard Worker
1816*9880d681SAndroid Build Coastguard Worker if (!HWCreatePreheader)
1817*9880d681SAndroid Build Coastguard Worker return nullptr;
1818*9880d681SAndroid Build Coastguard Worker
1819*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Header = L->getHeader();
1820*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Latch = L->getLoopLatch();
1821*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ExitingBlock = getExitingBlock(L);
1822*9880d681SAndroid Build Coastguard Worker MachineFunction *MF = Header->getParent();
1823*9880d681SAndroid Build Coastguard Worker DebugLoc DL;
1824*9880d681SAndroid Build Coastguard Worker
1825*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
1826*9880d681SAndroid Build Coastguard Worker if ((PHFn != "") && (PHFn != MF->getName()))
1827*9880d681SAndroid Build Coastguard Worker return nullptr;
1828*9880d681SAndroid Build Coastguard Worker #endif
1829*9880d681SAndroid Build Coastguard Worker
1830*9880d681SAndroid Build Coastguard Worker if (!Latch || !ExitingBlock || Header->hasAddressTaken())
1831*9880d681SAndroid Build Coastguard Worker return nullptr;
1832*9880d681SAndroid Build Coastguard Worker
1833*9880d681SAndroid Build Coastguard Worker typedef MachineBasicBlock::instr_iterator instr_iterator;
1834*9880d681SAndroid Build Coastguard Worker
1835*9880d681SAndroid Build Coastguard Worker // Verify that all existing predecessors have analyzable branches
1836*9880d681SAndroid Build Coastguard Worker // (or no branches at all).
1837*9880d681SAndroid Build Coastguard Worker typedef std::vector<MachineBasicBlock*> MBBVector;
1838*9880d681SAndroid Build Coastguard Worker MBBVector Preds(Header->pred_begin(), Header->pred_end());
1839*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,2> Tmp1;
1840*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TB = nullptr, *FB = nullptr;
1841*9880d681SAndroid Build Coastguard Worker
1842*9880d681SAndroid Build Coastguard Worker if (TII->analyzeBranch(*ExitingBlock, TB, FB, Tmp1, false))
1843*9880d681SAndroid Build Coastguard Worker return nullptr;
1844*9880d681SAndroid Build Coastguard Worker
1845*9880d681SAndroid Build Coastguard Worker for (MBBVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) {
1846*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PB = *I;
1847*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*PB, TB, FB, Tmp1, false);
1848*9880d681SAndroid Build Coastguard Worker if (NotAnalyzed)
1849*9880d681SAndroid Build Coastguard Worker return nullptr;
1850*9880d681SAndroid Build Coastguard Worker }
1851*9880d681SAndroid Build Coastguard Worker
1852*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *NewPH = MF->CreateMachineBasicBlock();
1853*9880d681SAndroid Build Coastguard Worker MF->insert(Header->getIterator(), NewPH);
1854*9880d681SAndroid Build Coastguard Worker
1855*9880d681SAndroid Build Coastguard Worker if (Header->pred_size() > 2) {
1856*9880d681SAndroid Build Coastguard Worker // Ensure that the header has only two predecessors: the preheader and
1857*9880d681SAndroid Build Coastguard Worker // the loop latch. Any additional predecessors of the header should
1858*9880d681SAndroid Build Coastguard Worker // join at the newly created preheader. Inspect all PHI nodes from the
1859*9880d681SAndroid Build Coastguard Worker // header and create appropriate corresponding PHI nodes in the preheader.
1860*9880d681SAndroid Build Coastguard Worker
1861*9880d681SAndroid Build Coastguard Worker for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1862*9880d681SAndroid Build Coastguard Worker I != E && I->isPHI(); ++I) {
1863*9880d681SAndroid Build Coastguard Worker MachineInstr *PN = &*I;
1864*9880d681SAndroid Build Coastguard Worker
1865*9880d681SAndroid Build Coastguard Worker const MCInstrDesc &PD = TII->get(TargetOpcode::PHI);
1866*9880d681SAndroid Build Coastguard Worker MachineInstr *NewPN = MF->CreateMachineInstr(PD, DL);
1867*9880d681SAndroid Build Coastguard Worker NewPH->insert(NewPH->end(), NewPN);
1868*9880d681SAndroid Build Coastguard Worker
1869*9880d681SAndroid Build Coastguard Worker unsigned PR = PN->getOperand(0).getReg();
1870*9880d681SAndroid Build Coastguard Worker const TargetRegisterClass *RC = MRI->getRegClass(PR);
1871*9880d681SAndroid Build Coastguard Worker unsigned NewPR = MRI->createVirtualRegister(RC);
1872*9880d681SAndroid Build Coastguard Worker NewPN->addOperand(MachineOperand::CreateReg(NewPR, true));
1873*9880d681SAndroid Build Coastguard Worker
1874*9880d681SAndroid Build Coastguard Worker // Copy all non-latch operands of a header's PHI node to the newly
1875*9880d681SAndroid Build Coastguard Worker // created PHI node in the preheader.
1876*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = PN->getNumOperands(); i < n; i += 2) {
1877*9880d681SAndroid Build Coastguard Worker unsigned PredR = PN->getOperand(i).getReg();
1878*9880d681SAndroid Build Coastguard Worker unsigned PredRSub = PN->getOperand(i).getSubReg();
1879*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PredB = PN->getOperand(i+1).getMBB();
1880*9880d681SAndroid Build Coastguard Worker if (PredB == Latch)
1881*9880d681SAndroid Build Coastguard Worker continue;
1882*9880d681SAndroid Build Coastguard Worker
1883*9880d681SAndroid Build Coastguard Worker MachineOperand MO = MachineOperand::CreateReg(PredR, false);
1884*9880d681SAndroid Build Coastguard Worker MO.setSubReg(PredRSub);
1885*9880d681SAndroid Build Coastguard Worker NewPN->addOperand(MO);
1886*9880d681SAndroid Build Coastguard Worker NewPN->addOperand(MachineOperand::CreateMBB(PredB));
1887*9880d681SAndroid Build Coastguard Worker }
1888*9880d681SAndroid Build Coastguard Worker
1889*9880d681SAndroid Build Coastguard Worker // Remove copied operands from the old PHI node and add the value
1890*9880d681SAndroid Build Coastguard Worker // coming from the preheader's PHI.
1891*9880d681SAndroid Build Coastguard Worker for (int i = PN->getNumOperands()-2; i > 0; i -= 2) {
1892*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PredB = PN->getOperand(i+1).getMBB();
1893*9880d681SAndroid Build Coastguard Worker if (PredB != Latch) {
1894*9880d681SAndroid Build Coastguard Worker PN->RemoveOperand(i+1);
1895*9880d681SAndroid Build Coastguard Worker PN->RemoveOperand(i);
1896*9880d681SAndroid Build Coastguard Worker }
1897*9880d681SAndroid Build Coastguard Worker }
1898*9880d681SAndroid Build Coastguard Worker PN->addOperand(MachineOperand::CreateReg(NewPR, false));
1899*9880d681SAndroid Build Coastguard Worker PN->addOperand(MachineOperand::CreateMBB(NewPH));
1900*9880d681SAndroid Build Coastguard Worker }
1901*9880d681SAndroid Build Coastguard Worker
1902*9880d681SAndroid Build Coastguard Worker } else {
1903*9880d681SAndroid Build Coastguard Worker assert(Header->pred_size() == 2);
1904*9880d681SAndroid Build Coastguard Worker
1905*9880d681SAndroid Build Coastguard Worker // The header has only two predecessors, but the non-latch predecessor
1906*9880d681SAndroid Build Coastguard Worker // is not a preheader (e.g. it has other successors, etc.)
1907*9880d681SAndroid Build Coastguard Worker // In such a case we don't need any extra PHI nodes in the new preheader,
1908*9880d681SAndroid Build Coastguard Worker // all we need is to adjust existing PHIs in the header to now refer to
1909*9880d681SAndroid Build Coastguard Worker // the new preheader.
1910*9880d681SAndroid Build Coastguard Worker for (instr_iterator I = Header->instr_begin(), E = Header->instr_end();
1911*9880d681SAndroid Build Coastguard Worker I != E && I->isPHI(); ++I) {
1912*9880d681SAndroid Build Coastguard Worker MachineInstr *PN = &*I;
1913*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1, n = PN->getNumOperands(); i < n; i += 2) {
1914*9880d681SAndroid Build Coastguard Worker MachineOperand &MO = PN->getOperand(i+1);
1915*9880d681SAndroid Build Coastguard Worker if (MO.getMBB() != Latch)
1916*9880d681SAndroid Build Coastguard Worker MO.setMBB(NewPH);
1917*9880d681SAndroid Build Coastguard Worker }
1918*9880d681SAndroid Build Coastguard Worker }
1919*9880d681SAndroid Build Coastguard Worker }
1920*9880d681SAndroid Build Coastguard Worker
1921*9880d681SAndroid Build Coastguard Worker // "Reroute" the CFG edges to link in the new preheader.
1922*9880d681SAndroid Build Coastguard Worker // If any of the predecessors falls through to the header, insert a branch
1923*9880d681SAndroid Build Coastguard Worker // to the new preheader in that place.
1924*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,1> Tmp2;
1925*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand,1> EmptyCond;
1926*9880d681SAndroid Build Coastguard Worker
1927*9880d681SAndroid Build Coastguard Worker TB = FB = nullptr;
1928*9880d681SAndroid Build Coastguard Worker
1929*9880d681SAndroid Build Coastguard Worker for (MBBVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++I) {
1930*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *PB = *I;
1931*9880d681SAndroid Build Coastguard Worker if (PB != Latch) {
1932*9880d681SAndroid Build Coastguard Worker Tmp2.clear();
1933*9880d681SAndroid Build Coastguard Worker bool NotAnalyzed = TII->analyzeBranch(*PB, TB, FB, Tmp2, false);
1934*9880d681SAndroid Build Coastguard Worker (void)NotAnalyzed; // suppress compiler warning
1935*9880d681SAndroid Build Coastguard Worker assert (!NotAnalyzed && "Should be analyzable!");
1936*9880d681SAndroid Build Coastguard Worker if (TB != Header && (Tmp2.empty() || FB != Header))
1937*9880d681SAndroid Build Coastguard Worker TII->InsertBranch(*PB, NewPH, nullptr, EmptyCond, DL);
1938*9880d681SAndroid Build Coastguard Worker PB->ReplaceUsesOfBlockWith(Header, NewPH);
1939*9880d681SAndroid Build Coastguard Worker }
1940*9880d681SAndroid Build Coastguard Worker }
1941*9880d681SAndroid Build Coastguard Worker
1942*9880d681SAndroid Build Coastguard Worker // It can happen that the latch block will fall through into the header.
1943*9880d681SAndroid Build Coastguard Worker // Insert an unconditional branch to the header.
1944*9880d681SAndroid Build Coastguard Worker TB = FB = nullptr;
1945*9880d681SAndroid Build Coastguard Worker bool LatchNotAnalyzed = TII->analyzeBranch(*Latch, TB, FB, Tmp2, false);
1946*9880d681SAndroid Build Coastguard Worker (void)LatchNotAnalyzed; // suppress compiler warning
1947*9880d681SAndroid Build Coastguard Worker assert (!LatchNotAnalyzed && "Should be analyzable!");
1948*9880d681SAndroid Build Coastguard Worker if (!TB && !FB)
1949*9880d681SAndroid Build Coastguard Worker TII->InsertBranch(*Latch, Header, nullptr, EmptyCond, DL);
1950*9880d681SAndroid Build Coastguard Worker
1951*9880d681SAndroid Build Coastguard Worker // Finally, the branch from the preheader to the header.
1952*9880d681SAndroid Build Coastguard Worker TII->InsertBranch(*NewPH, Header, nullptr, EmptyCond, DL);
1953*9880d681SAndroid Build Coastguard Worker NewPH->addSuccessor(Header);
1954*9880d681SAndroid Build Coastguard Worker
1955*9880d681SAndroid Build Coastguard Worker MachineLoop *ParentLoop = L->getParentLoop();
1956*9880d681SAndroid Build Coastguard Worker if (ParentLoop)
1957*9880d681SAndroid Build Coastguard Worker ParentLoop->addBasicBlockToLoop(NewPH, MLI->getBase());
1958*9880d681SAndroid Build Coastguard Worker
1959*9880d681SAndroid Build Coastguard Worker // Update the dominator information with the new preheader.
1960*9880d681SAndroid Build Coastguard Worker if (MDT) {
1961*9880d681SAndroid Build Coastguard Worker MachineDomTreeNode *HDom = MDT->getNode(Header);
1962*9880d681SAndroid Build Coastguard Worker MDT->addNewBlock(NewPH, HDom->getIDom()->getBlock());
1963*9880d681SAndroid Build Coastguard Worker MDT->changeImmediateDominator(Header, NewPH);
1964*9880d681SAndroid Build Coastguard Worker }
1965*9880d681SAndroid Build Coastguard Worker
1966*9880d681SAndroid Build Coastguard Worker return NewPH;
1967*9880d681SAndroid Build Coastguard Worker }
1968