blob: 0a87fb4533c2045735528f3bff18dccd84eea65c [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"
Craig Topper59925352017-12-17 03:16:23 +000029#include <bitset>
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 {
Craig Topper59925352017-12-17 03:16:23 +000046enum RegDomain { NoDomain = -1, GPRDomain, MaskDomain, OtherDomain, NumDomains };
Guy Blank92d5ce32017-10-22 11:43:08 +000047
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.
Craig Topper59925352017-12-17 03:16:23 +0000320 std::bitset<NumDomains> LegalDstDomains;
Guy Blank92d5ce32017-10-22 11:43:08 +0000321
322 /// Enqueue \p Reg to be considered for addition to the closure.
323 void visitRegister(unsigned Reg, SmallVectorImpl<unsigned> &Worklist);
324
325 /// Add \p MI to this closure.
326 void encloseInstr(MachineInstr *MI);
327
328 /// Calculate the total cost of reassigning the closure to \p Domain.
329 double calculateCost(RegDomain Domain) const;
330
331 /// All edges that are included in some closure.
332 DenseSet<unsigned> &EnclosedEdges;
333
334 /// All instructions that are included in some closure.
335 DenseMap<MachineInstr *, Closure *> &EnclosedInstrs;
336
337public:
338 Closure(const TargetInstrInfo *TII, MachineRegisterInfo *MRI,
339 const InstrConverterBaseMap &Converters,
Craig Topper59925352017-12-17 03:16:23 +0000340 std::initializer_list<RegDomain> LegalDstDomainList,
Guy Blank92d5ce32017-10-22 11:43:08 +0000341 DenseSet<unsigned> &EnclosedEdges,
342 DenseMap<MachineInstr *, Closure *> &EnclosedInstrs)
343 : TII(TII), MRI(MRI), Converters(Converters), Domain(NoDomain),
Craig Topper59925352017-12-17 03:16:23 +0000344 EnclosedEdges(EnclosedEdges), EnclosedInstrs(EnclosedInstrs) {
345 for (RegDomain D : LegalDstDomainList)
346 LegalDstDomains.set(D);
347 }
Guy Blank92d5ce32017-10-22 11:43:08 +0000348
349 /// Starting from \Reg, expand the closure as much as possible.
350 void buildClosure(unsigned E);
351
352 /// /returns true if it is profitable to reassign the closure to \p Domain.
353 bool isReassignmentProfitable(RegDomain Domain) const;
354
355 /// Reassign the closure to \p Domain.
356 void Reassign(RegDomain Domain) const;
357
358 /// Mark this closure as illegal for reassignment to all domains.
Craig Topper59925352017-12-17 03:16:23 +0000359 void setAllIllegal() { LegalDstDomains.reset(); }
Guy Blank92d5ce32017-10-22 11:43:08 +0000360
361 /// \returns true if this closure has domains which are legal to reassign to.
Craig Topper59925352017-12-17 03:16:23 +0000362 bool hasLegalDstDomain() const { return LegalDstDomains.any(); }
Guy Blank92d5ce32017-10-22 11:43:08 +0000363
364 /// \returns true if is legal to reassign this closure to domain \p RD.
Craig Topper59925352017-12-17 03:16:23 +0000365 bool isLegal(RegDomain RD) const { return LegalDstDomains[RD]; }
Guy Blank92d5ce32017-10-22 11:43:08 +0000366
367 bool empty() const { return Edges.empty(); }
368};
369
370class X86DomainReassignment : public MachineFunctionPass {
371public:
372 static char ID;
373
374 X86DomainReassignment() : MachineFunctionPass(ID) {
375 initializeX86DomainReassignmentPass(*PassRegistry::getPassRegistry());
376 }
377
378 bool runOnMachineFunction(MachineFunction &MF) override;
379
380 void getAnalysisUsage(AnalysisUsage &AU) const override {
381 AU.setPreservesCFG();
382 MachineFunctionPass::getAnalysisUsage(AU);
383 }
384
385 StringRef getPassName() const override {
386 return "X86 Domain Reassignment Pass";
387 }
388
389private:
390 const X86Subtarget *STI;
391 MachineRegisterInfo *MRI;
392 const X86InstrInfo *TII;
393
394 /// A map of available Instruction Converters.
395 InstrConverterBaseMap Converters;
396
397 /// Initialize Converters map.
398 void initConverters();
399};
400
401char X86DomainReassignment::ID = 0;
402
403} // End anonymous namespace.
404
405void Closure::visitRegister(unsigned Reg, SmallVectorImpl<unsigned> &Worklist) {
406 if (EnclosedEdges.count(Reg))
407 return;
408
409 if (!TargetRegisterInfo::isVirtualRegister(Reg))
410 return;
411
412 if (!MRI->hasOneDef(Reg))
413 return;
414
415 RegDomain RD = getDomain(MRI->getRegClass(Reg), MRI->getTargetRegisterInfo());
416 // First edge in closure sets the domain.
417 if (Domain == NoDomain)
418 Domain = RD;
419
420 if (Domain != RD)
421 return;
422
423 Worklist.push_back(Reg);
424}
425
426void Closure::encloseInstr(MachineInstr *MI) {
427 auto I = EnclosedInstrs.find(MI);
428 if (I != EnclosedInstrs.end()) {
429 if (I->second != this)
430 // Instruction already belongs to another closure, avoid conflicts between
431 // closure and mark this closure as illegal.
432 setAllIllegal();
433 return;
434 }
435
436 EnclosedInstrs[MI] = this;
437 Instrs.push_back(MI);
438
439 // Mark closure as illegal for reassignment to domains, if there is no
440 // converter for the instruction or if the converter cannot convert the
441 // instruction.
Craig Topper59925352017-12-17 03:16:23 +0000442 for (unsigned i = 0; i != LegalDstDomains.size(); ++i) {
443 if (LegalDstDomains[i]) {
444 InstrConverterBase *IC = Converters.lookup({i, MI->getOpcode()});
445 if (!IC || !IC->isLegal(MI, TII))
446 LegalDstDomains[i] = false;
447 }
448 }
Guy Blank92d5ce32017-10-22 11:43:08 +0000449}
450
451double Closure::calculateCost(RegDomain DstDomain) const {
452 assert(isLegal(DstDomain) && "Cannot calculate cost for illegal closure");
453
454 double Cost = 0.0;
455 for (auto MI : Instrs)
456 Cost +=
457 Converters.lookup({DstDomain, MI->getOpcode()})->getExtraCost(MI, MRI);
458 return Cost;
459}
460
461bool Closure::isReassignmentProfitable(RegDomain Domain) const {
462 return calculateCost(Domain) < 0.0;
463}
464
465void Closure::Reassign(RegDomain Domain) const {
466 assert(isLegal(Domain) && "Cannot convert illegal closure");
467
468 // Iterate all instructions in the closure, convert each one using the
469 // appropriate converter.
470 SmallVector<MachineInstr *, 8> ToErase;
471 for (auto MI : Instrs)
472 if (Converters.lookup({Domain, MI->getOpcode()})
473 ->convertInstr(MI, TII, MRI))
474 ToErase.push_back(MI);
475
476 // Iterate all registers in the closure, replace them with registers in the
477 // destination domain.
478 for (unsigned Reg : Edges) {
479 MRI->setRegClass(Reg, getDstRC(MRI->getRegClass(Reg), Domain));
480 for (auto &MO : MRI->use_operands(Reg)) {
481 if (MO.isReg())
482 // Remove all subregister references as they are not valid in the
483 // destination domain.
484 MO.setSubReg(0);
485 }
486 }
487
488 for (auto MI : ToErase)
489 MI->eraseFromParent();
490}
491
492/// \returns true when \p Reg is used as part of an address calculation in \p
493/// MI.
494static bool usedAsAddr(const MachineInstr &MI, unsigned Reg,
495 const TargetInstrInfo *TII) {
496 if (!MI.mayLoadOrStore())
497 return false;
498
499 const MCInstrDesc &Desc = TII->get(MI.getOpcode());
500 int MemOpStart = X86II::getMemoryOperandNo(Desc.TSFlags);
501 if (MemOpStart == -1)
502 return false;
503
504 MemOpStart += X86II::getOperandBias(Desc);
505 for (unsigned MemOpIdx = MemOpStart,
506 MemOpEnd = MemOpStart + X86::AddrNumOperands;
507 MemOpIdx < MemOpEnd; ++MemOpIdx) {
508 auto &Op = MI.getOperand(MemOpIdx);
509 if (Op.isReg() && Op.getReg() == Reg)
510 return true;
511 }
512 return false;
513}
514
515void Closure::buildClosure(unsigned Reg) {
516 SmallVector<unsigned, 4> Worklist;
517 visitRegister(Reg, Worklist);
518 while (!Worklist.empty()) {
519 unsigned CurReg = Worklist.pop_back_val();
520
521 // Register already in this closure.
522 if (!Edges.insert(CurReg).second)
523 continue;
524
525 MachineInstr *DefMI = MRI->getVRegDef(CurReg);
526 encloseInstr(DefMI);
527
528 // Add register used by the defining MI to the worklist.
529 // Do not add registers which are used in address calculation, they will be
530 // added to a different closure.
531 int OpEnd = DefMI->getNumOperands();
532 const MCInstrDesc &Desc = DefMI->getDesc();
533 int MemOp = X86II::getMemoryOperandNo(Desc.TSFlags);
534 if (MemOp != -1)
535 MemOp += X86II::getOperandBias(Desc);
536 for (int OpIdx = 0; OpIdx < OpEnd; ++OpIdx) {
537 if (OpIdx == MemOp) {
538 // skip address calculation.
539 OpIdx += (X86::AddrNumOperands - 1);
540 continue;
541 }
542 auto &Op = DefMI->getOperand(OpIdx);
543 if (!Op.isReg() || !Op.isUse())
544 continue;
545 visitRegister(Op.getReg(), Worklist);
546 }
547
548 // Expand closure through register uses.
549 for (auto &UseMI : MRI->use_nodbg_instructions(CurReg)) {
550 // We would like to avoid converting closures which calculare addresses,
551 // as this should remain in GPRs.
552 if (usedAsAddr(UseMI, CurReg, TII)) {
553 setAllIllegal();
554 continue;
555 }
556 encloseInstr(&UseMI);
557
558 for (auto &DefOp : UseMI.defs()) {
559 if (!DefOp.isReg())
560 continue;
561
562 unsigned DefReg = DefOp.getReg();
563 if (!TargetRegisterInfo::isVirtualRegister(DefReg)) {
564 setAllIllegal();
565 continue;
566 }
567 visitRegister(DefReg, Worklist);
568 }
569 }
570 }
571}
572
573void X86DomainReassignment::initConverters() {
574 Converters[{MaskDomain, TargetOpcode::PHI}] =
575 new InstrIgnore(TargetOpcode::PHI);
576
577 Converters[{MaskDomain, TargetOpcode::IMPLICIT_DEF}] =
578 new InstrDeleter(TargetOpcode::IMPLICIT_DEF);
579
580 Converters[{MaskDomain, TargetOpcode::INSERT_SUBREG}] =
581 new InstrReplaceWithCopy(TargetOpcode::INSERT_SUBREG, 2);
582
583 Converters[{MaskDomain, TargetOpcode::COPY}] =
584 new InstrCOPYReplacer(TargetOpcode::COPY, MaskDomain, TargetOpcode::COPY);
585
586 auto createReplacerDstCOPY = [&](unsigned From, unsigned To) {
587 Converters[{MaskDomain, From}] = new InstrReplacerDstCOPY(From, To);
588 };
589
590 createReplacerDstCOPY(X86::MOVZX32rm16, X86::KMOVWkm);
591 createReplacerDstCOPY(X86::MOVZX64rm16, X86::KMOVWkm);
592
593 createReplacerDstCOPY(X86::MOVZX32rr16, X86::KMOVWkk);
594 createReplacerDstCOPY(X86::MOVZX64rr16, X86::KMOVWkk);
595
596 if (STI->hasDQI()) {
597 createReplacerDstCOPY(X86::MOVZX16rm8, X86::KMOVBkm);
598 createReplacerDstCOPY(X86::MOVZX32rm8, X86::KMOVBkm);
599 createReplacerDstCOPY(X86::MOVZX64rm8, X86::KMOVBkm);
600
601 createReplacerDstCOPY(X86::MOVZX16rr8, X86::KMOVBkk);
602 createReplacerDstCOPY(X86::MOVZX32rr8, X86::KMOVBkk);
603 createReplacerDstCOPY(X86::MOVZX64rr8, X86::KMOVBkk);
604 }
605
606 auto createReplacer = [&](unsigned From, unsigned To) {
607 Converters[{MaskDomain, From}] = new InstrReplacer(From, To);
608 };
609
610 createReplacer(X86::MOV16rm, X86::KMOVWkm);
611 createReplacer(X86::MOV16mr, X86::KMOVWmk);
612 createReplacer(X86::MOV16rr, X86::KMOVWkk);
613 createReplacer(X86::SHR16ri, X86::KSHIFTRWri);
614 createReplacer(X86::SHL16ri, X86::KSHIFTLWri);
615 createReplacer(X86::NOT16r, X86::KNOTWrr);
616 createReplacer(X86::OR16rr, X86::KORWrr);
617 createReplacer(X86::AND16rr, X86::KANDWrr);
618 createReplacer(X86::XOR16rr, X86::KXORWrr);
619
620 if (STI->hasBWI()) {
621 createReplacer(X86::MOV32rm, X86::KMOVDkm);
622 createReplacer(X86::MOV64rm, X86::KMOVQkm);
623
624 createReplacer(X86::MOV32mr, X86::KMOVDmk);
625 createReplacer(X86::MOV64mr, X86::KMOVQmk);
626
627 createReplacer(X86::MOV32rr, X86::KMOVDkk);
628 createReplacer(X86::MOV64rr, X86::KMOVQkk);
629
630 createReplacer(X86::SHR32ri, X86::KSHIFTRDri);
631 createReplacer(X86::SHR64ri, X86::KSHIFTRQri);
632
633 createReplacer(X86::SHL32ri, X86::KSHIFTLDri);
634 createReplacer(X86::SHL64ri, X86::KSHIFTLQri);
635
636 createReplacer(X86::ADD32rr, X86::KADDDrr);
637 createReplacer(X86::ADD64rr, X86::KADDQrr);
638
639 createReplacer(X86::NOT32r, X86::KNOTDrr);
640 createReplacer(X86::NOT64r, X86::KNOTQrr);
641
642 createReplacer(X86::OR32rr, X86::KORDrr);
643 createReplacer(X86::OR64rr, X86::KORQrr);
644
645 createReplacer(X86::AND32rr, X86::KANDDrr);
646 createReplacer(X86::AND64rr, X86::KANDQrr);
647
648 createReplacer(X86::ANDN32rr, X86::KANDNDrr);
649 createReplacer(X86::ANDN64rr, X86::KANDNQrr);
650
651 createReplacer(X86::XOR32rr, X86::KXORDrr);
652 createReplacer(X86::XOR64rr, X86::KXORQrr);
653
654 createReplacer(X86::TEST32rr, X86::KTESTDrr);
655 createReplacer(X86::TEST64rr, X86::KTESTQrr);
656 }
657
658 if (STI->hasDQI()) {
659 createReplacer(X86::ADD8rr, X86::KADDBrr);
660 createReplacer(X86::ADD16rr, X86::KADDWrr);
661
662 createReplacer(X86::AND8rr, X86::KANDBrr);
663
664 createReplacer(X86::MOV8rm, X86::KMOVBkm);
665 createReplacer(X86::MOV8mr, X86::KMOVBmk);
666 createReplacer(X86::MOV8rr, X86::KMOVBkk);
667
668 createReplacer(X86::NOT8r, X86::KNOTBrr);
669
670 createReplacer(X86::OR8rr, X86::KORBrr);
671
672 createReplacer(X86::SHR8ri, X86::KSHIFTRBri);
673 createReplacer(X86::SHL8ri, X86::KSHIFTLBri);
674
675 createReplacer(X86::TEST8rr, X86::KTESTBrr);
676 createReplacer(X86::TEST16rr, X86::KTESTWrr);
677
678 createReplacer(X86::XOR8rr, X86::KXORBrr);
679 }
680}
681
682bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) {
Matthias Braunf1caa282017-12-15 22:22:58 +0000683 if (skipFunction(MF.getFunction()))
Guy Blank92d5ce32017-10-22 11:43:08 +0000684 return false;
685 if (DisableX86DomainReassignment)
686 return false;
687
688 DEBUG(dbgs() << "***** Machine Function before Domain Reassignment *****\n");
689 DEBUG(MF.print(dbgs()));
690
691 STI = &MF.getSubtarget<X86Subtarget>();
692 // GPR->K is the only transformation currently supported, bail out early if no
693 // AVX512.
694 if (!STI->hasAVX512())
695 return false;
696
697 MRI = &MF.getRegInfo();
698 assert(MRI->isSSA() && "Expected MIR to be in SSA form");
699
700 TII = STI->getInstrInfo();
701 initConverters();
702 bool Changed = false;
703
704 DenseSet<unsigned> EnclosedEdges;
705 DenseMap<MachineInstr *, Closure *> EnclosedInstrs;
706
707 std::vector<Closure> Closures;
708
709 // Go over all virtual registers and calculate a closure.
710 for (unsigned Idx = 0; Idx < MRI->getNumVirtRegs(); ++Idx) {
711 unsigned Reg = TargetRegisterInfo::index2VirtReg(Idx);
712
713 // GPR only current source domain supported.
714 if (!isGPR(MRI->getRegClass(Reg)))
715 continue;
716
717 // Register already in closure.
718 if (EnclosedEdges.count(Reg))
719 continue;
720
721 // Calculate closure starting with Reg.
722 Closure C(TII, MRI, Converters, {MaskDomain}, EnclosedEdges,
723 EnclosedInstrs);
724 C.buildClosure(Reg);
725
726 // Collect all closures that can potentially be converted.
727 if (!C.empty() && C.isLegal(MaskDomain))
728 Closures.push_back(std::move(C));
729 }
730
731 for (Closure &C : Closures)
732 if (C.isReassignmentProfitable(MaskDomain)) {
733 C.Reassign(MaskDomain);
734 ++NumClosuresConverted;
735 Changed = true;
736 }
737
738 for (auto I : Converters)
739 delete I.second;
740
741 DEBUG(dbgs() << "***** Machine Function after Domain Reassignment *****\n");
742 DEBUG(MF.print(dbgs()));
743
744 return Changed;
745}
746
747INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment",
Haojian Wu1afddd42017-10-23 09:02:59 +0000748 "X86 Domain Reassignment Pass", false, false)
Guy Blank92d5ce32017-10-22 11:43:08 +0000749
750/// Returns an instance of the Domain Reassignment pass.
751FunctionPass *llvm::createX86DomainReassignmentPass() {
752 return new X86DomainReassignment();
753}