LLVM API Documentation
00001 //===-- HexagonSplitTFRCondSets.cpp - split TFR condsets into xfers -------===// 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 //===----------------------------------------------------------------------===// 00010 // This pass tries to provide opportunities for better optimization of muxes. 00011 // The default code generated for something like: flag = (a == b) ? 1 : 3; 00012 // would be: 00013 // 00014 // {p0 = cmp.eq(r0,r1)} 00015 // {r3 = mux(p0,#1,#3)} 00016 // 00017 // This requires two packets. If we use .new predicated immediate transfers, 00018 // then we can do this in a single packet, e.g.: 00019 // 00020 // {p0 = cmp.eq(r0,r1) 00021 // if (p0.new) r3 = #1 00022 // if (!p0.new) r3 = #3} 00023 // 00024 // Note that the conditional assignments are not generated in .new form here. 00025 // We assume opptimisically that they will be formed later. 00026 // 00027 //===----------------------------------------------------------------------===// 00028 00029 #include "Hexagon.h" 00030 #include "HexagonMachineFunctionInfo.h" 00031 #include "HexagonSubtarget.h" 00032 #include "HexagonTargetMachine.h" 00033 #include "llvm/CodeGen/LatencyPriorityQueue.h" 00034 #include "llvm/CodeGen/MachineDominators.h" 00035 #include "llvm/CodeGen/MachineFunctionPass.h" 00036 #include "llvm/CodeGen/MachineInstrBuilder.h" 00037 #include "llvm/CodeGen/MachineLoopInfo.h" 00038 #include "llvm/CodeGen/MachineRegisterInfo.h" 00039 #include "llvm/CodeGen/Passes.h" 00040 #include "llvm/CodeGen/ScheduleHazardRecognizer.h" 00041 #include "llvm/CodeGen/SchedulerRegistry.h" 00042 #include "llvm/Support/Compiler.h" 00043 #include "llvm/Support/Debug.h" 00044 #include "llvm/Support/MathExtras.h" 00045 #include "llvm/Target/TargetInstrInfo.h" 00046 #include "llvm/Target/TargetMachine.h" 00047 #include "llvm/Target/TargetRegisterInfo.h" 00048 00049 using namespace llvm; 00050 00051 #define DEBUG_TYPE "xfer" 00052 00053 namespace llvm { 00054 void initializeHexagonSplitTFRCondSetsPass(PassRegistry&); 00055 } 00056 00057 00058 namespace { 00059 00060 class HexagonSplitTFRCondSets : public MachineFunctionPass { 00061 const HexagonTargetMachine &QTM; 00062 const HexagonSubtarget &QST; 00063 00064 public: 00065 static char ID; 00066 HexagonSplitTFRCondSets(const HexagonTargetMachine& TM) : 00067 MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) { 00068 initializeHexagonSplitTFRCondSetsPass(*PassRegistry::getPassRegistry()); 00069 } 00070 00071 const char *getPassName() const override { 00072 return "Hexagon Split TFRCondSets"; 00073 } 00074 bool runOnMachineFunction(MachineFunction &Fn) override; 00075 }; 00076 00077 00078 char HexagonSplitTFRCondSets::ID = 0; 00079 00080 00081 bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) { 00082 00083 const TargetInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo(); 00084 00085 // Loop over all of the basic blocks. 00086 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 00087 MBBb != MBBe; ++MBBb) { 00088 MachineBasicBlock* MBB = MBBb; 00089 // Traverse the basic block. 00090 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 00091 ++MII) { 00092 MachineInstr *MI = MII; 00093 int Opc1, Opc2; 00094 switch(MI->getOpcode()) { 00095 case Hexagon::TFR_condset_rr: 00096 case Hexagon::TFR_condset_rr_f: 00097 case Hexagon::TFR_condset_rr64_f: { 00098 int DestReg = MI->getOperand(0).getReg(); 00099 int SrcReg1 = MI->getOperand(2).getReg(); 00100 int SrcReg2 = MI->getOperand(3).getReg(); 00101 00102 if (MI->getOpcode() == Hexagon::TFR_condset_rr || 00103 MI->getOpcode() == Hexagon::TFR_condset_rr_f) { 00104 Opc1 = Hexagon::TFR_cPt; 00105 Opc2 = Hexagon::TFR_cNotPt; 00106 } 00107 else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) { 00108 Opc1 = Hexagon::TFR64_cPt; 00109 Opc2 = Hexagon::TFR64_cNotPt; 00110 } 00111 00112 // Minor optimization: do not emit the predicated copy if the source 00113 // and the destination is the same register. 00114 if (DestReg != SrcReg1) { 00115 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc1), 00116 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 00117 } 00118 if (DestReg != SrcReg2) { 00119 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc2), 00120 DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 00121 } 00122 MII = MBB->erase(MI); 00123 --MII; 00124 break; 00125 } 00126 case Hexagon::TFR_condset_ri: 00127 case Hexagon::TFR_condset_ri_f: { 00128 int DestReg = MI->getOperand(0).getReg(); 00129 int SrcReg1 = MI->getOperand(2).getReg(); 00130 00131 // Do not emit the predicated copy if the source and the destination 00132 // is the same register. 00133 if (DestReg != SrcReg1) { 00134 BuildMI(*MBB, MII, MI->getDebugLoc(), 00135 TII->get(Hexagon::TFR_cPt), DestReg). 00136 addReg(MI->getOperand(1).getReg()).addReg(SrcReg1); 00137 } 00138 if (MI->getOpcode() == Hexagon::TFR_condset_ri ) { 00139 BuildMI(*MBB, MII, MI->getDebugLoc(), 00140 TII->get(Hexagon::TFRI_cNotPt), DestReg). 00141 addReg(MI->getOperand(1).getReg()). 00142 addImm(MI->getOperand(3).getImm()); 00143 } else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) { 00144 BuildMI(*MBB, MII, MI->getDebugLoc(), 00145 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 00146 addReg(MI->getOperand(1).getReg()). 00147 addFPImm(MI->getOperand(3).getFPImm()); 00148 } 00149 00150 MII = MBB->erase(MI); 00151 --MII; 00152 break; 00153 } 00154 case Hexagon::TFR_condset_ir: 00155 case Hexagon::TFR_condset_ir_f: { 00156 int DestReg = MI->getOperand(0).getReg(); 00157 int SrcReg2 = MI->getOperand(3).getReg(); 00158 00159 if (MI->getOpcode() == Hexagon::TFR_condset_ir ) { 00160 BuildMI(*MBB, MII, MI->getDebugLoc(), 00161 TII->get(Hexagon::TFRI_cPt), DestReg). 00162 addReg(MI->getOperand(1).getReg()). 00163 addImm(MI->getOperand(2).getImm()); 00164 } else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) { 00165 BuildMI(*MBB, MII, MI->getDebugLoc(), 00166 TII->get(Hexagon::TFRI_cPt_f), DestReg). 00167 addReg(MI->getOperand(1).getReg()). 00168 addFPImm(MI->getOperand(2).getFPImm()); 00169 } 00170 00171 // Do not emit the predicated copy if the source and 00172 // the destination is the same register. 00173 if (DestReg != SrcReg2) { 00174 BuildMI(*MBB, MII, MI->getDebugLoc(), 00175 TII->get(Hexagon::TFR_cNotPt), DestReg). 00176 addReg(MI->getOperand(1).getReg()).addReg(SrcReg2); 00177 } 00178 MII = MBB->erase(MI); 00179 --MII; 00180 break; 00181 } 00182 case Hexagon::TFR_condset_ii: 00183 case Hexagon::TFR_condset_ii_f: { 00184 int DestReg = MI->getOperand(0).getReg(); 00185 int SrcReg1 = MI->getOperand(1).getReg(); 00186 00187 if (MI->getOpcode() == Hexagon::TFR_condset_ii ) { 00188 int Immed1 = MI->getOperand(2).getImm(); 00189 int Immed2 = MI->getOperand(3).getImm(); 00190 BuildMI(*MBB, MII, MI->getDebugLoc(), 00191 TII->get(Hexagon::TFRI_cPt), 00192 DestReg).addReg(SrcReg1).addImm(Immed1); 00193 BuildMI(*MBB, MII, MI->getDebugLoc(), 00194 TII->get(Hexagon::TFRI_cNotPt), 00195 DestReg).addReg(SrcReg1).addImm(Immed2); 00196 } else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) { 00197 BuildMI(*MBB, MII, MI->getDebugLoc(), 00198 TII->get(Hexagon::TFRI_cPt_f), DestReg). 00199 addReg(SrcReg1). 00200 addFPImm(MI->getOperand(2).getFPImm()); 00201 BuildMI(*MBB, MII, MI->getDebugLoc(), 00202 TII->get(Hexagon::TFRI_cNotPt_f), DestReg). 00203 addReg(SrcReg1). 00204 addFPImm(MI->getOperand(3).getFPImm()); 00205 } 00206 MII = MBB->erase(MI); 00207 --MII; 00208 break; 00209 } 00210 } 00211 } 00212 } 00213 return true; 00214 } 00215 00216 } 00217 00218 //===----------------------------------------------------------------------===// 00219 // Public Constructor Functions 00220 //===----------------------------------------------------------------------===// 00221 00222 static void initializePassOnce(PassRegistry &Registry) { 00223 const char *Name = "Hexagon Split TFRCondSets"; 00224 PassInfo *PI = new PassInfo(Name, "hexagon-split-tfr", 00225 &HexagonSplitTFRCondSets::ID, nullptr, false, 00226 false); 00227 Registry.registerPass(*PI, true); 00228 } 00229 00230 void llvm::initializeHexagonSplitTFRCondSetsPass(PassRegistry &Registry) { 00231 CALL_ONCE_INITIALIZATION(initializePassOnce) 00232 } 00233 00234 FunctionPass* 00235 llvm::createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM) { 00236 return new HexagonSplitTFRCondSets(TM); 00237 }