LLVM  7.0.0svn
X86DomainReassignment.cpp
Go to the documentation of this file.
1 //===--- X86DomainReassignment.cpp - Selectively switch register classes---===//
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 attempts to find instruction chains (closures) in one domain,
11 // and convert them to equivalent instructions in a different domain,
12 // if profitable.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "X86.h"
17 #include "X86InstrInfo.h"
18 #include "X86Subtarget.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/DenseMapInfo.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Statistic.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/Printable.h"
30 #include <bitset>
31 
32 using namespace llvm;
33 
34 namespace llvm {
36 }
37 
38 #define DEBUG_TYPE "x86-domain-reassignment"
39 
40 STATISTIC(NumClosuresConverted, "Number of closures converted by the pass");
41 
43  "disable-x86-domain-reassignment", cl::Hidden,
44  cl::desc("X86: Disable Virtual Register Reassignment."), cl::init(false));
45 
46 namespace {
47 enum RegDomain { NoDomain = -1, GPRDomain, MaskDomain, OtherDomain, NumDomains };
48 
49 static bool isGPR(const TargetRegisterClass *RC) {
50  return X86::GR64RegClass.hasSubClassEq(RC) ||
51  X86::GR32RegClass.hasSubClassEq(RC) ||
52  X86::GR16RegClass.hasSubClassEq(RC) ||
53  X86::GR8RegClass.hasSubClassEq(RC);
54 }
55 
56 static bool isMask(const TargetRegisterClass *RC,
57  const TargetRegisterInfo *TRI) {
58  return X86::VK16RegClass.hasSubClassEq(RC);
59 }
60 
61 static RegDomain getDomain(const TargetRegisterClass *RC,
62  const TargetRegisterInfo *TRI) {
63  if (isGPR(RC))
64  return GPRDomain;
65  if (isMask(RC, TRI))
66  return MaskDomain;
67  return OtherDomain;
68 }
69 
70 /// Return a register class equivalent to \p SrcRC, in \p Domain.
71 static const TargetRegisterClass *getDstRC(const TargetRegisterClass *SrcRC,
72  RegDomain Domain) {
73  assert(Domain == MaskDomain && "add domain");
74  if (X86::GR8RegClass.hasSubClassEq(SrcRC))
75  return &X86::VK8RegClass;
76  if (X86::GR16RegClass.hasSubClassEq(SrcRC))
77  return &X86::VK16RegClass;
78  if (X86::GR32RegClass.hasSubClassEq(SrcRC))
79  return &X86::VK32RegClass;
80  if (X86::GR64RegClass.hasSubClassEq(SrcRC))
81  return &X86::VK64RegClass;
82  llvm_unreachable("add register class");
83  return nullptr;
84 }
85 
86 /// Abstract Instruction Converter class.
87 class InstrConverterBase {
88 protected:
89  unsigned SrcOpcode;
90 
91 public:
92  InstrConverterBase(unsigned SrcOpcode) : SrcOpcode(SrcOpcode) {}
93 
94  virtual ~InstrConverterBase() {}
95 
96  /// \returns true if \p MI is legal to convert.
97  virtual bool isLegal(const MachineInstr *MI,
98  const TargetInstrInfo *TII) const {
99  assert(MI->getOpcode() == SrcOpcode &&
100  "Wrong instruction passed to converter");
101  return true;
102  }
103 
104  /// Applies conversion to \p MI.
105  ///
106  /// \returns true if \p MI is no longer need, and can be deleted.
107  virtual bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
108  MachineRegisterInfo *MRI) const = 0;
109 
110  /// \returns the cost increment incurred by converting \p MI.
111  virtual double getExtraCost(const MachineInstr *MI,
112  MachineRegisterInfo *MRI) const = 0;
113 };
114 
115 /// An Instruction Converter which ignores the given instruction.
116 /// For example, PHI instructions can be safely ignored since only the registers
117 /// need to change.
118 class InstrIgnore : public InstrConverterBase {
119 public:
120  InstrIgnore(unsigned SrcOpcode) : InstrConverterBase(SrcOpcode) {}
121 
122  bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
123  MachineRegisterInfo *MRI) const override {
124  assert(isLegal(MI, TII) && "Cannot convert instruction");
125  return false;
126  }
127 
128  double getExtraCost(const MachineInstr *MI,
129  MachineRegisterInfo *MRI) const override {
130  return 0;
131  }
132 };
133 
134 /// An Instruction Converter which replaces an instruction with another.
135 class InstrReplacer : public InstrConverterBase {
136 public:
137  /// Opcode of the destination instruction.
138  unsigned DstOpcode;
139 
140  InstrReplacer(unsigned SrcOpcode, unsigned DstOpcode)
141  : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
142 
143  bool isLegal(const MachineInstr *MI,
144  const TargetInstrInfo *TII) const override {
145  if (!InstrConverterBase::isLegal(MI, TII))
146  return false;
147  // It's illegal to replace an instruction that implicitly defines a register
148  // with an instruction that doesn't, unless that register dead.
149  for (auto &MO : MI->implicit_operands())
150  if (MO.isReg() && MO.isDef() && !MO.isDead() &&
151  !TII->get(DstOpcode).hasImplicitDefOfPhysReg(MO.getReg()))
152  return false;
153  return true;
154  }
155 
156  bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
157  MachineRegisterInfo *MRI) const override {
158  assert(isLegal(MI, TII) && "Cannot convert instruction");
159  MachineInstrBuilder Bld =
160  BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(DstOpcode));
161  // Transfer explicit operands from original instruction. Implicit operands
162  // are handled by BuildMI.
163  for (auto &Op : MI->explicit_operands())
164  Bld.add(Op);
165  return true;
166  }
167 
168  double getExtraCost(const MachineInstr *MI,
169  MachineRegisterInfo *MRI) const override {
170  // Assuming instructions have the same cost.
171  return 0;
172  }
173 };
174 
175 /// An Instruction Converter which replaces an instruction with another, and
176 /// adds a COPY from the new instruction's destination to the old one's.
177 class InstrReplacerDstCOPY : public InstrConverterBase {
178 public:
179  unsigned DstOpcode;
180 
181  InstrReplacerDstCOPY(unsigned SrcOpcode, unsigned DstOpcode)
182  : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
183 
184  bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
185  MachineRegisterInfo *MRI) const override {
186  assert(isLegal(MI, TII) && "Cannot convert instruction");
187  MachineBasicBlock *MBB = MI->getParent();
188  auto &DL = MI->getDebugLoc();
189 
190  unsigned Reg = MRI->createVirtualRegister(
191  TII->getRegClass(TII->get(DstOpcode), 0, MRI->getTargetRegisterInfo(),
192  *MBB->getParent()));
193  MachineInstrBuilder Bld = BuildMI(*MBB, MI, DL, TII->get(DstOpcode), Reg);
194  for (unsigned Idx = 1, End = MI->getNumOperands(); Idx < End; ++Idx)
195  Bld.add(MI->getOperand(Idx));
196 
197  BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY))
198  .add(MI->getOperand(0))
199  .addReg(Reg);
200 
201  return true;
202  }
203 
204  double getExtraCost(const MachineInstr *MI,
205  MachineRegisterInfo *MRI) const override {
206  // Assuming instructions have the same cost, and that COPY is in the same
207  // domain so it will be eliminated.
208  return 0;
209  }
210 };
211 
212 /// An Instruction Converter for replacing COPY instructions.
213 class InstrCOPYReplacer : public InstrReplacer {
214 public:
215  RegDomain DstDomain;
216 
217  InstrCOPYReplacer(unsigned SrcOpcode, RegDomain DstDomain, unsigned DstOpcode)
218  : InstrReplacer(SrcOpcode, DstOpcode), DstDomain(DstDomain) {}
219 
220  double getExtraCost(const MachineInstr *MI,
221  MachineRegisterInfo *MRI) const override {
222  assert(MI->getOpcode() == TargetOpcode::COPY && "Expected a COPY");
223 
224  for (auto &MO : MI->operands()) {
225  // Physical registers will not be converted. Assume that converting the
226  // COPY to the destination domain will eventually result in a actual
227  // instruction.
229  return 1;
230 
231  RegDomain OpDomain = getDomain(MRI->getRegClass(MO.getReg()),
232  MRI->getTargetRegisterInfo());
233  // Converting a cross domain COPY to a same domain COPY should eliminate
234  // an insturction
235  if (OpDomain == DstDomain)
236  return -1;
237  }
238  return 0;
239  }
240 };
241 
242 /// An Instruction Converter which replaces an instruction with a COPY.
243 class InstrReplaceWithCopy : public InstrConverterBase {
244 public:
245  // Source instruction operand Index, to be used as the COPY source.
246  unsigned SrcOpIdx;
247 
248  InstrReplaceWithCopy(unsigned SrcOpcode, unsigned SrcOpIdx)
249  : InstrConverterBase(SrcOpcode), SrcOpIdx(SrcOpIdx) {}
250 
251  bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
252  MachineRegisterInfo *MRI) const override {
253  assert(isLegal(MI, TII) && "Cannot convert instruction");
254  BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
255  TII->get(TargetOpcode::COPY))
256  .add({MI->getOperand(0), MI->getOperand(SrcOpIdx)});
257  return true;
258  }
259 
260  double getExtraCost(const MachineInstr *MI,
261  MachineRegisterInfo *MRI) const override {
262  return 0;
263  }
264 };
265 
266 // Key type to be used by the Instruction Converters map.
267 // A converter is identified by <destination domain, source opcode>
268 typedef std::pair<int, unsigned> InstrConverterBaseKeyTy;
269 
271  InstrConverterBaseMap;
272 
273 /// A closure is a set of virtual register representing all of the edges in
274 /// the closure, as well as all of the instructions connected by those edges.
275 ///
276 /// A closure may encompass virtual registers in the same register bank that
277 /// have different widths. For example, it may contain 32-bit GPRs as well as
278 /// 64-bit GPRs.
279 ///
280 /// A closure that computes an address (i.e. defines a virtual register that is
281 /// used in a memory operand) excludes the instructions that contain memory
282 /// operands using the address. Such an instruction will be included in a
283 /// different closure that manipulates the loaded or stored value.
284 class Closure {
285 private:
286  /// Virtual registers in the closure.
287  DenseSet<unsigned> Edges;
288 
289  /// Instructions in the closure.
291 
292  /// Domains which this closure can legally be reassigned to.
293  std::bitset<NumDomains> LegalDstDomains;
294 
295  /// An ID to uniquely identify this closure, even when it gets
296  /// moved around
297  unsigned ID;
298 
299 public:
300  Closure(unsigned ID, std::initializer_list<RegDomain> LegalDstDomainList) : ID(ID) {
301  for (RegDomain D : LegalDstDomainList)
302  LegalDstDomains.set(D);
303  }
304 
305  /// Mark this closure as illegal for reassignment to all domains.
306  void setAllIllegal() { LegalDstDomains.reset(); }
307 
308  /// \returns true if this closure has domains which are legal to reassign to.
309  bool hasLegalDstDomain() const { return LegalDstDomains.any(); }
310 
311  /// \returns true if is legal to reassign this closure to domain \p RD.
312  bool isLegal(RegDomain RD) const { return LegalDstDomains[RD]; }
313 
314  /// Mark this closure as illegal for reassignment to domain \p RD.
315  void setIllegal(RegDomain RD) { LegalDstDomains[RD] = false; }
316 
317  bool empty() const { return Edges.empty(); }
318 
319  bool insertEdge(unsigned Reg) {
320  return Edges.insert(Reg).second;
321  }
322 
323  using const_edge_iterator = DenseSet<unsigned>::const_iterator;
325  return iterator_range<const_edge_iterator>(Edges.begin(), Edges.end());
326  }
327 
328  void addInstruction(MachineInstr *I) {
329  Instrs.push_back(I);
330  }
331 
333  return Instrs;
334  }
335 
336  LLVM_DUMP_METHOD void dump(const MachineRegisterInfo *MRI) const {
337  dbgs() << "Registers: ";
338  bool First = true;
339  for (unsigned Reg : Edges) {
340  if (!First)
341  dbgs() << ", ";
342  First = false;
343  dbgs() << printReg(Reg, MRI->getTargetRegisterInfo(), 0, MRI);
344  }
345  dbgs() << "\n" << "Instructions:";
346  for (MachineInstr *MI : Instrs) {
347  dbgs() << "\n ";
348  MI->print(dbgs());
349  }
350  dbgs() << "\n";
351  }
352 
353  unsigned getID() const {
354  return ID;
355  }
356 
357 };
358 
359 class X86DomainReassignment : public MachineFunctionPass {
360  const X86Subtarget *STI;
362  const X86InstrInfo *TII;
363 
364  /// All edges that are included in some closure
365  DenseSet<unsigned> EnclosedEdges;
366 
367  /// All instructions that are included in some closure.
368  DenseMap<MachineInstr *, unsigned> EnclosedInstrs;
369 
370 public:
371  static char ID;
372 
373  X86DomainReassignment() : MachineFunctionPass(ID) {
375  }
376 
377  bool runOnMachineFunction(MachineFunction &MF) override;
378 
379  void getAnalysisUsage(AnalysisUsage &AU) const override {
380  AU.setPreservesCFG();
382  }
383 
384  StringRef getPassName() const override {
385  return "X86 Domain Reassignment Pass";
386  }
387 
388 private:
389  /// A map of available Instruction Converters.
390  InstrConverterBaseMap Converters;
391 
392  /// Initialize Converters map.
393  void initConverters();
394 
395  /// Starting from \Reg, expand the closure as much as possible.
396  void buildClosure(Closure &, unsigned Reg);
397 
398  /// Enqueue \p Reg to be considered for addition to the closure.
399  void visitRegister(Closure &, unsigned Reg, RegDomain &Domain,
400  SmallVectorImpl<unsigned> &Worklist);
401 
402  /// Reassign the closure to \p Domain.
403  void reassign(const Closure &C, RegDomain Domain) const;
404 
405  /// Add \p MI to the closure.
406  void encloseInstr(Closure &C, MachineInstr *MI);
407 
408  /// /returns true if it is profitable to reassign the closure to \p Domain.
409  bool isReassignmentProfitable(const Closure &C, RegDomain Domain) const;
410 
411  /// Calculate the total cost of reassigning the closure to \p Domain.
412  double calculateCost(const Closure &C, RegDomain Domain) const;
413 };
414 
416 
417 } // End anonymous namespace.
418 
419 void X86DomainReassignment::visitRegister(Closure &C, unsigned Reg,
420  RegDomain &Domain,
421  SmallVectorImpl<unsigned> &Worklist) {
422  if (EnclosedEdges.count(Reg))
423  return;
424 
426  return;
427 
428  if (!MRI->hasOneDef(Reg))
429  return;
430 
431  RegDomain RD = getDomain(MRI->getRegClass(Reg), MRI->getTargetRegisterInfo());
432  // First edge in closure sets the domain.
433  if (Domain == NoDomain)
434  Domain = RD;
435 
436  if (Domain != RD)
437  return;
438 
439  Worklist.push_back(Reg);
440 }
441 
442 void X86DomainReassignment::encloseInstr(Closure &C, MachineInstr *MI) {
443  auto I = EnclosedInstrs.find(MI);
444  if (I != EnclosedInstrs.end()) {
445  if (I->second != C.getID())
446  // Instruction already belongs to another closure, avoid conflicts between
447  // closure and mark this closure as illegal.
448  C.setAllIllegal();
449  return;
450  }
451 
452  EnclosedInstrs[MI] = C.getID();
453  C.addInstruction(MI);
454 
455  // Mark closure as illegal for reassignment to domains, if there is no
456  // converter for the instruction or if the converter cannot convert the
457  // instruction.
458  for (int i = 0; i != NumDomains; ++i) {
459  if (C.isLegal((RegDomain)i)) {
460  InstrConverterBase *IC = Converters.lookup({i, MI->getOpcode()});
461  if (!IC || !IC->isLegal(MI, TII))
462  C.setIllegal((RegDomain)i);
463  }
464  }
465 }
466 
467 double X86DomainReassignment::calculateCost(const Closure &C,
468  RegDomain DstDomain) const {
469  assert(C.isLegal(DstDomain) && "Cannot calculate cost for illegal closure");
470 
471  double Cost = 0.0;
472  for (auto *MI : C.instructions())
473  Cost +=
474  Converters.lookup({DstDomain, MI->getOpcode()})->getExtraCost(MI, MRI);
475  return Cost;
476 }
477 
478 bool X86DomainReassignment::isReassignmentProfitable(const Closure &C,
479  RegDomain Domain) const {
480  return calculateCost(C, Domain) < 0.0;
481 }
482 
483 void X86DomainReassignment::reassign(const Closure &C, RegDomain Domain) const {
484  assert(C.isLegal(Domain) && "Cannot convert illegal closure");
485 
486  // Iterate all instructions in the closure, convert each one using the
487  // appropriate converter.
489  for (auto *MI : C.instructions())
490  if (Converters.lookup({Domain, MI->getOpcode()})
491  ->convertInstr(MI, TII, MRI))
492  ToErase.push_back(MI);
493 
494  // Iterate all registers in the closure, replace them with registers in the
495  // destination domain.
496  for (unsigned Reg : C.edges()) {
497  MRI->setRegClass(Reg, getDstRC(MRI->getRegClass(Reg), Domain));
498  for (auto &MO : MRI->use_operands(Reg)) {
499  if (MO.isReg())
500  // Remove all subregister references as they are not valid in the
501  // destination domain.
502  MO.setSubReg(0);
503  }
504  }
505 
506  for (auto MI : ToErase)
507  MI->eraseFromParent();
508 }
509 
510 /// \returns true when \p Reg is used as part of an address calculation in \p
511 /// MI.
512 static bool usedAsAddr(const MachineInstr &MI, unsigned Reg,
513  const TargetInstrInfo *TII) {
514  if (!MI.mayLoadOrStore())
515  return false;
516 
517  const MCInstrDesc &Desc = TII->get(MI.getOpcode());
518  int MemOpStart = X86II::getMemoryOperandNo(Desc.TSFlags);
519  if (MemOpStart == -1)
520  return false;
521 
522  MemOpStart += X86II::getOperandBias(Desc);
523  for (unsigned MemOpIdx = MemOpStart,
524  MemOpEnd = MemOpStart + X86::AddrNumOperands;
525  MemOpIdx < MemOpEnd; ++MemOpIdx) {
526  auto &Op = MI.getOperand(MemOpIdx);
527  if (Op.isReg() && Op.getReg() == Reg)
528  return true;
529  }
530  return false;
531 }
532 
533 void X86DomainReassignment::buildClosure(Closure &C, unsigned Reg) {
534  SmallVector<unsigned, 4> Worklist;
535  RegDomain Domain = NoDomain;
536  visitRegister(C, Reg, Domain, Worklist);
537  while (!Worklist.empty()) {
538  unsigned CurReg = Worklist.pop_back_val();
539 
540  // Register already in this closure.
541  if (!C.insertEdge(CurReg))
542  continue;
543 
544  MachineInstr *DefMI = MRI->getVRegDef(CurReg);
545  encloseInstr(C, DefMI);
546 
547  // Add register used by the defining MI to the worklist.
548  // Do not add registers which are used in address calculation, they will be
549  // added to a different closure.
550  int OpEnd = DefMI->getNumOperands();
551  const MCInstrDesc &Desc = DefMI->getDesc();
552  int MemOp = X86II::getMemoryOperandNo(Desc.TSFlags);
553  if (MemOp != -1)
554  MemOp += X86II::getOperandBias(Desc);
555  for (int OpIdx = 0; OpIdx < OpEnd; ++OpIdx) {
556  if (OpIdx == MemOp) {
557  // skip address calculation.
558  OpIdx += (X86::AddrNumOperands - 1);
559  continue;
560  }
561  auto &Op = DefMI->getOperand(OpIdx);
562  if (!Op.isReg() || !Op.isUse())
563  continue;
564  visitRegister(C, Op.getReg(), Domain, Worklist);
565  }
566 
567  // Expand closure through register uses.
568  for (auto &UseMI : MRI->use_nodbg_instructions(CurReg)) {
569  // We would like to avoid converting closures which calculare addresses,
570  // as this should remain in GPRs.
571  if (usedAsAddr(UseMI, CurReg, TII)) {
572  C.setAllIllegal();
573  continue;
574  }
575  encloseInstr(C, &UseMI);
576 
577  for (auto &DefOp : UseMI.defs()) {
578  if (!DefOp.isReg())
579  continue;
580 
581  unsigned DefReg = DefOp.getReg();
583  C.setAllIllegal();
584  continue;
585  }
586  visitRegister(C, DefReg, Domain, Worklist);
587  }
588  }
589  }
590 }
591 
592 void X86DomainReassignment::initConverters() {
593  Converters[{MaskDomain, TargetOpcode::PHI}] =
594  new InstrIgnore(TargetOpcode::PHI);
595 
596  Converters[{MaskDomain, TargetOpcode::IMPLICIT_DEF}] =
597  new InstrIgnore(TargetOpcode::IMPLICIT_DEF);
598 
599  Converters[{MaskDomain, TargetOpcode::INSERT_SUBREG}] =
600  new InstrReplaceWithCopy(TargetOpcode::INSERT_SUBREG, 2);
601 
602  Converters[{MaskDomain, TargetOpcode::COPY}] =
603  new InstrCOPYReplacer(TargetOpcode::COPY, MaskDomain, TargetOpcode::COPY);
604 
605  auto createReplacerDstCOPY = [&](unsigned From, unsigned To) {
606  Converters[{MaskDomain, From}] = new InstrReplacerDstCOPY(From, To);
607  };
608 
609  createReplacerDstCOPY(X86::MOVZX32rm16, X86::KMOVWkm);
610  createReplacerDstCOPY(X86::MOVZX64rm16, X86::KMOVWkm);
611 
612  createReplacerDstCOPY(X86::MOVZX32rr16, X86::KMOVWkk);
613  createReplacerDstCOPY(X86::MOVZX64rr16, X86::KMOVWkk);
614 
615  if (STI->hasDQI()) {
616  createReplacerDstCOPY(X86::MOVZX16rm8, X86::KMOVBkm);
617  createReplacerDstCOPY(X86::MOVZX32rm8, X86::KMOVBkm);
618  createReplacerDstCOPY(X86::MOVZX64rm8, X86::KMOVBkm);
619 
620  createReplacerDstCOPY(X86::MOVZX16rr8, X86::KMOVBkk);
621  createReplacerDstCOPY(X86::MOVZX32rr8, X86::KMOVBkk);
622  createReplacerDstCOPY(X86::MOVZX64rr8, X86::KMOVBkk);
623  }
624 
625  auto createReplacer = [&](unsigned From, unsigned To) {
626  Converters[{MaskDomain, From}] = new InstrReplacer(From, To);
627  };
628 
629  createReplacer(X86::MOV16rm, X86::KMOVWkm);
630  createReplacer(X86::MOV16mr, X86::KMOVWmk);
631  createReplacer(X86::MOV16rr, X86::KMOVWkk);
632  createReplacer(X86::SHR16ri, X86::KSHIFTRWri);
633  createReplacer(X86::SHL16ri, X86::KSHIFTLWri);
634  createReplacer(X86::NOT16r, X86::KNOTWrr);
635  createReplacer(X86::OR16rr, X86::KORWrr);
636  createReplacer(X86::AND16rr, X86::KANDWrr);
637  createReplacer(X86::XOR16rr, X86::KXORWrr);
638 
639  if (STI->hasBWI()) {
640  createReplacer(X86::MOV32rm, X86::KMOVDkm);
641  createReplacer(X86::MOV64rm, X86::KMOVQkm);
642 
643  createReplacer(X86::MOV32mr, X86::KMOVDmk);
644  createReplacer(X86::MOV64mr, X86::KMOVQmk);
645 
646  createReplacer(X86::MOV32rr, X86::KMOVDkk);
647  createReplacer(X86::MOV64rr, X86::KMOVQkk);
648 
649  createReplacer(X86::SHR32ri, X86::KSHIFTRDri);
650  createReplacer(X86::SHR64ri, X86::KSHIFTRQri);
651 
652  createReplacer(X86::SHL32ri, X86::KSHIFTLDri);
653  createReplacer(X86::SHL64ri, X86::KSHIFTLQri);
654 
655  createReplacer(X86::ADD32rr, X86::KADDDrr);
656  createReplacer(X86::ADD64rr, X86::KADDQrr);
657 
658  createReplacer(X86::NOT32r, X86::KNOTDrr);
659  createReplacer(X86::NOT64r, X86::KNOTQrr);
660 
661  createReplacer(X86::OR32rr, X86::KORDrr);
662  createReplacer(X86::OR64rr, X86::KORQrr);
663 
664  createReplacer(X86::AND32rr, X86::KANDDrr);
665  createReplacer(X86::AND64rr, X86::KANDQrr);
666 
667  createReplacer(X86::ANDN32rr, X86::KANDNDrr);
668  createReplacer(X86::ANDN64rr, X86::KANDNQrr);
669 
670  createReplacer(X86::XOR32rr, X86::KXORDrr);
671  createReplacer(X86::XOR64rr, X86::KXORQrr);
672 
673  // TODO: KTEST is not a replacement for TEST due to flag differences. Need
674  // to prove only Z flag is used.
675  //createReplacer(X86::TEST32rr, X86::KTESTDrr);
676  //createReplacer(X86::TEST64rr, X86::KTESTQrr);
677  }
678 
679  if (STI->hasDQI()) {
680  createReplacer(X86::ADD8rr, X86::KADDBrr);
681  createReplacer(X86::ADD16rr, X86::KADDWrr);
682 
683  createReplacer(X86::AND8rr, X86::KANDBrr);
684 
685  createReplacer(X86::MOV8rm, X86::KMOVBkm);
686  createReplacer(X86::MOV8mr, X86::KMOVBmk);
687  createReplacer(X86::MOV8rr, X86::KMOVBkk);
688 
689  createReplacer(X86::NOT8r, X86::KNOTBrr);
690 
691  createReplacer(X86::OR8rr, X86::KORBrr);
692 
693  createReplacer(X86::SHR8ri, X86::KSHIFTRBri);
694  createReplacer(X86::SHL8ri, X86::KSHIFTLBri);
695 
696  // TODO: KTEST is not a replacement for TEST due to flag differences. Need
697  // to prove only Z flag is used.
698  //createReplacer(X86::TEST8rr, X86::KTESTBrr);
699  //createReplacer(X86::TEST16rr, X86::KTESTWrr);
700 
701  createReplacer(X86::XOR8rr, X86::KXORBrr);
702  }
703 }
704 
705 bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
706  if (skipFunction(MF.getFunction()))
707  return false;
709  return false;
710 
711  LLVM_DEBUG(
712  dbgs() << "***** Machine Function before Domain Reassignment *****\n");
713  LLVM_DEBUG(MF.print(dbgs()));
714 
715  STI = &MF.getSubtarget<X86Subtarget>();
716  // GPR->K is the only transformation currently supported, bail out early if no
717  // AVX512.
718  if (!STI->hasAVX512())
719  return false;
720 
721  MRI = &MF.getRegInfo();
722  assert(MRI->isSSA() && "Expected MIR to be in SSA form");
723 
724  TII = STI->getInstrInfo();
725  initConverters();
726  bool Changed = false;
727 
728  EnclosedEdges.clear();
729  EnclosedInstrs.clear();
730 
731  std::vector<Closure> Closures;
732 
733  // Go over all virtual registers and calculate a closure.
734  unsigned ClosureID = 0;
735  for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
736  unsigned Reg = TargetRegisterInfo::index2VirtReg(Idx);
737 
738  // GPR only current source domain supported.
739  if (!isGPR(MRI->getRegClass(Reg)))
740  continue;
741 
742  // Register already in closure.
743  if (EnclosedEdges.count(Reg))
744  continue;
745 
746  // Calculate closure starting with Reg.
747  Closure C(ClosureID++, {MaskDomain});
748  buildClosure(C, Reg);
749 
750  // Collect all closures that can potentially be converted.
751  if (!C.empty() && C.isLegal(MaskDomain))
752  Closures.push_back(std::move(C));
753  }
754 
755  for (Closure &C : Closures) {
756  LLVM_DEBUG(C.dump(MRI));
757  if (isReassignmentProfitable(C, MaskDomain)) {
758  reassign(C, MaskDomain);
759  ++NumClosuresConverted;
760  Changed = true;
761  }
762  }
763 
764  DeleteContainerSeconds(Converters);
765 
766  LLVM_DEBUG(
767  dbgs() << "***** Machine Function after Domain Reassignment *****\n");
768  LLVM_DEBUG(MF.print(dbgs()));
769 
770  return Changed;
771 }
772 
773 INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment",
774  "X86 Domain Reassignment Pass", false, false)
775 
776 /// Returns an instance of the Domain Reassignment pass.
778  return new X86DomainReassignment();
779 }
void DeleteContainerSeconds(Container &C)
In a container of pairs (usually a map) whose second element is a pointer, deletes the second element...
Definition: STLExtras.h:892
uint64_t CallInst * C
const MachineInstrBuilder & add(const MachineOperand &MO) const
static bool usedAsAddr(const MachineInstr &MI, unsigned Reg, const TargetInstrInfo *TII)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:449
iterator_range< mop_iterator > explicit_operands()
Definition: MachineInstr.h:367
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:285
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:161
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned Reg
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
Definition: MachineInstr.h:682
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:361
FunctionPass * createX86DomainReassignmentPass()
Return a Machine IR pass that reassigns instruction chains from one domain to another, when profitable.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:314
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment", "X86 Domain Reassignment Pass", false, false) FunctionPass *llvm
Returns an instance of the Domain Reassignment pass.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:311
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
Definition: MachineInstr.h:308
static int getID(struct InternalInstruction *insn, const void *miiArg)
const TargetRegisterClass * getRegClass(const MCInstrDesc &TID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const
Given a machine instruction descriptor, returns the register class constraint for OpNum...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:410
const TargetRegisterInfo * getTargetRegisterInfo() const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned const MachineRegisterInfo * MRI
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineInstrBuilder & UseMI
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:187
Represent the analysis usage information of a pass.
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
unsigned getOperandBias(const MCInstrDesc &Desc)
getOperandBias - compute whether all of the def operands are repeated in the uses and therefore shoul...
Definition: X86BaseInfo.h:653
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
void print(raw_ostream &OS, const SlotIndexes *=nullptr) const
print - Print out the MachineFunction in a format suitable for debugging to the specified stream...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void initializeX86DomainReassignmentPass(PassRegistry &)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
MachineInstrBuilder MachineInstrBuilder & DefMI
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:382
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:286
const Function & getFunction() const
Return the LLVM function that this machine code represents.
AddrNumOperands - Total number of operands in a memory reference.
Definition: X86BaseInfo.h:42
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
A range adaptor for a pair of iterators.
iterator_range< mop_iterator > implicit_operands()
Definition: MachineInstr.h:375
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:156
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:60
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static cl::opt< bool > DisableX86DomainReassignment("disable-x86-domain-reassignment", cl::Hidden, cl::desc("X86: Disable Virtual Register Reassignment."), cl::init(false))
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:62
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
#define I(x, y, z)
Definition: MD5.cpp:58
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:124
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
inst_range instructions(Function *F)
Definition: InstIterator.h:134
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:39
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
Definition: MCInstrDesc.cpp:54
#define LLVM_DEBUG(X)
Definition: Debug.h:119
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:316
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
int getMemoryOperandNo(uint64_t TSFlags)
getMemoryOperandNo - The function returns the MCInst operand # for the first field of the memory oper...
Definition: X86BaseInfo.h:694