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 "Hexagon.h" 31 #include "HexagonMachineFunctionInfo.h" 32 #include "HexagonSubtarget.h" 33 #include "HexagonTargetMachine.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/Passes.h" 41 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 42 #include "llvm/CodeGen/SchedulerRegistry.h" 43 #include "llvm/Support/Compiler.h" 44 #include "llvm/Support/Debug.h" 45 #include "llvm/Support/MathExtras.h" 46 #include "llvm/Target/TargetInstrInfo.h" 47 #include "llvm/Target/TargetMachine.h" 48 #include "llvm/Target/TargetRegisterInfo.h" 49 50 using namespace llvm; 51 52 namespace llvm { 53 void initializeHexagonSplitTFRCondSetsPass(PassRegistry&); 54 } 55 56 57 namespace { 58 59 class HexagonSplitTFRCondSets : public MachineFunctionPass { 60 const HexagonTargetMachine &QTM; 61 const HexagonSubtarget &QST; 62 63 public: 64 static char ID; 65 HexagonSplitTFRCondSets(const HexagonTargetMachine& TM) : 66 MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) { 67 initializeHexagonSplitTFRCondSetsPass(*PassRegistry::getPassRegistry()); 68 } 69 70 const char *getPassName() const { 71 return "Hexagon Split TFRCondSets"; 72 } 73 bool runOnMachineFunction(MachineFunction &Fn); 74 }; 75 76 77 char HexagonSplitTFRCondSets::ID = 0; 78 79 80 bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) { 81 82 const TargetInstrInfo *TII = QTM.getInstrInfo(); 83 84 // Loop over all of the basic blocks. 85 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 86 MBBb != MBBe; ++MBBb) { 87 MachineBasicBlock* MBB = MBBb; 88 // Traverse the basic block. 89 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 90 ++MII) { 91 MachineInstr *MI = MII; 92 int Opc1, Opc2; 93 switch(MI->getOpcode()) { 94 case Hexagon::TFR_condset_rr: 95 case Hexagon::TFR_condset_rr_f: 96 case Hexagon::TFR_condset_rr64_f: { 97 int DestReg = MI->getOperand(0).getReg(); 98 int SrcReg1 = MI->getOperand(2).getReg(); 99 int SrcReg2 = MI->getOperand(3).getReg(); 100 101 if (MI->getOpcode() == Hexagon::TFR_condset_rr || 102 MI->getOpcode() == Hexagon::TFR_condset_rr_f) { 103 Opc1 = Hexagon::TFR_cPt; 104 Opc2 = Hexagon::TFR_cNotPt; 105 } 106 else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) { 107 Opc1 = Hexagon::TFR64_cPt; 108 Opc2 = Hexagon::TFR64_cNotPt; 109 } 110 111 // Minor optimization: do not emit the predicated copy if the source 112 // and the destination is the same register. 113 if (DestReg != SrcReg1) { 114 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc1), 115 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 116 } 117 if (DestReg != SrcReg2) { 118 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc2), 119 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 120 } 121 MII = MBB->erase(MI); 122 --MII; 123 break; 124 } 125 case Hexagon::TFR_condset_ri: 126 case Hexagon::TFR_condset_ri_f: { 127 int DestReg = MI->getOperand(0).getReg(); 128 int SrcReg1 = MI->getOperand(2).getReg(); 129 130 // Do not emit the predicated copy if the source and the destination 131 // is the same register. 132 if (DestReg != SrcReg1) { 133 BuildMI(*MBB, MII, MI->getDebugLoc(), 134 TII->get(Hexagon::TFR_cPt), DestReg). 135 addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 136 } 137 if (MI->getOpcode() == Hexagon::TFR_condset_ri ) { 138 BuildMI(*MBB, MII, MI->getDebugLoc(), 139 TII->get(Hexagon::TFRI_cNotPt), DestReg). 140 addReg(MI->getOperand(1).getReg()). 141 addImm(MI->getOperand(3).getImm()); 142 } else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) { 143 BuildMI(*MBB, MII, MI->getDebugLoc(), 144 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 145 addReg(MI->getOperand(1).getReg()). 146 addFPImm(MI->getOperand(3).getFPImm()); 147 } 148 149 MII = MBB->erase(MI); 150 --MII; 151 break; 152 } 153 case Hexagon::TFR_condset_ir: 154 case Hexagon::TFR_condset_ir_f: { 155 int DestReg = MI->getOperand(0).getReg(); 156 int SrcReg2 = MI->getOperand(3).getReg(); 157 158 if (MI->getOpcode() == Hexagon::TFR_condset_ir ) { 159 BuildMI(*MBB, MII, MI->getDebugLoc(), 160 TII->get(Hexagon::TFRI_cPt), DestReg). 161 addReg(MI->getOperand(1).getReg()). 162 addImm(MI->getOperand(2).getImm()); 163 } else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) { 164 BuildMI(*MBB, MII, MI->getDebugLoc(), 165 TII->get(Hexagon::TFRI_cPt_f), DestReg). 166 addReg(MI->getOperand(1).getReg()). 167 addFPImm(MI->getOperand(2).getFPImm()); 168 } 169 170 // Do not emit the predicated copy if the source and 171 // the destination is the same register. 172 if (DestReg != SrcReg2) { 173 BuildMI(*MBB, MII, MI->getDebugLoc(), 174 TII->get(Hexagon::TFR_cNotPt), DestReg). 175 addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 176 } 177 MII = MBB->erase(MI); 178 --MII; 179 break; 180 } 181 case Hexagon::TFR_condset_ii: 182 case Hexagon::TFR_condset_ii_f: { 183 int DestReg = MI->getOperand(0).getReg(); 184 int SrcReg1 = MI->getOperand(1).getReg(); 185 186 if (MI->getOpcode() == Hexagon::TFR_condset_ii ) { 187 int Immed1 = MI->getOperand(2).getImm(); 188 int Immed2 = MI->getOperand(3).getImm(); 189 BuildMI(*MBB, MII, MI->getDebugLoc(), 190 TII->get(Hexagon::TFRI_cPt), 191 DestReg).addReg(SrcReg1).addImm(Immed1); 192 BuildMI(*MBB, MII, MI->getDebugLoc(), 193 TII->get(Hexagon::TFRI_cNotPt), 194 DestReg).addReg(SrcReg1).addImm(Immed2); 195 } else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) { 196 BuildMI(*MBB, MII, MI->getDebugLoc(), 197 TII->get(Hexagon::TFRI_cPt_f), DestReg). 198 addReg(SrcReg1). 199 addFPImm(MI->getOperand(2).getFPImm()); 200 BuildMI(*MBB, MII, MI->getDebugLoc(), 201 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 202 addReg(SrcReg1). 203 addFPImm(MI->getOperand(3).getFPImm()); 204 } 205 MII = MBB->erase(MI); 206 --MII; 207 break; 208 } 209 } 210 } 211 } 212 return true; 213 } 214 215 } 216 217 //===----------------------------------------------------------------------===// 218 // Public Constructor Functions 219 //===----------------------------------------------------------------------===// 220 221 static void initializePassOnce(PassRegistry &Registry) { 222 const char *Name = "Hexagon Split TFRCondSets"; 223 PassInfo *PI = new PassInfo(Name, "hexagon-split-tfr", 224 &HexagonSplitTFRCondSets::ID, 0, false, false); 225 Registry.registerPass(*PI, true); 226 } 227 228 void llvm::initializeHexagonSplitTFRCondSetsPass(PassRegistry &Registry) { 229 CALL_ONCE_INITIALIZATION(initializePassOnce) 230 } 231 232 FunctionPass* 233 llvm::createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM) { 234 return new HexagonSplitTFRCondSets(TM); 235 } 236