LLVM: lib/Target/Hexagon/HexagonGenPredicate.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
30#include
31#include
32#include
33
34#define DEBUG_TYPE "gen-pred"
35
36using namespace llvm;
37
38namespace {
39
41
42struct PrintRegister {
44
47
48private:
51};
52
54 const PrintRegister &PR);
56 return OS << printReg(PR.Reg.Reg, &PR.TRI, PR.Reg.SubReg);
57}
58
60 public:
61 static char ID;
62
64
65 StringRef getPassName() const override {
66 return "Hexagon generate predicate operations";
67 }
68
69 void getAnalysisUsage(AnalysisUsage &AU) const override {
73 }
74
76
77 private:
81
85 SetOfReg PredGPRs;
86 VectOfInst PUsers;
87 RegToRegMap G2P;
88
92 unsigned getPredForm(unsigned Opc);
94 bool isScalarCmp(unsigned Opc);
99 };
100
101}
102
103char HexagonGenPredicate::ID = 0;
104
106 "Hexagon generate predicate operations", false, false)
109 "Hexagon generate predicate operations", false, false)
110
111bool HexagonGenPredicate::isPredReg(Register R) {
112 if (!R.isVirtual())
113 return false;
115 return RC == &Hexagon::PredRegsRegClass;
116}
117
118unsigned HexagonGenPredicate::getPredForm(unsigned Opc) {
119 using namespace Hexagon;
120
121 switch (Opc) {
122 case A2_and:
123 case A2_andp:
124 return C2_and;
125 case A4_andn:
126 case A4_andnp:
127 return C2_andn;
128 case M4_and_and:
129 return C4_and_and;
130 case M4_and_andn:
131 return C4_and_andn;
132 case M4_and_or:
133 return C4_and_or;
134
135 case A2_or:
136 case A2_orp:
137 return C2_or;
138 case A4_orn:
139 case A4_ornp:
140 return C2_orn;
141 case M4_or_and:
142 return C4_or_and;
143 case M4_or_andn:
144 return C4_or_andn;
145 case M4_or_or:
146 return C4_or_or;
147
148 case A2_xor:
149 case A2_xorp:
150 return C2_xor;
151
152 case C2_tfrrp:
153 return COPY;
154 }
155
156
157
158 static_assert(PHI == 0, "Use different value for ");
159 return 0;
160}
161
162bool HexagonGenPredicate::isConvertibleToPredForm(const MachineInstr *MI) {
163 unsigned Opc = MI->getOpcode();
164 if (getPredForm(Opc) != 0)
165 return true;
166
167
168
169
170
171 switch (Opc) {
172 case Hexagon::C2_cmpeqi:
173 case Hexagon::C4_cmpneqi:
174 if (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
175 return true;
176 break;
177 }
178 return false;
179}
180
181void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
182 for (MachineBasicBlock &B : MF) {
183 for (MachineInstr &MI : B) {
184 unsigned Opc = MI.getOpcode();
185 switch (Opc) {
186 case Hexagon::C2_tfrpr:
187 case TargetOpcode::COPY:
188 if (isPredReg(MI.getOperand(1).getReg())) {
192 }
193 break;
194 }
195 }
196 }
197}
198
199void HexagonGenPredicate::processPredicateGPR(const RegSubRegPair &Reg) {
201 << "\n");
203
204 use_iterator I = MRI->use_begin(Reg.Reg), E = MRI->use_end();
207 << '\n');
208 MachineInstr *DefI = MRI->getVRegDef(Reg.Reg);
210 return;
211 }
212
214 MachineInstr *UseI = I->getParent();
215 if (isConvertibleToPredForm(UseI))
217 }
218}
219
221
222
223
225 RegToRegMap::iterator F = G2P.find(Reg);
227 return F->second;
228
230 MachineInstr *DefI = MRI->getVRegDef(Reg.Reg);
233 if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) {
236 G2P.insert(std::make_pair(Reg, PR));
238 return PR;
239 }
240
241 MachineBasicBlock &B = *DefI->getParent();
243 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
244 Register NewPR = MRI->createVirtualRegister(PredRC);
245
246
247
248 if (isConvertibleToPredForm(DefI)) {
250 BuildMI(B, std::next(DefIt), DL, TII->get(TargetOpcode::COPY), NewPR)
254 << '\n');
256 }
257
259}
260
261bool HexagonGenPredicate::isScalarCmp(unsigned Opc) {
262 switch (Opc) {
263 case Hexagon::C2_cmpeq:
264 case Hexagon::C2_cmpgt:
265 case Hexagon::C2_cmpgtu:
266 case Hexagon::C2_cmpeqp:
267 case Hexagon::C2_cmpgtp:
268 case Hexagon::C2_cmpgtup:
269 case Hexagon::C2_cmpeqi:
270 case Hexagon::C2_cmpgti:
271 case Hexagon::C2_cmpgtui:
272 case Hexagon::C2_cmpgei:
273 case Hexagon::C2_cmpgeui:
274 case Hexagon::C4_cmpneqi:
275 case Hexagon::C4_cmpltei:
276 case Hexagon::C4_cmplteui:
277 case Hexagon::C4_cmpneq:
278 case Hexagon::C4_cmplte:
279 case Hexagon::C4_cmplteu:
280 case Hexagon::A4_cmpbeq:
281 case Hexagon::A4_cmpbeqi:
282 case Hexagon::A4_cmpbgtu:
283 case Hexagon::A4_cmpbgtui:
284 case Hexagon::A4_cmpbgt:
285 case Hexagon::A4_cmpbgti:
286 case Hexagon::A4_cmpheq:
287 case Hexagon::A4_cmphgt:
288 case Hexagon::A4_cmphgtu:
289 case Hexagon::A4_cmpheqi:
290 case Hexagon::A4_cmphgti:
291 case Hexagon::A4_cmphgtui:
292 return true;
293 }
294 return false;
295}
296
297bool HexagonGenPredicate::isScalarPred(RegSubRegPair PredReg) {
298 std::queue WorkQ;
299 WorkQ.push(PredReg);
300
301 while (!WorkQ.empty()) {
303 WorkQ.pop();
304 const MachineInstr *DefI = MRI->getVRegDef(PR.Reg);
305 if (!DefI)
306 return false;
307 unsigned DefOpc = DefI->getOpcode();
308 switch (DefOpc) {
309 case TargetOpcode::COPY: {
310 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
311 if (MRI->getRegClass(PR.Reg) != PredRC)
312 return false;
313
314 [[fallthrough]];
315 }
316 case Hexagon::C2_and:
317 case Hexagon::C2_andn:
318 case Hexagon::C4_and_and:
319 case Hexagon::C4_and_andn:
320 case Hexagon::C4_and_or:
321 case Hexagon::C2_or:
322 case Hexagon::C2_orn:
323 case Hexagon::C4_or_and:
324 case Hexagon::C4_or_andn:
325 case Hexagon::C4_or_or:
326 case Hexagon::C4_or_orn:
327 case Hexagon::C2_xor:
328
329 for (const MachineOperand &MO : DefI->operands())
330 if (MO.isReg() && MO.isUse())
332 break;
333
334
335 default:
336 return isScalarCmp(DefOpc);
337 }
338 }
339
340 return true;
341}
342
343bool HexagonGenPredicate::convertToPredForm(MachineInstr *MI) {
345
346 unsigned Opc = MI->getOpcode();
347 assert(isConvertibleToPredForm(MI));
348 unsigned NumOps = MI->getNumOperands();
349 for (unsigned i = 0; i < NumOps; ++i) {
350 MachineOperand &MO = MI->getOperand(i);
352 continue;
354 if (Reg.SubReg && Reg.SubReg != Hexagon::isub_lo)
355 return false;
357 return false;
358 }
359
360 MachineBasicBlock &B = *MI->getParent();
362
363 unsigned NewOpc = getPredForm(Opc);
364
365 if (NewOpc == 0) {
366 switch (Opc) {
367 case Hexagon::C2_cmpeqi:
368 NewOpc = Hexagon::C2_not;
369 break;
370 case Hexagon::C4_cmpneqi:
371 NewOpc = TargetOpcode::COPY;
372 break;
373 default:
374 return false;
375 }
376
377
378
379
381 if (!isScalarPred(PR))
382 return false;
383
384
386 }
387
388
389 MachineOperand &Op0 = MI->getOperand(0);
392
393
394
395
396 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
398 MachineInstrBuilder MIB = BuildMI(B, MI, DL, TII->get(NewOpc), NewPR.Reg);
399
400
401 for (unsigned i = 1; i < NumOps; ++i) {
405 }
407
408
409
410 const TargetRegisterClass *RC = MRI->getRegClass(OutR.Reg);
411 Register NewOutR = MRI->createVirtualRegister(RC);
412 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), NewOutR)
414 MRI->replaceRegWith(OutR.Reg, NewOutR);
415 MI->eraseFromParent();
416
417
418
419
423 processPredicateGPR(R);
424 }
425 return true;
426}
427
428bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
430 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
432 VectOfInst Erase;
433
434
435
436
437
438
439
440
441
442
443
444 for (MachineBasicBlock &MBB : MF) {
445 for (MachineInstr &MI : MBB) {
446 if (MI.getOpcode() != TargetOpcode::COPY)
447 continue;
451 continue;
453 continue;
454 if (MRI->getRegClass(DR.Reg) != PredRC)
455 continue;
456 if (MRI->getRegClass(SR.Reg) != PredRC)
457 continue;
459 MRI->replaceRegWith(DR.Reg, SR.Reg);
460 Erase.insert(&MI);
462 }
463 }
464
465 for (MachineInstr *MI : Erase)
466 MI->eraseFromParent();
467
469}
470
471bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
473 return false;
474
475 TII = MF.getSubtarget().getInstrInfo();
476 TRI = MF.getSubtarget().getRegisterInfo();
478 PredGPRs.clear();
481
483 collectPredicateGPR(MF);
485 processPredicateGPR(R);
486
487 bool Again;
488 do {
489 Again = false;
490 VectOfInst Processed, Copy;
491
492 Copy = PUsers;
493 for (MachineInstr *MI : Copy) {
494 bool Done = convertToPredForm(MI);
496 Processed.insert(MI);
497 Again = true;
498 }
499 }
501
502 auto Done = [Processed] (MachineInstr *MI) -> bool {
503 return Processed.count(MI);
504 };
506 } while (Again);
507
508 Changed |= eliminatePredCopies(MF);
510}
511
513 return new HexagonGenPredicate();
514}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
A vector that has set insertion semantics.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isPredReg(MCRegisterInfo const &MRI, MCRegister Reg)
This is an optimization pass for GlobalISel generic memory operations.
TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)
Create RegSubRegPair from a register MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonGenPredicate()
Definition HexagonGenPredicate.cpp:512
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A pair composed of a register and a sub-register index.