HexagonSplitTFRCondSets.cpp revision 249423
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
50using namespace llvm;
51
52namespace {
53
54class HexagonSplitTFRCondSets : public MachineFunctionPass {
55    HexagonTargetMachine& QTM;
56    const HexagonSubtarget &QST;
57
58 public:
59    static char ID;
60    HexagonSplitTFRCondSets(HexagonTargetMachine& TM) :
61      MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) {}
62
63    const char *getPassName() const {
64      return "Hexagon Split TFRCondSets";
65    }
66    bool runOnMachineFunction(MachineFunction &Fn);
67};
68
69
70char HexagonSplitTFRCondSets::ID = 0;
71
72
73bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
74
75  const TargetInstrInfo *TII = QTM.getInstrInfo();
76
77  // Loop over all of the basic blocks.
78  for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
79       MBBb != MBBe; ++MBBb) {
80    MachineBasicBlock* MBB = MBBb;
81    // Traverse the basic block.
82    for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
83         ++MII) {
84      MachineInstr *MI = MII;
85      int Opc1, Opc2;
86      switch(MI->getOpcode()) {
87        case Hexagon::TFR_condset_rr:
88        case Hexagon::TFR_condset_rr_f:
89        case Hexagon::TFR_condset_rr64_f: {
90          int DestReg = MI->getOperand(0).getReg();
91          int SrcReg1 = MI->getOperand(2).getReg();
92          int SrcReg2 = MI->getOperand(3).getReg();
93
94          if (MI->getOpcode() == Hexagon::TFR_condset_rr ||
95              MI->getOpcode() == Hexagon::TFR_condset_rr_f) {
96            Opc1 = Hexagon::TFR_cPt;
97            Opc2 = Hexagon::TFR_cNotPt;
98          }
99          else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) {
100            Opc1 = Hexagon::TFR64_cPt;
101            Opc2 = Hexagon::TFR64_cNotPt;
102          }
103
104          // Minor optimization: do not emit the predicated copy if the source
105          // and the destination is the same register.
106          if (DestReg != SrcReg1) {
107            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc1),
108                    DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
109          }
110          if (DestReg != SrcReg2) {
111            BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Opc2),
112                    DestReg).addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
113          }
114          MII = MBB->erase(MI);
115          --MII;
116          break;
117        }
118        case Hexagon::TFR_condset_ri:
119        case Hexagon::TFR_condset_ri_f: {
120          int DestReg = MI->getOperand(0).getReg();
121          int SrcReg1 = MI->getOperand(2).getReg();
122
123          //  Do not emit the predicated copy if the source and the destination
124          // is the same register.
125          if (DestReg != SrcReg1) {
126            BuildMI(*MBB, MII, MI->getDebugLoc(),
127              TII->get(Hexagon::TFR_cPt), DestReg).
128              addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
129          }
130          if (MI->getOpcode() ==  Hexagon::TFR_condset_ri ) {
131            BuildMI(*MBB, MII, MI->getDebugLoc(),
132              TII->get(Hexagon::TFRI_cNotPt), DestReg).
133              addReg(MI->getOperand(1).getReg()).
134              addImm(MI->getOperand(3).getImm());
135          } else if (MI->getOpcode() ==  Hexagon::TFR_condset_ri_f ) {
136            BuildMI(*MBB, MII, MI->getDebugLoc(),
137              TII->get(Hexagon::TFRI_cNotPt_f), DestReg).
138              addReg(MI->getOperand(1).getReg()).
139              addFPImm(MI->getOperand(3).getFPImm());
140          }
141
142          MII = MBB->erase(MI);
143          --MII;
144          break;
145        }
146        case Hexagon::TFR_condset_ir:
147        case Hexagon::TFR_condset_ir_f: {
148          int DestReg = MI->getOperand(0).getReg();
149          int SrcReg2 = MI->getOperand(3).getReg();
150
151          if (MI->getOpcode() ==  Hexagon::TFR_condset_ir ) {
152            BuildMI(*MBB, MII, MI->getDebugLoc(),
153              TII->get(Hexagon::TFRI_cPt), DestReg).
154              addReg(MI->getOperand(1).getReg()).
155              addImm(MI->getOperand(2).getImm());
156          } else if (MI->getOpcode() ==  Hexagon::TFR_condset_ir_f ) {
157            BuildMI(*MBB, MII, MI->getDebugLoc(),
158              TII->get(Hexagon::TFRI_cPt_f), DestReg).
159              addReg(MI->getOperand(1).getReg()).
160              addFPImm(MI->getOperand(2).getFPImm());
161          }
162
163          // Do not emit the predicated copy if the source and
164          // the destination is the same register.
165          if (DestReg != SrcReg2) {
166            BuildMI(*MBB, MII, MI->getDebugLoc(),
167              TII->get(Hexagon::TFR_cNotPt), DestReg).
168              addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
169          }
170          MII = MBB->erase(MI);
171          --MII;
172          break;
173        }
174        case Hexagon::TFR_condset_ii:
175        case Hexagon::TFR_condset_ii_f: {
176          int DestReg = MI->getOperand(0).getReg();
177          int SrcReg1 = MI->getOperand(1).getReg();
178
179          if (MI->getOpcode() ==  Hexagon::TFR_condset_ii ) {
180            int Immed1 = MI->getOperand(2).getImm();
181            int Immed2 = MI->getOperand(3).getImm();
182            BuildMI(*MBB, MII, MI->getDebugLoc(),
183                    TII->get(Hexagon::TFRI_cPt),
184                    DestReg).addReg(SrcReg1).addImm(Immed1);
185            BuildMI(*MBB, MII, MI->getDebugLoc(),
186                    TII->get(Hexagon::TFRI_cNotPt),
187                    DestReg).addReg(SrcReg1).addImm(Immed2);
188          } else if (MI->getOpcode() ==  Hexagon::TFR_condset_ii_f ) {
189            BuildMI(*MBB, MII, MI->getDebugLoc(),
190                    TII->get(Hexagon::TFRI_cPt_f), DestReg).
191                    addReg(SrcReg1).
192                    addFPImm(MI->getOperand(2).getFPImm());
193            BuildMI(*MBB, MII, MI->getDebugLoc(),
194                    TII->get(Hexagon::TFRI_cNotPt_f), DestReg).
195                    addReg(SrcReg1).
196                    addFPImm(MI->getOperand(3).getFPImm());
197          }
198          MII = MBB->erase(MI);
199          --MII;
200          break;
201        }
202      }
203    }
204  }
205  return true;
206}
207
208}
209
210//===----------------------------------------------------------------------===//
211//                         Public Constructor Functions
212//===----------------------------------------------------------------------===//
213
214FunctionPass *llvm::createHexagonSplitTFRCondSets(HexagonTargetMachine &TM) {
215  return new HexagonSplitTFRCondSets(TM);
216}
217