1 //===--- X86DomainReassignment.cpp - Selectively switch register classes---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass attempts to find instruction chains (closures) in one domain, 11 // and convert them to equivalent instructions in a different domain, 12 // if profitable. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "X86.h" 17 #include "X86InstrInfo.h" 18 #include "X86Subtarget.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/DenseMapInfo.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/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" 28 #include "llvm/CodeGen/TargetRegisterInfo.h" 29 #include "llvm/Support/Debug.h" 30 31 using namespace llvm; 32 33 namespace llvm { 34 void initializeX86DomainReassignmentPass(PassRegistry &); 35 } 36 37 #define DEBUG_TYPE "x86-domain-reassignment" 38 39 STATISTIC(NumClosuresConverted, "Number of closures converted by the pass"); 40 41 static cl::opt<bool> DisableX86DomainReassignment( 42 "disable-x86-domain-reassignment", cl::Hidden, 43 cl::desc("X86: Disable Virtual Register Reassignment."), cl::init(false)); 44 45 namespace { 46 enum RegDomain { NoDomain = -1, GPRDomain, MaskDomain, OtherDomain }; 47 48 static 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 55 static bool isMask(const TargetRegisterClass *RC, 56 const TargetRegisterInfo *TRI) { 57 return X86::VK16RegClass.hasSubClassEq(RC); 58 } 59 60 static 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. 70 static const TargetRegisterClass *getDstRC(const TargetRegisterClass *SrcRC, 71 RegDomain Domain) { 72 assert(Domain == MaskDomain && "add domain"); 73 if (X86::GR8RegClass.hasSubClassEq(SrcRC)) 74 return &X86::VK8RegClass; 75 if (X86::GR16RegClass.hasSubClassEq(SrcRC)) 76 return &X86::VK16RegClass; 77 if (X86::GR32RegClass.hasSubClassEq(SrcRC)) 78 return &X86::VK32RegClass; 79 if (X86::GR64RegClass.hasSubClassEq(SrcRC)) 80 return &X86::VK64RegClass; 81 llvm_unreachable("add register class"); 82 return nullptr; 83 } 84 85 /// Abstract Instruction Converter class. 86 class InstrConverterBase { 87 protected: 88 unsigned SrcOpcode; 89 90 public: 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. 117 class InstrIgnore : public InstrConverterBase { 118 public: 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. 134 class InstrReplacer : public InstrConverterBase { 135 public: 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. 176 class InstrReplacerDstCOPY : public InstrConverterBase { 177 public: 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. 212 class InstrCOPYReplacer : public InstrReplacer { 213 public: 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. 242 class InstrReplaceWithCopy : public InstrConverterBase { 243 public: 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. 268 class InstrDeleter : public InstrConverterBase { 269 public: 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> 286 typedef std::pair<int, unsigned> InstrConverterBaseKeyTy; 287 288 typedef 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. 302 class Closure { 303 private: 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 341 public: 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 372 class X86DomainReassignment : public MachineFunctionPass { 373 public: 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 391 private: 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 403 char X86DomainReassignment::ID = 0; 404 405 } // End anonymous namespace. 406 407 void 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 428 void 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 450 double 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 460 bool Closure::isReassignmentProfitable(RegDomain Domain) const { 461 return calculateCost(Domain) < 0.0; 462 } 463 464 void 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. 493 static 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 514 void 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 572 void 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 681 bool 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 746 INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment", 747 "X86 Domain Reassignment Pass", false, false) 748 749 /// Returns an instance of the Domain Reassignment pass. 750 FunctionPass *llvm::createX86DomainReassignmentPass() { 751 return new X86DomainReassignment(); 752 } 753