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 }
65 }
66
67 bool runOnMachineFunction(MachineFunction &MF) override;
68
69public:
70 static char ID; // Pass identification, replacement for typeid
71 WebAssemblyRegStackifyLegacy(CodeGenOptLevel OptLevel)
73 WebAssemblyRegStackifyLegacy()
74 : WebAssemblyRegStackifyLegacy(CodeGenOptLevel::Default) {}
75};
76} // end anonymous namespace
77
78char WebAssemblyRegStackifyLegacy::ID = 0;
79INITIALIZE_PASS(WebAssemblyRegStackifyLegacy, DEBUG_TYPE,
80 "Reorder instructions to use the WebAssembly value stack",
81 false, false)
82
85 return new WebAssemblyRegStackifyLegacy(OptLevel);
86}
87
88// Decorate the given instruction with implicit operands that enforce the
89// expression stack ordering constraints for an instruction which is on
90// the expression stack.
92 // Write the opaque VALUE_STACK register.
93 if (!MI->definesRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
94 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
95 /*isDef=*/true,
96 /*isImp=*/true));
97
98 // Also read the opaque VALUE_STACK register.
99 if (!MI->readsRegister(WebAssembly::VALUE_STACK, /*TRI=*/nullptr))
100 MI->addOperand(MachineOperand::CreateReg(WebAssembly::VALUE_STACK,
101 /*isDef=*/false,
102 /*isImp=*/true));
103}
104
105// Convert an IMPLICIT_DEF instruction into an instruction which defines
106// a constant zero value.
109 const TargetInstrInfo *TII,
110 MachineFunction &MF) {
111 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
112
113 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
114 if (RegClass == &WebAssembly::I32RegClass) {
115 MI->setDesc(TII->get(WebAssembly::CONST_I32));
116 MI->addOperand(MachineOperand::CreateImm(0));
117 } else if (RegClass == &WebAssembly::I64RegClass) {
118 MI->setDesc(TII->get(WebAssembly::CONST_I64));
119 MI->addOperand(MachineOperand::CreateImm(0));
120 } else if (RegClass == &WebAssembly::F32RegClass) {
121 MI->setDesc(TII->get(WebAssembly::CONST_F32));
124 MI->addOperand(MachineOperand::CreateFPImm(Val));
125 } else if (RegClass == &WebAssembly::F64RegClass) {
126 MI->setDesc(TII->get(WebAssembly::CONST_F64));
129 MI->addOperand(MachineOperand::CreateFPImm(Val));
130 } else if (RegClass == &WebAssembly::V128RegClass) {
131 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
132 MI->addOperand(MachineOperand::CreateImm(0));
133 MI->addOperand(MachineOperand::CreateImm(0));
134 } else {
135 llvm_unreachable("Unexpected reg class");
136 }
137}
138
139// Determine whether a call to the callee referenced by
140// MI->getOperand(CalleeOpNo) reads memory, writes memory, and/or has side
141// effects.
142static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write,
143 bool &Effects, bool &StackPointer) {
144 // All calls can use the stack pointer.
145 StackPointer = true;
146
148 if (MO.isGlobal()) {
149 const Constant *GV = MO.getGlobal();
150 if (const auto *GA = dyn_cast<GlobalAlias>(GV))
151 if (!GA->isInterposable())
152 GV = GA->getAliasee();
153
154 if (const auto *F = dyn_cast<Function>(GV)) {
155 if (!F->doesNotThrow())
156 Effects = true;
157 if (F->doesNotAccessMemory())
158 return;
159 if (F->onlyReadsMemory()) {
160 Read = true;
161 return;
162 }
163 }
164 }
165
166 // Assume the worst.
167 Write = true;
168 Read = true;
169 Effects = true;
170}
171
172// Determine whether MI reads memory, writes memory, has side effects,
173// and/or uses the stack pointer value.
174static void query(const MachineInstr &MI, bool &Read, bool &Write,
175 bool &Effects, bool &StackPointer) {
176 assert(!MI.isTerminator());
177
178 if (MI.isDebugInstr() || MI.isPosition())
179 return;
180
181 // Check for loads.
182 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
183 Read = true;
184
185 // Check for stores.
186 if (MI.mayStore()) {
187 Write = true;
188 } else if (MI.hasOrderedMemoryRef()) {
189 switch (MI.getOpcode()) {
190 case WebAssembly::DIV_S_I32:
191 case WebAssembly::DIV_S_I64:
192 case WebAssembly::REM_S_I32:
193 case WebAssembly::REM_S_I64:
194 case WebAssembly::DIV_U_I32:
195 case WebAssembly::DIV_U_I64:
196 case WebAssembly::REM_U_I32:
197 case WebAssembly::REM_U_I64:
198 case WebAssembly::I32_TRUNC_S_F32:
199 case WebAssembly::I64_TRUNC_S_F32:
200 case WebAssembly::I32_TRUNC_S_F64:
201 case WebAssembly::I64_TRUNC_S_F64:
202 case WebAssembly::I32_TRUNC_U_F32:
203 case WebAssembly::I64_TRUNC_U_F32:
204 case WebAssembly::I32_TRUNC_U_F64:
205 case WebAssembly::I64_TRUNC_U_F64:
206 // These instruction have hasUnmodeledSideEffects() returning true
207 // because they trap on overflow and invalid so they can't be arbitrarily
208 // moved, however hasOrderedMemoryRef() interprets this plus their lack
209 // of memoperands as having a potential unknown memory reference.
210 break;
211 default:
212 // Record volatile accesses, unless it's a call, as calls are handled
213 // specially below.
214 if (!MI.isCall()) {
215 Write = true;
216 Effects = true;
217 }
218 break;
219 }
220 }
221
222 // Check for side effects.
223 if (MI.hasUnmodeledSideEffects()) {
224 switch (MI.getOpcode()) {
225 case WebAssembly::DIV_S_I32:
226 case WebAssembly::DIV_S_I64:
227 case WebAssembly::REM_S_I32:
228 case WebAssembly::REM_S_I64:
229 case WebAssembly::DIV_U_I32:
230 case WebAssembly::DIV_U_I64:
231 case WebAssembly::REM_U_I32:
232 case WebAssembly::REM_U_I64:
233 case WebAssembly::I32_TRUNC_S_F32:
234 case WebAssembly::I64_TRUNC_S_F32:
235 case WebAssembly::I32_TRUNC_S_F64:
236 case WebAssembly::I64_TRUNC_S_F64:
237 case WebAssembly::I32_TRUNC_U_F32:
238 case WebAssembly::I64_TRUNC_U_F32:
239 case WebAssembly::I32_TRUNC_U_F64:
240 case WebAssembly::I64_TRUNC_U_F64:
241 // These instructions have hasUnmodeledSideEffects() returning true
242 // because they trap on overflow and invalid so they can't be arbitrarily
243 // moved, however in the specific case of register stackifying, it is safe
244 // to move them because overflow and invalid are Undefined Behavior.
245 break;
246 default:
247 Effects = true;
248 break;
249 }
250 }
251
252 // Check for writes to __stack_pointer global.
253 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
254 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
255 MI.getOperand(0).isSymbol() &&
256 !strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer"))
257 StackPointer = true;
258
259 if (MI.isCall() && MI.getOperand(0).isSymbol() &&
260 !strcmp(MI.getOperand(0).getSymbolName(), "__wasm_get_stack_pointer"))
261 StackPointer = true;
262
263 // Analyze calls.
264 if (MI.isCall()) {
265 queryCallee(MI, Read, Write, Effects, StackPointer);
266 }
267}
268
269// Test whether Def is safe and profitable to rematerialize.
270static bool shouldRematerialize(const MachineInstr &Def,
271 const WebAssemblyInstrInfo *TII) {
272 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);
273}
274
275// Identify the definition for this register at this point. This is a
276// generalization of MachineRegisterInfo::getUniqueVRegDef that uses
277// LiveIntervals to handle complex cases.
278static MachineInstr *getVRegDef(unsigned Reg, const MachineInstr *Insert,
279 const MachineRegisterInfo &MRI,
280 const LiveIntervals *LIS) {
281 // Most registers are in SSA form here so we try a quick MRI query first.
282 if (MachineInstr *Def = MRI.getUniqueVRegDef(Reg))
283 return Def;
284
285 // MRI doesn't know what the Def is. Try asking LIS.
286 if (LIS != nullptr) {
287 SlotIndex InstIndex = LIS->getInstructionIndex(*Insert);
288 if (const VNInfo *ValNo = LIS->getInterval(Reg).getVNInfoBefore(InstIndex))
289 return LIS->getInstructionFromIndex(ValNo->def);
290 }
291
292 return nullptr;
293}
294
295// Test whether Reg, as defined at Def, has exactly one use. This is a
296// generalization of MachineRegisterInfo::hasOneNonDBGUse that uses
297// LiveIntervals to handle complex cases in optimized code.
298static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI,
299 const MachineFunction &MF, bool Optimize,
300 MachineInstr *Def, LiveIntervals *LIS) {
301 auto &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
302 // The frame base always has an implicit DBG use as DW_AT_frame_base.
303 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
304 // When using global thread context, the frame base can be encoded
305 // as an offset from __stack_pointer, so the vreg can be stackified.
306 // However, when using libcall thread context, we need to keep the frame
307 // base vreg around if debug info is enabled, because there is no
308 // global to refer to.
309 bool NeedsRegForDebug =
310 MF.getFunction().getSubprogram() &&
311 MF.getSubtarget<WebAssemblySubtarget>().hasLibcallThreadContext();
312 if (!Optimize || NeedsRegForDebug)
313 return false;
314 }
315 if (!Optimize) {
316 // Using "hasOneUse" instead of "hasOneNonDBGUse" here because we don't
317 // want to stackify DBG_VALUE operands - WASM stack locations are less
318 // useful and less widely supported than WASM local locations.
319 if (!MRI.hasOneUse(Reg))
320 return false;
321 return true;
322 }
323
324 // Most registers are in SSA form here so we try a quick MRI query first.
325 if (MRI.hasOneNonDBGUse(Reg))
326 return true;
327
328 if (LIS == nullptr)
329 return false;
330
331 bool HasOne = false;
332 const LiveInterval &LI = LIS->getInterval(Reg);
333 const VNInfo *DefVNI =
335 assert(DefVNI);
336 for (auto &I : MRI.use_nodbg_operands(Reg)) {
337 const auto &Result = LI.Query(LIS->getInstructionIndex(*I.getParent()));
338 if (Result.valueIn() == DefVNI) {
339 if (!Result.isKill())
340 return false;
341 if (HasOne)
342 return false;
343 HasOne = true;
344 }
345 }
346 return HasOne;
347}
348
349// Test whether it's safe to move Def to just before Insert.
350// TODO: Compute memory dependencies in a way that doesn't require always
351// walking the block.
352// TODO: Compute memory dependencies in a way that uses AliasAnalysis to be
353// more precise.
354static bool isSafeToMove(const MachineOperand *Def, const MachineOperand *Use,
355 const MachineInstr *Insert,
356 const WebAssemblyFunctionInfo &MFI,
357 const MachineRegisterInfo &MRI, bool Optimize) {
358 const MachineInstr *DefI = Def->getParent();
359 assert(DefI->getParent() == Insert->getParent());
360 assert(Use->getParent()->getParent() == Insert->getParent());
361
362 // For now avoid stackifying any multi-def instructions. While it's
363 // theoretically possible to do so for the first def in some cases this has
364 // historically led to bugs such as #199910 and #98323. For now this
365 // conservatively skips all multi-def instructions as a consequence. Note that
366 // multi-def instructions are expected to be not all that common so this in
367 // theory doesn't have a massive impact, but nevertheless this'd still be
368 // something to optimize better in the future.
369 if (DefI->getNumExplicitDefs() > 1)
370 return false;
371
372 // If moving is a semantic nop, it is always allowed
373 const MachineBasicBlock *MBB = DefI->getParent();
374 auto NextI = std::next(MachineBasicBlock::const_iterator(DefI));
375 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
376 ;
377 if (NextI == Insert)
378 return true;
379
380 // When not optimizing, we only handle the trivial case above
381 // to guarantee no impact to debugging and to avoid spending
382 // compile time.
383 if (!Optimize)
384 return false;
385
386 // 'catch' and 'catch_all' should be the first instruction of a BB and cannot
387 // move.
388 if (WebAssembly::isCatch(DefI->getOpcode()))
389 return false;
390
391 // Check for register dependencies.
392 SmallVector<unsigned, 4> MutableRegisters;
393 for (const MachineOperand &MO : DefI->operands()) {
394 if (!MO.isReg() || MO.isUndef())
395 continue;
396 Register Reg = MO.getReg();
397
398 // If the register is dead here and at Insert, ignore it.
399 if (MO.isDead() && Insert->definesRegister(Reg, /*TRI=*/nullptr) &&
400 !Insert->readsRegister(Reg, /*TRI=*/nullptr))
401 continue;
402
403 if (Reg.isPhysical()) {
404 // Ignore ARGUMENTS; it's just used to keep the ARGUMENT_* instructions
405 // from moving down, and we've already checked for that.
406 if (Reg == WebAssembly::ARGUMENTS)
407 continue;
408 // If the physical register is never modified, ignore it.
409 if (!MRI.isPhysRegModified(Reg))
410 continue;
411 // Otherwise, it's a physical register with unknown liveness.
412 return false;
413 }
414
415 // If one of the operands isn't in SSA form, it has different values at
416 // different times, and we need to make sure we don't move our use across
417 // a different def.
418 if (!MO.isDef() && !MRI.hasOneDef(Reg))
419 MutableRegisters.push_back(Reg);
420 }
421
422 bool Read = false, Write = false, Effects = false, StackPointer = false;
423 query(*DefI, Read, Write, Effects, StackPointer);
424
425 // If the instruction does not access memory and has no side effects, it has
426 // no additional dependencies.
427 bool HasMutableRegisters = !MutableRegisters.empty();
428 if (!Read && !Write && !Effects && !StackPointer && !HasMutableRegisters)
429 return true;
430
431 // Scan through the intervening instructions between DefI and Insert.
433 for (--I; I != D; --I) {
434 bool InterveningRead = false;
435 bool InterveningWrite = false;
436 bool InterveningEffects = false;
437 bool InterveningStackPointer = false;
438 query(*I, InterveningRead, InterveningWrite, InterveningEffects,
439 InterveningStackPointer);
440 if (Effects && InterveningEffects)
441 return false;
442 if (Read && InterveningWrite)
443 return false;
444 if (Write && (InterveningRead || InterveningWrite))
445 return false;
446 if (StackPointer && InterveningStackPointer)
447 return false;
448
449 for (unsigned Reg : MutableRegisters)
450 for (const MachineOperand &MO : I->operands())
451 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
452 return false;
453 }
454
455 return true;
456}
457
458/// Test whether OneUse, a use of Reg, dominates all of Reg's other uses.
459static bool oneUseDominatesOtherUses(unsigned Reg, const MachineOperand &OneUse,
460 const MachineBasicBlock &MBB,
461 const MachineRegisterInfo &MRI,
462 const MachineDominatorTree &MDT,
463 LiveIntervals &LIS,
465 const LiveInterval &LI = LIS.getInterval(Reg);
466
467 const MachineInstr *OneUseInst = OneUse.getParent();
468 VNInfo *OneUseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*OneUseInst));
469
470 for (const MachineOperand &Use : MRI.use_nodbg_operands(Reg)) {
471 if (&Use == &OneUse)
472 continue;
473
474 const MachineInstr *UseInst = Use.getParent();
475 VNInfo *UseVNI = LI.getVNInfoBefore(LIS.getInstructionIndex(*UseInst));
476
477 if (UseVNI != OneUseVNI)
478 continue;
479
480 if (UseInst == OneUseInst) {
481 // Another use in the same instruction. We need to ensure that the one
482 // selected use happens "before" it.
483 if (&OneUse > &Use)
484 return false;
485 } else {
486 // Test that the use is dominated by the one selected use.
487 while (!MDT.dominates(OneUseInst, UseInst)) {
488 // Actually, dominating is over-conservative. Test that the use would
489 // happen after the one selected use in the stack evaluation order.
490 //
491 // This is needed as a consequence of using implicit local.gets for
492 // uses and implicit local.sets for defs.
493 if (UseInst->getDesc().getNumDefs() == 0)
494 return false;
495 const MachineOperand &MO = UseInst->getOperand(0);
496 if (!MO.isReg())
497 return false;
498 Register DefReg = MO.getReg();
499 if (!DefReg.isVirtual() || !MFI.isVRegStackified(DefReg))
500 return false;
501 assert(MRI.hasOneNonDBGUse(DefReg));
502 const MachineOperand &NewUse = *MRI.use_nodbg_begin(DefReg);
503 const MachineInstr *NewUseInst = NewUse.getParent();
504 if (NewUseInst == OneUseInst) {
505 if (&OneUse > &NewUse)
506 return false;
507 break;
508 }
509 UseInst = NewUseInst;
510 }
511 }
512 }
513 return true;
514}
515
516/// Get the appropriate tee opcode for the given register class.
517static unsigned getTeeOpcode(const TargetRegisterClass *RC) {
518 if (RC == &WebAssembly::I32RegClass)
519 return WebAssembly::TEE_I32;
520 if (RC == &WebAssembly::I64RegClass)
521 return WebAssembly::TEE_I64;
522 if (RC == &WebAssembly::F32RegClass)
523 return WebAssembly::TEE_F32;
524 if (RC == &WebAssembly::F64RegClass)
525 return WebAssembly::TEE_F64;
526 if (RC == &WebAssembly::V128RegClass)
527 return WebAssembly::TEE_V128;
528 if (RC == &WebAssembly::EXTERNREFRegClass)
529 return WebAssembly::TEE_EXTERNREF;
530 if (RC == &WebAssembly::FUNCREFRegClass)
531 return WebAssembly::TEE_FUNCREF;
532 if (RC == &WebAssembly::EXNREFRegClass)
533 return WebAssembly::TEE_EXNREF;
534 llvm_unreachable("Unexpected register class");
535}
536
537// Shrink LI to its uses, cleaning up LI.
539 if (LIS.shrinkToUses(&LI)) {
541 LIS.splitSeparateComponents(LI, SplitLIs);
542 }
543}
544
545/// A single-use def in the same block with no intervening memory or register
546/// dependencies; move the def down and nest it with the current instruction.
549 MachineInstr *Insert, LiveIntervals *LIS,
551 MachineRegisterInfo &MRI) {
552 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
553
555 DefDIs.sink(Insert);
556 if (LIS != nullptr)
557 LIS->handleMove(*Def);
558
559 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {
560 // No one else is using this register for anything so we can just stackify
561 // it in place.
562 MFI.stackifyVReg(MRI, Reg);
563 } else {
564 // The register may have unrelated uses or defs; create a new register for
565 // just our one def and use so that we can stackify it.
567 Op.setReg(NewReg);
568 DefDIs.updateReg(NewReg);
569
570 if (LIS != nullptr) {
571 // Tell LiveIntervals about the new register.
573
574 // Tell LiveIntervals about the changes to the old register.
575 LiveInterval &LI = LIS->getInterval(Reg);
577 LIS->getInstructionIndex(*Op.getParent()).getRegSlot(),
578 /*RemoveDeadValNo=*/true);
579 }
580
581 MFI.stackifyVReg(MRI, NewReg);
582 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
583 }
584
586 return Def;
587}
588
590 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())
591 if (!I->isDebugInstr())
592 return I;
593 return nullptr;
594}
595
596/// A trivially cloneable instruction; clone it and nest the new copy with the
597/// current instruction.
598static MachineInstr *
603 const WebAssemblyInstrInfo *TII) {
604 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
605 LLVM_DEBUG(dbgs() << " - for use in "; Op.getParent()->dump());
606
607 WebAssemblyDebugValueManager DefDIs(&Def);
608
610 DefDIs.cloneSink(&*Insert, NewReg);
611 Op.setReg(NewReg);
612 MachineInstr *Clone = getPrevNonDebugInst(&*Insert);
613 assert(Clone);
614 LIS.InsertMachineInstrInMaps(*Clone);
616 MFI.stackifyVReg(MRI, NewReg);
617 imposeStackOrdering(Clone);
618
619 LLVM_DEBUG(dbgs() << " - Cloned to "; Clone->dump());
620
621 // Shrink the interval.
622 bool IsDead = MRI.use_empty(Reg);
623 if (!IsDead) {
624 LiveInterval &LI = LIS.getInterval(Reg);
625 shrinkToUses(LI, LIS);
627 }
628
629 // If that was the last use of the original, delete the original.
630 if (IsDead) {
631 LLVM_DEBUG(dbgs() << " - Deleting original\n");
633 LIS.removePhysRegDefAt(MCRegister::from(WebAssembly::ARGUMENTS), Idx);
634 LIS.removeInterval(Reg);
636 DefDIs.removeDef();
637 }
638
639 return Clone;
640}
641
642/// A multiple-use def in the same block with no intervening memory or register
643/// dependencies; move the def down, nest it with the current instruction, and
644/// insert a tee to satisfy the rest of the uses. As an illustration, rewrite
645/// this:
646///
647/// Reg = INST ... // Def
648/// INST ..., Reg, ... // Insert
649/// INST ..., Reg, ...
650/// INST ..., Reg, ...
651///
652/// to this:
653///
654/// DefReg = INST ... // Def (to become the new Insert)
655/// TeeReg, Reg = TEE_... DefReg
656/// INST ..., TeeReg, ... // Insert
657/// INST ..., Reg, ...
658/// INST ..., Reg, ...
659///
660/// with DefReg and TeeReg stackified. This eliminates a local.get from the
661/// resulting code.
666 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
667
668 const auto *RegClass = MRI.getRegClass(Reg);
669 Register TeeReg = MRI.createVirtualRegister(RegClass);
670 Register DefReg = MRI.createVirtualRegister(RegClass);
671
672 // Move Def into place.
674 DefDIs.sink(Insert);
675 LIS.handleMove(*Def);
676
677 // Create the Tee and attach the registers.
678 MachineOperand &DefMO = Def->getOperand(0);
679 MachineInstr *Tee = BuildMI(MBB, Insert, Insert->getDebugLoc(),
680 TII->get(getTeeOpcode(RegClass)), TeeReg)
682 .addReg(DefReg, getUndefRegState(DefMO.isDead()));
683 Op.setReg(TeeReg);
684 DefDIs.updateReg(DefReg);
685 SlotIndex TeeIdx = LIS.InsertMachineInstrInMaps(*Tee).getRegSlot();
686 SlotIndex DefIdx = LIS.getInstructionIndex(*Def).getRegSlot();
687
688 // Tell LiveIntervals we moved the original vreg def from Def to Tee.
689 LiveInterval &LI = LIS.getInterval(Reg);
691 VNInfo *ValNo = LI.getVNInfoAt(DefIdx);
692 I->start = TeeIdx;
693 ValNo->def = TeeIdx;
694 shrinkToUses(LI, LIS);
695
696 // Finish stackifying the new regs.
699 MFI.stackifyVReg(MRI, DefReg);
700 MFI.stackifyVReg(MRI, TeeReg);
703
704 // Even though 'TeeReg, Reg = TEE ...', has two defs, we don't need to clone
705 // DBG_VALUEs for both of them, given that the latter will cancel the former
706 // anyway. Here we only clone DBG_VALUEs for TeeReg, which will be converted
707 // to a local index in ExplicitLocals pass.
708 DefDIs.cloneSink(Insert, TeeReg, /* CloneDef */ false);
709
710 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
711 LLVM_DEBUG(dbgs() << " - Tee instruction: "; Tee->dump());
712 return Def;
713}
714
715namespace {
716/// A stack for walking the tree of instructions being built, visiting the
717/// MachineOperands in DFS order.
718class TreeWalkerState {
719 using mop_iterator = MachineInstr::mop_iterator;
720 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
721 using RangeTy = iterator_range<mop_reverse_iterator>;
723
724public:
725 explicit TreeWalkerState(MachineInstr *Insert) {
726 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
727 if (!Range.empty())
728 Worklist.push_back(reverse(Range));
729 }
730
731 bool done() const { return Worklist.empty(); }
732
733 MachineOperand &pop() {
734 RangeTy &Range = Worklist.back();
735 MachineOperand &Op = *Range.begin();
737 if (Range.empty())
738 Worklist.pop_back();
739 assert((Worklist.empty() || !Worklist.back().empty()) &&
740 "Empty ranges shouldn't remain in the worklist");
741 return Op;
742 }
743
744 /// Push Instr's operands onto the stack to be visited.
745 void pushOperands(MachineInstr *Instr) {
746 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
747 if (!Range.empty())
748 Worklist.push_back(reverse(Range));
749 }
750
751 /// Some of Instr's operands are on the top of the stack; remove them and
752 /// re-insert them starting from the beginning (because we've commuted them).
753 void resetTopOperands(MachineInstr *Instr) {
754 assert(hasRemainingOperands(Instr) &&
755 "Reseting operands should only be done when the instruction has "
756 "an operand still on the stack");
757 Worklist.back() = reverse(Instr->explicit_uses());
758 }
759
760 /// Test whether Instr has operands remaining to be visited at the top of
761 /// the stack.
762 bool hasRemainingOperands(const MachineInstr *Instr) const {
763 if (Worklist.empty())
764 return false;
765 const RangeTy &Range = Worklist.back();
766 return !Range.empty() && Range.begin()->getParent() == Instr;
767 }
768
769 /// Test whether the given register is present on the stack, indicating an
770 /// operand in the tree that we haven't visited yet. Moving a definition of
771 /// Reg to a point in the tree after that would change its value.
772 ///
773 /// This is needed as a consequence of using implicit local.gets for
774 /// uses and implicit local.sets for defs.
775 bool isOnStack(unsigned Reg) const {
776 for (const RangeTy &Range : Worklist)
777 for (const MachineOperand &MO : Range)
778 if (MO.isReg() && MO.getReg() == Reg)
779 return true;
780 return false;
781 }
782};
783
784/// State to keep track of whether commuting is in flight or whether it's been
785/// tried for the current instruction and didn't work.
786class CommutingState {
787 /// There are effectively three states: the initial state where we haven't
788 /// started commuting anything and we don't know anything yet, the tentative
789 /// state where we've commuted the operands of the current instruction and are
790 /// revisiting it, and the declined state where we've reverted the operands
791 /// back to their original order and will no longer commute it further.
792 bool TentativelyCommuting = false;
793 bool Declined = false;
794
795 /// During the tentative state, these hold the operand indices of the commuted
796 /// operands.
797 unsigned Operand0, Operand1;
798
799public:
800 /// Stackification for an operand was not successful due to ordering
801 /// constraints. If possible, and if we haven't already tried it and declined
802 /// it, commute Insert's operands and prepare to revisit it.
803 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
804 const WebAssemblyInstrInfo *TII) {
805 if (TentativelyCommuting) {
806 assert(!Declined &&
807 "Don't decline commuting until you've finished trying it");
808 // Commuting didn't help. Revert it.
809 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
810 TentativelyCommuting = false;
811 Declined = true;
812 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
815 if (TII->findCommutedOpIndices(*Insert, Operand0, Operand1)) {
816 // Tentatively commute the operands and try again.
817 TII->commuteInstruction(*Insert, /*NewMI=*/false, Operand0, Operand1);
818 TreeWalker.resetTopOperands(Insert);
819 TentativelyCommuting = true;
820 Declined = false;
821 }
822 }
823 }
824
825 /// Stackification for some operand was successful. Reset to the default
826 /// state.
827 void reset() {
828 TentativelyCommuting = false;
829 Declined = false;
830 }
831};
832} // end anonymous namespace
833
836 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
837 "********** Function: "
838 << MF.getName() << '\n');
839
840 bool Changed = false;
843 const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
844 if (Optimize) {
845 assert(MDT && "expected MDT to be available");
846 assert(LIS && "expected LIS to be available");
847 }
848
849 // Walk the instructions from the bottom up. Currently we don't look past
850 // block boundaries, and the blocks aren't ordered so the block visitation
851 // order isn't significant, but we may want to change this in the future.
852 for (MachineBasicBlock &MBB : MF) {
853 // Don't use a range-based for loop, because we modify the list as we're
854 // iterating over it and the end iterator may change.
855 for (auto MII = MBB.rbegin(); MII != MBB.rend(); ++MII) {
856 MachineInstr *Insert = &*MII;
857 // Don't nest anything inside an inline asm, because we don't have
858 // constraints for $push inputs.
859 if (Insert->isInlineAsm())
860 continue;
861
862 // Ignore debugging intrinsics.
863 if (Insert->isDebugValue())
864 continue;
865
866 // Ignore FAKE_USEs, which are no-ops and will be deleted later.
867 if (Insert->isFakeUse())
868 continue;
869
870 // Iterate through the inputs in reverse order, since we'll be pulling
871 // operands off the stack in LIFO order.
872 CommutingState Commuting;
873 TreeWalkerState TreeWalker(Insert);
874 while (!TreeWalker.done()) {
875 MachineOperand &Use = TreeWalker.pop();
876
877 // We're only interested in explicit virtual register operands.
878 if (!Use.isReg())
879 continue;
880
881 Register Reg = Use.getReg();
882 assert(Use.isUse() && "explicit_uses() should only iterate over uses");
883 assert(!Use.isImplicit() &&
884 "explicit_uses() should only iterate over explicit operands");
885 if (Reg.isPhysical())
886 continue;
887
888 // Identify the definition for this register at this point.
889 MachineInstr *DefI = getVRegDef(Reg, Insert, MRI, LIS);
890 if (!DefI)
891 continue;
892
893 // Don't nest an INLINE_ASM def into anything, because we don't have
894 // constraints for $pop outputs.
895 if (DefI->isInlineAsm())
896 continue;
897
898 // Argument instructions represent live-in registers and not real
899 // instructions.
901 continue;
902
903 MachineOperand *Def =
904 DefI->findRegisterDefOperand(Reg, /*TRI=*/nullptr);
905 assert(Def != nullptr);
906
907 // Decide which strategy to take. Prefer to move a single-use value
908 // over cloning it, and prefer cloning over introducing a tee.
909 // For moving, we require the def to be in the same block as the use;
910 // this makes things simpler (LiveIntervals' handleMove function only
911 // supports intra-block moves) and it's MachineSink's job to catch all
912 // the sinking opportunities anyway.
913 bool SameBlock = DefI->getParent() == &MBB;
914 bool CanMove = SameBlock &&
915 isSafeToMove(Def, &Use, Insert, MFI, MRI, Optimize) &&
916 !TreeWalker.isOnStack(Reg);
917 if (CanMove && hasSingleUse(Reg, MRI, MF, Optimize, DefI, LIS)) {
918 Insert = moveForSingleUse(Reg, Use, DefI, MBB, Insert, LIS, MFI, MRI);
919
920 // If we are removing the frame base reg completely, remove the debug
921 // info as well.
922 // TODO: Encode this properly as a stackified value.
923 if (MFI.isFrameBaseVirtual() && MFI.getFrameBaseVreg() == Reg) {
924 assert(
925 Optimize &&
926 "Stackifying away frame base in unoptimized code not expected");
927 MFI.clearFrameBaseVreg();
928 }
929 } else if (Optimize && shouldRematerialize(*DefI, TII)) {
930 Insert = rematerializeCheapDef(Reg, Use, *DefI, Insert->getIterator(),
931 *LIS, MFI, MRI, TII);
932 } else if (Optimize && CanMove &&
933 oneUseDominatesOtherUses(Reg, Use, MBB, MRI, *MDT, *LIS,
934 MFI)) {
935 Insert = moveAndTeeForMultiUse(Reg, Use, DefI, MBB, Insert, *LIS, MFI,
936 MRI, TII);
937 } else {
938 // We failed to stackify the operand. If the problem was ordering
939 // constraints, Commuting may be able to help.
940 if (!CanMove && SameBlock)
941 Commuting.maybeCommute(Insert, TreeWalker, TII);
942 // Proceed to the next operand.
943 continue;
944 }
945
946 // Stackifying a multivalue def may unlock in-place stackification of
947 // subsequent defs. TODO: Handle the case where the consecutive uses are
948 // not all in the same instruction.
949 auto *SubsequentDef = Insert->defs().begin();
950 auto *SubsequentUse = &Use;
951 while (SubsequentDef != Insert->defs().end() &&
952 SubsequentUse != Use.getParent()->uses().end()) {
953 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
954 break;
955 Register DefReg = SubsequentDef->getReg();
956 Register UseReg = SubsequentUse->getReg();
957 // TODO: This single-use restriction could be relaxed by using tees
958 if (DefReg != UseReg ||
959 !hasSingleUse(DefReg, MRI, MF, Optimize, nullptr, nullptr))
960 break;
961 MFI.stackifyVReg(MRI, DefReg);
962 ++SubsequentDef;
963 ++SubsequentUse;
964 }
965
966 // If the instruction we just stackified is an IMPLICIT_DEF, convert it
967 // to a constant 0 so that the def is explicit, and the push/pop
968 // correspondence is maintained.
969 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
970 convertImplicitDefToConstZero(Insert, MRI, TII, MF);
971
972 // We stackified an operand. Add the defining instruction's operands to
973 // the worklist stack now to continue to build an ever deeper tree.
974 Commuting.reset();
975 TreeWalker.pushOperands(Insert);
976 }
977
978 // If we stackified any operands, skip over the tree to start looking for
979 // the next instruction we can build a tree on.
980 if (Insert != &*MII) {
981 imposeStackOrdering(&*MII);
983 Changed = true;
984 }
985 }
986 }
987
988 // If we used VALUE_STACK anywhere, add it to the live-in sets everywhere so
989 // that it never looks like a use-before-def.
990 if (Changed) {
991 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
992 for (MachineBasicBlock &MBB : MF)
993 MBB.addLiveIn(WebAssembly::VALUE_STACK);
994 }
995
996#ifndef NDEBUG
997 // Verify that pushes and pops are performed in LIFO order.
999 for (MachineBasicBlock &MBB : MF) {
1000 for (MachineInstr &MI : MBB) {
1001 if (MI.isDebugInstr())
1002 continue;
1003 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
1004 if (!MO.isReg())
1005 continue;
1006 Register Reg = MO.getReg();
1007 if (MFI.isVRegStackified(Reg))
1008 assert(Stack.pop_back_val() == Reg &&
1009 "Register stack pop should be paired with a push");
1010 }
1011 for (MachineOperand &MO : MI.defs()) {
1012 if (!MO.isReg())
1013 continue;
1014 Register Reg = MO.getReg();
1015 if (MFI.isVRegStackified(Reg))
1016 Stack.push_back(MO.getReg());
1017 }
1018 }
1019 // TODO: Generalize this code to support keeping values on the stack across
1020 // basic block boundaries.
1021 assert(Stack.empty() &&
1022 "Register stack pushes and pops should be balanced");
1023 }
1024#endif
1025
1026 return Changed;
1027}
1028
1029bool WebAssemblyRegStackifyLegacy::runOnMachineFunction(MachineFunction &MF) {
1030 MachineDominatorTree *MDT = nullptr;
1031 LiveIntervals *LIS = nullptr;
1032 if (Optimize) {
1033 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1034 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
1035 }
1036 return regStackify(MF, Optimize, MDT, LIS);
1037}
1038
1039PreservedAnalyses
1042 MachineDominatorTree *MDT = nullptr;
1043 LiveIntervals *LIS = nullptr;
1044 if (Optimize) {
1045 MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
1046 LIS = &MFAM.getResult<LiveIntervalsAnalysis>(MF);
1047 }
1048 bool Changed = regStackify(MF, Optimize, MDT, LIS);
1049 if (!Changed)
1050 return PreservedAnalyses::all();
1053 .preserve<LiveIntervalsAnalysis>()
1054 .preserve<SlotIndexesAnalysis>();
1055}
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
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:82
@ Default
-O2, -Os, -Oz
Definition CodeGen.h:85
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