LLVM: lib/Target/WebAssembly/WebAssemblyRegStackify.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
37#include
38using namespace llvm;
39
40#define DEBUG_TYPE "wasm-reg-stackify"
41
42namespace {
45
46 StringRef getPassName() const override {
47 return "WebAssembly Register Stackify";
48 }
49
50 void getAnalysisUsage(AnalysisUsage &AU) const override {
55 }
62 }
63
65
66public:
67 static char ID;
71};
72}
73
74char WebAssemblyRegStackify::ID = 0;
76 "Reorder instructions to use the WebAssembly value stack",
77 false, false)
78
80 return new WebAssemblyRegStackify(OptLevel);
81}
82
83
84
85
87
88 if (->definesRegister(WebAssembly::VALUE_STACK, nullptr))
90 true,
91 true));
92
93
94 if (->readsRegister(WebAssembly::VALUE_STACK, nullptr))
96 false,
97 true));
98}
99
100
101
106 assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
107
108 const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
109 if (RegClass == &WebAssembly::I32RegClass) {
110 MI->setDesc(TII->get(WebAssembly::CONST_I32));
112 } else if (RegClass == &WebAssembly::I64RegClass) {
113 MI->setDesc(TII->get(WebAssembly::CONST_I64));
115 } else if (RegClass == &WebAssembly::F32RegClass) {
116 MI->setDesc(TII->get(WebAssembly::CONST_F32));
120 } else if (RegClass == &WebAssembly::F64RegClass) {
121 MI->setDesc(TII->get(WebAssembly::CONST_F64));
125 } else if (RegClass == &WebAssembly::V128RegClass) {
126 MI->setDesc(TII->get(WebAssembly::CONST_V128_I64x2));
129 } else {
131 }
132}
133
134
135
136
138 bool &Effects, bool &StackPointer) {
139
140 StackPointer = true;
141
146 if (!GA->isInterposable())
147 GV = GA->getAliasee();
148
150 if (->doesNotThrow())
151 Effects = true;
152 if (F->doesNotAccessMemory())
153 return;
154 if (F->onlyReadsMemory()) {
156 return;
157 }
158 }
159 }
160
161
164 Effects = true;
165}
166
167
168
170 bool &Effects, bool &StackPointer) {
172
173 if (MI.isDebugInstr() || MI.isPosition())
174 return;
175
176
177 if (MI.mayLoad() && .isDereferenceableInvariantLoad())
179
180
181 if (MI.mayStore()) {
183 } else if (MI.hasOrderedMemoryRef()) {
184 switch (MI.getOpcode()) {
185 case WebAssembly::DIV_S_I32:
186 case WebAssembly::DIV_S_I64:
187 case WebAssembly::REM_S_I32:
188 case WebAssembly::REM_S_I64:
189 case WebAssembly::DIV_U_I32:
190 case WebAssembly::DIV_U_I64:
191 case WebAssembly::REM_U_I32:
192 case WebAssembly::REM_U_I64:
193 case WebAssembly::I32_TRUNC_S_F32:
194 case WebAssembly::I64_TRUNC_S_F32:
195 case WebAssembly::I32_TRUNC_S_F64:
196 case WebAssembly::I64_TRUNC_S_F64:
197 case WebAssembly::I32_TRUNC_U_F32:
198 case WebAssembly::I64_TRUNC_U_F32:
199 case WebAssembly::I32_TRUNC_U_F64:
200 case WebAssembly::I64_TRUNC_U_F64:
201
202
203
204
205 break;
206 default:
207
208
209 if (.isCall()) {
211 Effects = true;
212 }
213 break;
214 }
215 }
216
217
218 if (MI.hasUnmodeledSideEffects()) {
219 switch (MI.getOpcode()) {
220 case WebAssembly::DIV_S_I32:
221 case WebAssembly::DIV_S_I64:
222 case WebAssembly::REM_S_I32:
223 case WebAssembly::REM_S_I64:
224 case WebAssembly::DIV_U_I32:
225 case WebAssembly::DIV_U_I64:
226 case WebAssembly::REM_U_I32:
227 case WebAssembly::REM_U_I64:
228 case WebAssembly::I32_TRUNC_S_F32:
229 case WebAssembly::I64_TRUNC_S_F32:
230 case WebAssembly::I32_TRUNC_S_F64:
231 case WebAssembly::I64_TRUNC_S_F64:
232 case WebAssembly::I32_TRUNC_U_F32:
233 case WebAssembly::I64_TRUNC_U_F32:
234 case WebAssembly::I32_TRUNC_U_F64:
235 case WebAssembly::I64_TRUNC_U_F64:
236
237
238
239
240 break;
241 default:
242 Effects = true;
243 break;
244 }
245 }
246
247
248 if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
249 MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
250 MI.getOperand(0).isSymbol() &&
251 !strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer"))
252 StackPointer = true;
253
254
255 if (MI.isCall()) {
257 }
258}
259
260
263 return Def.isAsCheapAsAMove() && TII->isTriviallyReMaterializable(Def);
264}
265
266
267
268
272
274 return Def;
275
276
277 if (LIS != nullptr) {
281 }
282
283 return nullptr;
284}
285
286
287
288
293
294
295
296 if (.hasOneUse(Reg))
297 return false;
298
300 return false;
301 return true;
302 }
303
304
305 if (MRI.hasOneNonDBGUse(Reg))
306 return true;
307
308 if (LIS == nullptr)
309 return false;
310
311 bool HasOne = false;
313 const VNInfo *DefVNI =
316 for (auto &I : MRI.use_nodbg_operands(Reg)) {
318 if (Result.valueIn() == DefVNI) {
319 if (!Result.isKill())
320 return false;
321 if (HasOne)
322 return false;
323 HasOne = true;
324 }
325 }
326 return HasOne;
327}
328
329
330
331
332
333
342
343
344
345
346
347
348
349
350
351
352
353
355 return false;
356
357
358
359
360
361
362 for (const auto &SubsequentDef : drop_begin(DefI->defs())) {
366 for (const auto &PriorUse : I->uses()) {
367 if (&PriorUse == Use)
368 break;
369 if (PriorUse.isReg() && SubsequentDef.getReg() == PriorUse.getReg())
370 return false;
371 }
372 }
373 }
374
375
378 for (auto E = MBB->end(); NextI != E && NextI->isDebugInstr(); ++NextI)
379 ;
380 if (NextI == Insert)
381 return true;
382
383
384
385
387 return false;
388
389
390
392 return false;
393
394
397 if (!MO.isReg() || MO.isUndef())
398 continue;
400
401
402 if (MO.isDead() && Insert->definesRegister(Reg, nullptr) &&
403 !Insert->readsRegister(Reg, nullptr))
404 continue;
405
406 if (Reg.isPhysical()) {
407
408
409 if (Reg == WebAssembly::ARGUMENTS)
410 continue;
411
412 if (.isPhysRegModified(Reg))
413 continue;
414
415 return false;
416 }
417
418
419
420
421 if (!MO.isDef() && .hasOneDef(Reg))
423 }
424
425 bool Read = false, Write = false, Effects = false, StackPointer = false;
427
428
429
430 bool HasMutableRegisters = !MutableRegisters.empty();
431 if ( &&
&& !Effects && !StackPointer && !HasMutableRegisters)
432 return true;
433
434
437 bool InterveningRead = false;
438 bool InterveningWrite = false;
439 bool InterveningEffects = false;
440 bool InterveningStackPointer = false;
441 query(*I, InterveningRead, InterveningWrite, InterveningEffects,
442 InterveningStackPointer);
443 if (Effects && InterveningEffects)
444 return false;
445 if (Read && InterveningWrite)
446 return false;
447 if (Write && (InterveningRead || InterveningWrite))
448 return false;
449 if (StackPointer && InterveningStackPointer)
450 return false;
451
452 for (unsigned Reg : MutableRegisters)
454 if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
455 return false;
456 }
457
458 return true;
459}
460
461
469
472
474 if (&Use == &OneUse)
475 continue;
476
479
480 if (UseVNI != OneUseVNI)
481 continue;
482
483 if (UseInst == OneUseInst) {
484
485
486 if (&OneUse > &Use)
487 return false;
488 } else {
489
490 while (!MDT.dominates(OneUseInst, UseInst)) {
491
492
493
494
495
497 return false;
500 return false;
503 return false;
504 assert(MRI.hasOneNonDBGUse(DefReg));
507 if (NewUseInst == OneUseInst) {
508 if (&OneUse > &NewUse)
509 return false;
510 break;
511 }
512 UseInst = NewUseInst;
513 }
514 }
515 }
516 return true;
517}
518
519
521 if (RC == &WebAssembly::I32RegClass)
522 return WebAssembly::TEE_I32;
523 if (RC == &WebAssembly::I64RegClass)
524 return WebAssembly::TEE_I64;
525 if (RC == &WebAssembly::F32RegClass)
526 return WebAssembly::TEE_F32;
527 if (RC == &WebAssembly::F64RegClass)
528 return WebAssembly::TEE_F64;
529 if (RC == &WebAssembly::V128RegClass)
530 return WebAssembly::TEE_V128;
531 if (RC == &WebAssembly::EXTERNREFRegClass)
532 return WebAssembly::TEE_EXTERNREF;
533 if (RC == &WebAssembly::FUNCREFRegClass)
534 return WebAssembly::TEE_FUNCREF;
535 if (RC == &WebAssembly::EXNREFRegClass)
536 return WebAssembly::TEE_EXNREF;
538}
539
540
547
548
549
555 LLVM_DEBUG(dbgs() << "Move for single use: "; Def->dump());
556
558 DefDIs.sink(Insert);
559 if (LIS != nullptr)
561
562 if (MRI.hasOneDef(Reg) && MRI.hasOneNonDBGUse(Reg)) {
563
564
566 } else {
567
568
569 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
570 Op.setReg(NewReg);
572
573 if (LIS != nullptr) {
574
576
577
581 true);
582 }
583
585 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
586 }
587
589 return Def;
590}
591
593 for (auto *I = MI->getPrevNode(); I; I = I->getPrevNode())
594 if (->isDebugInstr())
595 return I;
596 return nullptr;
597}
598
599
600
607 LLVM_DEBUG(dbgs() << "Rematerializing cheap def: "; Def.dump());
609
611
612 Register NewReg = MRI.createVirtualRegister(MRI.getRegClass(Reg));
613 DefDIs.cloneSink(&*Insert, NewReg);
614 Op.setReg(NewReg);
621
623
624
630 }
631
632
640 }
641
642 return Clone;
643}
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
669 LLVM_DEBUG(dbgs() << "Move and tee for multi-use:"; Def->dump());
670
671 const auto *RegClass = MRI.getRegClass(Reg);
672 Register TeeReg = MRI.createVirtualRegister(RegClass);
673 Register DefReg = MRI.createVirtualRegister(RegClass);
674
675
677 DefDIs.sink(Insert);
679
680
686 Op.setReg(TeeReg);
690
691
695 I->start = TeeIdx;
696 ValNo->def = TeeIdx;
698
699
706
707
708
709
710
711 DefDIs.cloneSink(Insert, TeeReg, false);
712
713 LLVM_DEBUG(dbgs() << " - Replaced register: "; Def->dump());
715 return Def;
716}
717
718namespace {
719
720
721class TreeWalkerState {
723 using mop_reverse_iterator = std::reverse_iterator<mop_iterator>;
724 using RangeTy = iterator_range<mop_reverse_iterator>;
726
727public:
728 explicit TreeWalkerState(MachineInstr *Insert) {
729 const iterator_range<mop_iterator> &Range = Insert->explicit_uses();
730 if (.empty())
732 }
733
734 bool done() const { return Worklist.empty(); }
735
736 MachineOperand &pop() {
737 RangeTy &Range = Worklist.back();
738 MachineOperand &Op = *Range.begin();
740 if (Range.empty())
741 Worklist.pop_back();
742 assert((Worklist.empty() || !Worklist.back().empty()) &&
743 "Empty ranges shouldn't remain in the worklist");
744 return Op;
745 }
746
747
748 void pushOperands(MachineInstr *Instr) {
749 const iterator_range<mop_iterator> &Range(Instr->explicit_uses());
750 if (.empty())
752 }
753
754
755
756 void resetTopOperands(MachineInstr *Instr) {
757 assert(hasRemainingOperands(Instr) &&
758 "Reseting operands should only be done when the instruction has "
759 "an operand still on the stack");
760 Worklist.back() = reverse(Instr->explicit_uses());
761 }
762
763
764
765 bool hasRemainingOperands(const MachineInstr *Instr) const {
766 if (Worklist.empty())
767 return false;
768 const RangeTy &Range = Worklist.back();
769 return .empty() && Range.begin()->getParent() == Instr;
770 }
771
772
773
774
775
776
777
778 bool isOnStack(unsigned Reg) const {
779 for (const RangeTy &Range : Worklist)
780 for (const MachineOperand &MO : Range)
781 if (MO.isReg() && MO.getReg() == Reg)
782 return true;
783 return false;
784 }
785};
786
787
788
789class CommutingState {
790
791
792
793
794
795 bool TentativelyCommuting = false;
796 bool Declined = false;
797
798
799
800 unsigned Operand0, Operand1;
801
802public:
803
804
805
806 void maybeCommute(MachineInstr *Insert, TreeWalkerState &TreeWalker,
807 const WebAssemblyInstrInfo *TII) {
808 if (TentativelyCommuting) {
810 "Don't decline commuting until you've finished trying it");
811
813 TentativelyCommuting = false;
814 Declined = true;
815 } else if (!Declined && TreeWalker.hasRemainingOperands(Insert)) {
819
821 TreeWalker.resetTopOperands(Insert);
822 TentativelyCommuting = true;
823 Declined = false;
824 }
825 }
826 }
827
828
829
830 void reset() {
831 TentativelyCommuting = false;
832 Declined = false;
833 }
834};
835}
836
837bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
838 LLVM_DEBUG(dbgs() << "********** Register Stackifying **********\n"
839 "********** Function: "
840 << MF.getName() << '\n');
841
844 WebAssemblyFunctionInfo &MFI = *MF.getInfo();
845 const auto *TII = MF.getSubtarget().getInstrInfo();
846 MachineDominatorTree *MDT = nullptr;
847 LiveIntervals *LIS = nullptr;
849 MDT = &getAnalysis().getDomTree();
850 LIS = &getAnalysis().getLIS();
851 }
852
853
854
855
856 for (MachineBasicBlock &MBB : MF) {
857
858
860 MachineInstr *Insert = &*MII;
861
862
863 if (Insert->isInlineAsm())
864 continue;
865
866
867 if (Insert->isDebugValue())
868 continue;
869
870
871 if (Insert->isFakeUse())
872 continue;
873
874
875
876 CommutingState Commuting;
877 TreeWalkerState TreeWalker(Insert);
878 while (!TreeWalker.done()) {
879 MachineOperand &Use = TreeWalker.pop();
880
881
882 if (.isReg())
883 continue;
884
886 assert(Use.isUse() && "explicit_uses() should only iterate over uses");
888 "explicit_uses() should only iterate over explicit operands");
890 continue;
891
892
894 if (!DefI)
895 continue;
896
897
898
900 continue;
901
902
903
905 continue;
906
907 MachineOperand *Def =
909 assert(Def != nullptr);
910
911
912
913
914
915
916
918 bool CanMove = SameBlock &&
920 !TreeWalker.isOnStack(Reg);
923
924
925
926
930 "Stackifying away frame base in unoptimized code not expected");
932 }
936 } else if (Optimize && CanMove &&
938 MFI)) {
941 } else {
942
943
944 if (!CanMove && SameBlock)
945 Commuting.maybeCommute(Insert, TreeWalker, TII);
946
947 continue;
948 }
949
950
951
952
953 auto *SubsequentDef = Insert->defs().begin();
954 auto *SubsequentUse = &Use;
955 while (SubsequentDef != Insert->defs().end() &&
956 SubsequentUse != Use.getParent()->uses().end()) {
957 if (!SubsequentDef->isReg() || !SubsequentUse->isReg())
958 break;
959 Register DefReg = SubsequentDef->getReg();
961
962 if (DefReg != UseReg ||
964 break;
966 ++SubsequentDef;
967 ++SubsequentUse;
968 }
969
970
971
972
973 if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
975
976
977
978 Commuting.reset();
979 TreeWalker.pushOperands(Insert);
980 }
981
982
983
984 if (Insert != &*MII) {
988 }
989 }
990 }
991
992
993
995 MF.getRegInfo().addLiveIn(WebAssembly::VALUE_STACK);
996 for (MachineBasicBlock &MBB : MF)
998 }
999
1000#ifndef NDEBUG
1001
1002 SmallVector<unsigned, 0> Stack;
1003 for (MachineBasicBlock &MBB : MF) {
1004 for (MachineInstr &MI : MBB) {
1005 if (MI.isDebugInstr())
1006 continue;
1007 for (MachineOperand &MO : reverse(MI.explicit_uses())) {
1008 if (!MO.isReg())
1009 continue;
1013 "Register stack pop should be paired with a push");
1014 }
1015 for (MachineOperand &MO : MI.defs()) {
1016 if (!MO.isReg())
1017 continue;
1020 Stack.push_back(MO.getReg());
1021 }
1022 }
1023
1024
1026 "Register stack pushes and pops should be balanced");
1027 }
1028#endif
1029
1031}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Register UseReg(const MachineOperand &MO)
Promote Memory to Register
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isSafeToMove(const MachineInstr &From, const MachineInstr &To)
Check if it's safe to move From down to To, checking that no physical registers are clobbered.
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)
Definition WebAssemblyRegStackify.cpp:334
static unsigned getTeeOpcode(const TargetRegisterClass *RC)
Get the appropriate tee opcode for the given register class.
Definition WebAssemblyRegStackify.cpp:520
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.
Definition WebAssemblyRegStackify.cpp:602
static void imposeStackOrdering(MachineInstr *MI)
Definition WebAssemblyRegStackify.cpp:86
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 ...
Definition WebAssemblyRegStackify.cpp:550
static void query(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
Definition WebAssemblyRegStackify.cpp:169
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
Definition WebAssemblyRegStackify.cpp:541
static void convertImplicitDefToConstZero(MachineInstr *MI, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineFunction &MF)
Definition WebAssemblyRegStackify.cpp:102
static bool hasSingleUse(unsigned Reg, MachineRegisterInfo &MRI, WebAssemblyFunctionInfo &MFI, bool Optimize, MachineInstr *Def, LiveIntervals *LIS)
Definition WebAssemblyRegStackify.cpp:289
static MachineInstr * getPrevNonDebugInst(MachineInstr *MI)
Definition WebAssemblyRegStackify.cpp:592
static bool shouldRematerialize(const MachineInstr &Def, const WebAssemblyInstrInfo *TII)
Definition WebAssemblyRegStackify.cpp:261
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...
Definition WebAssemblyRegStackify.cpp:665
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.
Definition WebAssemblyRegStackify.cpp:462
static void queryCallee(const MachineInstr &MI, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
Definition WebAssemblyRegStackify.cpp:137
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
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:
This is an important base class in LLVM.
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.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
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.
MachineInstrBundleIterator< const MachineInstr > const_iterator
Instructions::iterator instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
reverse_iterator rbegin()
MachineInstrBundleIterator< MachineInstr > iterator
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, unsigned flags=0, 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.
mop_range defs()
Returns all explicit operands that are register definitions.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
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,...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
SlotIndex - An opaque wrapper around machine indexes.
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.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const
This method commutes the operands of the given machine instruction MI.
static const unsigned CommuteAnyOperandIndex
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
void updateReg(Register Reg)
void cloneSink(MachineInstr *Insert, Register NewReg=Register(), bool CloneDef=true) const
void sink(MachineInstr *Insert)
This class is derived from MachineFunctionInfo and contains private WebAssembly-specific information ...
void stackifyVReg(MachineRegisterInfo &MRI, Register VReg)
unsigned getFrameBaseVreg() const
bool isVRegStackified(Register VReg) const
void clearFrameBaseVreg()
bool isFrameBaseVirtual() const
#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.
@ Define
Register definition.
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< DefNode * > Def
NodeAddr< InstrNode * > Instr
NodeAddr< UseNode * > Use
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.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
FunctionPass * createWebAssemblyRegStackify(CodeGenOptLevel OptLevel)
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
unsigned getUndefRegState(bool B)
DWARFExpression::Operation Op
LLVM_ABI char & LiveVariablesID
LiveVariables pass - This pass computes the set of blocks in which each variable is life and sets mac...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)