LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HexagonSplitTFRCondSets.cpp
Go to the documentation of this file.
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"
32 #include "HexagonSubtarget.h"
33 #include "HexagonTargetMachine.h"
40 #include "llvm/CodeGen/Passes.h"
43 #include "llvm/Support/Compiler.h"
44 #include "llvm/Support/Debug.h"
49 
50 using namespace llvm;
51 
52 namespace llvm {
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()) {
68  }
69 
70  const char *getPassName() const {
71  return "Hexagon Split TFRCondSets";
72  }
73  bool runOnMachineFunction(MachineFunction &Fn);
74 };
75 
76 
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 
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 
230 }
231 
234  return new HexagonSplitTFRCondSets(TM);
235 }
instr_iterator erase(instr_iterator I)
static PassRegistry * getPassRegistry()
const ConstantFP * getFPImm() const
const HexagonInstrInfo * TII
void initializeHexagonSplitTFRCondSetsPass(PassRegistry &)
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
int getOpcode() const
Definition: MachineInstr.h:261
int64_t getImm() const
bundle_iterator< MachineInstr, instr_iterator > iterator
const MCInstrInfo & MII
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
static void initializePassOnce(PassRegistry &Registry)
const MCInstrDesc & get(unsigned Opcode) const
Definition: MCInstrInfo.h:48
FunctionPass * createHexagonSplitTFRCondSets(const HexagonTargetMachine &TM)
unsigned getReg() const
getReg - Returns the register number.
#define CALL_ONCE_INITIALIZATION(function)
Definition: PassSupport.h:133
BasicBlockListType::iterator iterator
void registerPass(const PassInfo &PI, bool ShouldFree=false)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244