| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 1 | //===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===// | 
|  | 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 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // This pass replaces transfer instructions by combine instructions. | 
|  | 10 | // We walk along a basic block and look for two combinable instructions and try | 
|  | 11 | // to move them together. If we can move them next to each other we do so and | 
|  | 12 | // replace them with a combine instruction. | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 | #define DEBUG_TYPE "hexagon-copy-combine" | 
|  | 15 |  | 
|  | 16 | #include "llvm/PassSupport.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 17 | #include "Hexagon.h" | 
|  | 18 | #include "HexagonInstrInfo.h" | 
|  | 19 | #include "HexagonMachineFunctionInfo.h" | 
|  | 20 | #include "HexagonRegisterInfo.h" | 
|  | 21 | #include "HexagonSubtarget.h" | 
|  | 22 | #include "HexagonTargetMachine.h" | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 23 | #include "llvm/ADT/DenseMap.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/DenseSet.h" | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 25 | #include "llvm/CodeGen/MachineBasicBlock.h" | 
|  | 26 | #include "llvm/CodeGen/MachineFunction.h" | 
|  | 27 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
|  | 28 | #include "llvm/CodeGen/MachineInstr.h" | 
|  | 29 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 30 | #include "llvm/CodeGen/Passes.h" | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 31 | #include "llvm/Support/CodeGen.h" | 
|  | 32 | #include "llvm/Support/CommandLine.h" | 
|  | 33 | #include "llvm/Support/Debug.h" | 
|  | 34 | #include "llvm/Support/raw_ostream.h" | 
| Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 35 | #include "llvm/Target/TargetRegisterInfo.h" | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 36 |  | 
|  | 37 | using namespace llvm; | 
|  | 38 |  | 
|  | 39 | static | 
|  | 40 | cl::opt<bool> IsCombinesDisabled("disable-merge-into-combines", | 
|  | 41 | cl::Hidden, cl::ZeroOrMore, | 
|  | 42 | cl::init(false), | 
|  | 43 | cl::desc("Disable merging into combines")); | 
|  | 44 | static | 
|  | 45 | cl::opt<unsigned> | 
|  | 46 | MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", | 
|  | 47 | cl::Hidden, cl::init(4), | 
|  | 48 | cl::desc("Maximum distance between a tfr feeding a store we " | 
|  | 49 | "consider the store still to be newifiable")); | 
|  | 50 |  | 
|  | 51 | namespace llvm { | 
|  | 52 | void initializeHexagonCopyToCombinePass(PassRegistry&); | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 |  | 
|  | 56 | namespace { | 
|  | 57 |  | 
|  | 58 | class HexagonCopyToCombine : public MachineFunctionPass  { | 
|  | 59 | const HexagonInstrInfo *TII; | 
|  | 60 | const TargetRegisterInfo *TRI; | 
|  | 61 | bool ShouldCombineAggressively; | 
|  | 62 |  | 
|  | 63 | DenseSet<MachineInstr *> PotentiallyNewifiableTFR; | 
|  | 64 | public: | 
|  | 65 | static char ID; | 
|  | 66 |  | 
|  | 67 | HexagonCopyToCombine() : MachineFunctionPass(ID) { | 
|  | 68 | initializeHexagonCopyToCombinePass(*PassRegistry::getPassRegistry()); | 
|  | 69 | } | 
|  | 70 |  | 
|  | 71 | virtual void getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 72 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | const char *getPassName() const { | 
|  | 76 | return "Hexagon Copy-To-Combine Pass"; | 
|  | 77 | } | 
|  | 78 |  | 
|  | 79 | virtual bool runOnMachineFunction(MachineFunction &Fn); | 
|  | 80 |  | 
|  | 81 | private: | 
|  | 82 | MachineInstr *findPairable(MachineInstr *I1, bool &DoInsertAtI1); | 
|  | 83 |  | 
|  | 84 | void findPotentialNewifiableTFRs(MachineBasicBlock &); | 
|  | 85 |  | 
|  | 86 | void combine(MachineInstr *I1, MachineInstr *I2, | 
|  | 87 | MachineBasicBlock::iterator &MI, bool DoInsertAtI1); | 
|  | 88 |  | 
|  | 89 | bool isSafeToMoveTogether(MachineInstr *I1, MachineInstr *I2, | 
|  | 90 | unsigned I1DestReg, unsigned I2DestReg, | 
|  | 91 | bool &DoInsertAtI1); | 
|  | 92 |  | 
|  | 93 | void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg, | 
|  | 94 | MachineOperand &HiOperand, MachineOperand &LoOperand); | 
|  | 95 |  | 
|  | 96 | void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg, | 
|  | 97 | MachineOperand &HiOperand, MachineOperand &LoOperand); | 
|  | 98 |  | 
|  | 99 | void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg, | 
|  | 100 | MachineOperand &HiOperand, MachineOperand &LoOperand); | 
|  | 101 |  | 
|  | 102 | void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg, | 
|  | 103 | MachineOperand &HiOperand, MachineOperand &LoOperand); | 
|  | 104 | }; | 
|  | 105 |  | 
|  | 106 | } // End anonymous namespace. | 
|  | 107 |  | 
|  | 108 | char HexagonCopyToCombine::ID = 0; | 
|  | 109 |  | 
|  | 110 | INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine", | 
|  | 111 | "Hexagon Copy-To-Combine Pass", false, false) | 
|  | 112 |  | 
|  | 113 | static bool isCombinableInstType(MachineInstr *MI, | 
|  | 114 | const HexagonInstrInfo *TII, | 
|  | 115 | bool ShouldCombineAggressively) { | 
|  | 116 | switch(MI->getOpcode()) { | 
|  | 117 | case Hexagon::TFR: { | 
|  | 118 | // A COPY instruction can be combined if its arguments are IntRegs (32bit). | 
|  | 119 | assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg()); | 
|  | 120 |  | 
|  | 121 | unsigned DestReg = MI->getOperand(0).getReg(); | 
|  | 122 | unsigned SrcReg = MI->getOperand(1).getReg(); | 
|  | 123 | return Hexagon::IntRegsRegClass.contains(DestReg) && | 
|  | 124 | Hexagon::IntRegsRegClass.contains(SrcReg); | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | case Hexagon::TFRI: { | 
|  | 128 | // A transfer-immediate can be combined if its argument is a signed 8bit | 
|  | 129 | // value. | 
|  | 130 | assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); | 
|  | 131 | unsigned DestReg = MI->getOperand(0).getReg(); | 
|  | 132 |  | 
|  | 133 | // Only combine constant extended TFRI if we are in aggressive mode. | 
|  | 134 | return Hexagon::IntRegsRegClass.contains(DestReg) && | 
|  | 135 | (ShouldCombineAggressively || isInt<8>(MI->getOperand(1).getImm())); | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | case Hexagon::TFRI_V4: { | 
|  | 139 | if (!ShouldCombineAggressively) | 
|  | 140 | return false; | 
|  | 141 | assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal()); | 
|  | 142 |  | 
|  | 143 | // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a | 
|  | 144 | // workaround for an ABI bug that prevents GOT relocations on combine | 
|  | 145 | // instructions | 
|  | 146 | if (MI->getOperand(1).getTargetFlags() != HexagonII::MO_NO_FLAG) | 
|  | 147 | return false; | 
|  | 148 |  | 
|  | 149 | unsigned DestReg = MI->getOperand(0).getReg(); | 
|  | 150 | return Hexagon::IntRegsRegClass.contains(DestReg); | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | default: | 
|  | 154 | break; | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | return false; | 
|  | 158 | } | 
|  | 159 |  | 
|  | 160 | static bool isGreaterThan8BitTFRI(MachineInstr *I) { | 
|  | 161 | return I->getOpcode() == Hexagon::TFRI && | 
|  | 162 | !isInt<8>(I->getOperand(1).getImm()); | 
|  | 163 | } | 
|  | 164 | static bool isGreaterThan6BitTFRI(MachineInstr *I) { | 
|  | 165 | return I->getOpcode() == Hexagon::TFRI && | 
|  | 166 | !isUInt<6>(I->getOperand(1).getImm()); | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | /// areCombinableOperations - Returns true if the two instruction can be merge | 
|  | 170 | /// into a combine (ignoring register constraints). | 
|  | 171 | static bool areCombinableOperations(const TargetRegisterInfo *TRI, | 
|  | 172 | MachineInstr *HighRegInst, | 
|  | 173 | MachineInstr *LowRegInst) { | 
|  | 174 | assert((HighRegInst->getOpcode() == Hexagon::TFR || | 
|  | 175 | HighRegInst->getOpcode() == Hexagon::TFRI || | 
|  | 176 | HighRegInst->getOpcode() == Hexagon::TFRI_V4) && | 
|  | 177 | (LowRegInst->getOpcode() == Hexagon::TFR || | 
|  | 178 | LowRegInst->getOpcode() == Hexagon::TFRI || | 
|  | 179 | LowRegInst->getOpcode() == Hexagon::TFRI_V4) && | 
|  | 180 | "Assume individual instructions are of a combinable type"); | 
|  | 181 |  | 
|  | 182 | const HexagonRegisterInfo *QRI = | 
|  | 183 | static_cast<const HexagonRegisterInfo *>(TRI); | 
|  | 184 |  | 
|  | 185 | // V4 added some combine variations (mixed immediate and register source | 
|  | 186 | // operands), if we are on < V4 we can only combine 2 register-to-register | 
|  | 187 | // moves and 2 immediate-to-register moves. We also don't have | 
|  | 188 | // constant-extenders. | 
|  | 189 | if (!QRI->Subtarget.hasV4TOps()) | 
|  | 190 | return HighRegInst->getOpcode() == LowRegInst->getOpcode() && | 
|  | 191 | !isGreaterThan8BitTFRI(HighRegInst) && | 
|  | 192 | !isGreaterThan6BitTFRI(LowRegInst); | 
|  | 193 |  | 
|  | 194 | // There is no combine of two constant extended values. | 
|  | 195 | if ((HighRegInst->getOpcode() == Hexagon::TFRI_V4 || | 
|  | 196 | isGreaterThan8BitTFRI(HighRegInst)) && | 
|  | 197 | (LowRegInst->getOpcode() == Hexagon::TFRI_V4 || | 
|  | 198 | isGreaterThan6BitTFRI(LowRegInst))) | 
|  | 199 | return false; | 
|  | 200 |  | 
|  | 201 | return true; | 
|  | 202 | } | 
|  | 203 |  | 
|  | 204 | static bool isEvenReg(unsigned Reg) { | 
|  | 205 | assert(TargetRegisterInfo::isPhysicalRegister(Reg) && | 
|  | 206 | Hexagon::IntRegsRegClass.contains(Reg)); | 
|  | 207 | return (Reg - Hexagon::R0) % 2 == 0; | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 | static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled) { | 
|  | 211 | for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { | 
|  | 212 | MachineOperand &Op = MI->getOperand(I); | 
|  | 213 | if (!Op.isReg() || Op.getReg() != RegNotKilled || !Op.isKill()) | 
|  | 214 | continue; | 
|  | 215 | Op.setIsKill(false); | 
|  | 216 | } | 
|  | 217 | } | 
|  | 218 |  | 
| Jyotsna Verma | cceafb2 | 2013-05-28 19:01:45 +0000 | [diff] [blame] | 219 | /// isUnsafeToMoveAcross - Returns true if it is unsafe to move a copy | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 220 | /// instruction from \p UseReg to \p DestReg over the instruction \p I. | 
| Jyotsna Verma | cceafb2 | 2013-05-28 19:01:45 +0000 | [diff] [blame] | 221 | static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg, | 
| Benjamin Kramer | e79beac | 2013-05-23 15:43:11 +0000 | [diff] [blame] | 222 | unsigned DestReg, | 
|  | 223 | const TargetRegisterInfo *TRI) { | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 224 | return (UseReg && (I->modifiesRegister(UseReg, TRI))) || | 
|  | 225 | I->modifiesRegister(DestReg, TRI) || | 
|  | 226 | I->readsRegister(DestReg, TRI) || | 
|  | 227 | I->hasUnmodeledSideEffects() || | 
|  | 228 | I->isInlineAsm() || I->isDebugValue(); | 
|  | 229 | } | 
|  | 230 |  | 
|  | 231 | /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such | 
|  | 232 | /// that the two instructions can be paired in a combine. | 
|  | 233 | bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr *I1, | 
|  | 234 | MachineInstr *I2, | 
|  | 235 | unsigned I1DestReg, | 
|  | 236 | unsigned I2DestReg, | 
|  | 237 | bool &DoInsertAtI1) { | 
|  | 238 |  | 
|  | 239 | bool IsImmUseReg = I2->getOperand(1).isImm() || I2->getOperand(1).isGlobal(); | 
|  | 240 | unsigned I2UseReg = IsImmUseReg ? 0 : I2->getOperand(1).getReg(); | 
|  | 241 |  | 
|  | 242 | // It is not safe to move I1 and I2 into one combine if I2 has a true | 
|  | 243 | // dependence on I1. | 
|  | 244 | if (I2UseReg && I1->modifiesRegister(I2UseReg, TRI)) | 
|  | 245 | return false; | 
|  | 246 |  | 
|  | 247 | bool isSafe = true; | 
|  | 248 |  | 
|  | 249 | // First try to move I2 towards I1. | 
|  | 250 | { | 
|  | 251 | // A reverse_iterator instantiated like below starts before I2, and I1 | 
|  | 252 | // respectively. | 
|  | 253 | // Look at instructions I in between I2 and (excluding) I1. | 
|  | 254 | MachineBasicBlock::reverse_iterator I(I2), | 
|  | 255 | End = --(MachineBasicBlock::reverse_iterator(I1)); | 
|  | 256 | // At 03 we got better results (dhrystone!) by being more conservative. | 
|  | 257 | if (!ShouldCombineAggressively) | 
|  | 258 | End = MachineBasicBlock::reverse_iterator(I1); | 
|  | 259 | // If I2 kills its operand and we move I2 over an instruction that also | 
|  | 260 | // uses I2's use reg we need to modify that (first) instruction to now kill | 
|  | 261 | // this reg. | 
|  | 262 | unsigned KilledOperand = 0; | 
|  | 263 | if (I2->killsRegister(I2UseReg)) | 
|  | 264 | KilledOperand = I2UseReg; | 
|  | 265 | MachineInstr *KillingInstr = 0; | 
|  | 266 |  | 
|  | 267 | for (; I != End; ++I) { | 
|  | 268 | // If the intervening instruction I: | 
|  | 269 | //   * modifies I2's use reg | 
|  | 270 | //   * modifies I2's def reg | 
|  | 271 | //   * reads I2's def reg | 
|  | 272 | //   * or has unmodelled side effects | 
|  | 273 | // we can't move I2 across it. | 
| Jyotsna Verma | cceafb2 | 2013-05-28 19:01:45 +0000 | [diff] [blame] | 274 | if (isUnsafeToMoveAcross(&*I, I2UseReg, I2DestReg, TRI)) { | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 275 | isSafe = false; | 
|  | 276 | break; | 
|  | 277 | } | 
|  | 278 |  | 
|  | 279 | // Update first use of the killed operand. | 
|  | 280 | if (!KillingInstr && KilledOperand && | 
|  | 281 | I->readsRegister(KilledOperand, TRI)) | 
|  | 282 | KillingInstr = &*I; | 
|  | 283 | } | 
|  | 284 | if (isSafe) { | 
|  | 285 | // Update the intermediate instruction to with the kill flag. | 
|  | 286 | if (KillingInstr) { | 
|  | 287 | bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true); | 
| Alp Toker | cb40291 | 2014-01-24 17:20:08 +0000 | [diff] [blame] | 288 | (void)Added; // suppress compiler warning | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 289 | assert(Added && "Must successfully update kill flag"); | 
|  | 290 | removeKillInfo(I2, KilledOperand); | 
|  | 291 | } | 
|  | 292 | DoInsertAtI1 = true; | 
|  | 293 | return true; | 
|  | 294 | } | 
|  | 295 | } | 
|  | 296 |  | 
|  | 297 | // Try to move I1 towards I2. | 
|  | 298 | { | 
|  | 299 | // Look at instructions I in between I1 and (excluding) I2. | 
|  | 300 | MachineBasicBlock::iterator I(I1), End(I2); | 
|  | 301 | // At O3 we got better results (dhrystone) by being more conservative here. | 
|  | 302 | if (!ShouldCombineAggressively) | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 303 | End = std::next(MachineBasicBlock::iterator(I2)); | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 304 | IsImmUseReg = I1->getOperand(1).isImm() || I1->getOperand(1).isGlobal(); | 
|  | 305 | unsigned I1UseReg = IsImmUseReg ? 0 : I1->getOperand(1).getReg(); | 
| Jyotsna Verma | cceafb2 | 2013-05-28 19:01:45 +0000 | [diff] [blame] | 306 | // Track killed operands. If we move across an instruction that kills our | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 307 | // operand, we need to update the kill information on the moved I1. It kills | 
|  | 308 | // the operand now. | 
|  | 309 | MachineInstr *KillingInstr = 0; | 
|  | 310 | unsigned KilledOperand = 0; | 
|  | 311 |  | 
|  | 312 | while(++I != End) { | 
|  | 313 | // If the intervening instruction I: | 
|  | 314 | //   * modifies I1's use reg | 
|  | 315 | //   * modifies I1's def reg | 
|  | 316 | //   * reads I1's def reg | 
|  | 317 | //   * or has unmodelled side effects | 
|  | 318 | //   We introduce this special case because llvm has no api to remove a | 
|  | 319 | //   kill flag for a register (a removeRegisterKilled() analogous to | 
|  | 320 | //   addRegisterKilled) that handles aliased register correctly. | 
|  | 321 | //   * or has a killed aliased register use of I1's use reg | 
|  | 322 | //           %D4<def> = TFRI64 16 | 
|  | 323 | //           %R6<def> = TFR %R9 | 
|  | 324 | //           %R8<def> = KILL %R8, %D4<imp-use,kill> | 
|  | 325 | //      If we want to move R6 = across the KILL instruction we would have | 
|  | 326 | //      to remove the %D4<imp-use,kill> operand. For now, we are | 
|  | 327 | //      conservative and disallow the move. | 
|  | 328 | // we can't move I1 across it. | 
| Jyotsna Verma | cceafb2 | 2013-05-28 19:01:45 +0000 | [diff] [blame] | 329 | if (isUnsafeToMoveAcross(I, I1UseReg, I1DestReg, TRI) || | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 330 | // Check for an aliased register kill. Bail out if we see one. | 
|  | 331 | (!I->killsRegister(I1UseReg) && I->killsRegister(I1UseReg, TRI))) | 
|  | 332 | return false; | 
|  | 333 |  | 
|  | 334 | // Check for an exact kill (registers match). | 
|  | 335 | if (I1UseReg && I->killsRegister(I1UseReg)) { | 
|  | 336 | assert(KillingInstr == 0 && "Should only see one killing instruction"); | 
|  | 337 | KilledOperand = I1UseReg; | 
|  | 338 | KillingInstr = &*I; | 
|  | 339 | } | 
|  | 340 | } | 
|  | 341 | if (KillingInstr) { | 
|  | 342 | removeKillInfo(KillingInstr, KilledOperand); | 
|  | 343 | // Update I1 to set the kill flag. This flag will later be picked up by | 
|  | 344 | // the new COMBINE instruction. | 
|  | 345 | bool Added = I1->addRegisterKilled(KilledOperand, TRI); | 
| Alp Toker | cb40291 | 2014-01-24 17:20:08 +0000 | [diff] [blame] | 346 | (void)Added; // suppress compiler warning | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 347 | assert(Added && "Must successfully update kill flag"); | 
|  | 348 | } | 
|  | 349 | DoInsertAtI1 = false; | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | return true; | 
|  | 353 | } | 
|  | 354 |  | 
|  | 355 | /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be | 
|  | 356 | /// newified. (A use of a 64 bit register define can not be newified) | 
|  | 357 | void | 
|  | 358 | HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) { | 
|  | 359 | DenseMap<unsigned, MachineInstr *> LastDef; | 
|  | 360 | for (MachineBasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { | 
|  | 361 | MachineInstr *MI = I; | 
|  | 362 | // Mark TFRs that feed a potential new value store as such. | 
|  | 363 | if(TII->mayBeNewStore(MI)) { | 
|  | 364 | // Look for uses of TFR instructions. | 
|  | 365 | for (unsigned OpdIdx = 0, OpdE = MI->getNumOperands(); OpdIdx != OpdE; | 
|  | 366 | ++OpdIdx) { | 
|  | 367 | MachineOperand &Op = MI->getOperand(OpdIdx); | 
|  | 368 |  | 
|  | 369 | // Skip over anything except register uses. | 
|  | 370 | if (!Op.isReg() || !Op.isUse() || !Op.getReg()) | 
|  | 371 | continue; | 
|  | 372 |  | 
|  | 373 | // Look for the defining instruction. | 
|  | 374 | unsigned Reg = Op.getReg(); | 
|  | 375 | MachineInstr *DefInst = LastDef[Reg]; | 
|  | 376 | if (!DefInst) | 
|  | 377 | continue; | 
|  | 378 | if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively)) | 
|  | 379 | continue; | 
|  | 380 |  | 
|  | 381 | // Only close newifiable stores should influence the decision. | 
|  | 382 | MachineBasicBlock::iterator It(DefInst); | 
|  | 383 | unsigned NumInstsToDef = 0; | 
|  | 384 | while (&*It++ != MI) | 
|  | 385 | ++NumInstsToDef; | 
|  | 386 |  | 
|  | 387 | if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR) | 
|  | 388 | continue; | 
|  | 389 |  | 
|  | 390 | PotentiallyNewifiableTFR.insert(DefInst); | 
|  | 391 | } | 
|  | 392 | // Skip to next instruction. | 
|  | 393 | continue; | 
|  | 394 | } | 
|  | 395 |  | 
|  | 396 | // Put instructions that last defined integer or double registers into the | 
|  | 397 | // map. | 
|  | 398 | for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { | 
|  | 399 | MachineOperand &Op = MI->getOperand(I); | 
|  | 400 | if (!Op.isReg() || !Op.isDef() || !Op.getReg()) | 
|  | 401 | continue; | 
|  | 402 | unsigned Reg = Op.getReg(); | 
|  | 403 | if (Hexagon::DoubleRegsRegClass.contains(Reg)) { | 
|  | 404 | for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) { | 
|  | 405 | LastDef[*SubRegs] = MI; | 
|  | 406 | } | 
|  | 407 | } else if (Hexagon::IntRegsRegClass.contains(Reg)) | 
|  | 408 | LastDef[Reg] = MI; | 
|  | 409 | } | 
|  | 410 | } | 
|  | 411 | } | 
|  | 412 |  | 
|  | 413 | bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { | 
|  | 414 |  | 
|  | 415 | if (IsCombinesDisabled) return false; | 
|  | 416 |  | 
|  | 417 | bool HasChanged = false; | 
|  | 418 |  | 
|  | 419 | // Get target info. | 
|  | 420 | TRI = MF.getTarget().getRegisterInfo(); | 
|  | 421 | TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo()); | 
|  | 422 |  | 
|  | 423 | // Combine aggressively (for code size) | 
|  | 424 | ShouldCombineAggressively = | 
|  | 425 | MF.getTarget().getOptLevel() <= CodeGenOpt::Default; | 
|  | 426 |  | 
|  | 427 | // Traverse basic blocks. | 
|  | 428 | for (MachineFunction::iterator BI = MF.begin(), BE = MF.end(); BI != BE; | 
|  | 429 | ++BI) { | 
|  | 430 | PotentiallyNewifiableTFR.clear(); | 
|  | 431 | findPotentialNewifiableTFRs(*BI); | 
|  | 432 |  | 
|  | 433 | // Traverse instructions in basic block. | 
|  | 434 | for(MachineBasicBlock::iterator MI = BI->begin(), End = BI->end(); | 
|  | 435 | MI != End;) { | 
|  | 436 | MachineInstr *I1 = MI++; | 
|  | 437 | // Don't combine a TFR whose user could be newified (instructions that | 
|  | 438 | // define double registers can not be newified - Programmer's Ref Manual | 
|  | 439 | // 5.4.2 New-value stores). | 
|  | 440 | if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I1)) | 
|  | 441 | continue; | 
|  | 442 |  | 
|  | 443 | // Ignore instructions that are not combinable. | 
|  | 444 | if (!isCombinableInstType(I1, TII, ShouldCombineAggressively)) | 
|  | 445 | continue; | 
|  | 446 |  | 
|  | 447 | // Find a second instruction that can be merged into a combine | 
|  | 448 | // instruction. | 
|  | 449 | bool DoInsertAtI1 = false; | 
|  | 450 | MachineInstr *I2 = findPairable(I1, DoInsertAtI1); | 
|  | 451 | if (I2) { | 
|  | 452 | HasChanged = true; | 
|  | 453 | combine(I1, I2, MI, DoInsertAtI1); | 
|  | 454 | } | 
|  | 455 | } | 
|  | 456 | } | 
|  | 457 |  | 
|  | 458 | return HasChanged; | 
|  | 459 | } | 
|  | 460 |  | 
|  | 461 | /// findPairable - Returns an instruction that can be merged with \p I1 into a | 
|  | 462 | /// COMBINE instruction or 0 if no such instruction can be found. Returns true | 
|  | 463 | /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1 | 
|  | 464 | /// false if the combine must be inserted at the returned instruction. | 
|  | 465 | MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr *I1, | 
|  | 466 | bool &DoInsertAtI1) { | 
| Benjamin Kramer | b6d0bd4 | 2014-03-02 12:27:27 +0000 | [diff] [blame] | 467 | MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1)); | 
| Jyotsna Verma | 803e506 | 2013-05-14 18:54:06 +0000 | [diff] [blame] | 468 | unsigned I1DestReg = I1->getOperand(0).getReg(); | 
|  | 469 |  | 
|  | 470 | for (MachineBasicBlock::iterator End = I1->getParent()->end(); I2 != End; | 
|  | 471 | ++I2) { | 
|  | 472 | // Bail out early if we see a second definition of I1DestReg. | 
|  | 473 | if (I2->modifiesRegister(I1DestReg, TRI)) | 
|  | 474 | break; | 
|  | 475 |  | 
|  | 476 | // Ignore non-combinable instructions. | 
|  | 477 | if (!isCombinableInstType(I2, TII, ShouldCombineAggressively)) | 
|  | 478 | continue; | 
|  | 479 |  | 
|  | 480 | // Don't combine a TFR whose user could be newified. | 
|  | 481 | if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2)) | 
|  | 482 | continue; | 
|  | 483 |  | 
|  | 484 | unsigned I2DestReg = I2->getOperand(0).getReg(); | 
|  | 485 |  | 
|  | 486 | // Check that registers are adjacent and that the first destination register | 
|  | 487 | // is even. | 
|  | 488 | bool IsI1LowReg = (I2DestReg - I1DestReg) == 1; | 
|  | 489 | bool IsI2LowReg = (I1DestReg - I2DestReg) == 1; | 
|  | 490 | unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg; | 
|  | 491 | if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex)) | 
|  | 492 | continue; | 
|  | 493 |  | 
|  | 494 | // Check that the two instructions are combinable. V4 allows more | 
|  | 495 | // instructions to be merged into a combine. | 
|  | 496 | // The order matters because in a TFRI we might can encode a int8 as the | 
|  | 497 | // hi reg operand but only a uint6 as the low reg operand. | 
|  | 498 | if ((IsI2LowReg && !areCombinableOperations(TRI, I1, I2)) || | 
|  | 499 | (IsI1LowReg && !areCombinableOperations(TRI, I2, I1))) | 
|  | 500 | break; | 
|  | 501 |  | 
|  | 502 | if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg, | 
|  | 503 | DoInsertAtI1)) | 
|  | 504 | return I2; | 
|  | 505 |  | 
|  | 506 | // Not safe. Stop searching. | 
|  | 507 | break; | 
|  | 508 | } | 
|  | 509 | return 0; | 
|  | 510 | } | 
|  | 511 |  | 
|  | 512 | void HexagonCopyToCombine::combine(MachineInstr *I1, MachineInstr *I2, | 
|  | 513 | MachineBasicBlock::iterator &MI, | 
|  | 514 | bool DoInsertAtI1) { | 
|  | 515 | // We are going to delete I2. If MI points to I2 advance it to the next | 
|  | 516 | // instruction. | 
|  | 517 | if ((MachineInstr *)MI == I2) ++MI; | 
|  | 518 |  | 
|  | 519 | // Figure out whether I1 or I2 goes into the lowreg part. | 
|  | 520 | unsigned I1DestReg = I1->getOperand(0).getReg(); | 
|  | 521 | unsigned I2DestReg = I2->getOperand(0).getReg(); | 
|  | 522 | bool IsI1Loreg = (I2DestReg - I1DestReg) == 1; | 
|  | 523 | unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg; | 
|  | 524 |  | 
|  | 525 | // Get the double word register. | 
|  | 526 | unsigned DoubleRegDest = | 
|  | 527 | TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg, | 
|  | 528 | &Hexagon::DoubleRegsRegClass); | 
|  | 529 | assert(DoubleRegDest != 0 && "Expect a valid register"); | 
|  | 530 |  | 
|  | 531 |  | 
|  | 532 | // Setup source operands. | 
|  | 533 | MachineOperand &LoOperand = IsI1Loreg ? I1->getOperand(1) : | 
|  | 534 | I2->getOperand(1); | 
|  | 535 | MachineOperand &HiOperand = IsI1Loreg ? I2->getOperand(1) : | 
|  | 536 | I1->getOperand(1); | 
|  | 537 |  | 
|  | 538 | // Figure out which source is a register and which a constant. | 
|  | 539 | bool IsHiReg = HiOperand.isReg(); | 
|  | 540 | bool IsLoReg = LoOperand.isReg(); | 
|  | 541 |  | 
|  | 542 | MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2); | 
|  | 543 | // Emit combine. | 
|  | 544 | if (IsHiReg && IsLoReg) | 
|  | 545 | emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand); | 
|  | 546 | else if (IsHiReg) | 
|  | 547 | emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand); | 
|  | 548 | else if (IsLoReg) | 
|  | 549 | emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand); | 
|  | 550 | else | 
|  | 551 | emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand); | 
|  | 552 |  | 
|  | 553 | I1->eraseFromParent(); | 
|  | 554 | I2->eraseFromParent(); | 
|  | 555 | } | 
|  | 556 |  | 
|  | 557 | void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, | 
|  | 558 | unsigned DoubleDestReg, | 
|  | 559 | MachineOperand &HiOperand, | 
|  | 560 | MachineOperand &LoOperand) { | 
|  | 561 | DebugLoc DL = InsertPt->getDebugLoc(); | 
|  | 562 | MachineBasicBlock *BB = InsertPt->getParent(); | 
|  | 563 |  | 
|  | 564 | // Handle  globals. | 
|  | 565 | if (HiOperand.isGlobal()) { | 
|  | 566 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg) | 
|  | 567 | .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), | 
|  | 568 | HiOperand.getTargetFlags()) | 
|  | 569 | .addImm(LoOperand.getImm()); | 
|  | 570 | return; | 
|  | 571 | } | 
|  | 572 | if (LoOperand.isGlobal()) { | 
|  | 573 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg) | 
|  | 574 | .addImm(HiOperand.getImm()) | 
|  | 575 | .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), | 
|  | 576 | LoOperand.getTargetFlags()); | 
|  | 577 | return; | 
|  | 578 | } | 
|  | 579 |  | 
|  | 580 | // Handle constant extended immediates. | 
|  | 581 | if (!isInt<8>(HiOperand.getImm())) { | 
|  | 582 | assert(isInt<8>(LoOperand.getImm())); | 
|  | 583 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg) | 
|  | 584 | .addImm(HiOperand.getImm()) | 
|  | 585 | .addImm(LoOperand.getImm()); | 
|  | 586 | return; | 
|  | 587 | } | 
|  | 588 |  | 
|  | 589 | if (!isUInt<6>(LoOperand.getImm())) { | 
|  | 590 | assert(isInt<8>(HiOperand.getImm())); | 
|  | 591 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg) | 
|  | 592 | .addImm(HiOperand.getImm()) | 
|  | 593 | .addImm(LoOperand.getImm()); | 
|  | 594 | return; | 
|  | 595 | } | 
|  | 596 |  | 
|  | 597 | // Insert new combine instruction. | 
|  | 598 | //  DoubleRegDest = combine #HiImm, #LoImm | 
|  | 599 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg) | 
|  | 600 | .addImm(HiOperand.getImm()) | 
|  | 601 | .addImm(LoOperand.getImm()); | 
|  | 602 | } | 
|  | 603 |  | 
|  | 604 | void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, | 
|  | 605 | unsigned DoubleDestReg, | 
|  | 606 | MachineOperand &HiOperand, | 
|  | 607 | MachineOperand &LoOperand) { | 
|  | 608 | unsigned LoReg = LoOperand.getReg(); | 
|  | 609 | unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); | 
|  | 610 |  | 
|  | 611 | DebugLoc DL = InsertPt->getDebugLoc(); | 
|  | 612 | MachineBasicBlock *BB = InsertPt->getParent(); | 
|  | 613 |  | 
|  | 614 | // Handle global. | 
|  | 615 | if (HiOperand.isGlobal()) { | 
|  | 616 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg) | 
|  | 617 | .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), | 
|  | 618 | HiOperand.getTargetFlags()) | 
|  | 619 | .addReg(LoReg, LoRegKillFlag); | 
|  | 620 | return; | 
|  | 621 | } | 
|  | 622 | // Insert new combine instruction. | 
|  | 623 | //  DoubleRegDest = combine #HiImm, LoReg | 
|  | 624 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg) | 
|  | 625 | .addImm(HiOperand.getImm()) | 
|  | 626 | .addReg(LoReg, LoRegKillFlag); | 
|  | 627 | } | 
|  | 628 |  | 
|  | 629 | void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, | 
|  | 630 | unsigned DoubleDestReg, | 
|  | 631 | MachineOperand &HiOperand, | 
|  | 632 | MachineOperand &LoOperand) { | 
|  | 633 | unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); | 
|  | 634 | unsigned HiReg = HiOperand.getReg(); | 
|  | 635 |  | 
|  | 636 | DebugLoc DL = InsertPt->getDebugLoc(); | 
|  | 637 | MachineBasicBlock *BB = InsertPt->getParent(); | 
|  | 638 |  | 
|  | 639 | // Handle global. | 
|  | 640 | if (LoOperand.isGlobal()) { | 
|  | 641 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg) | 
|  | 642 | .addReg(HiReg, HiRegKillFlag) | 
|  | 643 | .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), | 
|  | 644 | LoOperand.getTargetFlags()); | 
|  | 645 | return; | 
|  | 646 | } | 
|  | 647 |  | 
|  | 648 | // Insert new combine instruction. | 
|  | 649 | //  DoubleRegDest = combine HiReg, #LoImm | 
|  | 650 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg) | 
|  | 651 | .addReg(HiReg, HiRegKillFlag) | 
|  | 652 | .addImm(LoOperand.getImm()); | 
|  | 653 | } | 
|  | 654 |  | 
|  | 655 | void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, | 
|  | 656 | unsigned DoubleDestReg, | 
|  | 657 | MachineOperand &HiOperand, | 
|  | 658 | MachineOperand &LoOperand) { | 
|  | 659 | unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); | 
|  | 660 | unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); | 
|  | 661 | unsigned LoReg = LoOperand.getReg(); | 
|  | 662 | unsigned HiReg = HiOperand.getReg(); | 
|  | 663 |  | 
|  | 664 | DebugLoc DL = InsertPt->getDebugLoc(); | 
|  | 665 | MachineBasicBlock *BB = InsertPt->getParent(); | 
|  | 666 |  | 
|  | 667 | // Insert new combine instruction. | 
|  | 668 | //  DoubleRegDest = combine HiReg, LoReg | 
|  | 669 | BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg) | 
|  | 670 | .addReg(HiReg, HiRegKillFlag) | 
|  | 671 | .addReg(LoReg, LoRegKillFlag); | 
|  | 672 | } | 
|  | 673 |  | 
|  | 674 | FunctionPass *llvm::createHexagonCopyToCombine() { | 
|  | 675 | return new HexagonCopyToCombine(); | 
|  | 676 | } |