LLVM API Documentation

HexagonSplitTFRCondSets.cpp
Go to the documentation of this file.
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 }