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 "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