1 //===----------- PPCVSXSwapRemoval.cpp - Remove VSX LE Swaps -------------===// 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 analyzes vector computations and removes unnecessary 11 // doubleword swaps (xxswapd instructions). This pass is performed 12 // only for little-endian VSX code generation. 13 // 14 // For this specific case, loads and stores of v4i32, v4f32, v2i64, 15 // and v2f64 vectors are inefficient. These are implemented using 16 // the lxvd2x and stxvd2x instructions, which invert the order of 17 // doublewords in a vector register. Thus code generation inserts 18 // an xxswapd after each such load, and prior to each such store. 19 // 20 // The extra xxswapd instructions reduce performance. The purpose 21 // of this pass is to reduce the number of xxswapd instructions 22 // required for correctness. 23 // 24 // The primary insight is that much code that operates on vectors 25 // does not care about the relative order of elements in a register, 26 // so long as the correct memory order is preserved. If we have a 27 // computation where all input values are provided by lxvd2x/xxswapd, 28 // all outputs are stored using xxswapd/lxvd2x, and all intermediate 29 // computations are lane-insensitive (independent of element order), 30 // then all the xxswapd instructions associated with the loads and 31 // stores may be removed without changing observable semantics. 32 // 33 // This pass uses standard equivalence class infrastructure to create 34 // maximal webs of computations fitting the above description. Each 35 // such web is then optimized by removing its unnecessary xxswapd 36 // instructions. 37 // 38 // There are some lane-sensitive operations for which we can still 39 // permit the optimization, provided we modify those operations 40 // accordingly. Such operations are identified as using "special 41 // handling" within this module. 42 // 43 //===---------------------------------------------------------------------===// 44 45 #include "PPCInstrInfo.h" 46 #include "PPC.h" 47 #include "PPCInstrBuilder.h" 48 #include "PPCTargetMachine.h" 49 #include "llvm/ADT/DenseMap.h" 50 #include "llvm/ADT/EquivalenceClasses.h" 51 #include "llvm/CodeGen/MachineFunctionPass.h" 52 #include "llvm/CodeGen/MachineInstrBuilder.h" 53 #include "llvm/CodeGen/MachineRegisterInfo.h" 54 #include "llvm/Support/Debug.h" 55 #include "llvm/Support/Format.h" 56 #include "llvm/Support/raw_ostream.h" 57 58 using namespace llvm; 59 60 #define DEBUG_TYPE "ppc-vsx-swaps" 61 62 namespace llvm { 63 void initializePPCVSXSwapRemovalPass(PassRegistry&); 64 } 65 66 namespace { 67 68 // A PPCVSXSwapEntry is created for each machine instruction that 69 // is relevant to a vector computation. 70 struct PPCVSXSwapEntry { 71 // Pointer to the instruction. 72 MachineInstr *VSEMI; 73 74 // Unique ID (position in the swap vector). 75 int VSEId; 76 77 // Attributes of this node. 78 unsigned int IsLoad : 1; 79 unsigned int IsStore : 1; 80 unsigned int IsSwap : 1; 81 unsigned int MentionsPhysVR : 1; 82 unsigned int HasImplicitSubreg : 1; 83 unsigned int IsSwappable : 1; 84 unsigned int SpecialHandling : 3; 85 unsigned int WebRejected : 1; 86 unsigned int WillRemove : 1; 87 }; 88 89 enum SHValues { 90 SH_NONE = 0, 91 SH_EXTRACT, 92 SH_INSERT, 93 SH_NOSWAP_LD, 94 SH_NOSWAP_ST, 95 SH_SPLAT 96 }; 97 98 struct PPCVSXSwapRemoval : public MachineFunctionPass { 99 100 static char ID; 101 const PPCInstrInfo *TII; 102 MachineFunction *MF; 103 MachineRegisterInfo *MRI; 104 105 // Swap entries are allocated in a vector for better performance. 106 std::vector<PPCVSXSwapEntry> SwapVector; 107 108 // A mapping is maintained between machine instructions and 109 // their swap entries. The key is the address of the MI. 110 DenseMap<MachineInstr*, int> SwapMap; 111 112 // Equivalence classes are used to gather webs of related computation. 113 // Swap entries are represented by their VSEId fields. 114 EquivalenceClasses<int> *EC; 115 116 PPCVSXSwapRemoval() : MachineFunctionPass(ID) { 117 initializePPCVSXSwapRemovalPass(*PassRegistry::getPassRegistry()); 118 } 119 120 private: 121 // Initialize data structures. 122 void initialize(MachineFunction &MFParm); 123 124 // Walk the machine instructions to gather vector usage information. 125 // Return true iff vector mentions are present. 126 bool gatherVectorInstructions(); 127 128 // Add an entry to the swap vector and swap map. 129 int addSwapEntry(MachineInstr *MI, PPCVSXSwapEntry &SwapEntry); 130 131 // Hunt backwards through COPY and SUBREG_TO_REG chains for a 132 // source register. VecIdx indicates the swap vector entry to 133 // mark as mentioning a physical register if the search leads 134 // to one. 135 unsigned lookThruCopyLike(unsigned SrcReg, unsigned VecIdx); 136 137 // Generate equivalence classes for related computations (webs). 138 void formWebs(); 139 140 // Analyze webs and determine those that cannot be optimized. 141 void recordUnoptimizableWebs(); 142 143 // Record which swap instructions can be safely removed. 144 void markSwapsForRemoval(); 145 146 // Remove swaps and update other instructions requiring special 147 // handling. Return true iff any changes are made. 148 bool removeSwaps(); 149 150 // Update instructions requiring special handling. 151 void handleSpecialSwappables(int EntryIdx); 152 153 // Dump a description of the entries in the swap vector. 154 void dumpSwapVector(); 155 156 // Return true iff the given register is in the given class. 157 bool isRegInClass(unsigned Reg, const TargetRegisterClass *RC) { 158 if (TargetRegisterInfo::isVirtualRegister(Reg)) 159 return RC->hasSubClassEq(MRI->getRegClass(Reg)); 160 if (RC->contains(Reg)) 161 return true; 162 return false; 163 } 164 165 // Return true iff the given register is a full vector register. 166 bool isVecReg(unsigned Reg) { 167 return (isRegInClass(Reg, &PPC::VSRCRegClass) || 168 isRegInClass(Reg, &PPC::VRRCRegClass)); 169 } 170 171 public: 172 // Main entry point for this pass. 173 bool runOnMachineFunction(MachineFunction &MF) override { 174 // If we don't have VSX on the subtarget, don't do anything. 175 const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>(); 176 if (!STI.hasVSX()) 177 return false; 178 179 bool Changed = false; 180 initialize(MF); 181 182 if (gatherVectorInstructions()) { 183 formWebs(); 184 recordUnoptimizableWebs(); 185 markSwapsForRemoval(); 186 Changed = removeSwaps(); 187 } 188 189 // FIXME: See the allocation of EC in initialize(). 190 delete EC; 191 return Changed; 192 } 193 }; 194 195 // Initialize data structures for this pass. In particular, clear the 196 // swap vector and allocate the equivalence class mapping before 197 // processing each function. 198 void PPCVSXSwapRemoval::initialize(MachineFunction &MFParm) { 199 MF = &MFParm; 200 MRI = &MF->getRegInfo(); 201 TII = static_cast<const PPCInstrInfo*>(MF->getSubtarget().getInstrInfo()); 202 203 // An initial vector size of 256 appears to work well in practice. 204 // Small/medium functions with vector content tend not to incur a 205 // reallocation at this size. Three of the vector tests in 206 // projects/test-suite reallocate, which seems like a reasonable rate. 207 const int InitialVectorSize(256); 208 SwapVector.clear(); 209 SwapVector.reserve(InitialVectorSize); 210 211 // FIXME: Currently we allocate EC each time because we don't have 212 // access to the set representation on which to call clear(). Should 213 // consider adding a clear() method to the EquivalenceClasses class. 214 EC = new EquivalenceClasses<int>; 215 } 216 217 // Create an entry in the swap vector for each instruction that mentions 218 // a full vector register, recording various characteristics of the 219 // instructions there. 220 bool PPCVSXSwapRemoval::gatherVectorInstructions() { 221 bool RelevantFunction = false; 222 223 for (MachineBasicBlock &MBB : *MF) { 224 for (MachineInstr &MI : MBB) { 225 226 bool RelevantInstr = false; 227 bool ImplicitSubreg = false; 228 229 for (const MachineOperand &MO : MI.operands()) { 230 if (!MO.isReg()) 231 continue; 232 unsigned Reg = MO.getReg(); 233 if (isVecReg(Reg)) { 234 RelevantInstr = true; 235 if (MO.getSubReg() != 0) 236 ImplicitSubreg = true; 237 break; 238 } 239 } 240 241 if (!RelevantInstr) 242 continue; 243 244 RelevantFunction = true; 245 246 // Create a SwapEntry initialized to zeros, then fill in the 247 // instruction and ID fields before pushing it to the back 248 // of the swap vector. 249 PPCVSXSwapEntry SwapEntry{}; 250 int VecIdx = addSwapEntry(&MI, SwapEntry); 251 252 if (ImplicitSubreg) 253 SwapVector[VecIdx].HasImplicitSubreg = 1; 254 255 switch(MI.getOpcode()) { 256 default: 257 // Unless noted otherwise, an instruction is considered 258 // safe for the optimization. There are a large number of 259 // such true-SIMD instructions (all vector math, logical, 260 // select, compare, etc.). 261 SwapVector[VecIdx].IsSwappable = 1; 262 break; 263 case PPC::XXPERMDI: 264 // This is a swap if it is of the form XXPERMDI t, s, s, 2. 265 // Unfortunately, MachineCSE ignores COPY and SUBREG_TO_REG, so we 266 // can also see XXPERMDI t, SUBREG_TO_REG(s), SUBREG_TO_REG(s), 2, 267 // for example. We have to look through chains of COPY and 268 // SUBREG_TO_REG to find the real source value for comparison. 269 // If the real source value is a physical register, then mark the 270 // XXPERMDI as mentioning a physical register. 271 // Any other form of XXPERMDI is lane-sensitive and unsafe 272 // for the optimization. 273 if (MI.getOperand(3).getImm() == 2) { 274 unsigned trueReg1 = lookThruCopyLike(MI.getOperand(1).getReg(), 275 VecIdx); 276 unsigned trueReg2 = lookThruCopyLike(MI.getOperand(2).getReg(), 277 VecIdx); 278 if (trueReg1 == trueReg2) 279 SwapVector[VecIdx].IsSwap = 1; 280 } 281 break; 282 case PPC::LVX: 283 // Non-permuting loads are currently unsafe. We can use special 284 // handling for this in the future. By not marking these as 285 // IsSwap, we ensure computations containing them will be rejected 286 // for now. 287 SwapVector[VecIdx].IsLoad = 1; 288 break; 289 case PPC::LXVD2X: 290 case PPC::LXVW4X: 291 // Permuting loads are marked as both load and swap, and are 292 // safe for optimization. 293 SwapVector[VecIdx].IsLoad = 1; 294 SwapVector[VecIdx].IsSwap = 1; 295 break; 296 case PPC::STVX: 297 // Non-permuting stores are currently unsafe. We can use special 298 // handling for this in the future. By not marking these as 299 // IsSwap, we ensure computations containing them will be rejected 300 // for now. 301 SwapVector[VecIdx].IsStore = 1; 302 break; 303 case PPC::STXVD2X: 304 case PPC::STXVW4X: 305 // Permuting stores are marked as both store and swap, and are 306 // safe for optimization. 307 SwapVector[VecIdx].IsStore = 1; 308 SwapVector[VecIdx].IsSwap = 1; 309 break; 310 case PPC::SUBREG_TO_REG: 311 // These are fine provided they are moving between full vector 312 // register classes. For example, the VRs are a subset of the 313 // VSRs, but each VR and each VSR is a full 128-bit register. 314 if (isVecReg(MI.getOperand(0).getReg()) && 315 isVecReg(MI.getOperand(2).getReg())) 316 SwapVector[VecIdx].IsSwappable = 1; 317 break; 318 case PPC::COPY: 319 // These are fine provided they are moving between full vector 320 // register classes. 321 if (isVecReg(MI.getOperand(0).getReg()) && 322 isVecReg(MI.getOperand(1).getReg())) 323 SwapVector[VecIdx].IsSwappable = 1; 324 break; 325 case PPC::VSPLTB: 326 case PPC::VSPLTH: 327 case PPC::VSPLTW: 328 // Splats are lane-sensitive, but we can use special handling 329 // to adjust the source lane for the splat. This is not yet 330 // implemented. When it is, we need to uncomment the following: 331 SwapVector[VecIdx].IsSwappable = 1; 332 SwapVector[VecIdx].SpecialHandling = SHValues::SH_SPLAT; 333 break; 334 // The presence of the following lane-sensitive operations in a 335 // web will kill the optimization, at least for now. For these 336 // we do nothing, causing the optimization to fail. 337 // FIXME: Some of these could be permitted with special handling, 338 // and will be phased in as time permits. 339 // FIXME: There is no simple and maintainable way to express a set 340 // of opcodes having a common attribute in TableGen. Should this 341 // change, this is a prime candidate to use such a mechanism. 342 case PPC::INLINEASM: 343 case PPC::EXTRACT_SUBREG: 344 case PPC::INSERT_SUBREG: 345 case PPC::COPY_TO_REGCLASS: 346 case PPC::LVEBX: 347 case PPC::LVEHX: 348 case PPC::LVEWX: 349 case PPC::LVSL: 350 case PPC::LVSR: 351 case PPC::LVXL: 352 case PPC::LXVDSX: 353 case PPC::STVEBX: 354 case PPC::STVEHX: 355 case PPC::STVEWX: 356 case PPC::STVXL: 357 case PPC::STXSDX: 358 case PPC::VCIPHER: 359 case PPC::VCIPHERLAST: 360 case PPC::VMRGHB: 361 case PPC::VMRGHH: 362 case PPC::VMRGHW: 363 case PPC::VMRGLB: 364 case PPC::VMRGLH: 365 case PPC::VMRGLW: 366 case PPC::VMULESB: 367 case PPC::VMULESH: 368 case PPC::VMULESW: 369 case PPC::VMULEUB: 370 case PPC::VMULEUH: 371 case PPC::VMULEUW: 372 case PPC::VMULOSB: 373 case PPC::VMULOSH: 374 case PPC::VMULOSW: 375 case PPC::VMULOUB: 376 case PPC::VMULOUH: 377 case PPC::VMULOUW: 378 case PPC::VNCIPHER: 379 case PPC::VNCIPHERLAST: 380 case PPC::VPERM: 381 case PPC::VPERMXOR: 382 case PPC::VPKPX: 383 case PPC::VPKSHSS: 384 case PPC::VPKSHUS: 385 case PPC::VPKSWSS: 386 case PPC::VPKSWUS: 387 case PPC::VPKUHUM: 388 case PPC::VPKUHUS: 389 case PPC::VPKUWUM: 390 case PPC::VPKUWUS: 391 case PPC::VPMSUMB: 392 case PPC::VPMSUMD: 393 case PPC::VPMSUMH: 394 case PPC::VPMSUMW: 395 case PPC::VRLB: 396 case PPC::VRLD: 397 case PPC::VRLH: 398 case PPC::VRLW: 399 case PPC::VSBOX: 400 case PPC::VSHASIGMAD: 401 case PPC::VSHASIGMAW: 402 case PPC::VSL: 403 case PPC::VSLDOI: 404 case PPC::VSLO: 405 case PPC::VSR: 406 case PPC::VSRO: 407 case PPC::VSUM2SWS: 408 case PPC::VSUM4SBS: 409 case PPC::VSUM4SHS: 410 case PPC::VSUM4UBS: 411 case PPC::VSUMSWS: 412 case PPC::VUPKHPX: 413 case PPC::VUPKHSB: 414 case PPC::VUPKHSH: 415 case PPC::VUPKLPX: 416 case PPC::VUPKLSB: 417 case PPC::VUPKLSH: 418 case PPC::XXMRGHW: 419 case PPC::XXMRGLW: 420 case PPC::XXSPLTW: 421 break; 422 } 423 } 424 } 425 426 if (RelevantFunction) { 427 DEBUG(dbgs() << "Swap vector when first built\n\n"); 428 dumpSwapVector(); 429 } 430 431 return RelevantFunction; 432 } 433 434 // Add an entry to the swap vector and swap map, and make a 435 // singleton equivalence class for the entry. 436 int PPCVSXSwapRemoval::addSwapEntry(MachineInstr *MI, 437 PPCVSXSwapEntry& SwapEntry) { 438 SwapEntry.VSEMI = MI; 439 SwapEntry.VSEId = SwapVector.size(); 440 SwapVector.push_back(SwapEntry); 441 EC->insert(SwapEntry.VSEId); 442 SwapMap[MI] = SwapEntry.VSEId; 443 return SwapEntry.VSEId; 444 } 445 446 // This is used to find the "true" source register for an 447 // XXPERMDI instruction, since MachineCSE does not handle the 448 // "copy-like" operations (Copy and SubregToReg). Returns 449 // the original SrcReg unless it is the target of a copy-like 450 // operation, in which case we chain backwards through all 451 // such operations to the ultimate source register. If a 452 // physical register is encountered, we stop the search and 453 // flag the swap entry indicated by VecIdx (the original 454 // XXPERMDI) as mentioning a physical register. Similarly 455 // for implicit subregister mentions (which should never 456 // happen). 457 unsigned PPCVSXSwapRemoval::lookThruCopyLike(unsigned SrcReg, 458 unsigned VecIdx) { 459 MachineInstr *MI = MRI->getVRegDef(SrcReg); 460 if (!MI->isCopyLike()) 461 return SrcReg; 462 463 unsigned CopySrcReg, CopySrcSubreg; 464 if (MI->isCopy()) { 465 CopySrcReg = MI->getOperand(1).getReg(); 466 CopySrcSubreg = MI->getOperand(1).getSubReg(); 467 } else { 468 assert(MI->isSubregToReg() && "bad opcode for lookThruCopyLike"); 469 CopySrcReg = MI->getOperand(2).getReg(); 470 CopySrcSubreg = MI->getOperand(2).getSubReg(); 471 } 472 473 if (!TargetRegisterInfo::isVirtualRegister(CopySrcReg)) { 474 SwapVector[VecIdx].MentionsPhysVR = 1; 475 return CopySrcReg; 476 } 477 478 if (CopySrcSubreg != 0) { 479 SwapVector[VecIdx].HasImplicitSubreg = 1; 480 return CopySrcReg; 481 } 482 483 return lookThruCopyLike(CopySrcReg, VecIdx); 484 } 485 486 // Generate equivalence classes for related computations (webs) by 487 // def-use relationships of virtual registers. Mention of a physical 488 // register terminates the generation of equivalence classes as this 489 // indicates a use of a parameter, definition of a return value, use 490 // of a value returned from a call, or definition of a parameter to a 491 // call. Computations with physical register mentions are flagged 492 // as such so their containing webs will not be optimized. 493 void PPCVSXSwapRemoval::formWebs() { 494 495 DEBUG(dbgs() << "\n*** Forming webs for swap removal ***\n\n"); 496 497 for (unsigned EntryIdx = 0; EntryIdx < SwapVector.size(); ++EntryIdx) { 498 499 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 500 501 DEBUG(dbgs() << "\n" << SwapVector[EntryIdx].VSEId << " "); 502 DEBUG(MI->dump()); 503 504 // It's sufficient to walk vector uses and join them to their unique 505 // definitions. In addition, check *all* vector register operands 506 // for physical regs. 507 for (const MachineOperand &MO : MI->operands()) { 508 if (!MO.isReg()) 509 continue; 510 511 unsigned Reg = MO.getReg(); 512 if (!isVecReg(Reg)) 513 continue; 514 515 if (!TargetRegisterInfo::isVirtualRegister(Reg)) { 516 SwapVector[EntryIdx].MentionsPhysVR = 1; 517 continue; 518 } 519 520 if (!MO.isUse()) 521 continue; 522 523 MachineInstr* DefMI = MRI->getVRegDef(Reg); 524 assert(SwapMap.find(DefMI) != SwapMap.end() && 525 "Inconsistency: def of vector reg not found in swap map!"); 526 int DefIdx = SwapMap[DefMI]; 527 (void)EC->unionSets(SwapVector[DefIdx].VSEId, 528 SwapVector[EntryIdx].VSEId); 529 530 DEBUG(dbgs() << format("Unioning %d with %d\n", SwapVector[DefIdx].VSEId, 531 SwapVector[EntryIdx].VSEId)); 532 DEBUG(dbgs() << " Def: "); 533 DEBUG(DefMI->dump()); 534 } 535 } 536 } 537 538 // Walk the swap vector entries looking for conditions that prevent their 539 // containing computations from being optimized. When such conditions are 540 // found, mark the representative of the computation's equivalence class 541 // as rejected. 542 void PPCVSXSwapRemoval::recordUnoptimizableWebs() { 543 544 DEBUG(dbgs() << "\n*** Rejecting webs for swap removal ***\n\n"); 545 546 for (unsigned EntryIdx = 0; EntryIdx < SwapVector.size(); ++EntryIdx) { 547 int Repr = EC->getLeaderValue(SwapVector[EntryIdx].VSEId); 548 549 // Reject webs containing mentions of physical registers or implicit 550 // subregs, or containing operations that we don't know how to handle 551 // in a lane-permuted region. 552 if (SwapVector[EntryIdx].MentionsPhysVR || 553 SwapVector[EntryIdx].HasImplicitSubreg || 554 !(SwapVector[EntryIdx].IsSwappable || SwapVector[EntryIdx].IsSwap)) { 555 556 SwapVector[Repr].WebRejected = 1; 557 558 DEBUG(dbgs() << 559 format("Web %d rejected for physreg, subreg, or not swap[pable]\n", 560 Repr)); 561 DEBUG(dbgs() << " in " << EntryIdx << ": "); 562 DEBUG(SwapVector[EntryIdx].VSEMI->dump()); 563 DEBUG(dbgs() << "\n"); 564 } 565 566 // Reject webs than contain swapping loads that feed something other 567 // than a swap instruction. 568 else if (SwapVector[EntryIdx].IsLoad && SwapVector[EntryIdx].IsSwap) { 569 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 570 unsigned DefReg = MI->getOperand(0).getReg(); 571 572 // We skip debug instructions in the analysis. (Note that debug 573 // location information is still maintained by this optimization 574 // because it remains on the LXVD2X and STXVD2X instructions after 575 // the XXPERMDIs are removed.) 576 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(DefReg)) { 577 int UseIdx = SwapMap[&UseMI]; 578 579 if (!SwapVector[UseIdx].IsSwap || SwapVector[UseIdx].IsLoad || 580 SwapVector[UseIdx].IsStore) { 581 582 SwapVector[Repr].WebRejected = 1; 583 584 DEBUG(dbgs() << 585 format("Web %d rejected for load not feeding swap\n", Repr)); 586 DEBUG(dbgs() << " def " << EntryIdx << ": "); 587 DEBUG(MI->dump()); 588 DEBUG(dbgs() << " use " << UseIdx << ": "); 589 DEBUG(UseMI.dump()); 590 DEBUG(dbgs() << "\n"); 591 } 592 } 593 594 // Reject webs than contain swapping stores that are fed by something 595 // other than a swap instruction. 596 } else if (SwapVector[EntryIdx].IsStore && SwapVector[EntryIdx].IsSwap) { 597 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 598 unsigned UseReg = MI->getOperand(0).getReg(); 599 MachineInstr *DefMI = MRI->getVRegDef(UseReg); 600 int DefIdx = SwapMap[DefMI]; 601 602 if (!SwapVector[DefIdx].IsSwap || SwapVector[DefIdx].IsLoad || 603 SwapVector[DefIdx].IsStore) { 604 605 SwapVector[Repr].WebRejected = 1; 606 607 DEBUG(dbgs() << 608 format("Web %d rejected for store not fed by swap\n", Repr)); 609 DEBUG(dbgs() << " def " << DefIdx << ": "); 610 DEBUG(DefMI->dump()); 611 DEBUG(dbgs() << " use " << EntryIdx << ": "); 612 DEBUG(MI->dump()); 613 DEBUG(dbgs() << "\n"); 614 } 615 } 616 } 617 618 DEBUG(dbgs() << "Swap vector after web analysis:\n\n"); 619 dumpSwapVector(); 620 } 621 622 // Walk the swap vector entries looking for swaps fed by permuting loads 623 // and swaps that feed permuting stores. If the containing computation 624 // has not been marked rejected, mark each such swap for removal. 625 // (Removal is delayed in case optimization has disturbed the pattern, 626 // such that multiple loads feed the same swap, etc.) 627 void PPCVSXSwapRemoval::markSwapsForRemoval() { 628 629 DEBUG(dbgs() << "\n*** Marking swaps for removal ***\n\n"); 630 631 for (unsigned EntryIdx = 0; EntryIdx < SwapVector.size(); ++EntryIdx) { 632 633 if (SwapVector[EntryIdx].IsLoad && SwapVector[EntryIdx].IsSwap) { 634 int Repr = EC->getLeaderValue(SwapVector[EntryIdx].VSEId); 635 636 if (!SwapVector[Repr].WebRejected) { 637 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 638 unsigned DefReg = MI->getOperand(0).getReg(); 639 640 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(DefReg)) { 641 int UseIdx = SwapMap[&UseMI]; 642 SwapVector[UseIdx].WillRemove = 1; 643 644 DEBUG(dbgs() << "Marking swap fed by load for removal: "); 645 DEBUG(UseMI.dump()); 646 } 647 } 648 649 } else if (SwapVector[EntryIdx].IsStore && SwapVector[EntryIdx].IsSwap) { 650 int Repr = EC->getLeaderValue(SwapVector[EntryIdx].VSEId); 651 652 if (!SwapVector[Repr].WebRejected) { 653 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 654 unsigned UseReg = MI->getOperand(0).getReg(); 655 MachineInstr *DefMI = MRI->getVRegDef(UseReg); 656 int DefIdx = SwapMap[DefMI]; 657 SwapVector[DefIdx].WillRemove = 1; 658 659 DEBUG(dbgs() << "Marking swap feeding store for removal: "); 660 DEBUG(DefMI->dump()); 661 } 662 663 } else if (SwapVector[EntryIdx].IsSwappable && 664 SwapVector[EntryIdx].SpecialHandling != 0) { 665 int Repr = EC->getLeaderValue(SwapVector[EntryIdx].VSEId); 666 667 if (!SwapVector[Repr].WebRejected) 668 handleSpecialSwappables(EntryIdx); 669 } 670 } 671 } 672 673 // The identified swap entry requires special handling to allow its 674 // containing computation to be optimized. Perform that handling 675 // here. 676 // FIXME: This code is to be phased in with subsequent patches. 677 void PPCVSXSwapRemoval::handleSpecialSwappables(int EntryIdx) { 678 switch (SwapVector[EntryIdx].SpecialHandling) { 679 680 default: 681 assert(false && "Unexpected special handling type"); 682 break; 683 684 // For splats based on an index into a vector, add N/2 modulo N 685 // to the index, where N is the number of vector elements. 686 case SHValues::SH_SPLAT: { 687 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 688 unsigned NElts; 689 690 DEBUG(dbgs() << "Changing splat: "); 691 DEBUG(MI->dump()); 692 693 switch (MI->getOpcode()) { 694 default: 695 assert(false && "Unexpected splat opcode"); 696 case PPC::VSPLTB: NElts = 16; break; 697 case PPC::VSPLTH: NElts = 8; break; 698 case PPC::VSPLTW: NElts = 4; break; 699 } 700 701 unsigned EltNo = MI->getOperand(1).getImm(); 702 EltNo = (EltNo + NElts / 2) % NElts; 703 MI->getOperand(1).setImm(EltNo); 704 705 DEBUG(dbgs() << " Into: "); 706 DEBUG(MI->dump()); 707 break; 708 } 709 710 } 711 } 712 713 // Walk the swap vector and replace each entry marked for removal with 714 // a copy operation. 715 bool PPCVSXSwapRemoval::removeSwaps() { 716 717 DEBUG(dbgs() << "\n*** Removing swaps ***\n\n"); 718 719 bool Changed = false; 720 721 for (unsigned EntryIdx = 0; EntryIdx < SwapVector.size(); ++EntryIdx) { 722 if (SwapVector[EntryIdx].WillRemove) { 723 Changed = true; 724 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 725 MachineBasicBlock *MBB = MI->getParent(); 726 BuildMI(*MBB, MI, MI->getDebugLoc(), 727 TII->get(TargetOpcode::COPY), MI->getOperand(0).getReg()) 728 .addOperand(MI->getOperand(1)); 729 730 DEBUG(dbgs() << format("Replaced %d with copy: ", 731 SwapVector[EntryIdx].VSEId)); 732 DEBUG(MI->dump()); 733 734 MI->eraseFromParent(); 735 } 736 } 737 738 return Changed; 739 } 740 741 // For debug purposes, dump the contents of the swap vector. 742 void PPCVSXSwapRemoval::dumpSwapVector() { 743 744 for (unsigned EntryIdx = 0; EntryIdx < SwapVector.size(); ++EntryIdx) { 745 746 MachineInstr *MI = SwapVector[EntryIdx].VSEMI; 747 int ID = SwapVector[EntryIdx].VSEId; 748 749 DEBUG(dbgs() << format("%6d", ID)); 750 DEBUG(dbgs() << format("%6d", EC->getLeaderValue(ID))); 751 DEBUG(dbgs() << format(" BB#%3d", MI->getParent()->getNumber())); 752 DEBUG(dbgs() << format(" %14s ", TII->getName(MI->getOpcode()))); 753 754 if (SwapVector[EntryIdx].IsLoad) 755 DEBUG(dbgs() << "load "); 756 if (SwapVector[EntryIdx].IsStore) 757 DEBUG(dbgs() << "store "); 758 if (SwapVector[EntryIdx].IsSwap) 759 DEBUG(dbgs() << "swap "); 760 if (SwapVector[EntryIdx].MentionsPhysVR) 761 DEBUG(dbgs() << "physreg "); 762 if (SwapVector[EntryIdx].HasImplicitSubreg) 763 DEBUG(dbgs() << "implsubreg "); 764 765 if (SwapVector[EntryIdx].IsSwappable) { 766 DEBUG(dbgs() << "swappable "); 767 switch(SwapVector[EntryIdx].SpecialHandling) { 768 default: 769 DEBUG(dbgs() << "special:**unknown**"); 770 break; 771 case SH_NONE: 772 break; 773 case SH_EXTRACT: 774 DEBUG(dbgs() << "special:extract "); 775 break; 776 case SH_INSERT: 777 DEBUG(dbgs() << "special:insert "); 778 break; 779 case SH_NOSWAP_LD: 780 DEBUG(dbgs() << "special:load "); 781 break; 782 case SH_NOSWAP_ST: 783 DEBUG(dbgs() << "special:store "); 784 break; 785 case SH_SPLAT: 786 DEBUG(dbgs() << "special:splat "); 787 break; 788 } 789 } 790 791 if (SwapVector[EntryIdx].WebRejected) 792 DEBUG(dbgs() << "rejected "); 793 if (SwapVector[EntryIdx].WillRemove) 794 DEBUG(dbgs() << "remove "); 795 796 DEBUG(dbgs() << "\n"); 797 798 // For no-asserts builds. 799 (void)MI; 800 (void)ID; 801 } 802 803 DEBUG(dbgs() << "\n"); 804 } 805 806 } // end default namespace 807 808 INITIALIZE_PASS_BEGIN(PPCVSXSwapRemoval, DEBUG_TYPE, 809 "PowerPC VSX Swap Removal", false, false) 810 INITIALIZE_PASS_END(PPCVSXSwapRemoval, DEBUG_TYPE, 811 "PowerPC VSX Swap Removal", false, false) 812 813 char PPCVSXSwapRemoval::ID = 0; 814 FunctionPass* 815 llvm::createPPCVSXSwapRemovalPass() { return new PPCVSXSwapRemoval(); } 816