Home | History | Annotate | Download | only in Hexagon
      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