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 Opc = MI->getOpcode();
     85       if (Opc == Hexagon::TFR_condset_rr) {
     86 
     87         int DestReg = MI->getOperand(0).getReg();
     88         int SrcReg1 = MI->getOperand(2).getReg();
     89         int SrcReg2 = MI->getOperand(3).getReg();
     90 
     91         // Minor optimization: do not emit the predicated copy if the source and
     92         // the destination is the same register
     93         if (DestReg != SrcReg1) {
     94           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_cPt),
     95                   DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
     96         }
     97         if (DestReg != SrcReg2) {
     98           BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_cNotPt),
     99                   DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
    100         }
    101         MII = MBB->erase(MI);
    102         --MII;
    103       } else if (Opc == Hexagon::TFR_condset_ii) {
    104         int DestReg = MI->getOperand(0).getReg();
    105         int SrcReg1 = MI->getOperand(1).getReg();
    106         int Immed1 = MI->getOperand(2).getImm();
    107         int Immed2 = MI->getOperand(3).getImm();
    108         BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFRI_cPt),
    109                 DestReg).addReg(SrcReg1).addImm(Immed1);
    110         BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFRI_cNotPt),
    111                 DestReg).addReg(SrcReg1).addImm(Immed2);
    112         MII = MBB->erase(MI);
    113         --MII;
    114       }
    115     }
    116   }
    117 
    118   return true;
    119 }
    120 
    121 }
    122 
    123 //===----------------------------------------------------------------------===//
    124 //                         Public Constructor Functions
    125 //===----------------------------------------------------------------------===//
    126 
    127 FunctionPass *llvm::createHexagonSplitTFRCondSets(HexagonTargetMachine &TM) {
    128   return new HexagonSplitTFRCondSets(TM);
    129 }
    130