1 //===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===// 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 /// \file 11 /// \brief This file implements a register stacking pass. 12 /// 13 /// This pass reorders instructions to put register uses and defs in an order 14 /// such that they form single-use expression trees. Registers fitting this form 15 /// are then marked as "stackified", meaning references to them are replaced by 16 /// "push" and "pop" from the stack. 17 /// 18 /// This is primarily a code size optimization, since temporary values on the 19 /// expression don't need to be named. 20 /// 21 //===----------------------------------------------------------------------===// 22 23 #include "WebAssembly.h" 24 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_* 25 #include "WebAssemblyMachineFunctionInfo.h" 26 #include "WebAssemblySubtarget.h" 27 #include "llvm/Analysis/AliasAnalysis.h" 28 #include "llvm/CodeGen/LiveIntervalAnalysis.h" 29 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" 30 #include "llvm/CodeGen/MachineDominators.h" 31 #include "llvm/CodeGen/MachineInstrBuilder.h" 32 #include "llvm/CodeGen/MachineRegisterInfo.h" 33 #include "llvm/CodeGen/Passes.h" 34 #include "llvm/Support/Debug.h" 35 #include "llvm/Support/raw_ostream.h" 36 using namespace llvm; 37 38 #define DEBUG_TYPE "wasm-reg-stackify" 39 40 namespace { 41 class WebAssemblyRegStackify final : public MachineFunctionPass { 42 const char *getPassName() const override { 43 return "WebAssembly Register Stackify"; 44 } 45 46 void getAnalysisUsage(AnalysisUsage &AU) const override { 47 AU.setPreservesCFG(); 48 AU.addRequired<AAResultsWrapperPass>(); 49 AU.addRequired<MachineDominatorTree>(); 50 AU.addRequired<LiveIntervals>(); 51 AU.addPreserved<MachineBlockFrequencyInfo>(); 52 AU.addPreserved<SlotIndexes>(); 53 AU.addPreserved<LiveIntervals>(); 54 AU.addPreservedID(LiveVariablesID); 55 AU.addPreserved<MachineDominatorTree>(); 56 MachineFunctionPass::getAnalysisUsage(AU); 57 } 58 59 bool runOnMachineFunction(MachineFunction &MF) override; 60 61 public: 62 static char ID; // Pass identification, replacement for typeid 63 WebAssemblyRegStackify() : MachineFunctionPass(ID) {} 64 }; 65 } // end anonymous namespace 66 67 char WebAssemblyRegStackify::ID = 0; 68 FunctionPass *llvm::createWebAssemblyRegStackify() { 69 return new WebAssemblyRegStackify(); 70 } 71 72 // Decorate the given instruction with implicit operands that enforce the 73 // expression stack ordering constraints for an instruction which is on 74 // the expression stack. 75 static void ImposeStackOrdering(MachineInstr *MI) { 76 // Write the opaque EXPR_STACK register. 77 if (!MI->definesRegister(WebAssembly::EXPR_STACK)) 78 MI->addOperand(MachineOperand::CreateReg(WebAssembly::EXPR_STACK, 79 /*isDef=*/true, 80 /*isImp=*/true)); 81 82 // Also read the opaque EXPR_STACK register. 83 if (!MI->readsRegister(WebAssembly::EXPR_STACK)) 84 MI->addOperand(MachineOperand::CreateReg(WebAssembly::EXPR_STACK, 85 /*isDef=*/false, 86 /*isImp=*/true)); 87 } 88 89 // Determine whether a call to the callee referenced by 90 // MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side 91 // effects. 92 static void QueryCallee(const MachineInstr &MI, unsigned CalleeOpNo, bool &Read, 93 bool &Write, bool &Effects, bool &StackPointer) { 94 // All calls can use the stack pointer. 95 StackPointer = true; 96 97 const MachineOperand &MO = MI.getOperand(CalleeOpNo); 98 if (MO.isGlobal()) { 99 const Constant *GV = MO.getGlobal(); 100 if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) 101 if (!GA->isInterposable()) 102 GV = GA->getAliasee(); 103 104 if (const Function *F = dyn_cast<Function>(GV)) { 105 if (!F->doesNotThrow()) 106 Effects = true; 107 if (F->doesNotAccessMemory()) 108 return; 109 if (F->onlyReadsMemory()) { 110 Read = true; 111 return; 112 } 113 } 114 } 115 116 // Assume the worst. 117 Write = true; 118 Read = true; 119 Effects = true; 120 } 121 122 // Determine whether MI reads memory, writes memory, has side effects, 123 // and/or uses the __stack_pointer value. 124 static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, 125 bool &Write, bool &Effects, bool &StackPointer) { 126 assert(!MI.isPosition()); 127 assert(!MI.isTerminator()); 128 129 if (MI.isDebugValue()) 130 return; 131 132 // Check for loads. 133 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad(&AA)) 134 Read = true; 135 136 // Check for stores. 137 if (MI.mayStore()) { 138 Write = true; 139 140 // Check for stores to __stack_pointer. 141 for (auto MMO : MI.memoperands()) { 142 const MachinePointerInfo &MPI = MMO->getPointerInfo(); 143 if (MPI.V.is<const PseudoSourceValue *>()) { 144 auto PSV = MPI.V.get<const PseudoSourceValue *>(); 145 if (const ExternalSymbolPseudoSourceValue *EPSV = 146 dyn_cast<ExternalSymbolPseudoSourceValue>(PSV)) 147 if (StringRef(EPSV->getSymbol()) == "__stack_pointer") 148 StackPointer = true; 149 } 150 } 151 } else if (MI.hasOrderedMemoryRef()) { 152 switch (MI.getOpcode()) { 153 case WebAssembly::DIV_S_I32: case WebAssembly::DIV_S_I64: 154 case WebAssembly::REM_S_I32: case WebAssembly::REM_S_I64: 155 case WebAssembly::DIV_U_I32: case WebAssembly::DIV_U_I64: 156 case WebAssembly::REM_U_I32: case WebAssembly::REM_U_I64: 157 case WebAssembly::I32_TRUNC_S_F32: case WebAssembly::I64_TRUNC_S_F32: 158 case WebAssembly::I32_TRUNC_S_F64: case WebAssembly::I64_TRUNC_S_F64: 159 case WebAssembly::I32_TRUNC_U_F32: case WebAssembly::I64_TRUNC_U_F32: 160 case WebAssembly::I32_TRUNC_U_F64: case WebAssembly::I64_TRUNC_U_F64: 161 // These instruction have hasUnmodeledSideEffects() returning true 162 // because they trap on overflow and invalid so they can't be arbitrarily 163 // moved, however hasOrderedMemoryRef() interprets this plus their lack 164 // of memoperands as having a potential unknown memory reference. 165 break; 166 default: 167 // Record volatile accesses, unless it's a call, as calls are handled 168 // specially below. 169 if (!MI.isCall()) { 170 Write = true; 171 Effects = true; 172 } 173 break; 174 } 175 } 176 177 // Check for side effects. 178 if (MI.hasUnmodeledSideEffects()) { 179 switch (MI.getOpcode()) { 180 case WebAssembly::DIV_S_I32: case WebAssembly::DIV_S_I64: 181 case WebAssembly::REM_S_I32: case WebAssembly::REM_S_I64: 182 case WebAssembly::DIV_U_I32: case WebAssembly::DIV_U_I64: 183 case WebAssembly::REM_U_I32: case WebAssembly::REM_U_I64: 184 case WebAssembly::I32_TRUNC_S_F32: case WebAssembly::I64_TRUNC_S_F32: 185 case WebAssembly::I32_TRUNC_S_F64: case WebAssembly::I64_TRUNC_S_F64: 186 case WebAssembly::I32_TRUNC_U_F32: case WebAssembly::I64_TRUNC_U_F32: 187 case WebAssembly::I32_TRUNC_U_F64: case WebAssembly::I64_TRUNC_U_F64: 188 // These instructions have hasUnmodeledSideEffects() returning true 189 // because they trap on overflow and invalid so they can't be arbitrarily 190 // moved, however in the specific case of register stackifying, it is safe 191 // to move them because overflow and invalid are Undefined Behavior. 192 break; 193 default: 194 Effects = true; 195 break; 196 } 197 } 198 199 // Analyze calls. 200 if (MI.isCall()) { 201 switch (MI.getOpcode()) { 202 case WebAssembly::CALL_VOID: 203 case WebAssembly::CALL_INDIRECT_VOID: 204 QueryCallee(MI, 0, Read, Write, Effects, StackPointer); 205 break; 206 case WebAssembly::CALL_I32: case WebAssembly::CALL_I64: 207 case WebAssembly::CALL_F32: case WebAssembly::CALL_F64: 208 case WebAssembly::CALL_INDIRECT_I32: case WebAssembly::CALL_INDIRECT_I64: 209 case WebAssembly::CALL_INDIRECT_F32: case WebAssembly::CALL_INDIRECT_F64: 210 QueryCallee(MI, 1, Read, Write, Effects, StackPointer); 211 break; 212 default: 213 llvm_unreachable("unexpected call opcode"); 214 } 215 } 216 } 217 218 // Test whether Def is safe and profitable to rematerialize. 219 static bool ShouldRematerialize(const MachineInstr &Def, AliasAnalysis &AA, 220 const WebAssemblyInstrInfo *TII) { 221 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def, &AA); 222 } 223 224 // Identify the definition for this register at this point. This is a 225 // generalization of MachineRegisterInfo::getUniqueVRegDef that uses 226 // LiveIntervals to handle complex cases. 227 static MachineInstr *GetVRegDef(unsigned Reg, const MachineInstr *Insert, 228 const MachineRegisterInfo &MRI, 229 const LiveIntervals &LIS) 230 { 231 // Most registers are in SSA form here so we try a quick MRI query first. 232 if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg)) 233 return Def; 234 235 // MRI doesn't know what the Def is. Try asking LIS. 236 if (const VNInfo *ValNo = LIS.getInterval(Reg).getVNInfoBefore( 237 LIS.getInstructionIndex(*Insert))) 238 return LIS.getInstructionFromIndex(ValNo->def); 239 240 return nullptr; 241 } 242 243 // Test whether Reg, as defined at Def, has exactly one use. This is a 244 // generalization of MachineRegisterInfo::hasOneUse that uses LiveIntervals 245 // to handle complex cases. 246 static bool HasOneUse(unsigned Reg, MachineInstr *Def, 247 MachineRegisterInfo &MRI, MachineDominatorTree &MDT, 248 LiveIntervals &LIS) { 249 // Most registers are in SSA form here so we try a quick MRI query first. 250 if (MRI.hasOneUse(Reg)) 251 return true; 252 253 bool HasOne = false; 254 const LiveInterval &LI = LIS.getInterval(Reg); 255 const VNInfo *DefVNI = LI.getVNInfoAt( 256 LIS.getInstructionIndex(*Def).getRegSlot()); 257 assert(DefVNI); 258 for (auto &I : MRI.use_nodbg_operands(Reg)) { 259 const auto &Result = LI.Query(LIS.getInstructionIndex(*I.getParent())); 260 if (Result.valueIn() == DefVNI) { 261 if (!Result.isKill()) 262 return false; 263 if (HasOne) 264 return false; 265 HasOne = true; 266 } 267 } 268 return HasOne; 269 } 270 271 // Test whether it's safe to move Def to just before Insert. 272 // TODO: Compute memory dependencies in a way that doesn't require always 273 // walking the block. 274 // TODO: Compute memory dependencies in a way that uses AliasAnalysis to be 275 // more precise. 276 static bool IsSafeToMove(const MachineInstr *Def, const MachineInstr *Insert, 277 AliasAnalysis &AA, const LiveIntervals &LIS, 278 const MachineRegisterInfo &MRI) { 279 assert(Def->getParent() == Insert->getParent()); 280 281 // Check for register dependencies. 282 for (const MachineOperand &MO : Def->operands()) { 283 if (!MO.isReg() || MO.isUndef()) 284 continue; 285 unsigned Reg = MO.getReg(); 286 287 // If the register is dead here and at Insert, ignore it. 288 if (MO.isDead() && Insert->definesRegister(Reg) && 289 !Insert->readsRegister(Reg)) 290 continue; 291 292 if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 293 // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions 294 // from moving down, and we've already checked for that. 295 if (Reg == WebAssembly::ARGUMENTS) 296 continue; 297 // If the physical register is never modified, ignore it. 298 if (!MRI.isPhysRegModified(Reg)) 299 continue; 300 // Otherwise, it's a physical register with unknown liveness. 301 return false; 302 } 303 304 // Ask LiveIntervals whether moving this virtual register use or def to 305 // Insert will change which value numbers are seen. 306 // 307 // If the operand is a use of a register that is also defined in the same 308 // instruction, test that the newly defined value reaches the insert point, 309 // since the operand will be moving along with the def. 310 const LiveInterval &LI = LIS.getInterval(Reg); 311 VNInfo *DefVNI = 312 (MO.isDef() || Def->definesRegister(Reg)) ? 313 LI.getVNInfoAt(LIS.getInstructionIndex(*Def).getRegSlot()) : 314 LI.getVNInfoBefore(LIS.getInstructionIndex(*Def)); 315 assert(DefVNI && "Instruction input missing value number"); 316 VNInfo *InsVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*Insert)); 317 if (InsVNI && DefVNI != InsVNI) 318 return false; 319 } 320 321 bool Read = false, Write = false, Effects = false, StackPointer = false; 322 Query(*Def, AA, Read, Write, Effects, StackPointer); 323 324 // If the instruction does not access memory and has no side effects, it has 325 // no additional dependencies. 326 if (!Read && !Write && !Effects && !StackPointer) 327 return true; 328 329 // Scan through the intervening instructions between Def and Insert. 330 MachineBasicBlock::const_iterator D(Def), I(Insert); 331 for (--I; I != D; --I) { 332 bool InterveningRead = false; 333 bool InterveningWrite = false; 334 bool InterveningEffects = false; 335 bool InterveningStackPointer = false; 336 Query(*I, AA, InterveningRead, InterveningWrite, InterveningEffects, 337 InterveningStackPointer); 338 if (Effects && InterveningEffects) 339 return false; 340 if (Read && InterveningWrite) 341 return false; 342 if (Write && (InterveningRead || InterveningWrite)) 343 return false; 344 if (StackPointer && InterveningStackPointer) 345 return false; 346 } 347 348 return true; 349 } 350 351 /// Test whether OneUse, a use of Reg, dominates all of Reg's other uses. 352 static bool OneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, 353 const MachineBasicBlock &MBB, 354 const MachineRegisterInfo &MRI, 355 const MachineDominatorTree &MDT, 356 LiveIntervals &LIS, 357 WebAssemblyFunctionInfo &MFI) { 358 const LiveInterval &LI = LIS.getInterval(Reg); 359 360 const MachineInstr *OneUseInst = OneUse.getParent(); 361 VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst)); 362 363 for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) { 364 if (&Use == &OneUse) 365 continue; 366 367 const MachineInstr *UseInst = Use.getParent(); 368 VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst)); 369 370 if (UseVNI != OneUseVNI) 371 continue; 372 373 const MachineInstr *OneUseInst = OneUse.getParent(); 374 if (UseInst == OneUseInst) { 375 // Another use in the same instruction. We need to ensure that the one 376 // selected use happens "before" it. 377 if (&OneUse > &Use) 378 return false; 379 } else { 380 // Test that the use is dominated by the one selected use. 381 while (!MDT.dominates(OneUseInst, UseInst)) { 382 // Actually, dominating is over-conservative. Test that the use would 383 // happen after the one selected use in the stack evaluation order. 384 // 385 // This is needed as a consequence of using implicit get_locals for 386 // uses and implicit set_locals for defs. 387 if (UseInst->getDesc().getNumDefs() == 0) 388 return false; 389 const MachineOperand &MO = UseInst->getOperand(0); 390 if (!MO.isReg()) 391 return false; 392 unsigned DefReg = MO.getReg(); 393 if (!TargetRegisterInfo::isVirtualRegister(DefReg) || 394 !MFI.isVRegStackified(DefReg)) 395 return false; 396 assert(MRI.hasOneUse(DefReg)); 397 const MachineOperand &NewUse = *MRI.use_begin(DefReg); 398 const MachineInstr *NewUseInst = NewUse.getParent(); 399 if (NewUseInst == OneUseInst) { 400 if (&OneUse > &NewUse) 401 return false; 402 break; 403 } 404 UseInst = NewUseInst; 405 } 406 } 407 } 408 return true; 409 } 410 411 /// Get the appropriate tee_local opcode for the given register class. 412 static unsigned GetTeeLocalOpcode(const TargetRegisterClass *RC) { 413 if (RC == &WebAssembly::I32RegClass) 414 return WebAssembly::TEE_LOCAL_I32; 415 if (RC == &WebAssembly::I64RegClass) 416 return WebAssembly::TEE_LOCAL_I64; 417 if (RC == &WebAssembly::F32RegClass) 418 return WebAssembly::TEE_LOCAL_F32; 419 if (RC == &WebAssembly::F64RegClass) 420 return WebAssembly::TEE_LOCAL_F64; 421 if (RC == &WebAssembly::V128RegClass) 422 return WebAssembly::TEE_LOCAL_V128; 423 llvm_unreachable("Unexpected register class"); 424 } 425 426 // Shrink LI to its uses, cleaning up LI. 427 static void ShrinkToUses(LiveInterval &LI, LiveIntervals &LIS) { 428 if (LIS.shrinkToUses(&LI)) { 429 SmallVector<LiveInterval*, 4> SplitLIs; 430 LIS.splitSeparateComponents(LI, SplitLIs); 431 } 432 } 433 434 /// A single-use def in the same block with no intervening memory or register 435 /// dependencies; move the def down and nest it with the current instruction. 436 static MachineInstr *MoveForSingleUse(unsigned Reg, MachineOperand& Op, 437 MachineInstr *Def, 438 MachineBasicBlock &MBB, 439 MachineInstr *Insert, LiveIntervals &LIS, 440 WebAssemblyFunctionInfo &MFI, 441 MachineRegisterInfo &MRI) { 442 DEBUG(dbgs() << "Move for single use: "; Def->dump()); 443 444 MBB.splice(Insert, &MBB, Def); 445 LIS.handleMove(*Def); 446 447 if (MRI.hasOneDef(Reg) && MRI.hasOneUse(Reg)) { 448 // No one else is using this register for anything so we can just stackify 449 // it in place. 450 MFI.stackifyVReg(Reg); 451 } else { 452 // The register may have unrelated uses or defs; create a new register for 453 // just our one def and use so that we can stackify it. 454 unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg)); 455 Def->getOperand(0).setReg(NewReg); 456 Op.setReg(NewReg); 457 458 // Tell LiveIntervals about the new register. 459 LIS.createAndComputeVirtRegInterval(NewReg); 460 461 // Tell LiveIntervals about the changes to the old register. 462 LiveInterval &LI = LIS.getInterval(Reg); 463 LI.removeSegment(LIS.getInstructionIndex(*Def).getRegSlot(), 464 LIS.getInstructionIndex(*Op.getParent()).getRegSlot(), 465 /*RemoveDeadValNo=*/true); 466 467 MFI.stackifyVReg(NewReg); 468 469 DEBUG(dbgs() << " - Replaced register: "; Def->dump()); 470 } 471 472 ImposeStackOrdering(Def); 473 return Def; 474 } 475 476 /// A trivially cloneable instruction; clone it and nest the new copy with the 477 /// current instruction. 478 static MachineInstr *RematerializeCheapDef( 479 unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock &MBB, 480 MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, 481 WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, 482 const WebAssemblyInstrInfo *TII, const WebAssemblyRegisterInfo *TRI) { 483 DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump()); 484 DEBUG(dbgs() << " - for use in "; Op.getParent()->dump()); 485 486 unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg)); 487 TII->reMaterialize(MBB, Insert, NewReg, 0, Def, *TRI); 488 Op.setReg(NewReg); 489 MachineInstr *Clone = &*std::prev(Insert); 490 LIS.InsertMachineInstrInMaps(*Clone); 491 LIS.createAndComputeVirtRegInterval(NewReg); 492 MFI.stackifyVReg(NewReg); 493 ImposeStackOrdering(Clone); 494 495 DEBUG(dbgs() << " - Cloned to "; Clone->dump()); 496 497 // Shrink the interval. 498 bool IsDead = MRI.use_empty(Reg); 499 if (!IsDead) { 500 LiveInterval &LI = LIS.getInterval(Reg); 501 ShrinkToUses(LI, LIS); 502 IsDead = !LI.liveAt(LIS.getInstructionIndex(Def).getDeadSlot()); 503 } 504 505 // If that was the last use of the original, delete the original. 506 if (IsDead) { 507 DEBUG(dbgs() << " - Deleting original\n"); 508 SlotIndex Idx = LIS.getInstructionIndex(Def).getRegSlot(); 509 LIS.removePhysRegDefAt(WebAssembly::ARGUMENTS, Idx); 510 LIS.removeInterval(Reg); 511 LIS.RemoveMachineInstrFromMaps(Def); 512 Def.eraseFromParent(); 513 } 514 515 return Clone; 516 } 517 518 /// A multiple-use def in the same block with no intervening memory or register 519 /// dependencies; move the def down, nest it with the current instruction, and 520 /// insert a tee_local to satisfy the rest of the uses. As an illustration, 521 /// rewrite this: 522 /// 523 /// Reg = INST ... // Def 524 /// INST ..., Reg, ... // Insert 525 /// INST ..., Reg, ... 526 /// INST ..., Reg, ... 527 /// 528 /// to this: 529 /// 530 /// DefReg = INST ... // Def (to become the new Insert) 531 /// TeeReg, Reg = TEE_LOCAL_... DefReg 532 /// INST ..., TeeReg, ... // Insert 533 /// INST ..., Reg, ... 534 /// INST ..., Reg, ... 535 /// 536 /// with DefReg and TeeReg stackified. This eliminates a get_local from the 537 /// resulting code. 538 static MachineInstr *MoveAndTeeForMultiUse( 539 unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, 540 MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, 541 MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII) { 542 DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump()); 543 544 // Move Def into place. 545 MBB.splice(Insert, &MBB, Def); 546 LIS.handleMove(*Def); 547 548 // Create the Tee and attach the registers. 549 const auto *RegClass = MRI.getRegClass(Reg); 550 unsigned TeeReg = MRI.createVirtualRegister(RegClass); 551 unsigned DefReg = MRI.createVirtualRegister(RegClass); 552 MachineOperand &DefMO = Def->getOperand(0); 553 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(), 554 TII->get(GetTeeLocalOpcode(RegClass)), TeeReg) 555 .addReg(Reg, RegState::Define) 556 .addReg(DefReg, getUndefRegState(DefMO.isDead())); 557 Op.setReg(TeeReg); 558 DefMO.setReg(DefReg); 559 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot(); 560 SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot(); 561 562 // Tell LiveIntervals we moved the original vreg def from Def to Tee. 563 LiveInterval &LI = LIS.getInterval(Reg); 564 LiveInterval::iterator I = LI.FindSegmentContaining(DefIdx); 565 VNInfo *ValNo = LI.getVNInfoAt(DefIdx); 566 I->start = TeeIdx; 567 ValNo->def = TeeIdx; 568 ShrinkToUses(LI, LIS); 569 570 // Finish stackifying the new regs. 571 LIS.createAndComputeVirtRegInterval(TeeReg); 572 LIS.createAndComputeVirtRegInterval(DefReg); 573 MFI.stackifyVReg(DefReg); 574 MFI.stackifyVReg(TeeReg); 575 ImposeStackOrdering(Def); 576 ImposeStackOrdering(Tee); 577 578 DEBUG(dbgs() << " - Replaced register: "; Def->dump()); 579 DEBUG(dbgs() << " - Tee instruction: "; Tee->dump()); 580 return Def; 581 } 582 583 namespace { 584 /// A stack for walking the tree of instructions being built, visiting the 585 /// MachineOperands in DFS order. 586 class TreeWalkerState { 587 typedef MachineInstr::mop_iterator mop_iterator; 588 typedef std::reverse_iterator<mop_iterator> mop_reverse_iterator; 589 typedef iterator_range<mop_reverse_iterator> RangeTy; 590 SmallVector<RangeTy, 4> Worklist; 591 592 public: 593 explicit TreeWalkerState(MachineInstr *Insert) { 594 const iterator_range<mop_iterator> &Range = Insert->explicit_uses(); 595 if (Range.begin() != Range.end()) 596 Worklist.push_back(reverse(Range)); 597 } 598 599 bool Done() const { return Worklist.empty(); } 600 601 MachineOperand &Pop() { 602 RangeTy &Range = Worklist.back(); 603 MachineOperand &Op = *Range.begin(); 604 Range = drop_begin(Range, 1); 605 if (Range.begin() == Range.end()) 606 Worklist.pop_back(); 607 assert((Worklist.empty() || 608 Worklist.back().begin() != Worklist.back().end()) && 609 "Empty ranges shouldn't remain in the worklist"); 610 return Op; 611 } 612 613 /// Push Instr's operands onto the stack to be visited. 614 void PushOperands(MachineInstr *Instr) { 615 const iterator_range<mop_iterator> &Range(Instr->explicit_uses()); 616 if (Range.begin() != Range.end()) 617 Worklist.push_back(reverse(Range)); 618 } 619 620 /// Some of Instr's operands are on the top of the stack; remove them and 621 /// re-insert them starting from the beginning (because we've commuted them). 622 void ResetTopOperands(MachineInstr *Instr) { 623 assert(HasRemainingOperands(Instr) && 624 "Reseting operands should only be done when the instruction has " 625 "an operand still on the stack"); 626 Worklist.back() = reverse(Instr->explicit_uses()); 627 } 628 629 /// Test whether Instr has operands remaining to be visited at the top of 630 /// the stack. 631 bool HasRemainingOperands(const MachineInstr *Instr) const { 632 if (Worklist.empty()) 633 return false; 634 const RangeTy &Range = Worklist.back(); 635 return Range.begin() != Range.end() && Range.begin()->getParent() == Instr; 636 } 637 638 /// Test whether the given register is present on the stack, indicating an 639 /// operand in the tree that we haven't visited yet. Moving a definition of 640 /// Reg to a point in the tree after that would change its value. 641 /// 642 /// This is needed as a consequence of using implicit get_locals for 643 /// uses and implicit set_locals for defs. 644 bool IsOnStack(unsigned Reg) const { 645 for (const RangeTy &Range : Worklist) 646 for (const MachineOperand &MO : Range) 647 if (MO.isReg() && MO.getReg() == Reg) 648 return true; 649 return false; 650 } 651 }; 652 653 /// State to keep track of whether commuting is in flight or whether it's been 654 /// tried for the current instruction and didn't work. 655 class CommutingState { 656 /// There are effectively three states: the initial state where we haven't 657 /// started commuting anything and we don't know anything yet, the tenative 658 /// state where we've commuted the operands of the current instruction and are 659 /// revisting it, and the declined state where we've reverted the operands 660 /// back to their original order and will no longer commute it further. 661 bool TentativelyCommuting; 662 bool Declined; 663 664 /// During the tentative state, these hold the operand indices of the commuted 665 /// operands. 666 unsigned Operand0, Operand1; 667 668 public: 669 CommutingState() : TentativelyCommuting(false), Declined(false) {} 670 671 /// Stackification for an operand was not successful due to ordering 672 /// constraints. If possible, and if we haven't already tried it and declined 673 /// it, commute Insert's operands and prepare to revisit it. 674 void MaybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker, 675 const WebAssemblyInstrInfo *TII) { 676 if (TentativelyCommuting) { 677 assert(!Declined && 678 "Don't decline commuting until you've finished trying it"); 679 // Commuting didn't help. Revert it. 680 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1); 681 TentativelyCommuting = false; 682 Declined = true; 683 } else if (!Declined && TreeWalker.HasRemainingOperands(Insert)) { 684 Operand0 = TargetInstrInfo::CommuteAnyOperandIndex; 685 Operand1 = TargetInstrInfo::CommuteAnyOperandIndex; 686 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) { 687 // Tentatively commute the operands and try again. 688 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1); 689 TreeWalker.ResetTopOperands(Insert); 690 TentativelyCommuting = true; 691 Declined = false; 692 } 693 } 694 } 695 696 /// Stackification for some operand was successful. Reset to the default 697 /// state. 698 void Reset() { 699 TentativelyCommuting = false; 700 Declined = false; 701 } 702 }; 703 } // end anonymous namespace 704 705 bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) { 706 DEBUG(dbgs() << "********** Register Stackifying **********\n" 707 "********** Function: " 708 << MF.getName() << '\n'); 709 710 bool Changed = false; 711 MachineRegisterInfo &MRI = MF.getRegInfo(); 712 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); 713 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 714 const auto *TRI = MF.getSubtarget<WebAssemblySubtarget>().getRegisterInfo(); 715 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults(); 716 MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 717 LiveIntervals &LIS = getAnalysis<LiveIntervals>(); 718 719 // Walk the instructions from the bottom up. Currently we don't look past 720 // block boundaries, and the blocks aren't ordered so the block visitation 721 // order isn't significant, but we may want to change this in the future. 722 for (MachineBasicBlock &MBB : MF) { 723 // Don't use a range-based for loop, because we modify the list as we're 724 // iterating over it and the end iterator may change. 725 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) { 726 MachineInstr *Insert = &*MII; 727 // Don't nest anything inside an inline asm, because we don't have 728 // constraints for $push inputs. 729 if (Insert->getOpcode() == TargetOpcode::INLINEASM) 730 continue; 731 732 // Ignore debugging intrinsics. 733 if (Insert->getOpcode() == TargetOpcode::DBG_VALUE) 734 continue; 735 736 // Iterate through the inputs in reverse order, since we'll be pulling 737 // operands off the stack in LIFO order. 738 CommutingState Commuting; 739 TreeWalkerState TreeWalker(Insert); 740 while (!TreeWalker.Done()) { 741 MachineOperand &Op = TreeWalker.Pop(); 742 743 // We're only interested in explicit virtual register operands. 744 if (!Op.isReg()) 745 continue; 746 747 unsigned Reg = Op.getReg(); 748 assert(Op.isUse() && "explicit_uses() should only iterate over uses"); 749 assert(!Op.isImplicit() && 750 "explicit_uses() should only iterate over explicit operands"); 751 if (TargetRegisterInfo::isPhysicalRegister(Reg)) 752 continue; 753 754 // Identify the definition for this register at this point. Most 755 // registers are in SSA form here so we try a quick MRI query first. 756 MachineInstr *Def = GetVRegDef(Reg, Insert, MRI, LIS); 757 if (!Def) 758 continue; 759 760 // Don't nest an INLINE_ASM def into anything, because we don't have 761 // constraints for $pop outputs. 762 if (Def->getOpcode() == TargetOpcode::INLINEASM) 763 continue; 764 765 // Argument instructions represent live-in registers and not real 766 // instructions. 767 if (Def->getOpcode() == WebAssembly::ARGUMENT_I32 || 768 Def->getOpcode() == WebAssembly::ARGUMENT_I64 || 769 Def->getOpcode() == WebAssembly::ARGUMENT_F32 || 770 Def->getOpcode() == WebAssembly::ARGUMENT_F64 || 771 Def->getOpcode() == WebAssembly::ARGUMENT_v16i8 || 772 Def->getOpcode() == WebAssembly::ARGUMENT_v8i16 || 773 Def->getOpcode() == WebAssembly::ARGUMENT_v4i32 || 774 Def->getOpcode() == WebAssembly::ARGUMENT_v4f32) 775 continue; 776 777 // Decide which strategy to take. Prefer to move a single-use value 778 // over cloning it, and prefer cloning over introducing a tee_local. 779 // For moving, we require the def to be in the same block as the use; 780 // this makes things simpler (LiveIntervals' handleMove function only 781 // supports intra-block moves) and it's MachineSink's job to catch all 782 // the sinking opportunities anyway. 783 bool SameBlock = Def->getParent() == &MBB; 784 bool CanMove = SameBlock && IsSafeToMove(Def, Insert, AA, LIS, MRI) && 785 !TreeWalker.IsOnStack(Reg); 786 if (CanMove && HasOneUse(Reg, Def, MRI, MDT, LIS)) { 787 Insert = MoveForSingleUse(Reg, Op, Def, MBB, Insert, LIS, MFI, MRI); 788 } else if (ShouldRematerialize(*Def, AA, TII)) { 789 Insert = 790 RematerializeCheapDef(Reg, Op, *Def, MBB, Insert->getIterator(), 791 LIS, MFI, MRI, TII, TRI); 792 } else if (CanMove && 793 OneUseDominatesOtherUses(Reg, Op, MBB, MRI, MDT, LIS, MFI)) { 794 Insert = MoveAndTeeForMultiUse(Reg, Op, Def, MBB, Insert, LIS, MFI, 795 MRI, TII); 796 } else { 797 // We failed to stackify the operand. If the problem was ordering 798 // constraints, Commuting may be able to help. 799 if (!CanMove && SameBlock) 800 Commuting.MaybeCommute(Insert, TreeWalker, TII); 801 // Proceed to the next operand. 802 continue; 803 } 804 805 // We stackified an operand. Add the defining instruction's operands to 806 // the worklist stack now to continue to build an ever deeper tree. 807 Commuting.Reset(); 808 TreeWalker.PushOperands(Insert); 809 } 810 811 // If we stackified any operands, skip over the tree to start looking for 812 // the next instruction we can build a tree on. 813 if (Insert != &*MII) { 814 ImposeStackOrdering(&*MII); 815 MII = MachineBasicBlock::iterator(Insert).getReverse(); 816 Changed = true; 817 } 818 } 819 } 820 821 // If we used EXPR_STACK anywhere, add it to the live-in sets everywhere so 822 // that it never looks like a use-before-def. 823 if (Changed) { 824 MF.getRegInfo().addLiveIn(WebAssembly::EXPR_STACK); 825 for (MachineBasicBlock &MBB : MF) 826 MBB.addLiveIn(WebAssembly::EXPR_STACK); 827 } 828 829 #ifndef NDEBUG 830 // Verify that pushes and pops are performed in LIFO order. 831 SmallVector<unsigned, 0> Stack; 832 for (MachineBasicBlock &MBB : MF) { 833 for (MachineInstr &MI : MBB) { 834 if (MI.isDebugValue()) 835 continue; 836 for (MachineOperand &MO : reverse(MI.explicit_operands())) { 837 if (!MO.isReg()) 838 continue; 839 unsigned Reg = MO.getReg(); 840 841 if (MFI.isVRegStackified(Reg)) { 842 if (MO.isDef()) 843 Stack.push_back(Reg); 844 else 845 assert(Stack.pop_back_val() == Reg && 846 "Register stack pop should be paired with a push"); 847 } 848 } 849 } 850 // TODO: Generalize this code to support keeping values on the stack across 851 // basic block boundaries. 852 assert(Stack.empty() && 853 "Register stack pushes and pops should be balanced"); 854 } 855 #endif 856 857 return Changed; 858 } 859