1 //===-- HexagonSplitTFRCondSets.cpp - split TFR condsets into xfers -------===// 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 //===----------------------------------------------------------------------===// 10 // This pass tries to provide opportunities for better optimization of muxes. 11 // The default code generated for something like: flag = (a == b) ? 1 : 3; 12 // would be: 13 // 14 // {p0 = cmp.eq(r0,r1)} 15 // {r3 = mux(p0,#1,#3)} 16 // 17 // This requires two packets. If we use .new predicated immediate transfers, 18 // then we can do this in a single packet, e.g.: 19 // 20 // {p0 = cmp.eq(r0,r1) 21 // if (p0.new) r3 = #1 22 // if (!p0.new) r3 = #3} 23 // 24 // Note that the conditional assignments are not generated in .new form here. 25 // We assume opptimisically that they will be formed later. 26 // 27 //===----------------------------------------------------------------------===// 28 29 #define DEBUG_TYPE "xfer" 30 #include "HexagonTargetMachine.h" 31 #include "HexagonSubtarget.h" 32 #include "HexagonMachineFunctionInfo.h" 33 #include "llvm/CodeGen/Passes.h" 34 #include "llvm/CodeGen/LatencyPriorityQueue.h" 35 #include "llvm/CodeGen/MachineDominators.h" 36 #include "llvm/CodeGen/MachineFunctionPass.h" 37 #include "llvm/CodeGen/MachineInstrBuilder.h" 38 #include "llvm/CodeGen/MachineLoopInfo.h" 39 #include "llvm/CodeGen/MachineRegisterInfo.h" 40 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 41 #include "llvm/CodeGen/SchedulerRegistry.h" 42 #include "llvm/Target/TargetInstrInfo.h" 43 #include "llvm/Target/TargetMachine.h" 44 #include "llvm/Target/TargetRegisterInfo.h" 45 #include "llvm/Support/Compiler.h" 46 #include "llvm/Support/Debug.h" 47 #include "llvm/Support/MathExtras.h" 48 49 using namespace llvm; 50 51 namespace { 52 53 class HexagonSplitTFRCondSets : public MachineFunctionPass { 54 HexagonTargetMachine& QTM; 55 const HexagonSubtarget &QST; 56 57 public: 58 static char ID; 59 HexagonSplitTFRCondSets(HexagonTargetMachine& TM) : 60 MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {} 61 62 const char *getPassName() const { 63 return "Hexagon Split TFRCondSets"; 64 } 65 bool runOnMachineFunction(MachineFunction &Fn); 66 }; 67 68 69 char HexagonSplitTFRCondSets::ID = 0; 70 71 72 bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) { 73 74 const TargetInstrInfo *TII = QTM.getInstrInfo(); 75 76 // Loop over all of the basic blocks. 77 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 78 MBBb != MBBe; ++MBBb) { 79 MachineBasicBlock* MBB = MBBb; 80 // Traverse the basic block. 81 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 82 ++MII) { 83 MachineInstr *MI = MII; 84 int Opc1, Opc2; 85 switch(MI->getOpcode()) { 86 case Hexagon::TFR_condset_rr: 87 case Hexagon::TFR_condset_rr_f: 88 case Hexagon::TFR_condset_rr64_f: { 89 int DestReg = MI->getOperand(0).getReg(); 90 int SrcReg1 = MI->getOperand(2).getReg(); 91 int SrcReg2 = MI->getOperand(3).getReg(); 92 93 if (MI->getOpcode() == Hexagon::TFR_condset_rr || 94 MI->getOpcode() == Hexagon::TFR_condset_rr_f) { 95 Opc1 = Hexagon::TFR_cPt; 96 Opc2 = Hexagon::TFR_cNotPt; 97 } 98 else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) { 99 Opc1 = Hexagon::TFR64_cPt; 100 Opc2 = Hexagon::TFR64_cNotPt; 101 } 102 103 // Minor optimization: do not emit the predicated copy if the source 104 // and the destination is the same register. 105 if (DestReg != SrcReg1) { 106 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc1), 107 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 108 } 109 if (DestReg != SrcReg2) { 110 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc2), 111 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 112 } 113 MII = MBB->erase(MI); 114 --MII; 115 break; 116 } 117 case Hexagon::TFR_condset_ri: 118 case Hexagon::TFR_condset_ri_f: { 119 int DestReg = MI->getOperand(0).getReg(); 120 int SrcReg1 = MI->getOperand(2).getReg(); 121 122 // Do not emit the predicated copy if the source and the destination 123 // is the same register. 124 if (DestReg != SrcReg1) { 125 BuildMI(*MBB, MII, MI->getDebugLoc(), 126 TII->get(Hexagon::TFR_cPt), DestReg). 127 addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 128 } 129 if (MI->getOpcode() == Hexagon::TFR_condset_ri ) { 130 BuildMI(*MBB, MII, MI->getDebugLoc(), 131 TII->get(Hexagon::TFRI_cNotPt), DestReg). 132 addReg(MI->getOperand(1).getReg()). 133 addImm(MI->getOperand(3).getImm()); 134 } else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) { 135 BuildMI(*MBB, MII, MI->getDebugLoc(), 136 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 137 addReg(MI->getOperand(1).getReg()). 138 addFPImm(MI->getOperand(3).getFPImm()); 139 } 140 141 MII = MBB->erase(MI); 142 --MII; 143 break; 144 } 145 case Hexagon::TFR_condset_ir: 146 case Hexagon::TFR_condset_ir_f: { 147 int DestReg = MI->getOperand(0).getReg(); 148 int SrcReg2 = MI->getOperand(3).getReg(); 149 150 if (MI->getOpcode() == Hexagon::TFR_condset_ir ) { 151 BuildMI(*MBB, MII, MI->getDebugLoc(), 152 TII->get(Hexagon::TFRI_cPt), DestReg). 153 addReg(MI->getOperand(1).getReg()). 154 addImm(MI->getOperand(2).getImm()); 155 } else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) { 156 BuildMI(*MBB, MII, MI->getDebugLoc(), 157 TII->get(Hexagon::TFRI_cPt_f), DestReg). 158 addReg(MI->getOperand(1).getReg()). 159 addFPImm(MI->getOperand(2).getFPImm()); 160 } 161 162 // Do not emit the predicated copy if the source and 163 // the destination is the same register. 164 if (DestReg != SrcReg2) { 165 BuildMI(*MBB, MII, MI->getDebugLoc(), 166 TII->get(Hexagon::TFR_cNotPt), DestReg). 167 addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 168 } 169 MII = MBB->erase(MI); 170 --MII; 171 break; 172 } 173 case Hexagon::TFR_condset_ii: 174 case Hexagon::TFR_condset_ii_f: { 175 int DestReg = MI->getOperand(0).getReg(); 176 int SrcReg1 = MI->getOperand(1).getReg(); 177 178 if (MI->getOpcode() == Hexagon::TFR_condset_ii ) { 179 int Immed1 = MI->getOperand(2).getImm(); 180 int Immed2 = MI->getOperand(3).getImm(); 181 BuildMI(*MBB, MII, MI->getDebugLoc(), 182 TII->get(Hexagon::TFRI_cPt), 183 DestReg).addReg(SrcReg1).addImm(Immed1); 184 BuildMI(*MBB, MII, MI->getDebugLoc(), 185 TII->get(Hexagon::TFRI_cNotPt), 186 DestReg).addReg(SrcReg1).addImm(Immed2); 187 } else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) { 188 BuildMI(*MBB, MII, MI->getDebugLoc(), 189 TII->get(Hexagon::TFRI_cPt_f), DestReg). 190 addReg(SrcReg1). 191 addFPImm(MI->getOperand(2).getFPImm()); 192 BuildMI(*MBB, MII, MI->getDebugLoc(), 193 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 194 addReg(SrcReg1). 195 addFPImm(MI->getOperand(3).getFPImm()); 196 } 197 MII = MBB->erase(MI); 198 --MII; 199 break; 200 } 201 } 202 } 203 } 204 return true; 205 } 206 207 } 208 209 //===----------------------------------------------------------------------===// 210 // Public Constructor Functions 211 //===----------------------------------------------------------------------===// 212 213 FunctionPass *llvm::createHexagonSplitTFRCondSets(HexagonTargetMachine &TM) { 214 return new HexagonSplitTFRCondSets(TM); 215 } 216