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/SmallVector.h" 23 #include "llvm/ADT/Statistic.h" 24 #include "llvm/CodeGen/MachineFunctionPass.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/CodeGen/TargetRegisterInfo.h" 28 #include "llvm/Support/Debug.h" 29 #include <bitset> 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, NumDomains }; 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 std::bitset<NumDomains> LegalDstDomains; 321 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 337 public: 338 Closure(const TargetInstrInfo *TII, MachineRegisterInfo *MRI, 339 const InstrConverterBaseMap &Converters, 340 std::initializer_list<RegDomain> LegalDstDomainList, 341 DenseSet<unsigned> &EnclosedEdges, 342 DenseMap<MachineInstr *, Closure *> &EnclosedInstrs) 343 : TII(TII), MRI(MRI), Converters(Converters), Domain(NoDomain), 344 EnclosedEdges(EnclosedEdges), EnclosedInstrs(EnclosedInstrs) { 345 for (RegDomain D : LegalDstDomainList) 346 LegalDstDomains.set(D); 347 } 348 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. 359 void setAllIllegal() { LegalDstDomains.reset(); } 360 361 /// \returns true if this closure has domains which are legal to reassign to. 362 bool hasLegalDstDomain() const { return LegalDstDomains.any(); } 363 364 /// \returns true if is legal to reassign this closure to domain \p RD. 365 bool isLegal(RegDomain RD) const { return LegalDstDomains[RD]; } 366 367 bool empty() const { return Edges.empty(); } 368 }; 369 370 class X86DomainReassignment : public MachineFunctionPass { 371 public: 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 389 private: 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 401 char X86DomainReassignment::ID = 0; 402 403 } // End anonymous namespace. 404 405 void 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 426 void 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. 442 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 } 449 } 450 451 double 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 461 bool Closure::isReassignmentProfitable(RegDomain Domain) const { 462 return calculateCost(Domain) < 0.0; 463 } 464 465 void 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. 494 static 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 515 void 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 573 void 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 682 bool X86DomainReassignment::runOnMachineFunction(MachineFunction &MF) { 683 if (skipFunction(MF.getFunction())) 684 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 747 INITIALIZE_PASS(X86DomainReassignment, "x86-domain-reassignment", 748 "X86 Domain Reassignment Pass", false, false) 749 750 /// Returns an instance of the Domain Reassignment pass. 751 FunctionPass *llvm::createX86DomainReassignmentPass() { 752 return new X86DomainReassignment(); 753 } 754