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