LLVM API Documentation
00001 //===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===// 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 //===----------------------------------------------------------------------===// 00009 // The Hexagon processor has no instructions that load or store predicate 00010 // registers directly. So, when these registers must be spilled a general 00011 // purpose register must be found and the value copied to/from it from/to 00012 // the predicate register. This code currently does not use the register 00013 // scavenger mechanism available in the allocator. There are two registers 00014 // reserved to allow spilling/restoring predicate registers. One is used to 00015 // hold the predicate value. The other is used when stack frame offsets are 00016 // too large. 00017 // 00018 //===----------------------------------------------------------------------===// 00019 00020 #include "Hexagon.h" 00021 #include "HexagonMachineFunctionInfo.h" 00022 #include "HexagonSubtarget.h" 00023 #include "HexagonTargetMachine.h" 00024 #include "llvm/ADT/Statistic.h" 00025 #include "llvm/CodeGen/LatencyPriorityQueue.h" 00026 #include "llvm/CodeGen/MachineDominators.h" 00027 #include "llvm/CodeGen/MachineFunctionPass.h" 00028 #include "llvm/CodeGen/MachineInstrBuilder.h" 00029 #include "llvm/CodeGen/MachineLoopInfo.h" 00030 #include "llvm/CodeGen/MachineRegisterInfo.h" 00031 #include "llvm/CodeGen/Passes.h" 00032 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 00033 #include "llvm/CodeGen/SchedulerRegistry.h" 00034 #include "llvm/Support/Compiler.h" 00035 #include "llvm/Support/Debug.h" 00036 #include "llvm/Support/MathExtras.h" 00037 #include "llvm/Target/TargetInstrInfo.h" 00038 #include "llvm/Target/TargetMachine.h" 00039 #include "llvm/Target/TargetRegisterInfo.h" 00040 00041 using namespace llvm; 00042 00043 00044 namespace llvm { 00045 void initializeHexagonExpandPredSpillCodePass(PassRegistry&); 00046 } 00047 00048 00049 namespace { 00050 00051 class HexagonExpandPredSpillCode : public MachineFunctionPass { 00052 const HexagonTargetMachine& QTM; 00053 const HexagonSubtarget &QST; 00054 00055 public: 00056 static char ID; 00057 HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) : 00058 MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) { 00059 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 00060 initializeHexagonExpandPredSpillCodePass(Registry); 00061 } 00062 00063 const char *getPassName() const override { 00064 return "Hexagon Expand Predicate Spill Code"; 00065 } 00066 bool runOnMachineFunction(MachineFunction &Fn) override; 00067 }; 00068 00069 00070 char HexagonExpandPredSpillCode::ID = 0; 00071 00072 00073 bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { 00074 00075 const HexagonInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo(); 00076 00077 // Loop over all of the basic blocks. 00078 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 00079 MBBb != MBBe; ++MBBb) { 00080 MachineBasicBlock* MBB = MBBb; 00081 // Traverse the basic block. 00082 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 00083 ++MII) { 00084 MachineInstr *MI = MII; 00085 int Opc = MI->getOpcode(); 00086 if (Opc == Hexagon::STriw_pred) { 00087 // STriw_pred [R30], ofst, SrcReg; 00088 unsigned FP = MI->getOperand(0).getReg(); 00089 assert( 00090 FP == 00091 QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() && 00092 "Not a Frame Pointer, Nor a Spill Slot"); 00093 assert(MI->getOperand(1).isImm() && "Not an offset"); 00094 int Offset = MI->getOperand(1).getImm(); 00095 int SrcReg = MI->getOperand(2).getReg(); 00096 assert(Hexagon::PredRegsRegClass.contains(SrcReg) && 00097 "Not a predicate register"); 00098 if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) { 00099 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 00100 BuildMI(*MBB, MII, MI->getDebugLoc(), 00101 TII->get(Hexagon::CONST32_Int_Real), 00102 HEXAGON_RESERVED_REG_1).addImm(Offset); 00103 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 00104 HEXAGON_RESERVED_REG_1) 00105 .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); 00106 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 00107 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 00108 BuildMI(*MBB, MII, MI->getDebugLoc(), 00109 TII->get(Hexagon::STriw_indexed)) 00110 .addReg(HEXAGON_RESERVED_REG_1) 00111 .addImm(0).addReg(HEXAGON_RESERVED_REG_2); 00112 } else { 00113 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 00114 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 00115 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 00116 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 00117 BuildMI(*MBB, MII, MI->getDebugLoc(), 00118 TII->get(Hexagon::STriw_indexed)) 00119 .addReg(HEXAGON_RESERVED_REG_1) 00120 .addImm(0) 00121 .addReg(HEXAGON_RESERVED_REG_2); 00122 } 00123 } else { 00124 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 00125 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 00126 BuildMI(*MBB, MII, MI->getDebugLoc(), 00127 TII->get(Hexagon::STriw_indexed)). 00128 addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); 00129 } 00130 MII = MBB->erase(MI); 00131 --MII; 00132 } else if (Opc == Hexagon::LDriw_pred) { 00133 // DstReg = LDriw_pred [R30], ofst. 00134 int DstReg = MI->getOperand(0).getReg(); 00135 assert(Hexagon::PredRegsRegClass.contains(DstReg) && 00136 "Not a predicate register"); 00137 unsigned FP = MI->getOperand(1).getReg(); 00138 assert( 00139 FP == 00140 QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() && 00141 "Not a Frame Pointer, Nor a Spill Slot"); 00142 assert(MI->getOperand(2).isImm() && "Not an offset"); 00143 int Offset = MI->getOperand(2).getImm(); 00144 if (!TII->isValidOffset(Hexagon::LDriw, Offset)) { 00145 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 00146 BuildMI(*MBB, MII, MI->getDebugLoc(), 00147 TII->get(Hexagon::CONST32_Int_Real), 00148 HEXAGON_RESERVED_REG_1).addImm(Offset); 00149 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 00150 HEXAGON_RESERVED_REG_1) 00151 .addReg(FP) 00152 .addReg(HEXAGON_RESERVED_REG_1); 00153 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 00154 HEXAGON_RESERVED_REG_2) 00155 .addReg(HEXAGON_RESERVED_REG_1) 00156 .addImm(0); 00157 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 00158 DstReg).addReg(HEXAGON_RESERVED_REG_2); 00159 } else { 00160 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 00161 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 00162 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 00163 HEXAGON_RESERVED_REG_2) 00164 .addReg(HEXAGON_RESERVED_REG_1) 00165 .addImm(0); 00166 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 00167 DstReg).addReg(HEXAGON_RESERVED_REG_2); 00168 } 00169 } else { 00170 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 00171 HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); 00172 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 00173 DstReg).addReg(HEXAGON_RESERVED_REG_2); 00174 } 00175 MII = MBB->erase(MI); 00176 --MII; 00177 } 00178 } 00179 } 00180 00181 return true; 00182 } 00183 00184 } 00185 00186 //===----------------------------------------------------------------------===// 00187 // Public Constructor Functions 00188 //===----------------------------------------------------------------------===// 00189 00190 static void initializePassOnce(PassRegistry &Registry) { 00191 const char *Name = "Hexagon Expand Predicate Spill Code"; 00192 PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred", 00193 &HexagonExpandPredSpillCode::ID, 00194 nullptr, false, false); 00195 Registry.registerPass(*PI, true); 00196 } 00197 00198 void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) { 00199 CALL_ONCE_INITIALIZATION(initializePassOnce) 00200 } 00201 00202 FunctionPass* 00203 llvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) { 00204 return new HexagonExpandPredSpillCode(TM); 00205 }