1 //===--- X86DomainReassignment.cpp - Selectively switch register classes---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass attempts to find instruction chains (closures) in one domain,
11 // and convert them to equivalent instructions in a different domain,
14 //===----------------------------------------------------------------------===//
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"
24 #include "llvm/CodeGen/MachineFunctionPass.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/CodeGen/TargetRegisterInfo.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/Printable.h"
35 void initializeX86DomainReassignmentPass(PassRegistry &);
38 #define DEBUG_TYPE "x86-domain-reassignment"
40 STATISTIC(NumClosuresConverted, "Number of closures converted by the pass");
42 static cl::opt<bool> DisableX86DomainReassignment(
43 "disable-x86-domain-reassignment", cl::Hidden,
44 cl::desc("X86: Disable Virtual Register Reassignment."), cl::init(false));
47 enum RegDomain { NoDomain = -1, GPRDomain, MaskDomain, OtherDomain, NumDomains };
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);
56 static bool isMask(const TargetRegisterClass *RC,
57 const TargetRegisterInfo *TRI) {
58 return X86::VK16RegClass.hasSubClassEq(RC);
61 static RegDomain getDomain(const TargetRegisterClass *RC,
62 const TargetRegisterInfo *TRI) {
70 /// Return a register class equivalent to \p SrcRC, in \p Domain.
71 static const TargetRegisterClass *getDstRC(const TargetRegisterClass *SrcRC,
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");
86 /// Abstract Instruction Converter class.
87 class InstrConverterBase {
92 InstrConverterBase(unsigned SrcOpcode) : SrcOpcode(SrcOpcode) {}
94 virtual ~InstrConverterBase() {}
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");
104 /// Applies conversion to \p MI.
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;
110 /// \returns the cost increment incurred by converting \p MI.
111 virtual double getExtraCost(const MachineInstr *MI,
112 MachineRegisterInfo *MRI) const = 0;
115 /// An Instruction Converter which ignores the given instruction.
116 /// For example, PHI instructions can be safely ignored since only the registers
118 class InstrIgnore : public InstrConverterBase {
120 InstrIgnore(unsigned SrcOpcode) : InstrConverterBase(SrcOpcode) {}
122 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
123 MachineRegisterInfo *MRI) const override {
124 assert(isLegal(MI, TII) && "Cannot convert instruction");
128 double getExtraCost(const MachineInstr *MI,
129 MachineRegisterInfo *MRI) const override {
134 /// An Instruction Converter which replaces an instruction with another.
135 class InstrReplacer : public InstrConverterBase {
137 /// Opcode of the destination instruction.
140 InstrReplacer(unsigned SrcOpcode, unsigned DstOpcode)
141 : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
143 bool isLegal(const MachineInstr *MI,
144 const TargetInstrInfo *TII) const override {
145 if (!InstrConverterBase::isLegal(MI, TII))
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()))
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())
168 double getExtraCost(const MachineInstr *MI,
169 MachineRegisterInfo *MRI) const override {
170 // Assuming instructions have the same cost.
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 {
181 InstrReplacerDstCOPY(unsigned SrcOpcode, unsigned DstOpcode)
182 : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
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();
190 unsigned Reg = MRI->createVirtualRegister(
191 TII->getRegClass(TII->get(DstOpcode), 0, MRI->getTargetRegisterInfo(),
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));
197 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY))
198 .add(MI->getOperand(0))
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.
212 /// An Instruction Converter for replacing COPY instructions.
213 class InstrCOPYReplacer : public InstrReplacer {
217 InstrCOPYReplacer(unsigned SrcOpcode, RegDomain DstDomain, unsigned DstOpcode)
218 : InstrReplacer(SrcOpcode, DstOpcode), DstDomain(DstDomain) {}
220 bool isLegal(const MachineInstr *MI,
221 const TargetInstrInfo *TII) const override {
222 if (!InstrConverterBase::isLegal(MI, TII))
225 // Don't allow copies to/flow GR8/GR16 physical registers.
226 // FIXME: Is there some better way to support this?
227 unsigned DstReg = MI->getOperand(0).getReg();
228 if (TargetRegisterInfo::isPhysicalRegister(DstReg) &&
229 (X86::GR8RegClass.contains(DstReg) ||
230 X86::GR16RegClass.contains(DstReg)))
232 unsigned SrcReg = MI->getOperand(1).getReg();
233 if (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
234 (X86::GR8RegClass.contains(SrcReg) ||
235 X86::GR16RegClass.contains(SrcReg)))
241 double getExtraCost(const MachineInstr *MI,
242 MachineRegisterInfo *MRI) const override {
243 assert(MI->getOpcode() == TargetOpcode::COPY && "Expected a COPY");
245 for (auto &MO : MI->operands()) {
246 // Physical registers will not be converted. Assume that converting the
247 // COPY to the destination domain will eventually result in a actual
249 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
252 RegDomain OpDomain = getDomain(MRI->getRegClass(MO.getReg()),
253 MRI->getTargetRegisterInfo());
254 // Converting a cross domain COPY to a same domain COPY should eliminate
256 if (OpDomain == DstDomain)
263 /// An Instruction Converter which replaces an instruction with a COPY.
264 class InstrReplaceWithCopy : public InstrConverterBase {
266 // Source instruction operand Index, to be used as the COPY source.
269 InstrReplaceWithCopy(unsigned SrcOpcode, unsigned SrcOpIdx)
270 : InstrConverterBase(SrcOpcode), SrcOpIdx(SrcOpIdx) {}
272 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
273 MachineRegisterInfo *MRI) const override {
274 assert(isLegal(MI, TII) && "Cannot convert instruction");
275 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
276 TII->get(TargetOpcode::COPY))
277 .add({MI->getOperand(0), MI->getOperand(SrcOpIdx)});
281 double getExtraCost(const MachineInstr *MI,
282 MachineRegisterInfo *MRI) const override {
287 // Key type to be used by the Instruction Converters map.
288 // A converter is identified by <destination domain, source opcode>
289 typedef std::pair<int, unsigned> InstrConverterBaseKeyTy;
291 typedef DenseMap<InstrConverterBaseKeyTy, InstrConverterBase *>
292 InstrConverterBaseMap;
294 /// A closure is a set of virtual register representing all of the edges in
295 /// the closure, as well as all of the instructions connected by those edges.
297 /// A closure may encompass virtual registers in the same register bank that
298 /// have different widths. For example, it may contain 32-bit GPRs as well as
301 /// A closure that computes an address (i.e. defines a virtual register that is
302 /// used in a memory operand) excludes the instructions that contain memory
303 /// operands using the address. Such an instruction will be included in a
304 /// different closure that manipulates the loaded or stored value.
307 /// Virtual registers in the closure.
308 DenseSet<unsigned> Edges;
310 /// Instructions in the closure.
311 SmallVector<MachineInstr *, 8> Instrs;
313 /// Domains which this closure can legally be reassigned to.
314 std::bitset<NumDomains> LegalDstDomains;
316 /// An ID to uniquely identify this closure, even when it gets
321 Closure(unsigned ID, std::initializer_list<RegDomain> LegalDstDomainList) : ID(ID) {
322 for (RegDomain D : LegalDstDomainList)
323 LegalDstDomains.set(D);
326 /// Mark this closure as illegal for reassignment to all domains.
327 void setAllIllegal() { LegalDstDomains.reset(); }
329 /// \returns true if this closure has domains which are legal to reassign to.
330 bool hasLegalDstDomain() const { return LegalDstDomains.any(); }
332 /// \returns true if is legal to reassign this closure to domain \p RD.
333 bool isLegal(RegDomain RD) const { return LegalDstDomains[RD]; }
335 /// Mark this closure as illegal for reassignment to domain \p RD.
336 void setIllegal(RegDomain RD) { LegalDstDomains[RD] = false; }
338 bool empty() const { return Edges.empty(); }
340 bool insertEdge(unsigned Reg) {
341 return Edges.insert(Reg).second;
344 using const_edge_iterator = DenseSet<unsigned>::const_iterator;
345 iterator_range<const_edge_iterator> edges() const {
346 return iterator_range<const_edge_iterator>(Edges.begin(), Edges.end());
349 void addInstruction(MachineInstr *I) {
353 ArrayRef<MachineInstr *> instructions() const {
357 LLVM_DUMP_METHOD void dump(const MachineRegisterInfo *MRI) const {
358 dbgs() << "Registers: ";
360 for (unsigned Reg : Edges) {
364 dbgs() << printReg(Reg, MRI->getTargetRegisterInfo(), 0, MRI);
366 dbgs() << "\n" << "Instructions:";
367 for (MachineInstr *MI : Instrs) {
374 unsigned getID() const {
380 class X86DomainReassignment : public MachineFunctionPass {
381 const X86Subtarget *STI;
382 MachineRegisterInfo *MRI;
383 const X86InstrInfo *TII;
385 /// All edges that are included in some closure
386 DenseSet<unsigned> EnclosedEdges;
388 /// All instructions that are included in some closure.
389 DenseMap<MachineInstr *, unsigned> EnclosedInstrs;
394 X86DomainReassignment() : MachineFunctionPass(ID) {
395 initializeX86DomainReassignmentPass(*PassRegistry::getPassRegistry());
398 bool runOnMachineFunction(MachineFunction &MF) override;
400 void getAnalysisUsage(AnalysisUsage &AU) const override {
401 AU.setPreservesCFG();
402 MachineFunctionPass::getAnalysisUsage(AU);
405 StringRef getPassName() const override {
406 return "X86 Domain Reassignment Pass";
410 /// A map of available Instruction Converters.
411 InstrConverterBaseMap Converters;
413 /// Initialize Converters map.
414 void initConverters();
416 /// Starting from \Reg, expand the closure as much as possible.
417 void buildClosure(Closure &, unsigned Reg);
419 /// Enqueue \p Reg to be considered for addition to the closure.
420 void visitRegister(Closure &, unsigned Reg, RegDomain &Domain,
421 SmallVectorImpl<unsigned> &Worklist);
423 /// Reassign the closure to \p Domain.
424 void reassign(const Closure &C, RegDomain Domain) const;
426 /// Add \p MI to the closure.
427 void encloseInstr(Closure &C, MachineInstr *MI);
429 /// /returns true if it is profitable to reassign the closure to \p Domain.
430 bool isReassignmentProfitable(const Closure &C, RegDomain Domain) const;
432 /// Calculate the total cost of reassigning the closure to \p Domain.
433 double calculateCost(const Closure &C, RegDomain Domain) const;
436 char X86DomainReassignment::ID = 0;
438 } // End anonymous namespace.
440 void X86DomainReassignment::visitRegister(Closure &C, unsigned Reg,
442 SmallVectorImpl<unsigned> &Worklist) {
443 if (EnclosedEdges.count(Reg))
446 if (!TargetRegisterInfo::isVirtualRegister(Reg))
449 if (!MRI->hasOneDef(Reg))
452 RegDomain RD = getDomain(MRI->getRegClass(Reg), MRI->getTargetRegisterInfo());
453 // First edge in closure sets the domain.
454 if (Domain == NoDomain)
460 Worklist.push_back(Reg);
463 void X86DomainReassignment::encloseInstr(Closure &C, MachineInstr *MI) {
464 auto I = EnclosedInstrs.find(MI);
465 if (I != EnclosedInstrs.end()) {
466 if (I->second != C.getID())
467 // Instruction already belongs to another closure, avoid conflicts between
468 // closure and mark this closure as illegal.
473 EnclosedInstrs[MI] = C.getID();
474 C.addInstruction(MI);
476 // Mark closure as illegal for reassignment to domains, if there is no
477 // converter for the instruction or if the converter cannot convert the
479 for (int i = 0; i != NumDomains; ++i) {
480 if (C.isLegal((RegDomain)i)) {
481 InstrConverterBase *IC = Converters.lookup({i, MI->getOpcode()});
482 if (!IC || !IC->isLegal(MI, TII))
483 C.setIllegal((RegDomain)i);
488 double X86DomainReassignment::calculateCost(const Closure &C,
489 RegDomain DstDomain) const {
490 assert(C.isLegal(DstDomain) && "Cannot calculate cost for illegal closure");
493 for (auto *MI : C.instructions())
495 Converters.lookup({DstDomain, MI->getOpcode()})->getExtraCost(MI, MRI);
499 bool X86DomainReassignment::isReassignmentProfitable(const Closure &C,
500 RegDomain Domain) const {
501 return calculateCost(C, Domain) < 0.0;
504 void X86DomainReassignment::reassign(const Closure &C, RegDomain Domain) const {
505 assert(C.isLegal(Domain) && "Cannot convert illegal closure");
507 // Iterate all instructions in the closure, convert each one using the
508 // appropriate converter.
509 SmallVector<MachineInstr *, 8> ToErase;
510 for (auto *MI : C.instructions())
511 if (Converters.lookup({Domain, MI->getOpcode()})
512 ->convertInstr(MI, TII, MRI))
513 ToErase.push_back(MI);
515 // Iterate all registers in the closure, replace them with registers in the
516 // destination domain.
517 for (unsigned Reg : C.edges()) {
518 MRI->setRegClass(Reg, getDstRC(MRI->getRegClass(Reg), Domain));
519 for (auto &MO : MRI->use_operands(Reg)) {
521 // Remove all subregister references as they are not valid in the
522 // destination domain.
527 for (auto MI : ToErase)
528 MI->eraseFromParent();
531 /// \returns true when \p Reg is used as part of an address calculation in \p
533 static bool usedAsAddr(const MachineInstr &MI, unsigned Reg,
534 const TargetInstrInfo *TII) {
535 if (!MI.mayLoadOrStore())
538 const MCInstrDesc &Desc = TII->get(MI.getOpcode());
539 int MemOpStart = X86II::getMemoryOperandNo(Desc.TSFlags);
540 if (MemOpStart == -1)
543 MemOpStart += X86II::getOperandBias(Desc);
544 for (unsigned MemOpIdx = MemOpStart,
545 MemOpEnd = MemOpStart + X86::AddrNumOperands;
546 MemOpIdx < MemOpEnd; ++MemOpIdx) {
547 auto &Op = MI.getOperand(MemOpIdx);
548 if (Op.isReg() && Op.getReg() == Reg)
554 void X86DomainReassignment::buildClosure(Closure &C, unsigned Reg) {
555 SmallVector<unsigned, 4> Worklist;
556 RegDomain Domain = NoDomain;
557 visitRegister(C, Reg, Domain, Worklist);
558 while (!Worklist.empty()) {
559 unsigned CurReg = Worklist.pop_back_val();
561 // Register already in this closure.
562 if (!C.insertEdge(CurReg))
565 MachineInstr *DefMI = MRI->getVRegDef(CurReg);
566 encloseInstr(C, DefMI);
568 // Add register used by the defining MI to the worklist.
569 // Do not add registers which are used in address calculation, they will be
570 // added to a different closure.
571 int OpEnd = DefMI->getNumOperands();
572 const MCInstrDesc &Desc = DefMI->getDesc();
573 int MemOp = X86II::getMemoryOperandNo(Desc.TSFlags);
575 MemOp += X86II::getOperandBias(Desc);
576 for (int OpIdx = 0; OpIdx < OpEnd; ++OpIdx) {
577 if (OpIdx == MemOp) {
578 // skip address calculation.
579 OpIdx += (X86::AddrNumOperands - 1);
582 auto &Op = DefMI->getOperand(OpIdx);
583 if (!Op.isReg() || !Op.isUse())
585 visitRegister(C, Op.getReg(), Domain, Worklist);
588 // Expand closure through register uses.
589 for (auto &UseMI : MRI->use_nodbg_instructions(CurReg)) {
590 // We would like to avoid converting closures which calculare addresses,
591 // as this should remain in GPRs.
592 if (usedAsAddr(UseMI, CurReg, TII)) {
596 encloseInstr(C, &UseMI);
598 for (auto &DefOp : UseMI.defs()) {
602 unsigned DefReg = DefOp.getReg();
603 if (!TargetRegisterInfo::isVirtualRegister(DefReg)) {
607 visitRegister(C, DefReg, Domain, Worklist);
613 void X86DomainReassignment::initConverters() {
614 Converters[{MaskDomain, TargetOpcode::PHI}] =
615 new InstrIgnore(TargetOpcode::PHI);
617 Converters[{MaskDomain, TargetOpcode::IMPLICIT_DEF}] =
618 new InstrIgnore(TargetOpcode::IMPLICIT_DEF);
620 Converters[{MaskDomain, TargetOpcode::INSERT_SUBREG}] =
621 new InstrReplaceWithCopy(TargetOpcode::INSERT_SUBREG, 2);
623 Converters[{MaskDomain, TargetOpcode::COPY}] =
624 new InstrCOPYReplacer(TargetOpcode::COPY, MaskDomain, TargetOpcode::COPY);
626 auto createReplacerDstCOPY = [&](unsigned From, unsigned To) {
627 Converters[{MaskDomain, From}] = new InstrReplacerDstCOPY(From, To);
630 createReplacerDstCOPY(X86::MOVZX32rm16, X86::KMOVWkm);
631 createReplacerDstCOPY(X86::MOVZX64rm16, X86::KMOVWkm);
633 createReplacerDstCOPY(X86::MOVZX32rr16, X86::KMOVWkk);
634 createReplacerDstCOPY(X86::MOVZX64rr16, X86::KMOVWkk);
637 createReplacerDstCOPY(X86::MOVZX16rm8, X86::KMOVBkm);
638 createReplacerDstCOPY(X86::MOVZX32rm8, X86::KMOVBkm);
639 createReplacerDstCOPY(X86::MOVZX64rm8, X86::KMOVBkm);
641 createReplacerDstCOPY(X86::MOVZX16rr8, X86::KMOVBkk);
642 createReplacerDstCOPY(X86::MOVZX32rr8, X86::KMOVBkk);
643 createReplacerDstCOPY(X86::MOVZX64rr8, X86::KMOVBkk);
646 auto createReplacer = [&](unsigned From, unsigned To) {
647 Converters[{MaskDomain, From}] = new InstrReplacer(From, To);
650 createReplacer(X86::MOV16rm, X86::KMOVWkm);
651 createReplacer(X86::MOV16mr, X86::KMOVWmk);
652 createReplacer(X86::MOV16rr, X86::KMOVWkk);
653 createReplacer(X86::SHR16ri, X86::KSHIFTRWri);
654 createReplacer(X86::SHL16ri, X86::KSHIFTLWri);
655 createReplacer(X86::NOT16r, X86::KNOTWrr);
656 createReplacer(X86::OR16rr, X86::KORWrr);
657 createReplacer(X86::AND16rr, X86::KANDWrr);
658 createReplacer(X86::XOR16rr, X86::KXORWrr);
661 createReplacer(X86::MOV32rm, X86::KMOVDkm);
662 createReplacer(X86::MOV64rm, X86::KMOVQkm);
664 createReplacer(X86::MOV32mr, X86::KMOVDmk);
665 createReplacer(X86::MOV64mr, X86::KMOVQmk);
667 createReplacer(X86::MOV32rr, X86::KMOVDkk);
668 createReplacer(X86::MOV64rr, X86::KMOVQkk);
670 createReplacer(X86::SHR32ri, X86::KSHIFTRDri);
671 createReplacer(X86::SHR64ri, X86::KSHIFTRQri);
673 createReplacer(X86::SHL32ri, X86::KSHIFTLDri);
674 createReplacer(X86::SHL64ri, X86::KSHIFTLQri);
676 createReplacer(X86::ADD32rr, X86::KADDDrr);
677 createReplacer(X86::ADD64rr, X86::KADDQrr);
679 createReplacer(X86::NOT32r, X86::KNOTDrr);
680 createReplacer(X86::NOT64r, X86::KNOTQrr);
682 createReplacer(X86::OR32rr, X86::KORDrr);
683 createReplacer(X86::OR64rr, X86::KORQrr);
685 createReplacer(X86::AND32rr, X86::KANDDrr);
686 createReplacer(X86::AND64rr, X86::KANDQrr);
688 createReplacer(X86::ANDN32rr, X86::KANDNDrr);
689 createReplacer(X86::ANDN64rr, X86::KANDNQrr);
691 createReplacer(X86::XOR32rr, X86::KXORDrr);
692 createReplacer(X86::XOR64rr, X86::KXORQrr);
694 // TODO: KTEST is not a replacement for TEST due to flag differences. Need
695 // to prove only Z flag is used.
696 //createReplacer(X86::TEST32rr, X86::KTESTDrr);
697 //createReplacer(X86::TEST64rr, X86::KTESTQrr);
701 createReplacer(X86::ADD8rr, X86::KADDBrr);
702 createReplacer(X86::ADD16rr, X86::KADDWrr);
704 createReplacer(X86::AND8rr, X86::KANDBrr);
706 createReplacer(X86::MOV8rm, X86::KMOVBkm);
707 createReplacer(X86::MOV8mr, X86::KMOVBmk);
708 createReplacer(X86::MOV8rr, X86::KMOVBkk);
710 createReplacer(X86::NOT8r, X86::KNOTBrr);
712 createReplacer(X86::OR8rr, X86::KORBrr);
714 createReplacer(X86::SHR8ri, X86::KSHIFTRBri);
715 createReplacer(X86::SHL8ri, X86::KSHIFTLBri);
717 // TODO: KTEST is not a replacement for TEST due to flag differences. Need
718 // to prove only Z flag is used.
719 //createReplacer(X86::TEST8rr, X86::KTESTBrr);
720 //createReplacer(X86::TEST16rr, X86::KTESTWrr);
722 createReplacer(X86::XOR8rr, X86::KXORBrr);
726 bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
727 if (skipFunction(MF.getFunction()))
729 if (DisableX86DomainReassignment)
733 dbgs() << "***** Machine Function before Domain Reassignment *****\n");
734 LLVM_DEBUG(MF.print(dbgs()));
736 STI = &MF.getSubtarget<X86Subtarget>();
737 // GPR->K is the only transformation currently supported, bail out early if no
739 if (!STI->hasAVX512())
742 MRI = &MF.getRegInfo();
743 assert(MRI->isSSA() && "Expected MIR to be in SSA form");
745 TII = STI->getInstrInfo();
747 bool Changed = false;
749 EnclosedEdges.clear();
750 EnclosedInstrs.clear();
752 std::vector<Closure> Closures;
754 // Go over all virtual registers and calculate a closure.
755 unsigned ClosureID = 0;
756 for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
757 unsigned Reg = TargetRegisterInfo::index2VirtReg(Idx);
759 // GPR only current source domain supported.
760 if (!isGPR(MRI->getRegClass(Reg)))
763 // Register already in closure.
764 if (EnclosedEdges.count(Reg))
767 // Calculate closure starting with Reg.
768 Closure C(ClosureID++, {MaskDomain});
769 buildClosure(C, Reg);
771 // Collect all closures that can potentially be converted.
772 if (!C.empty() && C.isLegal(MaskDomain))
773 Closures.push_back(std::move(C));
776 for (Closure &C : Closures) {
777 LLVM_DEBUG(C.dump(MRI));
778 if (isReassignmentProfitable(C, MaskDomain)) {
779 reassign(C, MaskDomain);
780 ++NumClosuresConverted;
785 DeleteContainerSeconds(Converters);
788 dbgs() << "***** Machine Function after Domain Reassignment *****\n");
789 LLVM_DEBUG(MF.print(dbgs()));
794 INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment",
795 "X86 Domain Reassignment Pass", false, false)
797 /// Returns an instance of the Domain Reassignment pass.
798 FunctionPass *llvm::createX86DomainReassignmentPass() {
799 return new X86DomainReassignment();