| Jia Liu | b22310f | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 1 | //===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===// | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
| Jia Liu | b22310f | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 9 | // The Hexagon processor has no instructions that load or store predicate | 
| Sirish Pande | f8e5e3c | 2012-05-03 21:52:53 +0000 | [diff] [blame] | 10 | // registers directly.  So, when these registers must be spilled a general | 
|  | 11 | // purpose register must be found and the value copied to/from it from/to | 
|  | 12 | // the predicate register.  This code currently does not use the register | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 13 | // scavenger mechanism available in the allocator.  There are two registers | 
|  | 14 | // reserved to allow spilling/restoring predicate registers.  One is used to | 
|  | 15 | // hold the predicate value.  The other is used when stack frame offsets are | 
|  | 16 | // too large. | 
|  | 17 | // | 
|  | 18 | //===----------------------------------------------------------------------===// | 
|  | 19 |  | 
| Benjamin Kramer | ae87d7b | 2012-02-06 10:19:29 +0000 | [diff] [blame] | 20 | #include "HexagonTargetMachine.h" | 
|  | 21 | #include "HexagonSubtarget.h" | 
|  | 22 | #include "HexagonMachineFunctionInfo.h" | 
|  | 23 | #include "llvm/ADT/Statistic.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/LatencyPriorityQueue.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 25 | #include "llvm/CodeGen/MachineDominators.h" | 
|  | 26 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
| Benjamin Kramer | ae87d7b | 2012-02-06 10:19:29 +0000 | [diff] [blame] | 27 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 28 | #include "llvm/CodeGen/MachineLoopInfo.h" | 
|  | 29 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Benjamin Kramer | ae87d7b | 2012-02-06 10:19:29 +0000 | [diff] [blame] | 30 | #include "llvm/CodeGen/Passes.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 31 | #include "llvm/CodeGen/ScheduleHazardRecognizer.h" | 
| Benjamin Kramer | ae87d7b | 2012-02-06 10:19:29 +0000 | [diff] [blame] | 32 | #include "llvm/CodeGen/SchedulerRegistry.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 33 | #include "llvm/Target/TargetMachine.h" | 
|  | 34 | #include "llvm/Target/TargetInstrInfo.h" | 
|  | 35 | #include "llvm/Target/TargetRegisterInfo.h" | 
|  | 36 | #include "llvm/Support/Compiler.h" | 
|  | 37 | #include "llvm/Support/Debug.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 38 | #include "llvm/Support/MathExtras.h" | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 39 |  | 
|  | 40 | using namespace llvm; | 
|  | 41 |  | 
|  | 42 |  | 
|  | 43 | namespace { | 
|  | 44 |  | 
|  | 45 | class HexagonExpandPredSpillCode : public MachineFunctionPass { | 
|  | 46 | HexagonTargetMachine& QTM; | 
|  | 47 | const HexagonSubtarget &QST; | 
|  | 48 |  | 
|  | 49 | public: | 
|  | 50 | static char ID; | 
|  | 51 | HexagonExpandPredSpillCode(HexagonTargetMachine& TM) : | 
|  | 52 | MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {} | 
|  | 53 |  | 
|  | 54 | const char *getPassName() const { | 
|  | 55 | return "Hexagon Expand Predicate Spill Code"; | 
|  | 56 | } | 
|  | 57 | bool runOnMachineFunction(MachineFunction &Fn); | 
|  | 58 | }; | 
|  | 59 |  | 
|  | 60 |  | 
|  | 61 | char HexagonExpandPredSpillCode::ID = 0; | 
|  | 62 |  | 
|  | 63 |  | 
|  | 64 | bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { | 
|  | 65 |  | 
|  | 66 | const HexagonInstrInfo *TII = QTM.getInstrInfo(); | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 67 |  | 
|  | 68 | // Loop over all of the basic blocks. | 
|  | 69 | for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); | 
|  | 70 | MBBb != MBBe; ++MBBb) { | 
|  | 71 | MachineBasicBlock* MBB = MBBb; | 
|  | 72 | // Traverse the basic block. | 
|  | 73 | for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); | 
|  | 74 | ++MII) { | 
|  | 75 | MachineInstr *MI = MII; | 
|  | 76 | int Opc = MI->getOpcode(); | 
|  | 77 | if (Opc == Hexagon::STriw_pred) { | 
|  | 78 | // STriw_pred [R30], ofst, SrcReg; | 
|  | 79 | unsigned FP = MI->getOperand(0).getReg(); | 
| Benjamin Kramer | b668401 | 2011-12-27 11:41:05 +0000 | [diff] [blame] | 80 | assert(FP == QTM.getRegisterInfo()->getFrameRegister() && | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 81 | "Not a Frame Pointer, Nor a Spill Slot"); | 
|  | 82 | assert(MI->getOperand(1).isImm() && "Not an offset"); | 
|  | 83 | int Offset = MI->getOperand(1).getImm(); | 
|  | 84 | int SrcReg = MI->getOperand(2).getReg(); | 
|  | 85 | assert(Hexagon::PredRegsRegClass.contains(SrcReg) && | 
|  | 86 | "Not a predicate register"); | 
| Sirish Pande | f8e5e3c | 2012-05-03 21:52:53 +0000 | [diff] [blame] | 87 | if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) { | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 88 | if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { | 
|  | 89 | BuildMI(*MBB, MII, MI->getDebugLoc(), | 
|  | 90 | TII->get(Hexagon::CONST32_Int_Real), | 
|  | 91 | HEXAGON_RESERVED_REG_1).addImm(Offset); | 
|  | 92 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), | 
|  | 93 | HEXAGON_RESERVED_REG_1) | 
|  | 94 | .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); | 
|  | 95 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), | 
|  | 96 | HEXAGON_RESERVED_REG_2).addReg(SrcReg); | 
|  | 97 | BuildMI(*MBB, MII, MI->getDebugLoc(), | 
| Sirish Pande | f8e5e3c | 2012-05-03 21:52:53 +0000 | [diff] [blame] | 98 | TII->get(Hexagon::STriw_indexed)) | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 99 | .addReg(HEXAGON_RESERVED_REG_1) | 
|  | 100 | .addImm(0).addReg(HEXAGON_RESERVED_REG_2); | 
|  | 101 | } else { | 
|  | 102 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), | 
|  | 103 | HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); | 
|  | 104 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), | 
|  | 105 | HEXAGON_RESERVED_REG_2).addReg(SrcReg); | 
| Sirish Pande | f8e5e3c | 2012-05-03 21:52:53 +0000 | [diff] [blame] | 106 | BuildMI(*MBB, MII, MI->getDebugLoc(), | 
|  | 107 | TII->get(Hexagon::STriw_indexed)) | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 108 | .addReg(HEXAGON_RESERVED_REG_1) | 
|  | 109 | .addImm(0) | 
|  | 110 | .addReg(HEXAGON_RESERVED_REG_2); | 
|  | 111 | } | 
|  | 112 | } else { | 
|  | 113 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), | 
|  | 114 | HEXAGON_RESERVED_REG_2).addReg(SrcReg); | 
| Sirish Pande | f8e5e3c | 2012-05-03 21:52:53 +0000 | [diff] [blame] | 115 | BuildMI(*MBB, MII, MI->getDebugLoc(), | 
|  | 116 | TII->get(Hexagon::STriw_indexed)). | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 117 | addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); | 
|  | 118 | } | 
|  | 119 | MII = MBB->erase(MI); | 
|  | 120 | --MII; | 
|  | 121 | } else if (Opc == Hexagon::LDriw_pred) { | 
|  | 122 | // DstReg = LDriw_pred [R30], ofst. | 
|  | 123 | int DstReg = MI->getOperand(0).getReg(); | 
|  | 124 | assert(Hexagon::PredRegsRegClass.contains(DstReg) && | 
|  | 125 | "Not a predicate register"); | 
|  | 126 | unsigned FP = MI->getOperand(1).getReg(); | 
| Benjamin Kramer | b668401 | 2011-12-27 11:41:05 +0000 | [diff] [blame] | 127 | assert(FP == QTM.getRegisterInfo()->getFrameRegister() && | 
| Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 128 | "Not a Frame Pointer, Nor a Spill Slot"); | 
|  | 129 | assert(MI->getOperand(2).isImm() && "Not an offset"); | 
|  | 130 | int Offset = MI->getOperand(2).getImm(); | 
|  | 131 | if (!TII->isValidOffset(Hexagon::LDriw, Offset)) { | 
|  | 132 | if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { | 
|  | 133 | BuildMI(*MBB, MII, MI->getDebugLoc(), | 
|  | 134 | TII->get(Hexagon::CONST32_Int_Real), | 
|  | 135 | HEXAGON_RESERVED_REG_1).addImm(Offset); | 
|  | 136 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), | 
|  | 137 | HEXAGON_RESERVED_REG_1) | 
|  | 138 | .addReg(FP) | 
|  | 139 | .addReg(HEXAGON_RESERVED_REG_1); | 
|  | 140 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), | 
|  | 141 | HEXAGON_RESERVED_REG_2) | 
|  | 142 | .addReg(HEXAGON_RESERVED_REG_1) | 
|  | 143 | .addImm(0); | 
|  | 144 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), | 
|  | 145 | DstReg).addReg(HEXAGON_RESERVED_REG_2); | 
|  | 146 | } else { | 
|  | 147 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), | 
|  | 148 | HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); | 
|  | 149 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), | 
|  | 150 | HEXAGON_RESERVED_REG_2) | 
|  | 151 | .addReg(HEXAGON_RESERVED_REG_1) | 
|  | 152 | .addImm(0); | 
|  | 153 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), | 
|  | 154 | DstReg).addReg(HEXAGON_RESERVED_REG_2); | 
|  | 155 | } | 
|  | 156 | } else { | 
|  | 157 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), | 
|  | 158 | HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); | 
|  | 159 | BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), | 
|  | 160 | DstReg).addReg(HEXAGON_RESERVED_REG_2); | 
|  | 161 | } | 
|  | 162 | MII = MBB->erase(MI); | 
|  | 163 | --MII; | 
|  | 164 | } | 
|  | 165 | } | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 | return true; | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | } | 
|  | 172 |  | 
|  | 173 | //===----------------------------------------------------------------------===// | 
|  | 174 | //                         Public Constructor Functions | 
|  | 175 | //===----------------------------------------------------------------------===// | 
|  | 176 |  | 
|  | 177 | FunctionPass *llvm::createHexagonExpandPredSpillCode(HexagonTargetMachine &TM) { | 
|  | 178 | return new HexagonExpandPredSpillCode(TM); | 
|  | 179 | } |