1b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===-- HexagonHardwareLoops.cpp - Identify and generate hardware loops ---===//
2b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
3b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//                     The LLVM Compiler Infrastructure
4b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
5b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This file is distributed under the University of Illinois Open Source
6b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// License. See LICENSE.TXT for details.
7b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
8b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
9b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
10b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// This pass identifies loops where we can generate the Hexagon hardware
11b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// loop instruction.  The hardware loop can perform loop branches with a
12b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// zero-cycle overhead.
13b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
14b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// The pattern that defines the induction variable can changed depending on
15b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// prior optimizations.  For example, the IndVarSimplify phase run by 'opt'
16b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// normalizes induction variables, and the Loop Strength Reduction pass
17b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// run by 'llc' may also make changes to the induction variable.
18b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// The pattern detected by this phase is due to running Strength Reduction.
19b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
20b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum// Criteria for hardware loops:
21b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//  - Countable loops (w/ ind. var for a trip count)
22b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//  - Assumes loops are normalized by IndVarSimplify
23b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//  - Try inner-most loops first
24b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//  - No nested hardware loops.
25b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//  - No function calls in loops.
26b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//
27b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum//===----------------------------------------------------------------------===//
28b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
29b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#define DEBUG_TYPE "hwloops"
3079aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "Hexagon.h"
3179aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#include "HexagonTargetMachine.h"
32b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Constants.h"
33b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/PassSupport.h"
34b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/ADT/DenseMap.h"
35b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/ADT/Statistic.h"
36b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/Passes.h"
37b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineDominators.h"
38b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunction.h"
39b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineFunctionPass.h"
40b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineInstrBuilder.h"
41b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineLoopInfo.h"
42b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/MachineRegisterInfo.h"
43b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/CodeGen/RegisterScavenging.h"
44b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/Debug.h"
45b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Support/raw_ostream.h"
46b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include "llvm/Target/TargetInstrInfo.h"
47b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum#include <algorithm>
48b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
49b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumusing namespace llvm;
50b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
51b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumSTATISTIC(NumHWLoops, "Number of loops converted to hardware loops");
52b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
53b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumnamespace {
54b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  class CountValue;
55b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  struct HexagonHardwareLoops : public MachineFunctionPass {
56b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineLoopInfo       *MLI;
57b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineRegisterInfo   *MRI;
58b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetInstrInfo *TII;
59b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
60b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  public:
61b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    static char ID;   // Pass identification, replacement for typeid
62b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
63b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    HexagonHardwareLoops() : MachineFunctionPass(ID) {}
64b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
65b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual bool runOnMachineFunction(MachineFunction &MF);
66b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
67b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const char *getPassName() const { return "Hexagon Hardware Loops"; }
68b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
69b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
70b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.setPreservesCFG();
71b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.addRequired<MachineDominatorTree>();
72b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.addPreserved<MachineDominatorTree>();
73b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.addRequired<MachineLoopInfo>();
74b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.addPreserved<MachineLoopInfo>();
75b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MachineFunctionPass::getAnalysisUsage(AU);
76b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
77b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
78b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  private:
79b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// getCanonicalInductionVariable - Check to see if the loop has a canonical
80b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// induction variable.
81b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// Should be defined in MachineLoop. Based upon version in class Loop.
82b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const MachineInstr *getCanonicalInductionVariable(MachineLoop *L) const;
83b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
84b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// getTripCount - Return a loop-invariant LLVM register indicating the
85b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// number of times the loop will be executed.  If the trip-count cannot
86b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// be determined, this return null.
87b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CountValue *getTripCount(MachineLoop *L) const;
88b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
89b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// isInductionOperation - Return true if the instruction matches the
90b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// pattern for an opertion that defines an induction variable.
91b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isInductionOperation(const MachineInstr *MI, unsigned IVReg) const;
92b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
93b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// isInvalidOperation - Return true if the instruction is not valid within
94b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// a hardware loop.
95b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isInvalidLoopOperation(const MachineInstr *MI) const;
96b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
97b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// containsInavlidInstruction - Return true if the loop contains an
98b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// instruction that inhibits using the hardware loop.
99b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool containsInvalidInstruction(MachineLoop *L) const;
100b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
101b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// converToHardwareLoop - Given a loop, check if we can convert it to a
102b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// hardware loop.  If so, then perform the conversion and return true.
103b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool convertToHardwareLoop(MachineLoop *L);
104b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
105b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
106b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
107b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  char HexagonHardwareLoops::ID = 0;
108b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
109b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
110b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // CountValue class - Abstraction for a trip count of a loop. A
111b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // smaller vesrsion of the MachineOperand class without the concerns
112b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // of changing the operand representation.
113b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  class CountValue {
114b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  public:
115b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    enum CountValueType {
116b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      CV_Register,
117b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      CV_Immediate
118b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    };
119b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  private:
120b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CountValueType Kind;
121b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    union Values {
122b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned RegNum;
123b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      int64_t ImmVal;
124b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Values(unsigned r) : RegNum(r) {}
125b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Values(int64_t i) : ImmVal(i) {}
126b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    } Contents;
127b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isNegative;
128b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
129b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  public:
130b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CountValue(unsigned r, bool neg) : Kind(CV_Register), Contents(r),
131b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                       isNegative(neg) {}
132b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    explicit CountValue(int64_t i) : Kind(CV_Immediate), Contents(i),
133b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                     isNegative(i < 0) {}
134b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    CountValueType getType() const { return Kind; }
135b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isReg() const { return Kind == CV_Register; }
136b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isImm() const { return Kind == CV_Immediate; }
137b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool isNeg() const { return isNegative; }
138b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
139b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned getReg() const {
140b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(isReg() && "Wrong CountValue accessor");
141b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return Contents.RegNum;
142b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
143b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void setReg(unsigned Val) {
144b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Contents.RegNum = Val;
145b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
146b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int64_t getImm() const {
147b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(isImm() && "Wrong CountValue accessor");
148b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (isNegative) {
149b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        return -Contents.ImmVal;
150b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
151b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return Contents.ImmVal;
152b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
153b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void setImm(int64_t Val) {
154b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Contents.ImmVal = Val;
155b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
156b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
157b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void print(raw_ostream &OS, const TargetMachine *TM = 0) const {
158b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (isReg()) { OS << PrintReg(getReg()); }
159b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (isImm()) { OS << getImm(); }
160b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
161b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
162b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
163b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  struct HexagonFixupHwLoops : public MachineFunctionPass {
164b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  public:
165b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    static char ID;     // Pass identification, replacement for typeid.
166b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
167b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    HexagonFixupHwLoops() : MachineFunctionPass(ID) {}
168b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
169b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual bool runOnMachineFunction(MachineFunction &MF);
170b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
171b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const char *getPassName() const { return "Hexagon Hardware Loop Fixup"; }
172b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
173b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
174b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      AU.setPreservesCFG();
175b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MachineFunctionPass::getAnalysisUsage(AU);
176b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
177b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
178b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  private:
179b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// Maximum distance between the loop instr and the basic block.
180b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// Just an estimate.
181b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    static const unsigned MAX_LOOP_DISTANCE = 200;
182b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
183b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// fixupLoopInstrs - Check the offset between each loop instruction and
184b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// the loop basic block to determine if we can use the LOOP instruction
185b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// or if we need to set the LC/SA registers explicitly.
186b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    bool fixupLoopInstrs(MachineFunction &MF);
187b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
188b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// convertLoopInstr - Add the instruction to set the LC and SA registers
189b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    /// explicitly.
190b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    void convertLoopInstr(MachineFunction &MF,
191b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          MachineBasicBlock::iterator &MII,
192b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                          RegScavenger &RS);
193b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
194b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  };
195b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
196b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  char HexagonFixupHwLoops::ID = 0;
197b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
198b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum} // end anonymous namespace
199b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
200b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
201b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isHardwareLoop - Returns true if the instruction is a hardware loop
202b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// instruction.
203b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool isHardwareLoop(const MachineInstr *MI) {
204b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return MI->getOpcode() == Hexagon::LOOP0_r ||
205b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MI->getOpcode() == Hexagon::LOOP0_i;
206b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
207b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
208b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isCompareEquals - Returns true if the instruction is a compare equals
209b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// instruction with an immediate operand.
210b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumstatic bool isCompareEqualsImm(const MachineInstr *MI) {
211b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return MI->getOpcode() == Hexagon::CMPEQri;
212b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
213b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
214b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
215b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// createHexagonHardwareLoops - Factory for creating
216b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// the hardware loop phase.
217b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumFunctionPass *llvm::createHexagonHardwareLoops() {
218b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return new HexagonHardwareLoops();
219b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
220b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
221b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
222b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) {
223b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DEBUG(dbgs() << "********* Hexagon Hardware Loops *********\n");
224b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
225b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool Changed = false;
226b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
227b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // get the loop information
228b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MLI = &getAnalysis<MachineLoopInfo>();
229b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // get the register information
230b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MRI = &MF.getRegInfo();
231b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // the target specific instructio info.
232b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  TII = MF.getTarget().getInstrInfo();
233b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
234b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end();
235b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       I != E; ++I) {
236b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineLoop *L = *I;
237b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!L->getParentLoop()) {
238b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      Changed |= convertToHardwareLoop(L);
239b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
240b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
241b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
242b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Changed;
243b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
244b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
245b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// getCanonicalInductionVariable - Check to see if the loop has a canonical
246b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// induction variable. We check for a simple recurrence pattern - an
247b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// integer recurrence that decrements by one each time through the loop and
248b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// ends at zero.  If so, return the phi node that corresponds to it.
249b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
250b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// Based upon the similar code in LoopInfo except this code is specific to
251b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// the machine.
252b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// This method assumes that the IndVarSimplify pass has been run by 'opt'.
253b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
254b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumconst MachineInstr
255b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum*HexagonHardwareLoops::getCanonicalInductionVariable(MachineLoop *L) const {
256b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *TopMBB = L->getTopBlock();
257b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::pred_iterator PI = TopMBB->pred_begin();
258b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  assert(PI != TopMBB->pred_end() &&
259b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         "Loop must have more than one incoming edge!");
260b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *Backedge = *PI++;
261b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (PI == TopMBB->pred_end()) return 0;  // dead loop
262b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *Incoming = *PI++;
263b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (PI != TopMBB->pred_end()) return 0;  // multiple backedges?
264b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
265b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // make sure there is one incoming and one backedge and determine which
266b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // is which.
267b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (L->contains(Incoming)) {
268b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (L->contains(Backedge))
269b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return 0;
270b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    std::swap(Incoming, Backedge);
271b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else if (!L->contains(Backedge))
272b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return 0;
273b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
274b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Loop over all of the PHI nodes, looking for a canonical induction variable:
275b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //   - The PHI node is "reg1 = PHI reg2, BB1, reg3, BB2".
276b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //   - The recurrence comes from the backedge.
277b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //   - the definition is an induction operatio.n
278b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (MachineBasicBlock::iterator I = TopMBB->begin(), E = TopMBB->end();
279b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       I != E && I->isPHI(); ++I) {
280b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const MachineInstr *MPhi = &*I;
281b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned DefReg = MPhi->getOperand(0).getReg();
282b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) {
283b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      // Check each operand for the value from the backedge.
284b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MachineBasicBlock *MBB = MPhi->getOperand(i+1).getMBB();
285b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (L->contains(MBB)) { // operands comes from the backedge
286b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // Check if the definition is an induction operation.
287b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        const MachineInstr *DI = MRI->getVRegDef(MPhi->getOperand(i).getReg());
288b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        if (isInductionOperation(DI, DefReg)) {
289b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          return MPhi;
290b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        }
291b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
292b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
293b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
294b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return 0;
295b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
296b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
297b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// getTripCount - Return a loop-invariant LLVM value indicating the
298b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// number of times the loop will be executed.  The trip count can
299b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// be either a register or a constant value.  If the trip-count
300b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// cannot be determined, this returns null.
301b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
302b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// We find the trip count from the phi instruction that defines the
303b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// induction variable.  We follow the links to the CMP instruction
304b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// to get the trip count.
305b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
306b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// Based upon getTripCount in LoopInfo.
307b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
308b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumCountValue *HexagonHardwareLoops::getTripCount(MachineLoop *L) const {
309b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Check that the loop has a induction variable.
310b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineInstr *IV_Inst = getCanonicalInductionVariable(L);
311b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (IV_Inst == 0) return 0;
312b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
313b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Canonical loops will end with a 'cmpeq_ri IV, Imm',
314b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  if Imm is 0, get the count from the PHI opnd
315b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  if Imm is -M, than M is the count
316b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  Otherwise, Imm is the count
317b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand *IV_Opnd;
318b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const MachineOperand *InitialValue;
319b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (!L->contains(IV_Inst->getOperand(2).getMBB())) {
320b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InitialValue = &IV_Inst->getOperand(1);
321b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    IV_Opnd = &IV_Inst->getOperand(3);
322b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
323b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InitialValue = &IV_Inst->getOperand(3);
324b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    IV_Opnd = &IV_Inst->getOperand(1);
325b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
326b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
327b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Look for the cmp instruction to determine if we
328b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // can get a useful trip count.  The trip count can
329b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // be either a register or an immediate.  The location
330b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // of the value depends upon the type (reg or imm).
331b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  while ((IV_Opnd = IV_Opnd->getNextOperandForReg())) {
332b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const MachineInstr *MI = IV_Opnd->getParent();
333b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (L->contains(MI) && isCompareEqualsImm(MI)) {
334b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineOperand &MO = MI->getOperand(2);
335b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(MO.isImm() && "IV Cmp Operand should be 0");
336b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      int64_t ImmVal = MO.getImm();
337b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
338b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineInstr *IV_DefInstr = MRI->getVRegDef(IV_Opnd->getReg());
339b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      assert(L->contains(IV_DefInstr->getParent()) &&
340b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum             "IV definition should occurs in loop");
341b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      int64_t iv_value = IV_DefInstr->getOperand(2).getImm();
342b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
343b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (ImmVal == 0) {
344b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        // Make sure the induction variable changes by one on each iteration.
345b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        if (iv_value != 1 && iv_value != -1) {
346b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          return 0;
347b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        }
348b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        return new CountValue(InitialValue->getReg(), iv_value > 0);
349b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
350b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        assert(InitialValue->isReg() && "Expecting register for init value");
351b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        const MachineInstr *DefInstr = MRI->getVRegDef(InitialValue->getReg());
352b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        if (DefInstr && DefInstr->getOpcode() == Hexagon::TFRI) {
353b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          int64_t count = ImmVal - DefInstr->getOperand(1).getImm();
354b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          if ((count % iv_value) != 0) {
355b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            return 0;
356b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          }
357b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          return new CountValue(count/iv_value);
358b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        }
359b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
360b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
361b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
362b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return 0;
363b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
364b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
365b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isInductionOperation - return true if the operation is matches the
366b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// pattern that defines an induction variable:
367b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///    add iv, c
368b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
369b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool
370b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonHardwareLoops::isInductionOperation(const MachineInstr *MI,
371b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           unsigned IVReg) const {
372b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return (MI->getOpcode() ==
373b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          Hexagon::ADD_ri && MI->getOperand(1).getReg() == IVReg);
374b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
375b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
376b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// isInvalidOperation - Return true if the operation is invalid within
377b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// hardware loop.
378b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool
379b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumHexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI) const {
380b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
381b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // call is not allowed because the callee may use a hardware loop
382b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MI->getDesc().isCall()) {
383b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return true;
384b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
385b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // do not allow nested hardware loops
386b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (isHardwareLoop(MI)) {
387b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return true;
388b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
389b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // check if the instruction defines a hardware loop register
390b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
391b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const MachineOperand &MO = MI->getOperand(i);
392b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (MO.isReg() && MO.isDef() &&
393b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        (MO.getReg() == Hexagon::LC0 || MO.getReg() == Hexagon::LC1 ||
394b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum         MO.getReg() == Hexagon::SA0 || MO.getReg() == Hexagon::SA0)) {
395b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return true;
396b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
397b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
398b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
399b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
400b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
401b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// containsInvalidInstruction - Return true if the loop contains
402b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// an instruction that inhibits the use of the hardware loop function.
403b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
404b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L) const {
405b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const std::vector<MachineBasicBlock*> Blocks = L->getBlocks();
406b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (unsigned i = 0, e = Blocks.size(); i != e; ++i) {
407b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock *MBB = Blocks[i];
408b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    for (MachineBasicBlock::iterator
409b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum           MII = MBB->begin(), E = MBB->end(); MII != E; ++MII) {
410b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      const MachineInstr *MI = &*MII;
411b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (isInvalidLoopOperation(MI)) {
412b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        return true;
413b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
414b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
415b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
416b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return false;
417b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
418b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
419b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// converToHardwareLoop - check if the loop is a candidate for
420b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// converting to a hardware loop.  If so, then perform the
421b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// transformation.
422b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
423b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// This function works on innermost loops first.  A loop can
424b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// be converted if it is a counting loop; either a register
425b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// value or an immediate.
426b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
427b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// The code makes several assumptions about the representation
428b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// of the loop in llvm.
429b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
430b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool Changed = false;
431b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Process nested loops first.
432b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I) {
433b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    Changed |= convertToHardwareLoop(*I);
434b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
435b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // If a nested loop has been converted, then we can't convert this loop.
436b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Changed) {
437b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return Changed;
438b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
439b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Are we able to determine the trip count for the loop?
440b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  CountValue *TripCount = getTripCount(L);
441b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (TripCount == 0) {
442b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
443b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
444b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Does the loop contain any invalid instructions?
445b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (containsInvalidInstruction(L)) {
446b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
447b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
448b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *Preheader = L->getLoopPreheader();
449b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // No preheader means there's not place for the loop instr.
450b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (Preheader == 0) {
451b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
452b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
453b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator InsertPos = Preheader->getFirstTerminator();
454b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
455b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *LastMBB = L->getExitingBlock();
456b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Don't generate hw loop if the loop has more than one exit.
457b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (LastMBB == 0) {
458b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    return false;
459b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
460b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock::iterator LastI = LastMBB->getFirstTerminator();
461b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
462b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Determine the loop start.
463b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *LoopStart = L->getTopBlock();
464b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (L->getLoopLatch() != LastMBB) {
465b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // When the exit and latch are not the same, use the latch block as the
466b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // start.
467b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // The loop start address is used only after the 1st iteration, and the loop
468b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // latch may contains instrs. that need to be executed after the 1st iter.
469b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    LoopStart = L->getLoopLatch();
470b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Make sure the latch is a successor of the exit, otherwise it won't work.
471b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!LastMBB->isSuccessor(LoopStart)) {
472b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      return false;
473b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
474b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
475b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
476b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Convert the loop to a hardware loop
477b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DEBUG(dbgs() << "Change to hardware loop at "; L->dump());
478b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
479b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (TripCount->isReg()) {
480b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Create a copy of the loop count register.
481b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineFunction *MF = LastMBB->getParent();
482b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    const TargetRegisterClass *RC =
483b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      MF->getRegInfo().getRegClass(TripCount->getReg());
484b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    unsigned CountReg = MF->getRegInfo().createVirtualRegister(RC);
485b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
486b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            TII->get(TargetOpcode::COPY), CountReg).addReg(TripCount->getReg());
487b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (TripCount->isNeg()) {
488b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      unsigned CountReg1 = CountReg;
489b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      CountReg = MF->getRegInfo().createVirtualRegister(RC);
490b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
491b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum              TII->get(Hexagon::NEG), CountReg).addReg(CountReg1);
492b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
493b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
494b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Add the Loop instruction to the begining of the loop.
495b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
496b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            TII->get(Hexagon::LOOP0_r)).addMBB(LoopStart).addReg(CountReg);
497b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
498b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    assert(TripCount->isImm() && "Expecting immedate vaule for trip count");
499b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Add the Loop immediate instruction to the beginning of the loop.
500b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    int64_t CountImm = TripCount->getImm();
501b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*Preheader, InsertPos, InsertPos->getDebugLoc(),
502b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum            TII->get(Hexagon::LOOP0_i)).addMBB(LoopStart).addImm(CountImm);
503b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
504b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
505b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Make sure the loop start always has a reference in the CFG.  We need to
506b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // create a BlockAddress operand to get this mechanism to work both the
507b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // MachineBasicBlock and BasicBlock objects need the flag set.
508b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  LoopStart->setHasAddressTaken();
509b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // This line is needed to set the hasAddressTaken flag on the BasicBlock
510b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // object
511b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  BlockAddress::get(const_cast<BasicBlock *>(LoopStart->getBasicBlock()));
512b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
513b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Replace the loop branch with an endloop instruction.
514b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DebugLoc dl = LastI->getDebugLoc();
515b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  BuildMI(*LastMBB, LastI, dl, TII->get(Hexagon::ENDLOOP0)).addMBB(LoopStart);
516b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
517b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // The loop ends with either:
518b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  - a conditional branch followed by an unconditional branch, or
519b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  //  - a conditional branch to the loop start.
520ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande  if (LastI->getOpcode() == Hexagon::JMP_c ||
521ab7955b9ce3197215406bc9fc97b22074127d035Sirish Pande      LastI->getOpcode() == Hexagon::JMP_cNot) {
522b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // delete one and change/add an uncond. branch to out of the loop
523b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
524b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    LastI = LastMBB->erase(LastI);
525b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    if (!L->contains(BranchTarget)) {
526b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (LastI != LastMBB->end()) {
527b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        TII->RemoveBranch(*LastMBB);
528b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
529b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      SmallVector<MachineOperand, 0> Cond;
530b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      TII->InsertBranch(*LastMBB, BranchTarget, 0, Cond, dl);
531b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
532b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
533b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Conditional branch to loop start; just delete it.
534b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    LastMBB->erase(LastI);
535b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
536b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  delete TripCount;
537b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
538b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  ++NumHWLoops;
539b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return true;
540b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
541b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
542b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// createHexagonFixupHwLoops - Factory for creating the hardware loop
543b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// phase.
544b4b54153ad760c69a00a08531abef4ed434a5092Tony LinthicumFunctionPass *llvm::createHexagonFixupHwLoops() {
545b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return new HexagonFixupHwLoops();
546b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
547b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
548b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFixupHwLoops::runOnMachineFunction(MachineFunction &MF) {
549b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DEBUG(dbgs() << "****** Hexagon Hardware Loop Fixup ******\n");
550b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
551b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool Changed = fixupLoopInstrs(MF);
552b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Changed;
553b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
554b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
555b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// fixupLoopInsts - For Hexagon, if the loop label is to far from the
556b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// loop instruction then we need to set the LC0 and SA0 registers
557b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// explicitly instead of using LOOP(start,count).  This function
558b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// checks the distance, and generates register assignments if needed.
559b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum///
560b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// This function makes two passes over the basic blocks.  The first
561b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// pass computes the offset of the basic block from the start.
562b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// The second pass checks all the loop instructions.
563b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumbool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
564b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
565b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Offset of the current instruction from the start.
566b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned InstOffset = 0;
567b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Map for each basic block to it's first instruction.
568b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DenseMap<MachineBasicBlock*, unsigned> BlockToInstOffset;
569b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
570b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // First pass - compute the offset of each basic block.
571b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end();
572b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       MBB != MBBe; ++MBB) {
573b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BlockToInstOffset[MBB] = InstOffset;
574b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InstOffset += (MBB->size() * 4);
575b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
576b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
577b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Second pass - check each loop instruction to see if it needs to
578b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // be converted.
579b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  InstOffset = 0;
580b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  bool Changed = false;
581b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  RegScavenger RS;
582b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
583b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Loop over all the basic blocks.
584b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end();
585b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum       MBB != MBBe; ++MBB) {
586b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    InstOffset = BlockToInstOffset[MBB];
587b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    RS.enterBasicBlock(MBB);
588b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
589b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Loop over all the instructions.
590b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock::iterator MIE = MBB->end();
591b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    MachineBasicBlock::iterator MII = MBB->begin();
592b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    while (MII != MIE) {
593b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      if (isHardwareLoop(MII)) {
594b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        RS.forward(MII);
595b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        assert(MII->getOperand(0).isMBB() &&
596b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum               "Expect a basic block as loop operand");
597b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        int diff = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()];
598b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        diff = (diff > 0 ? diff : -diff);
599b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        if ((unsigned)diff > MAX_LOOP_DISTANCE) {
600b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          // Convert to explicity setting LC0 and SA0.
601b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          convertLoopInstr(MF, MII, RS);
602b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          MII = MBB->erase(MII);
603b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          Changed = true;
604b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        } else {
605b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum          ++MII;
606b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        }
607b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      } else {
608b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum        ++MII;
609b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      }
610b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      InstOffset += 4;
611b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    }
612b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
613b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
614b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  return Changed;
615b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
616b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
617b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
618b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// convertLoopInstr - convert a loop instruction to a sequence of instructions
619b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum/// that set the lc and sa register explicitly.
620b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicumvoid HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF,
621b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           MachineBasicBlock::iterator &MII,
622b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum                                           RegScavenger &RS) {
623b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
624b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  MachineBasicBlock *MBB = MII->getParent();
625b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  DebugLoc DL = MII->getDebugLoc();
626b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  unsigned Scratch = RS.scavengeRegister(Hexagon::IntRegsRegisterClass, MII, 0);
627b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum
628b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // First, set the LC0 with the trip count.
629b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  if (MII->getOperand(1).isReg()) {
630b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Trip count is a register
631b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0)
632b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      .addReg(MII->getOperand(1).getReg());
633b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  } else {
634b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    // Trip count is an immediate.
635b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFRI), Scratch)
636b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      .addImm(MII->getOperand(1).getImm());
637b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0)
638b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum      .addReg(Scratch);
639b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  }
640b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  // Then, set the SA0 with the loop start address.
641b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  BuildMI(*MBB, MII, DL, TII->get(Hexagon::CONST32_Label), Scratch)
642b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum    .addMBB(MII->getOperand(0).getMBB());
643b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum  BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::SA0).addReg(Scratch);
644b4b54153ad760c69a00a08531abef4ed434a5092Tony Linthicum}
645