blob: 573b7caf29c0afb53e05ec7e1d2d4185ab738fc4 [file] [log] [blame]
Guy Blank92d5ce32017-10-22 11:43:08 +00001//===--- 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/SmallSet.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/Statistic.h"
25#include "llvm/CodeGen/MachineFunctionPass.h"
26#include "llvm/CodeGen/MachineInstrBuilder.h"
27#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000028#include "llvm/CodeGen/TargetRegisterInfo.h"
Guy Blank92d5ce32017-10-22 11:43:08 +000029#include "llvm/Support/Debug.h"
Guy Blank92d5ce32017-10-22 11:43:08 +000030
31using namespace llvm;
32
33namespace llvm {
34void initializeX86DomainReassignmentPass(PassRegistry &);
35}
36
37#define DEBUG_TYPE "x86-domain-reassignment"
38
39STATISTIC(NumClosuresConverted, "Number of closures converted by the pass");
40
41static cl::opt<bool> DisableX86DomainReassignment(
42 "disable-x86-domain-reassignment", cl::Hidden,
43 cl::desc("X86: Disable Virtual Register Reassignment."), cl::init(false));
44
45namespace {
46enum RegDomain { NoDomain = -1, GPRDomain, MaskDomain, OtherDomain };
47
48static bool isGPR(const TargetRegisterClass *RC) {
49 return X86::GR64RegClass.hasSubClassEq(RC) ||
50 X86::GR32RegClass.hasSubClassEq(RC) ||
51 X86::GR16RegClass.hasSubClassEq(RC) ||
52 X86::GR8RegClass.hasSubClassEq(RC);
53}
54
55static bool isMask(const TargetRegisterClass *RC,
56 const TargetRegisterInfo *TRI) {
57 return X86::VK16RegClass.hasSubClassEq(RC);
58}
59
60static RegDomain getDomain(const TargetRegisterClass *RC,
61 const TargetRegisterInfo *TRI) {
62 if (isGPR(RC))
63 return GPRDomain;
64 if (isMask(RC, TRI))
65 return MaskDomain;
66 return OtherDomain;
67}
68
69/// Return a register class equivalent to \p SrcRC, in \p Domain.
70static const TargetRegisterClass *getDstRC(const TargetRegisterClass *SrcRC,
71 RegDomain Domain) {
72 assert(Domain == MaskDomain && "add domain");
Guy Blankf3cefdd2017-12-05 09:08:24 +000073 if (X86::GR8RegClass.hasSubClassEq(SrcRC))
Guy Blank92d5ce32017-10-22 11:43:08 +000074 return &X86::VK8RegClass;
Guy Blankf3cefdd2017-12-05 09:08:24 +000075 if (X86::GR16RegClass.hasSubClassEq(SrcRC))
Guy Blank92d5ce32017-10-22 11:43:08 +000076 return &X86::VK16RegClass;
Guy Blankf3cefdd2017-12-05 09:08:24 +000077 if (X86::GR32RegClass.hasSubClassEq(SrcRC))
Guy Blank92d5ce32017-10-22 11:43:08 +000078 return &X86::VK32RegClass;
Guy Blankf3cefdd2017-12-05 09:08:24 +000079 if (X86::GR64RegClass.hasSubClassEq(SrcRC))
Guy Blank92d5ce32017-10-22 11:43:08 +000080 return &X86::VK64RegClass;
81 llvm_unreachable("add register class");
82 return nullptr;
83}
84
85/// Abstract Instruction Converter class.
86class InstrConverterBase {
87protected:
88 unsigned SrcOpcode;
89
90public:
91 InstrConverterBase(unsigned SrcOpcode) : SrcOpcode(SrcOpcode) {}
92
93 virtual ~InstrConverterBase() {}
94
95 /// \returns true if \p MI is legal to convert.
96 virtual bool isLegal(const MachineInstr *MI,
97 const TargetInstrInfo *TII) const {
98 assert(MI->getOpcode() == SrcOpcode &&
99 "Wrong instruction passed to converter");
100 return true;
101 }
102
103 /// Applies conversion to \p MI.
104 ///
105 /// \returns true if \p MI is no longer need, and can be deleted.
106 virtual bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
107 MachineRegisterInfo *MRI) const = 0;
108
109 /// \returns the cost increment incurred by converting \p MI.
110 virtual double getExtraCost(const MachineInstr *MI,
111 MachineRegisterInfo *MRI) const = 0;
112};
113
114/// An Instruction Converter which ignores the given instruction.
115/// For example, PHI instructions can be safely ignored since only the registers
116/// need to change.
117class InstrIgnore : public InstrConverterBase {
118public:
119 InstrIgnore(unsigned SrcOpcode) : InstrConverterBase(SrcOpcode) {}
120
121 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
122 MachineRegisterInfo *MRI) const override {
123 assert(isLegal(MI, TII) && "Cannot convert instruction");
124 return false;
125 }
126
127 double getExtraCost(const MachineInstr *MI,
128 MachineRegisterInfo *MRI) const override {
129 return 0;
130 }
131};
132
133/// An Instruction Converter which replaces an instruction with another.
134class InstrReplacer : public InstrConverterBase {
135public:
136 /// Opcode of the destination instruction.
137 unsigned DstOpcode;
138
139 InstrReplacer(unsigned SrcOpcode, unsigned DstOpcode)
140 : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
141
142 bool isLegal(const MachineInstr *MI,
143 const TargetInstrInfo *TII) const override {
144 if (!InstrConverterBase::isLegal(MI, TII))
145 return false;
146 // It's illegal to replace an instruction that implicitly defines a register
147 // with an instruction that doesn't, unless that register dead.
148 for (auto &MO : MI->implicit_operands())
149 if (MO.isReg() && MO.isDef() && !MO.isDead() &&
150 !TII->get(DstOpcode).hasImplicitDefOfPhysReg(MO.getReg()))
151 return false;
152 return true;
153 }
154
155 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
156 MachineRegisterInfo *MRI) const override {
157 assert(isLegal(MI, TII) && "Cannot convert instruction");
158 MachineInstrBuilder Bld =
159 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(), TII->get(DstOpcode));
160 // Transfer explicit operands from original instruction. Implicit operands
161 // are handled by BuildMI.
162 for (auto &Op : MI->explicit_operands())
163 Bld.add(Op);
164 return true;
165 }
166
167 double getExtraCost(const MachineInstr *MI,
168 MachineRegisterInfo *MRI) const override {
169 // Assuming instructions have the same cost.
170 return 0;
171 }
172};
173
174/// An Instruction Converter which replaces an instruction with another, and
175/// adds a COPY from the new instruction's destination to the old one's.
176class InstrReplacerDstCOPY : public InstrConverterBase {
177public:
178 unsigned DstOpcode;
179
180 InstrReplacerDstCOPY(unsigned SrcOpcode, unsigned DstOpcode)
181 : InstrConverterBase(SrcOpcode), DstOpcode(DstOpcode) {}
182
183 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
184 MachineRegisterInfo *MRI) const override {
185 assert(isLegal(MI, TII) && "Cannot convert instruction");
186 MachineBasicBlock *MBB = MI->getParent();
187 auto &DL = MI->getDebugLoc();
188
189 unsigned Reg = MRI->createVirtualRegister(
190 TII->getRegClass(TII->get(DstOpcode), 0, MRI->getTargetRegisterInfo(),
191 *MBB->getParent()));
192 MachineInstrBuilder Bld = BuildMI(*MBB, MI, DL, TII->get(DstOpcode), Reg);
193 for (unsigned Idx = 1, End = MI->getNumOperands(); Idx < End; ++Idx)
194 Bld.add(MI->getOperand(Idx));
195
196 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::COPY))
197 .add(MI->getOperand(0))
198 .addReg(Reg);
199
200 return true;
201 }
202
203 double getExtraCost(const MachineInstr *MI,
204 MachineRegisterInfo *MRI) const override {
205 // Assuming instructions have the same cost, and that COPY is in the same
206 // domain so it will be eliminated.
207 return 0;
208 }
209};
210
211/// An Instruction Converter for replacing COPY instructions.
212class InstrCOPYReplacer : public InstrReplacer {
213public:
214 RegDomain DstDomain;
215
216 InstrCOPYReplacer(unsigned SrcOpcode, RegDomain DstDomain, unsigned DstOpcode)
217 : InstrReplacer(SrcOpcode, DstOpcode), DstDomain(DstDomain) {}
218
219 double getExtraCost(const MachineInstr *MI,
220 MachineRegisterInfo *MRI) const override {
221 assert(MI->getOpcode() == TargetOpcode::COPY && "Expected a COPY");
222
223 for (auto &MO : MI->operands()) {
224 // Physical registers will not be converted. Assume that converting the
225 // COPY to the destination domain will eventually result in a actual
226 // instruction.
227 if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
228 return 1;
229
230 RegDomain OpDomain = getDomain(MRI->getRegClass(MO.getReg()),
231 MRI->getTargetRegisterInfo());
232 // Converting a cross domain COPY to a same domain COPY should eliminate
233 // an insturction
234 if (OpDomain == DstDomain)
235 return -1;
236 }
237 return 0;
238 }
239};
240
241/// An Instruction Converter which replaces an instruction with a COPY.
242class InstrReplaceWithCopy : public InstrConverterBase {
243public:
244 // Source instruction operand Index, to be used as the COPY source.
245 unsigned SrcOpIdx;
246
247 InstrReplaceWithCopy(unsigned SrcOpcode, unsigned SrcOpIdx)
248 : InstrConverterBase(SrcOpcode), SrcOpIdx(SrcOpIdx) {}
249
250 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
251 MachineRegisterInfo *MRI) const override {
252 assert(isLegal(MI, TII) && "Cannot convert instruction");
253 BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
254 TII->get(TargetOpcode::COPY))
255 .add({MI->getOperand(0), MI->getOperand(SrcOpIdx)});
256 return true;
257 }
258
259 double getExtraCost(const MachineInstr *MI,
260 MachineRegisterInfo *MRI) const override {
261 return 0;
262 }
263};
264
265/// An Instruction Converter which completely deletes an instruction.
266/// For example, IMPLICIT_DEF instructions can be deleted when converting from
267/// GPR to mask.
268class InstrDeleter : public InstrConverterBase {
269public:
270 InstrDeleter(unsigned SrcOpcode) : InstrConverterBase(SrcOpcode) {}
271
272 bool convertInstr(MachineInstr *MI, const TargetInstrInfo *TII,
273 MachineRegisterInfo *MRI) const override {
274 assert(isLegal(MI, TII) && "Cannot convert instruction");
275 return true;
276 }
277
278 double getExtraCost(const MachineInstr *MI,
279 MachineRegisterInfo *MRI) const override {
280 return 0;
281 }
282};
283
284// Key type to be used by the Instruction Converters map.
285// A converter is identified by <destination domain, source opcode>
286typedef std::pair<int, unsigned> InstrConverterBaseKeyTy;
287
288typedef DenseMap<InstrConverterBaseKeyTy, InstrConverterBase *>
289 InstrConverterBaseMap;
290
291/// A closure is a set of virtual register representing all of the edges in
292/// the closure, as well as all of the instructions connected by those edges.
293///
294/// A closure may encompass virtual registers in the same register bank that
295/// have different widths. For example, it may contain 32-bit GPRs as well as
296/// 64-bit GPRs.
297///
298/// A closure that computes an address (i.e. defines a virtual register that is
299/// used in a memory operand) excludes the instructions that contain memory
300/// operands using the address. Such an instruction will be included in a
301/// different closure that manipulates the loaded or stored value.
302class Closure {
303private:
304 const TargetInstrInfo *TII;
305 MachineRegisterInfo *MRI;
306
307 /// Virtual registers in the closure.
308 DenseSet<unsigned> Edges;
309
310 /// Instructions in the closure.
311 SmallVector<MachineInstr *, 8> Instrs;
312
313 /// A map of available Instruction Converters.
314 const InstrConverterBaseMap &Converters;
315
316 /// The register domain of this closure.
317 RegDomain Domain;
318
319 /// Domains which this closure can legally be reassigned to.
320 SmallVector<RegDomain, 2> LegalDstDomains;
321
322 SmallVector<RegDomain, 2> getLegalDstDomains() const {
323 return LegalDstDomains;
324 }
325
326 /// Enqueue \p Reg to be considered for addition to the closure.
327 void visitRegister(unsigned Reg, SmallVectorImpl<unsigned> &Worklist);
328
329 /// Add \p MI to this closure.
330 void encloseInstr(MachineInstr *MI);
331
332 /// Calculate the total cost of reassigning the closure to \p Domain.
333 double calculateCost(RegDomain Domain) const;
334
335 /// All edges that are included in some closure.
336 DenseSet<unsigned> &EnclosedEdges;
337
338 /// All instructions that are included in some closure.
339 DenseMap<MachineInstr *, Closure *> &EnclosedInstrs;
340
341public:
342 Closure(const TargetInstrInfo *TII, MachineRegisterInfo *MRI,
343 const InstrConverterBaseMap &Converters,
344 const SmallVector<RegDomain, 2> &LegalDstDomains,
345 DenseSet<unsigned> &EnclosedEdges,
346 DenseMap<MachineInstr *, Closure *> &EnclosedInstrs)
347 : TII(TII), MRI(MRI), Converters(Converters), Domain(NoDomain),
348 LegalDstDomains(LegalDstDomains), EnclosedEdges(EnclosedEdges),
349 EnclosedInstrs(EnclosedInstrs) {}
350
351 /// Starting from \Reg, expand the closure as much as possible.
352 void buildClosure(unsigned E);
353
354 /// /returns true if it is profitable to reassign the closure to \p Domain.
355 bool isReassignmentProfitable(RegDomain Domain) const;
356
357 /// Reassign the closure to \p Domain.
358 void Reassign(RegDomain Domain) const;
359
360 /// Mark this closure as illegal for reassignment to all domains.
361 void setAllIllegal() { LegalDstDomains.clear(); }
362
363 /// \returns true if this closure has domains which are legal to reassign to.
364 bool hasLegalDstDomain() const { return !LegalDstDomains.empty(); }
365
366 /// \returns true if is legal to reassign this closure to domain \p RD.
367 bool isLegal(RegDomain RD) const { return is_contained(LegalDstDomains, RD); }
368
369 bool empty() const { return Edges.empty(); }
370};
371
372class X86DomainReassignment : public MachineFunctionPass {
373public:
374 static char ID;
375
376 X86DomainReassignment() : MachineFunctionPass(ID) {
377 initializeX86DomainReassignmentPass(*PassRegistry::getPassRegistry());
378 }
379
380 bool runOnMachineFunction(MachineFunction &MF) override;
381
382 void getAnalysisUsage(AnalysisUsage &AU) const override {
383 AU.setPreservesCFG();
384 MachineFunctionPass::getAnalysisUsage(AU);
385 }
386
387 StringRef getPassName() const override {
388 return "X86 Domain Reassignment Pass";
389 }
390
391private:
392 const X86Subtarget *STI;
393 MachineRegisterInfo *MRI;
394 const X86InstrInfo *TII;
395
396 /// A map of available Instruction Converters.
397 InstrConverterBaseMap Converters;
398
399 /// Initialize Converters map.
400 void initConverters();
401};
402
403char X86DomainReassignment::ID = 0;
404
405} // End anonymous namespace.
406
407void Closure::visitRegister(unsigned Reg, SmallVectorImpl<unsigned> &Worklist) {
408 if (EnclosedEdges.count(Reg))
409 return;
410
411 if (!TargetRegisterInfo::isVirtualRegister(Reg))
412 return;
413
414 if (!MRI->hasOneDef(Reg))
415 return;
416
417 RegDomain RD = getDomain(MRI->getRegClass(Reg), MRI->getTargetRegisterInfo());
418 // First edge in closure sets the domain.
419 if (Domain == NoDomain)
420 Domain = RD;
421
422 if (Domain != RD)
423 return;
424
425 Worklist.push_back(Reg);
426}
427
428void Closure::encloseInstr(MachineInstr *MI) {
429 auto I = EnclosedInstrs.find(MI);
430 if (I != EnclosedInstrs.end()) {
431 if (I->second != this)
432 // Instruction already belongs to another closure, avoid conflicts between
433 // closure and mark this closure as illegal.
434 setAllIllegal();
435 return;
436 }
437
438 EnclosedInstrs[MI] = this;
439 Instrs.push_back(MI);
440
441 // Mark closure as illegal for reassignment to domains, if there is no
442 // converter for the instruction or if the converter cannot convert the
443 // instruction.
444 erase_if(LegalDstDomains, [&](RegDomain D) {
445 InstrConverterBase *IC = Converters.lookup({D, MI->getOpcode()});
446 return !IC || !IC->isLegal(MI, TII);
447 });
448}
449
450double Closure::calculateCost(RegDomain DstDomain) const {
451 assert(isLegal(DstDomain) && "Cannot calculate cost for illegal closure");
452
453 double Cost = 0.0;
454 for (auto MI : Instrs)
455 Cost +=
456 Converters.lookup({DstDomain, MI->getOpcode()})->getExtraCost(MI, MRI);
457 return Cost;
458}
459
460bool Closure::isReassignmentProfitable(RegDomain Domain) const {
461 return calculateCost(Domain) < 0.0;
462}
463
464void Closure::Reassign(RegDomain Domain) const {
465 assert(isLegal(Domain) && "Cannot convert illegal closure");
466
467 // Iterate all instructions in the closure, convert each one using the
468 // appropriate converter.
469 SmallVector<MachineInstr *, 8> ToErase;
470 for (auto MI : Instrs)
471 if (Converters.lookup({Domain, MI->getOpcode()})
472 ->convertInstr(MI, TII, MRI))
473 ToErase.push_back(MI);
474
475 // Iterate all registers in the closure, replace them with registers in the
476 // destination domain.
477 for (unsigned Reg : Edges) {
478 MRI->setRegClass(Reg, getDstRC(MRI->getRegClass(Reg), Domain));
479 for (auto &MO : MRI->use_operands(Reg)) {
480 if (MO.isReg())
481 // Remove all subregister references as they are not valid in the
482 // destination domain.
483 MO.setSubReg(0);
484 }
485 }
486
487 for (auto MI : ToErase)
488 MI->eraseFromParent();
489}
490
491/// \returns true when \p Reg is used as part of an address calculation in \p
492/// MI.
493static bool usedAsAddr(const MachineInstr &MI, unsigned Reg,
494 const TargetInstrInfo *TII) {
495 if (!MI.mayLoadOrStore())
496 return false;
497
498 const MCInstrDesc &Desc = TII->get(MI.getOpcode());
499 int MemOpStart = X86II::getMemoryOperandNo(Desc.TSFlags);
500 if (MemOpStart == -1)
501 return false;
502
503 MemOpStart += X86II::getOperandBias(Desc);
504 for (unsigned MemOpIdx = MemOpStart,
505 MemOpEnd = MemOpStart + X86::AddrNumOperands;
506 MemOpIdx < MemOpEnd; ++MemOpIdx) {
507 auto &Op = MI.getOperand(MemOpIdx);
508 if (Op.isReg() && Op.getReg() == Reg)
509 return true;
510 }
511 return false;
512}
513
514void Closure::buildClosure(unsigned Reg) {
515 SmallVector<unsigned, 4> Worklist;
516 visitRegister(Reg, Worklist);
517 while (!Worklist.empty()) {
518 unsigned CurReg = Worklist.pop_back_val();
519
520 // Register already in this closure.
521 if (!Edges.insert(CurReg).second)
522 continue;
523
524 MachineInstr *DefMI = MRI->getVRegDef(CurReg);
525 encloseInstr(DefMI);
526
527 // Add register used by the defining MI to the worklist.
528 // Do not add registers which are used in address calculation, they will be
529 // added to a different closure.
530 int OpEnd = DefMI->getNumOperands();
531 const MCInstrDesc &Desc = DefMI->getDesc();
532 int MemOp = X86II::getMemoryOperandNo(Desc.TSFlags);
533 if (MemOp != -1)
534 MemOp += X86II::getOperandBias(Desc);
535 for (int OpIdx = 0; OpIdx < OpEnd; ++OpIdx) {
536 if (OpIdx == MemOp) {
537 // skip address calculation.
538 OpIdx += (X86::AddrNumOperands - 1);
539 continue;
540 }
541 auto &Op = DefMI->getOperand(OpIdx);
542 if (!Op.isReg() || !Op.isUse())
543 continue;
544 visitRegister(Op.getReg(), Worklist);
545 }
546
547 // Expand closure through register uses.
548 for (auto &UseMI : MRI->use_nodbg_instructions(CurReg)) {
549 // We would like to avoid converting closures which calculare addresses,
550 // as this should remain in GPRs.
551 if (usedAsAddr(UseMI, CurReg, TII)) {
552 setAllIllegal();
553 continue;
554 }
555 encloseInstr(&UseMI);
556
557 for (auto &DefOp : UseMI.defs()) {
558 if (!DefOp.isReg())
559 continue;
560
561 unsigned DefReg = DefOp.getReg();
562 if (!TargetRegisterInfo::isVirtualRegister(DefReg)) {
563 setAllIllegal();
564 continue;
565 }
566 visitRegister(DefReg, Worklist);
567 }
568 }
569 }
570}
571
572void X86DomainReassignment::initConverters() {
573 Converters[{MaskDomain, TargetOpcode::PHI}] =
574 new InstrIgnore(TargetOpcode::PHI);
575
576 Converters[{MaskDomain, TargetOpcode::IMPLICIT_DEF}] =
577 new InstrDeleter(TargetOpcode::IMPLICIT_DEF);
578
579 Converters[{MaskDomain, TargetOpcode::INSERT_SUBREG}] =
580 new InstrReplaceWithCopy(TargetOpcode::INSERT_SUBREG, 2);
581
582 Converters[{MaskDomain, TargetOpcode::COPY}] =
583 new InstrCOPYReplacer(TargetOpcode::COPY, MaskDomain, TargetOpcode::COPY);
584
585 auto createReplacerDstCOPY = [&](unsigned From, unsigned To) {
586 Converters[{MaskDomain, From}] = new InstrReplacerDstCOPY(From, To);
587 };
588
589 createReplacerDstCOPY(X86::MOVZX32rm16, X86::KMOVWkm);
590 createReplacerDstCOPY(X86::MOVZX64rm16, X86::KMOVWkm);
591
592 createReplacerDstCOPY(X86::MOVZX32rr16, X86::KMOVWkk);
593 createReplacerDstCOPY(X86::MOVZX64rr16, X86::KMOVWkk);
594
595 if (STI->hasDQI()) {
596 createReplacerDstCOPY(X86::MOVZX16rm8, X86::KMOVBkm);
597 createReplacerDstCOPY(X86::MOVZX32rm8, X86::KMOVBkm);
598 createReplacerDstCOPY(X86::MOVZX64rm8, X86::KMOVBkm);
599
600 createReplacerDstCOPY(X86::MOVZX16rr8, X86::KMOVBkk);
601 createReplacerDstCOPY(X86::MOVZX32rr8, X86::KMOVBkk);
602 createReplacerDstCOPY(X86::MOVZX64rr8, X86::KMOVBkk);
603 }
604
605 auto createReplacer = [&](unsigned From, unsigned To) {
606 Converters[{MaskDomain, From}] = new InstrReplacer(From, To);
607 };
608
609 createReplacer(X86::MOV16rm, X86::KMOVWkm);
610 createReplacer(X86::MOV16mr, X86::KMOVWmk);
611 createReplacer(X86::MOV16rr, X86::KMOVWkk);
612 createReplacer(X86::SHR16ri, X86::KSHIFTRWri);
613 createReplacer(X86::SHL16ri, X86::KSHIFTLWri);
614 createReplacer(X86::NOT16r, X86::KNOTWrr);
615 createReplacer(X86::OR16rr, X86::KORWrr);
616 createReplacer(X86::AND16rr, X86::KANDWrr);
617 createReplacer(X86::XOR16rr, X86::KXORWrr);
618
619 if (STI->hasBWI()) {
620 createReplacer(X86::MOV32rm, X86::KMOVDkm);
621 createReplacer(X86::MOV64rm, X86::KMOVQkm);
622
623 createReplacer(X86::MOV32mr, X86::KMOVDmk);
624 createReplacer(X86::MOV64mr, X86::KMOVQmk);
625
626 createReplacer(X86::MOV32rr, X86::KMOVDkk);
627 createReplacer(X86::MOV64rr, X86::KMOVQkk);
628
629 createReplacer(X86::SHR32ri, X86::KSHIFTRDri);
630 createReplacer(X86::SHR64ri, X86::KSHIFTRQri);
631
632 createReplacer(X86::SHL32ri, X86::KSHIFTLDri);
633 createReplacer(X86::SHL64ri, X86::KSHIFTLQri);
634
635 createReplacer(X86::ADD32rr, X86::KADDDrr);
636 createReplacer(X86::ADD64rr, X86::KADDQrr);
637
638 createReplacer(X86::NOT32r, X86::KNOTDrr);
639 createReplacer(X86::NOT64r, X86::KNOTQrr);
640
641 createReplacer(X86::OR32rr, X86::KORDrr);
642 createReplacer(X86::OR64rr, X86::KORQrr);
643
644 createReplacer(X86::AND32rr, X86::KANDDrr);
645 createReplacer(X86::AND64rr, X86::KANDQrr);
646
647 createReplacer(X86::ANDN32rr, X86::KANDNDrr);
648 createReplacer(X86::ANDN64rr, X86::KANDNQrr);
649
650 createReplacer(X86::XOR32rr, X86::KXORDrr);
651 createReplacer(X86::XOR64rr, X86::KXORQrr);
652
653 createReplacer(X86::TEST32rr, X86::KTESTDrr);
654 createReplacer(X86::TEST64rr, X86::KTESTQrr);
655 }
656
657 if (STI->hasDQI()) {
658 createReplacer(X86::ADD8rr, X86::KADDBrr);
659 createReplacer(X86::ADD16rr, X86::KADDWrr);
660
661 createReplacer(X86::AND8rr, X86::KANDBrr);
662
663 createReplacer(X86::MOV8rm, X86::KMOVBkm);
664 createReplacer(X86::MOV8mr, X86::KMOVBmk);
665 createReplacer(X86::MOV8rr, X86::KMOVBkk);
666
667 createReplacer(X86::NOT8r, X86::KNOTBrr);
668
669 createReplacer(X86::OR8rr, X86::KORBrr);
670
671 createReplacer(X86::SHR8ri, X86::KSHIFTRBri);
672 createReplacer(X86::SHL8ri, X86::KSHIFTLBri);
673
674 createReplacer(X86::TEST8rr, X86::KTESTBrr);
675 createReplacer(X86::TEST16rr, X86::KTESTWrr);
676
677 createReplacer(X86::XOR8rr, X86::KXORBrr);
678 }
679}
680
681bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
682 if (skipFunction(*MF.getFunction()))
683 return false;
684 if (DisableX86DomainReassignment)
685 return false;
686
687 DEBUG(dbgs() << "***** Machine Function before Domain Reassignment *****\n");
688 DEBUG(MF.print(dbgs()));
689
690 STI = &MF.getSubtarget<X86Subtarget>();
691 // GPR->K is the only transformation currently supported, bail out early if no
692 // AVX512.
693 if (!STI->hasAVX512())
694 return false;
695
696 MRI = &MF.getRegInfo();
697 assert(MRI->isSSA() && "Expected MIR to be in SSA form");
698
699 TII = STI->getInstrInfo();
700 initConverters();
701 bool Changed = false;
702
703 DenseSet<unsigned> EnclosedEdges;
704 DenseMap<MachineInstr *, Closure *> EnclosedInstrs;
705
706 std::vector<Closure> Closures;
707
708 // Go over all virtual registers and calculate a closure.
709 for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
710 unsigned Reg = TargetRegisterInfo::index2VirtReg(Idx);
711
712 // GPR only current source domain supported.
713 if (!isGPR(MRI->getRegClass(Reg)))
714 continue;
715
716 // Register already in closure.
717 if (EnclosedEdges.count(Reg))
718 continue;
719
720 // Calculate closure starting with Reg.
721 Closure C(TII, MRI, Converters, {MaskDomain}, EnclosedEdges,
722 EnclosedInstrs);
723 C.buildClosure(Reg);
724
725 // Collect all closures that can potentially be converted.
726 if (!C.empty() && C.isLegal(MaskDomain))
727 Closures.push_back(std::move(C));
728 }
729
730 for (Closure &C : Closures)
731 if (C.isReassignmentProfitable(MaskDomain)) {
732 C.Reassign(MaskDomain);
733 ++NumClosuresConverted;
734 Changed = true;
735 }
736
737 for (auto I : Converters)
738 delete I.second;
739
740 DEBUG(dbgs() << "***** Machine Function after Domain Reassignment *****\n");
741 DEBUG(MF.print(dbgs()));
742
743 return Changed;
744}
745
746INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment",
Haojian Wu1afddd42017-10-23 09:02:59 +0000747 "X86 Domain Reassignment Pass", false, false)
Guy Blank92d5ce32017-10-22 11:43:08 +0000748
749/// Returns an instance of the Domain Reassignment pass.
750FunctionPass *llvm::createX86DomainReassignmentPass() {
751 return new X86DomainReassignment();
752}