LLVM 24.0.0git
WebAssemblyRegStackify.cpp
Go to the documentation of this file.
1//===-- WebAssemblyRegStackify.cpp - Register Stackification --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements a register stacking pass.
11///
12/// This pass reorders instructions to put register uses and defs in an order
13/// such that they form single-use expression trees. Registers fitting this form
14/// are then marked as "stackified", meaning references to them are replaced by
15/// "push" and "pop" from the value stack.
16///
17/// This is primarily a code size optimization, since temporary values on the
18/// value stack don't need to be named.
19///
20//===----------------------------------------------------------------------===//
21
22#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
23#include "WebAssembly.h"
35#include "llvm/CodeGen/Passes.h"
37#include "llvm/IR/Analysis.h"
38#include "llvm/IR/GlobalAlias.h"
39#include "llvm/Support/Debug.h"
41#include <iterator>
42using namespace llvm;
43
44#define DEBUG_TYPE "wasm-reg-stackify"
45
46namespace {
47class WebAssemblyRegStackifyLegacy final : public MachineFunctionPass {
48 bool Optimize;
49
50 StringRef getPassName() const override {
51 return "WebAssembly Register Stackify";
52 }
53
54 void getAnalysisUsage(AnalysisUsage &AU) const override {
55 AU.setPreservesCFG();
56 if (Optimize) {
59 }
63 }
64
65 bool runOnMachineFunction(MachineFunction &MF) override;
66
67public:
68 static char ID; // Pass identification, replacement for typeid
69 WebAssemblyRegStackifyLegacy(CodeGenOptLevel OptLevel)
71 WebAssemblyRegStackifyLegacy()
72 : WebAssemblyRegStackifyLegacy(CodeGenOptLevel::Default) {}
73};
74} // end anonymous namespace
75
76char WebAssemblyRegStackifyLegacy::ID = 0;
77INITIALIZE_PASS(WebAssemblyRegStackifyLegacy, DEBUG_TYPE,
78 "Reorder instructions to use the WebAssembly value stack",
79 false, false)
80
83 return new WebAssemblyRegStackifyLegacy(OptLevel);
84}
85
86// Decorate the given instruction with implicit operands that enforce the
87// expression stack ordering constraints for an instruction which is on
88// the expression stack.
90 // Write the opaque VALUE_STACK register.
91 if (!MI->definesRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
92 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
93 /*isDef=*/true,
94 /*isImp=*/true));
95
96 // Also read the opaque VALUE_STACK register.
97 if (!MI->readsRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
98 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
99 /*isDef=*/false,
100 /*isImp=*/true));
101}
102
103// Convert an IMPLICIT_DEF instruction into an instruction which defines
104// a constant zero value.
107 const TargetInstrInfo *TII,
108 MachineFunction &MF) {
109 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
110
111 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
112 if (RegClass == &WebAssembly::I32RegClass) {
113 MI->setDesc(TII->get(WebAssembly::CONST_I32));
114 MI->addOperand(MachineOperand::CreateImm(0));
115 } else if (RegClass == &WebAssembly::I64RegClass) {
116 MI->setDesc(TII->get(WebAssembly::CONST_I64));
117 MI->addOperand(MachineOperand::CreateImm(0));
118 } else if (RegClass == &WebAssembly::F32RegClass) {
119 MI->setDesc(TII->get(WebAssembly::CONST_F32));
122 MI->addOperand(MachineOperand::CreateFPImm(Val));
123 } else if (RegClass == &WebAssembly::F64RegClass) {
124 MI->setDesc(TII->get(WebAssembly::CONST_F64));
127 MI->addOperand(MachineOperand::CreateFPImm(Val));
128 } else if (RegClass == &WebAssembly::V128RegClass) {
129 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
130 MI->addOperand(MachineOperand::CreateImm(0));
131 MI->addOperand(MachineOperand::CreateImm(0));
132 } else {
133 llvm_unreachable("Unexpected reg class");
134 }
135}
136
137// Determine whether a call to the callee referenced by
138// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
139// effects.
140static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write,
141 bool &Effects, bool &StackPointer) {
142 // All calls can use the stack pointer.
143 StackPointer = true;
144
146 if (MO.isGlobal()) {
147 const Constant *GV = MO.getGlobal();
148 if (const auto *GA = dyn_cast<GlobalAlias>(GV))
149 if (!GA->isInterposable())
150 GV = GA->getAliasee();
151
152 if (const auto *F = dyn_cast<Function>(GV)) {
153 if (!F->doesNotThrow())
154 Effects = true;
155 if (F->doesNotAccessMemory())
156 return;
157 if (F->onlyReadsMemory()) {
158 Read = true;
159 return;
160 }
161 }
162 }
163
164 // Assume the worst.
165 Write = true;
166 Read = true;
167 Effects = true;
168}
169
170// Determine whether MI reads memory, writes memory, has side effects,
171// and/or uses the stack pointer value.
172static void query(const MachineInstr &MI, bool &Read, bool &Write,
173 bool &Effects, bool &StackPointer) {
174 assert(!MI.isTerminator());
175
176 if (MI.isDebugInstr() || MI.isPosition())
177 return;
178
179 // Check for loads.
180 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
181 Read = true;
182
183 // Check for stores.
184 if (MI.mayStore()) {
185 Write = true;
186 } else if (MI.hasOrderedMemoryRef()) {
187 switch (MI.getOpcode()) {
188 case WebAssembly::DIV_S_I32:
189 case WebAssembly::DIV_S_I64:
190 case WebAssembly::REM_S_I32:
191 case WebAssembly::REM_S_I64:
192 case WebAssembly::DIV_U_I32:
193 case WebAssembly::DIV_U_I64:
194 case WebAssembly::REM_U_I32:
195 case WebAssembly::REM_U_I64:
196 case WebAssembly::I32_TRUNC_S_F32:
197 case WebAssembly::I64_TRUNC_S_F32:
198 case WebAssembly::I32_TRUNC_S_F64:
199 case WebAssembly::I64_TRUNC_S_F64:
200 case WebAssembly::I32_TRUNC_U_F32:
201 case WebAssembly::I64_TRUNC_U_F32:
202 case WebAssembly::I32_TRUNC_U_F64:
203 case WebAssembly::I64_TRUNC_U_F64:
204 // These instruction have hasUnmodeledSideEffects() returning true
205 // because they trap on overflow and invalid so they can't be arbitrarily
206 // moved, however hasOrderedMemoryRef() interprets this plus their lack
207 // of memoperands as having a potential unknown memory reference.
208 break;
209 default:
210 // Record volatile accesses, unless it's a call, as calls are handled
211 // specially below.
212 if (!MI.isCall()) {
213 Write = true;
214 Effects = true;
215 }
216 break;
217 }
218 }
219
220 // Check for side effects.
221 if (MI.hasUnmodeledSideEffects()) {
222 switch (MI.getOpcode()) {
223 case WebAssembly::DIV_S_I32:
224 case WebAssembly::DIV_S_I64:
225 case WebAssembly::REM_S_I32:
226 case WebAssembly::REM_S_I64:
227 case WebAssembly::DIV_U_I32:
228 case WebAssembly::DIV_U_I64:
229 case WebAssembly::REM_U_I32:
230 case WebAssembly::REM_U_I64:
231 case WebAssembly::I32_TRUNC_S_F32:
232 case WebAssembly::I64_TRUNC_S_F32:
233 case WebAssembly::I32_TRUNC_S_F64:
234 case WebAssembly::I64_TRUNC_S_F64:
235 case WebAssembly::I32_TRUNC_U_F32:
236 case WebAssembly::I64_TRUNC_U_F32:
237 case WebAssembly::I32_TRUNC_U_F64:
238 case WebAssembly::I64_TRUNC_U_F64:
239 // These instructions have hasUnmodeledSideEffects() returning true
240 // because they trap on overflow and invalid so they can't be arbitrarily
241 // moved, however in the specific case of register stackifying, it is safe
242 // to move them because overflow and invalid are Undefined Behavior.
243 break;
244 default:
245 Effects = true;
246 break;
247 }
248 }
249
250 // Check for writes to __stack_pointer global.
251 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
252 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
253 MI.getOperand(0).isSymbol() &&
254 !strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer"))
255 StackPointer = true;
256
257 if (MI.isCall() && MI.getOperand(0).isSymbol() &&
258 !strcmp(MI.getOperand(0).getSymbolName(), "__wasm_get_stack_pointer"))
259 StackPointer = true;
260
261 // Analyze calls.
262 if (MI.isCall()) {
263 queryCallee(MI, Read, Write, Effects, StackPointer);
264 }
265}
266
267// Test whether Def is safe and profitable to rematerialize.
268static bool shouldRematerialize(const MachineInstr &Def,
269 const WebAssemblyInstrInfo *TII) {
270 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);
271}
272
273// Identify the definition for this register at this point. This is a
274// generalization of MachineRegisterInfo::getUniqueVRegDef that uses
275// LiveIntervals to handle complex cases.
276static MachineInstr *getVRegDef(unsigned Reg, const MachineInstr *Insert,
277 const MachineRegisterInfo &MRI,
278 const LiveIntervals *LIS) {
279 // Most registers are in SSA form here so we try a quick MRI query first.
280 if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
281 return Def;
282
283 // MRI doesn't know what the Def is. Try asking LIS.
284 if (LIS != nullptr) {
285 SlotIndex InstIndex = LIS->getInstructionIndex(*Insert);
286 if (const VNInfo *ValNo = LIS->getInterval(Reg).getVNInfoBefore(InstIndex))
287 return LIS->getInstructionFromIndex(ValNo->def);
288 }
289
290 return nullptr;
291}
292
293// Test whether Reg, as defined at Def, has exactly one use. This is a
294// generalization of MachineRegisterInfo::hasOneNonDBGUse that uses
295// LiveIntervals to handle complex cases in optimized code.
296static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI,
297 const MachineFunction &MF, bool Optimize,
298 MachineInstr *Def, LiveIntervals *LIS) {
299 auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
300 // The frame base always has an implicit DBG use as DW_AT_frame_base.
301 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
302 // When using global thread context, the frame base can be encoded
303 // as an offset from __stack_pointer, so the vreg can be stackified.
304 // However, when using libcall thread context, we need to keep the frame
305 // base vreg around if debug info is enabled, because there is no
306 // global to refer to.
307 bool NeedsRegForDebug =
308 MF.getFunction().getSubprogram() &&
309 MF.getSubtarget<WebAssemblySubtarget>().hasLibcallThreadContext();
310 if (!Optimize || NeedsRegForDebug)
311 return false;
312 }
313 if (!Optimize) {
314 // Using "hasOneUse" instead of "hasOneNonDBGUse" here because we don't
315 // want to stackify DBG_VALUE operands - WASM stack locations are less
316 // useful and less widely supported than WASM local locations.
317 if (!MRI.hasOneUse(Reg))
318 return false;
319 return true;
320 }
321
322 // Most registers are in SSA form here so we try a quick MRI query first.
323 if (MRI.hasOneNonDBGUse(Reg))
324 return true;
325
326 if (LIS == nullptr)
327 return false;
328
329 bool HasOne = false;
330 const LiveInterval &LI = LIS->getInterval(Reg);
331 const VNInfo *DefVNI =
333 assert(DefVNI);
334 for (auto &I : MRI.use_nodbg_operands(Reg)) {
335 const auto &Result = LI.Query(LIS->getInstructionIndex(*I.getParent()));
336 if (Result.valueIn() == DefVNI) {
337 if (!Result.isKill())
338 return false;
339 if (HasOne)
340 return false;
341 HasOne = true;
342 }
343 }
344 return HasOne;
345}
346
347// Test whether it's safe to move Def to just before Insert.
348// TODO: Compute memory dependencies in a way that doesn't require always
349// walking the block.
350// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
351// more precise.
352static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use,
353 const MachineInstr *Insert,
354 const WebAssemblyFunctionInfo &MFI,
355 const MachineRegisterInfo &MRI, bool Optimize) {
356 const MachineInstr *DefI = Def->getParent();
357 assert(DefI->getParent() == Insert->getParent());
358 assert(Use->getParent()->getParent() == Insert->getParent());
359
360 // For now avoid stackifying any multi-def instructions. While it's
361 // theoretically possible to do so for the first def in some cases this has
362 // historically led to bugs such as #199910 and #98323. For now this
363 // conservatively skips all multi-def instructions as a consequence. Note that
364 // multi-def instructions are expected to be not all that common so this in
365 // theory doesn't have a massive impact, but nevertheless this'd still be
366 // something to optimize better in the future.
367 if (DefI->getNumExplicitDefs() > 1)
368 return false;
369
370 // If moving is a semantic nop, it is always allowed
371 const MachineBasicBlock *MBB = DefI->getParent();
372 auto NextI = std::next(MachineBasicBlock::const_iterator(DefI));
373 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
374 ;
375 if (NextI == Insert)
376 return true;
377
378 // When not optimizing, we only handle the trivial case above
379 // to guarantee no impact to debugging and to avoid spending
380 // compile time.
381 if (!Optimize)
382 return false;
383
384 // 'catch' and 'catch_all' should be the first instruction of a BB and cannot
385 // move.
386 if (WebAssembly::isCatch(DefI->getOpcode()))
387 return false;
388
389 // Check for register dependencies.
390 SmallVector<unsigned, 4> MutableRegisters;
391 for (const MachineOperand &MO : DefI->operands()) {
392 if (!MO.isReg() || MO.isUndef())
393 continue;
394 Register Reg = MO.getReg();
395
396 // If the register is dead here and at Insert, ignore it.
397 if (MO.isDead() && Insert->definesRegister(Reg, /*TRI=*/nullptr) &&
398 !Insert->readsRegister(Reg, /*TRI=*/nullptr))
399 continue;
400
401 if (Reg.isPhysical()) {
402 // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
403 // from moving down, and we've already checked for that.
404 if (Reg == WebAssembly::ARGUMENTS)
405 continue;
406 // If the physical register is never modified, ignore it.
407 if (!MRI.isPhysRegModified(Reg))
408 continue;
409 // Otherwise, it's a physical register with unknown liveness.
410 return false;
411 }
412
413 // If one of the operands isn't in SSA form, it has different values at
414 // different times, and we need to make sure we don't move our use across
415 // a different def.
416 if (!MO.isDef() && !MRI.hasOneDef(Reg))
417 MutableRegisters.push_back(Reg);
418 }
419
420 bool Read = false, Write = false, Effects = false, StackPointer = false;
421 query(*DefI, Read, Write, Effects, StackPointer);
422
423 // If the instruction does not access memory and has no side effects, it has
424 // no additional dependencies.
425 bool HasMutableRegisters = !MutableRegisters.empty();
426 if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
427 return true;
428
429 // Scan through the intervening instructions between DefI and Insert.
431 for (--I; I != D; --I) {
432 bool InterveningRead = false;
433 bool InterveningWrite = false;
434 bool InterveningEffects = false;
435 bool InterveningStackPointer = false;
436 query(*I, InterveningRead, InterveningWrite, InterveningEffects,
437 InterveningStackPointer);
438 if (Effects && InterveningEffects)
439 return false;
440 if (Read && InterveningWrite)
441 return false;
442 if (Write && (InterveningRead || InterveningWrite))
443 return false;
444 if (StackPointer && InterveningStackPointer)
445 return false;
446
447 for (unsigned Reg : MutableRegisters)
448 for (const MachineOperand &MO : I->operands())
449 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
450 return false;
451 }
452
453 return true;
454}
455
456/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
457static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
458 const MachineBasicBlock &MBB,
459 const MachineRegisterInfo &MRI,
460 const MachineDominatorTree &MDT,
461 LiveIntervals &LIS,
463 const LiveInterval &LI = LIS.getInterval(Reg);
464
465 const MachineInstr *OneUseInst = OneUse.getParent();
466 VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
467
468 for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) {
469 if (&Use == &OneUse)
470 continue;
471
472 const MachineInstr *UseInst = Use.getParent();
473 VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
474
475 if (UseVNI != OneUseVNI)
476 continue;
477
478 if (UseInst == OneUseInst) {
479 // Another use in the same instruction. We need to ensure that the one
480 // selected use happens "before" it.
481 if (&OneUse > &Use)
482 return false;
483 } else {
484 // Test that the use is dominated by the one selected use.
485 while (!MDT.dominates(OneUseInst, UseInst)) {
486 // Actually, dominating is over-conservative. Test that the use would
487 // happen after the one selected use in the stack evaluation order.
488 //
489 // This is needed as a consequence of using implicit local.gets for
490 // uses and implicit local.sets for defs.
491 if (UseInst->getDesc().getNumDefs() == 0)
492 return false;
493 const MachineOperand &MO = UseInst->getOperand(0);
494 if (!MO.isReg())
495 return false;
496 Register DefReg = MO.getReg();
497 if (!DefReg.isVirtual() || !MFI.isVRegStackified(DefReg))
498 return false;
499 assert(MRI.hasOneNonDBGUse(DefReg));
500 const MachineOperand &NewUse = *MRI.use_nodbg_begin(DefReg);
501 const MachineInstr *NewUseInst = NewUse.getParent();
502 if (NewUseInst == OneUseInst) {
503 if (&OneUse > &NewUse)
504 return false;
505 break;
506 }
507 UseInst = NewUseInst;
508 }
509 }
510 }
511 return true;
512}
513
514/// Get the appropriate tee opcode for the given register class.
515static unsigned getTeeOpcode(const TargetRegisterClass *RC) {
516 if (RC == &WebAssembly::I32RegClass)
517 return WebAssembly::TEE_I32;
518 if (RC == &WebAssembly::I64RegClass)
519 return WebAssembly::TEE_I64;
520 if (RC == &WebAssembly::F32RegClass)
521 return WebAssembly::TEE_F32;
522 if (RC == &WebAssembly::F64RegClass)
523 return WebAssembly::TEE_F64;
524 if (RC == &WebAssembly::V128RegClass)
525 return WebAssembly::TEE_V128;
526 if (RC == &WebAssembly::EXTERNREFRegClass)
527 return WebAssembly::TEE_EXTERNREF;
528 if (RC == &WebAssembly::FUNCREFRegClass)
529 return WebAssembly::TEE_FUNCREF;
530 if (RC == &WebAssembly::EXNREFRegClass)
531 return WebAssembly::TEE_EXNREF;
532 llvm_unreachable("Unexpected register class");
533}
534
535// Shrink LI to its uses, cleaning up LI.
537 if (LIS.shrinkToUses(&LI)) {
539 LIS.splitSeparateComponents(LI, SplitLIs);
540 }
541}
542
543/// A single-use def in the same block with no intervening memory or register
544/// dependencies; move the def down and nest it with the current instruction.
547 MachineInstr *Insert, LiveIntervals *LIS,
549 MachineRegisterInfo &MRI) {
550 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
551
553 DefDIs.sink(Insert);
554 if (LIS != nullptr)
555 LIS->handleMove(*Def);
556
557 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {
558 // No one else is using this register for anything so we can just stackify
559 // it in place.
560 MFI.stackifyVReg(MRI, Reg);
561 } else {
562 // The register may have unrelated uses or defs; create a new register for
563 // just our one def and use so that we can stackify it.
565 Op.setReg(NewReg);
566 DefDIs.updateReg(NewReg);
567
568 if (LIS != nullptr) {
569 // Tell LiveIntervals about the new register.
571
572 // Tell LiveIntervals about the changes to the old register.
573 LiveInterval &LI = LIS->getInterval(Reg);
575 LIS->getInstructionIndex(*Op.getParent()).getRegSlot(),
576 /*RemoveDeadValNo=*/true);
577 }
578
579 MFI.stackifyVReg(MRI, NewReg);
580 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
581 }
582
584 return Def;
585}
586
588 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())
589 if (!I->isDebugInstr())
590 return I;
591 return nullptr;
592}
593
594/// A trivially cloneable instruction; clone it and nest the new copy with the
595/// current instruction.
596static MachineInstr *
601 const WebAssemblyInstrInfo *TII) {
602 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
603 LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
604
605 WebAssemblyDebugValueManager DefDIs(&Def);
606
608 DefDIs.cloneSink(&*Insert, NewReg);
609 Op.setReg(NewReg);
610 MachineInstr *Clone = getPrevNonDebugInst(&*Insert);
611 assert(Clone);
612 LIS.InsertMachineInstrInMaps(*Clone);
614 MFI.stackifyVReg(MRI, NewReg);
615 imposeStackOrdering(Clone);
616
617 LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump());
618
619 // Shrink the interval.
620 bool IsDead = MRI.use_empty(Reg);
621 if (!IsDead) {
622 LiveInterval &LI = LIS.getInterval(Reg);
623 shrinkToUses(LI, LIS);
625 }
626
627 // If that was the last use of the original, delete the original.
628 if (IsDead) {
629 LLVM_DEBUG(dbgs() << " - Deleting original\n");
631 LIS.removePhysRegDefAt(MCRegister::from(WebAssembly::ARGUMENTS), Idx);
632 LIS.removeInterval(Reg);
634 DefDIs.removeDef();
635 }
636
637 return Clone;
638}
639
640/// A multiple-use def in the same block with no intervening memory or register
641/// dependencies; move the def down, nest it with the current instruction, and
642/// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
643/// this:
644///
645/// Reg = INST ... // Def
646/// INST ..., Reg, ... // Insert
647/// INST ..., Reg, ...
648/// INST ..., Reg, ...
649///
650/// to this:
651///
652/// DefReg = INST ... // Def (to become the new Insert)
653/// TeeReg, Reg = TEE_... DefReg
654/// INST ..., TeeReg, ... // Insert
655/// INST ..., Reg, ...
656/// INST ..., Reg, ...
657///
658/// with DefReg and TeeReg stackified. This eliminates a local.get from the
659/// resulting code.
664 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
665
666 const auto *RegClass = MRI.getRegClass(Reg);
667 Register TeeReg = MRI.createVirtualRegister(RegClass);
668 Register DefReg = MRI.createVirtualRegister(RegClass);
669
670 // Move Def into place.
672 DefDIs.sink(Insert);
673 LIS.handleMove(*Def);
674
675 // Create the Tee and attach the registers.
676 MachineOperand &DefMO = Def->getOperand(0);
677 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
678 TII->get(getTeeOpcode(RegClass)), TeeReg)
680 .addReg(DefReg, getUndefRegState(DefMO.isDead()));
681 Op.setReg(TeeReg);
682 DefDIs.updateReg(DefReg);
683 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
684 SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
685
686 // Tell LiveIntervals we moved the original vreg def from Def to Tee.
687 LiveInterval &LI = LIS.getInterval(Reg);
689 VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
690 I->start = TeeIdx;
691 ValNo->def = TeeIdx;
692 shrinkToUses(LI, LIS);
693
694 // Finish stackifying the new regs.
697 MFI.stackifyVReg(MRI, DefReg);
698 MFI.stackifyVReg(MRI, TeeReg);
701
702 // Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone
703 // DBG_VALUEs for both of them, given that the latter will cancel the former
704 // anyway. Here we only clone DBG_VALUEs for TeeReg, which will be converted
705 // to a local index in ExplicitLocals pass.
706 DefDIs.cloneSink(Insert, TeeReg, /* CloneDef */ false);
707
708 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
709 LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
710 return Def;
711}
712
713namespace {
714/// A stack for walking the tree of instructions being built, visiting the
715/// MachineOperands in DFS order.
716class TreeWalkerState {
717 using mop_iterator = MachineInstr::mop_iterator;
718 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
719 using RangeTy = iterator_range<mop_reverse_iterator>;
721
722public:
723 explicit TreeWalkerState(MachineInstr *Insert) {
724 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
725 if (!Range.empty())
726 Worklist.push_back(reverse(Range));
727 }
728
729 bool done() const { return Worklist.empty(); }
730
731 MachineOperand &pop() {
732 RangeTy &Range = Worklist.back();
733 MachineOperand &Op = *Range.begin();
735 if (Range.empty())
736 Worklist.pop_back();
737 assert((Worklist.empty() || !Worklist.back().empty()) &&
738 "Empty ranges shouldn't remain in the worklist");
739 return Op;
740 }
741
742 /// Push Instr's operands onto the stack to be visited.
743 void pushOperands(MachineInstr *Instr) {
744 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
745 if (!Range.empty())
746 Worklist.push_back(reverse(Range));
747 }
748
749 /// Some of Instr's operands are on the top of the stack; remove them and
750 /// re-insert them starting from the beginning (because we've commuted them).
751 void resetTopOperands(MachineInstr *Instr) {
752 assert(hasRemainingOperands(Instr) &&
753 "Reseting operands should only be done when the instruction has "
754 "an operand still on the stack");
755 Worklist.back() = reverse(Instr->explicit_uses());
756 }
757
758 /// Test whether Instr has operands remaining to be visited at the top of
759 /// the stack.
760 bool hasRemainingOperands(const MachineInstr *Instr) const {
761 if (Worklist.empty())
762 return false;
763 const RangeTy &Range = Worklist.back();
764 return !Range.empty() && Range.begin()->getParent() == Instr;
765 }
766
767 /// Test whether the given register is present on the stack, indicating an
768 /// operand in the tree that we haven't visited yet. Moving a definition of
769 /// Reg to a point in the tree after that would change its value.
770 ///
771 /// This is needed as a consequence of using implicit local.gets for
772 /// uses and implicit local.sets for defs.
773 bool isOnStack(unsigned Reg) const {
774 for (const RangeTy &Range : Worklist)
775 for (const MachineOperand &MO : Range)
776 if (MO.isReg() && MO.getReg() == Reg)
777 return true;
778 return false;
779 }
780};
781
782/// State to keep track of whether commuting is in flight or whether it's been
783/// tried for the current instruction and didn't work.
784class CommutingState {
785 /// There are effectively three states: the initial state where we haven't
786 /// started commuting anything and we don't know anything yet, the tentative
787 /// state where we've commuted the operands of the current instruction and are
788 /// revisiting it, and the declined state where we've reverted the operands
789 /// back to their original order and will no longer commute it further.
790 bool TentativelyCommuting = false;
791 bool Declined = false;
792
793 /// During the tentative state, these hold the operand indices of the commuted
794 /// operands.
795 unsigned Operand0, Operand1;
796
797public:
798 /// Stackification for an operand was not successful due to ordering
799 /// constraints. If possible, and if we haven't already tried it and declined
800 /// it, commute Insert's operands and prepare to revisit it.
801 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
802 const WebAssemblyInstrInfo *TII) {
803 if (TentativelyCommuting) {
804 assert(!Declined &&
805 "Don't decline commuting until you've finished trying it");
806 // Commuting didn't help. Revert it.
807 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
808 TentativelyCommuting = false;
809 Declined = true;
810 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
813 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
814 // Tentatively commute the operands and try again.
815 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
816 TreeWalker.resetTopOperands(Insert);
817 TentativelyCommuting = true;
818 Declined = false;
819 }
820 }
821 }
822
823 /// Stackification for some operand was successful. Reset to the default
824 /// state.
825 void reset() {
826 TentativelyCommuting = false;
827 Declined = false;
828 }
829};
830} // end anonymous namespace
831
834 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
835 "********** Function: "
836 << MF.getName() << '\n');
837
838 bool Changed = false;
841 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
842 if (Optimize) {
843 assert(MDT && "expected MDT to be available");
844 assert(LIS && "expected LIS to be available");
845 }
846
847 // Walk the instructions from the bottom up. Currently we don't look past
848 // block boundaries, and the blocks aren't ordered so the block visitation
849 // order isn't significant, but we may want to change this in the future.
850 for (MachineBasicBlock &MBB : MF) {
851 // Don't use a range-based for loop, because we modify the list as we're
852 // iterating over it and the end iterator may change.
853 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
854 MachineInstr *Insert = &*MII;
855 // Don't nest anything inside an inline asm, because we don't have
856 // constraints for $push inputs.
857 if (Insert->isInlineAsm())
858 continue;
859
860 // Ignore debugging intrinsics.
861 if (Insert->isDebugValue())
862 continue;
863
864 // Ignore FAKE_USEs, which are no-ops and will be deleted later.
865 if (Insert->isFakeUse())
866 continue;
867
868 // Iterate through the inputs in reverse order, since we'll be pulling
869 // operands off the stack in LIFO order.
870 CommutingState Commuting;
871 TreeWalkerState TreeWalker(Insert);
872 while (!TreeWalker.done()) {
873 MachineOperand &Use = TreeWalker.pop();
874
875 // We're only interested in explicit virtual register operands.
876 if (!Use.isReg())
877 continue;
878
879 Register Reg = Use.getReg();
880 assert(Use.isUse() && "explicit_uses() should only iterate over uses");
881 assert(!Use.isImplicit() &&
882 "explicit_uses() should only iterate over explicit operands");
883 if (Reg.isPhysical())
884 continue;
885
886 // Identify the definition for this register at this point.
887 MachineInstr *DefI = getVRegDef(Reg, Insert, MRI, LIS);
888 if (!DefI)
889 continue;
890
891 // Don't nest an INLINE_ASM def into anything, because we don't have
892 // constraints for $pop outputs.
893 if (DefI->isInlineAsm())
894 continue;
895
896 // Argument instructions represent live-in registers and not real
897 // instructions.
899 continue;
900
901 MachineOperand *Def =
902 DefI->findRegisterDefOperand(Reg, /*TRI=*/nullptr);
903 assert(Def != nullptr);
904
905 // Decide which strategy to take. Prefer to move a single-use value
906 // over cloning it, and prefer cloning over introducing a tee.
907 // For moving, we require the def to be in the same block as the use;
908 // this makes things simpler (LiveIntervals' handleMove function only
909 // supports intra-block moves) and it's MachineSink's job to catch all
910 // the sinking opportunities anyway.
911 bool SameBlock = DefI->getParent() == &MBB;
912 bool CanMove = SameBlock &&
913 isSafeToMove(Def, &Use, Insert, MFI, MRI, Optimize) &&
914 !TreeWalker.isOnStack(Reg);
915 if (CanMove && hasSingleUse(Reg, MRI, MF, Optimize, DefI, LIS)) {
916 Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI);
917
918 // If we are removing the frame base reg completely, remove the debug
919 // info as well.
920 // TODO: Encode this properly as a stackified value.
921 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
922 assert(
923 Optimize &&
924 "Stackifying away frame base in unoptimized code not expected");
925 MFI.clearFrameBaseVreg();
926 }
927 } else if (Optimize && shouldRematerialize(*DefI, TII)) {
928 Insert = rematerializeCheapDef(Reg, Use, *DefI, Insert->getIterator(),
929 *LIS, MFI, MRI, TII);
930 } else if (Optimize && CanMove &&
931 oneUseDominatesOtherUses(Reg, Use, MBB, MRI, *MDT, *LIS,
932 MFI)) {
933 Insert = moveAndTeeForMultiUse(Reg, Use, DefI, MBB, Insert, *LIS, MFI,
934 MRI, TII);
935 } else {
936 // We failed to stackify the operand. If the problem was ordering
937 // constraints, Commuting may be able to help.
938 if (!CanMove && SameBlock)
939 Commuting.maybeCommute(Insert, TreeWalker, TII);
940 // Proceed to the next operand.
941 continue;
942 }
943
944 // Stackifying a multivalue def may unlock in-place stackification of
945 // subsequent defs. TODO: Handle the case where the consecutive uses are
946 // not all in the same instruction.
947 auto *SubsequentDef = Insert->defs().begin();
948 auto *SubsequentUse = &Use;
949 while (SubsequentDef != Insert->defs().end() &&
950 SubsequentUse != Use.getParent()->uses().end()) {
951 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
952 break;
953 Register DefReg = SubsequentDef->getReg();
954 Register UseReg = SubsequentUse->getReg();
955 // TODO: This single-use restriction could be relaxed by using tees
956 if (DefReg != UseReg ||
957 !hasSingleUse(DefReg, MRI, MF, Optimize, nullptr, nullptr))
958 break;
959 MFI.stackifyVReg(MRI, DefReg);
960 ++SubsequentDef;
961 ++SubsequentUse;
962 }
963
964 // If the instruction we just stackified is an IMPLICIT_DEF, convert it
965 // to a constant 0 so that the def is explicit, and the push/pop
966 // correspondence is maintained.
967 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
968 convertImplicitDefToConstZero(Insert, MRI, TII, MF);
969
970 // We stackified an operand. Add the defining instruction's operands to
971 // the worklist stack now to continue to build an ever deeper tree.
972 Commuting.reset();
973 TreeWalker.pushOperands(Insert);
974 }
975
976 // If we stackified any operands, skip over the tree to start looking for
977 // the next instruction we can build a tree on.
978 if (Insert != &*MII) {
979 imposeStackOrdering(&*MII);
981 Changed = true;
982 }
983 }
984 }
985
986 // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
987 // that it never looks like a use-before-def.
988 if (Changed) {
989 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
990 for (MachineBasicBlock &MBB : MF)
991 MBB.addLiveIn(WebAssembly::VALUE_STACK);
992 }
993
994#ifndef NDEBUG
995 // Verify that pushes and pops are performed in LIFO order.
997 for (MachineBasicBlock &MBB : MF) {
998 for (MachineInstr &MI : MBB) {
999 if (MI.isDebugInstr())
1000 continue;
1001 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
1002 if (!MO.isReg())
1003 continue;
1004 Register Reg = MO.getReg();
1005 if (MFI.isVRegStackified(Reg))
1006 assert(Stack.pop_back_val() == Reg &&
1007 "Register stack pop should be paired with a push");
1008 }
1009 for (MachineOperand &MO : MI.defs()) {
1010 if (!MO.isReg())
1011 continue;
1012 Register Reg = MO.getReg();
1013 if (MFI.isVRegStackified(Reg))
1014 Stack.push_back(MO.getReg());
1015 }
1016 }
1017 // TODO: Generalize this code to support keeping values on the stack across
1018 // basic block boundaries.
1019 assert(Stack.empty() &&
1020 "Register stack pushes and pops should be balanced");
1021 }
1022#endif
1023
1024 return Changed;
1025}
1026
1027bool WebAssemblyRegStackifyLegacy::runOnMachineFunction(MachineFunction &MF) {
1028 MachineDominatorTree *MDT = nullptr;
1029 LiveIntervals *LIS = nullptr;
1030 if (Optimize) {
1031 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1032 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
1033 }
1034 return regStackify(MF, Optimize, MDT, LIS);
1035}
1036
1037PreservedAnalyses
1040 MachineDominatorTree *MDT = nullptr;
1041 LiveIntervals *LIS = nullptr;
1042 if (Optimize) {
1043 MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
1044 LIS = &MFAM.getResult<LiveIntervalsAnalysis>(MF);
1045 }
1046 bool Changed = regStackify(MF, Optimize, MDT, LIS);
1047 if (!Changed)
1048 return PreservedAnalyses::all();
1051 .preserve<LiveIntervalsAnalysis>()
1052 .preserve<SlotIndexesAnalysis>();
1053}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
bool IsDead
#define LLVM_DEBUG(...)
Definition Debug.h:119
This file contains the declaration of the WebAssembly-specific manager for DebugValues associated wit...
This file provides WebAssembly-specific target descriptions.
This file declares WebAssembly-specific per-machine-function information.
static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use, const MachineInstr *Insert, const WebAssemblyFunctionInfo &MFI, const MachineRegisterInfo &MRI, bool Optimize)
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
static MachineInstr * rematerializeCheapDef(unsigned Reg, MachineOperand &Op, MachineInstr &Def, MachineBasicBlock::instr_iterator Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A trivially cloneable instruction; clone it and nest the new copy with the current instruction.
static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI, const MachineFunction &MF, bool Optimize, MachineInstr *Def, LiveIntervals *LIS)
static bool regStackify(MachineFunction &MF, bool Optimize, MachineDominatorTree *MDT, LiveIntervals *LIS)
static void imposeStackOrdering(MachineInstr *MI)
static MachineInstr * moveForSingleUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals *LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI)
A single-use def in the same block with no intervening memory or register dependencies; move the def ...
static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
static MachineInstr * moveAndTeeForMultiUse(unsigned Reg, MachineOperand &Op, MachineInstr *Def, MachineBasicBlock &MBB, MachineInstr *Insert, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI, const WebAssemblyInstrInfo *TII)
A multiple-use def in the same block with no intervening memory or register dependencies; move the de...
static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse, const MachineBasicBlock &MBB, const MachineRegisterInfo &MRI, const MachineDominatorTree &MDT, LiveIntervals &LIS, WebAssemblyFunctionInfo &MFI)
Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
This file declares the WebAssembly-specific subclass of TargetSubtarget.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:353
LiveInterval - This class represents the liveness of a register, or stack slot.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
LLVM_ABI void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
Segments::iterator iterator
bool liveAt(SlotIndex index) const
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
LLVM_ABI void removeSegment(SlotIndex Start, SlotIndex End, bool RemoveDeadValNo=false)
Remove the specified interval from this live range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition MCRegister.h:77
MachineInstrBundleIterator< const MachineInstr > const_iterator
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isInlineAsm() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
mop_range operands()
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
MachineOperand * mop_iterator
iterator/begin/end - Iterate over all operands of a machine instruction.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
static MachineOperand CreateFPImm(const ConstantFP *CFP)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getDeadSlot() const
Returns the dead def kill slot for the current instruction.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:287
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:286
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
iterator_range< use_iterator > uses()
Definition Value.h:380
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Changed
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isArgument(unsigned Opc)
const MachineOperand & getCalleeOp(const MachineInstr &MI)
Returns the operand number of a callee, assuming the argument is a call instruction.
bool isCatch(unsigned Opc)
NodeAddr< InstrNode * > Instr
Definition RDFGraph.h:389
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:149
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:152
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
FunctionPass * createWebAssemblyRegStackifyLegacyPass(CodeGenOptLevel OptLevel)
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58