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