LLVM API Documentation
00001 //===---- HexagonFixupHwLoops.cpp - Fixup HW loops too far from LOOPn. ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 // The loop start address in the LOOPn instruction is encoded as a distance 00009 // from the LOOPn instruction itself. If the start address is too far from 00010 // the LOOPn instruction, the loop needs to be set up manually, i.e. via 00011 // direct transfers to SAn and LCn. 00012 // This pass will identify and convert such LOOPn instructions to a proper 00013 // form. 00014 //===----------------------------------------------------------------------===// 00015 00016 00017 #include "llvm/ADT/DenseMap.h" 00018 #include "Hexagon.h" 00019 #include "HexagonTargetMachine.h" 00020 #include "llvm/CodeGen/MachineFunction.h" 00021 #include "llvm/CodeGen/MachineFunctionPass.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/CodeGen/Passes.h" 00024 #include "llvm/CodeGen/RegisterScavenging.h" 00025 #include "llvm/PassSupport.h" 00026 #include "llvm/Target/TargetInstrInfo.h" 00027 00028 using namespace llvm; 00029 00030 namespace llvm { 00031 void initializeHexagonFixupHwLoopsPass(PassRegistry&); 00032 } 00033 00034 namespace { 00035 struct HexagonFixupHwLoops : public MachineFunctionPass { 00036 public: 00037 static char ID; 00038 00039 HexagonFixupHwLoops() : MachineFunctionPass(ID) { 00040 initializeHexagonFixupHwLoopsPass(*PassRegistry::getPassRegistry()); 00041 } 00042 00043 bool runOnMachineFunction(MachineFunction &MF) override; 00044 00045 const char *getPassName() const override { 00046 return "Hexagon Hardware Loop Fixup"; 00047 } 00048 00049 void getAnalysisUsage(AnalysisUsage &AU) const override { 00050 AU.setPreservesCFG(); 00051 MachineFunctionPass::getAnalysisUsage(AU); 00052 } 00053 00054 private: 00055 /// \brief Maximum distance between the loop instr and the basic block. 00056 /// Just an estimate. 00057 static const unsigned MAX_LOOP_DISTANCE = 200; 00058 00059 /// \brief Check the offset between each loop instruction and 00060 /// the loop basic block to determine if we can use the LOOP instruction 00061 /// or if we need to set the LC/SA registers explicitly. 00062 bool fixupLoopInstrs(MachineFunction &MF); 00063 00064 /// \brief Add the instruction to set the LC and SA registers explicitly. 00065 void convertLoopInstr(MachineFunction &MF, 00066 MachineBasicBlock::iterator &MII, 00067 RegScavenger &RS); 00068 00069 }; 00070 00071 char HexagonFixupHwLoops::ID = 0; 00072 } 00073 00074 INITIALIZE_PASS(HexagonFixupHwLoops, "hwloopsfixup", 00075 "Hexagon Hardware Loops Fixup", false, false) 00076 00077 FunctionPass *llvm::createHexagonFixupHwLoops() { 00078 return new HexagonFixupHwLoops(); 00079 } 00080 00081 00082 /// \brief Returns true if the instruction is a hardware loop instruction. 00083 static bool isHardwareLoop(const MachineInstr *MI) { 00084 return MI->getOpcode() == Hexagon::LOOP0_r || 00085 MI->getOpcode() == Hexagon::LOOP0_i; 00086 } 00087 00088 00089 bool HexagonFixupHwLoops::runOnMachineFunction(MachineFunction &MF) { 00090 bool Changed = fixupLoopInstrs(MF); 00091 return Changed; 00092 } 00093 00094 00095 /// \brief For Hexagon, if the loop label is to far from the 00096 /// loop instruction then we need to set the LC0 and SA0 registers 00097 /// explicitly instead of using LOOP(start,count). This function 00098 /// checks the distance, and generates register assignments if needed. 00099 /// 00100 /// This function makes two passes over the basic blocks. The first 00101 /// pass computes the offset of the basic block from the start. 00102 /// The second pass checks all the loop instructions. 00103 bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) { 00104 00105 // Offset of the current instruction from the start. 00106 unsigned InstOffset = 0; 00107 // Map for each basic block to it's first instruction. 00108 DenseMap<MachineBasicBlock*, unsigned> BlockToInstOffset; 00109 00110 // First pass - compute the offset of each basic block. 00111 for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); 00112 MBB != MBBe; ++MBB) { 00113 BlockToInstOffset[MBB] = InstOffset; 00114 InstOffset += (MBB->size() * 4); 00115 } 00116 00117 // Second pass - check each loop instruction to see if it needs to 00118 // be converted. 00119 InstOffset = 0; 00120 bool Changed = false; 00121 RegScavenger RS; 00122 00123 // Loop over all the basic blocks. 00124 for (MachineFunction::iterator MBB = MF.begin(), MBBe = MF.end(); 00125 MBB != MBBe; ++MBB) { 00126 InstOffset = BlockToInstOffset[MBB]; 00127 RS.enterBasicBlock(MBB); 00128 00129 // Loop over all the instructions. 00130 MachineBasicBlock::iterator MIE = MBB->end(); 00131 MachineBasicBlock::iterator MII = MBB->begin(); 00132 while (MII != MIE) { 00133 if (isHardwareLoop(MII)) { 00134 RS.forward(MII); 00135 assert(MII->getOperand(0).isMBB() && 00136 "Expect a basic block as loop operand"); 00137 int Sub = InstOffset - BlockToInstOffset[MII->getOperand(0).getMBB()]; 00138 unsigned Dist = Sub > 0 ? Sub : -Sub; 00139 if (Dist > MAX_LOOP_DISTANCE) { 00140 // Convert to explicity setting LC0 and SA0. 00141 convertLoopInstr(MF, MII, RS); 00142 MII = MBB->erase(MII); 00143 Changed = true; 00144 } else { 00145 ++MII; 00146 } 00147 } else { 00148 ++MII; 00149 } 00150 InstOffset += 4; 00151 } 00152 } 00153 00154 return Changed; 00155 } 00156 00157 00158 /// \brief convert a loop instruction to a sequence of instructions that 00159 /// set the LC0 and SA0 register explicitly. 00160 void HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF, 00161 MachineBasicBlock::iterator &MII, 00162 RegScavenger &RS) { 00163 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 00164 MachineBasicBlock *MBB = MII->getParent(); 00165 DebugLoc DL = MII->getDebugLoc(); 00166 unsigned Scratch = RS.scavengeRegister(&Hexagon::IntRegsRegClass, MII, 0); 00167 00168 // First, set the LC0 with the trip count. 00169 if (MII->getOperand(1).isReg()) { 00170 // Trip count is a register 00171 BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0) 00172 .addReg(MII->getOperand(1).getReg()); 00173 } else { 00174 // Trip count is an immediate. 00175 BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFRI), Scratch) 00176 .addImm(MII->getOperand(1).getImm()); 00177 BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0) 00178 .addReg(Scratch); 00179 } 00180 // Then, set the SA0 with the loop start address. 00181 BuildMI(*MBB, MII, DL, TII->get(Hexagon::CONST32_Label), Scratch) 00182 .addMBB(MII->getOperand(0).getMBB()); 00183 BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::SA0) 00184 .addReg(Scratch); 00185 }