Make references to HexagonTargetMachine "const".
[oota-llvm.git] / lib / Target / Hexagon / HexagonSplitTFRCondSets.cpp
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 {
53
54 class HexagonSplitTFRCondSets : public MachineFunctionPass {
55     const HexagonTargetMachine &QTM;
56     const HexagonSubtarget &QST;
57
58  public:
59     static char ID;
60     HexagonSplitTFRCondSets(const 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
70 char HexagonSplitTFRCondSets::ID = 0;
71
72
73 bool 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
214 FunctionPass*
215 llvm::createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM) {
216   return new HexagonSplitTFRCondSets(TM);
217 }