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