LLVM: lib/Target/X86/X86FlagsCopyLowering.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
22
53#include
54#include
55#include
56
57using namespace llvm;
58
59#define PASS_KEY "x86-flags-copy-lowering"
60#define DEBUG_TYPE PASS_KEY
61
62STATISTIC(NumCopiesEliminated, "Number of copies of EFLAGS eliminated");
63STATISTIC(NumSetCCsInserted, "Number of setCC instructions inserted");
64STATISTIC(NumTestsInserted, "Number of test instructions inserted");
65STATISTIC(NumAddsInserted, "Number of adds instructions inserted");
66STATISTIC(NumNFsConvertedTo, "Number of NF instructions converted to");
67
69
70namespace {
71
72
73using CondRegArray = std::array<Register, X86::LAST_VALID_COND + 1>;
74
76public:
78
79 StringRef getPassName() const override { return "X86 EFLAGS copy lowering"; }
80 bool runOnMachineFunction(MachineFunction &MF) override;
81 void getAnalysisUsage(AnalysisUsage &AU) const override;
82
83
84 static char ID;
85
86private:
87 MachineRegisterInfo *MRI = nullptr;
88 const X86Subtarget *Subtarget = nullptr;
89 const X86InstrInfo *TII = nullptr;
90 const TargetRegisterInfo *TRI = nullptr;
91 const TargetRegisterClass *PromoteRC = nullptr;
92 MachineDominatorTree *MDT = nullptr;
93
94 CondRegArray collectCondsInRegs(MachineBasicBlock &MBB,
96
97 Register promoteCondToReg(MachineBasicBlock &MBB,
100 std::pair<Register, bool> getCondOrInverseInReg(
105
107 const DebugLoc &Loc, MachineInstr &MI,
108 CondRegArray &CondRegs);
109 void rewriteArithmetic(MachineBasicBlock &MBB,
111 MachineInstr &MI, CondRegArray &CondRegs);
113 const DebugLoc &Loc, MachineInstr &MI, CondRegArray &CondRegs);
114};
115
116}
117
119 "X86 EFLAGS copy lowering", false, false)
122
124 return new X86FlagsCopyLoweringPass();
125}
126
127char X86FlagsCopyLoweringPass::ID = 0;
128
129void X86FlagsCopyLoweringPass::getAnalysisUsage(AnalysisUsage &AU) const {
132}
133
135 return X86::isADC(Opc) || X86::isSBB(Opc) || X86::isRCL(Opc) ||
136 X86::isRCR(Opc) || (Opc == X86::SETB_C32r || Opc == X86::SETB_C64r);
137}
138
143
145 "Split instruction must be in the split block!");
147 "Only designed to split a tail of branch instructions!");
149 "Must split on an actual jCC instruction!");
150
151
153 assert(PrevI.isBranch() && "Must split after a branch!");
155 "Must split after an actual jCC instruction!");
157 "Must only have this one terminator prior to the split!");
158
159
161
162
163
164
165 bool IsEdgeSplit =
168 assert(MI.isTerminator() &&
169 "Should only have spliced terminators!");
170 return llvm::any_of(
171 MI.operands(), [&](MachineOperand &MOp) {
172 return MOp.isMBB() && MOp.getMBB() == &UnsplitSucc;
173 });
174 }) ||
176
177 MachineBasicBlock &NewMBB = *MF.CreateMachineBasicBlock();
178
179
180
182
183
185
186
187
189 if (IsEdgeSplit || *SI != &UnsplitSucc)
191
192 if (!IsEdgeSplit)
194
195
196
197 for (MachineBasicBlock *Succ : NewMBB.successors())
198 if (Succ != &UnsplitSucc)
199 MBB.replaceSuccessor(Succ, &NewMBB);
200
201
203 "Failed to make the new block a successor!");
204
205
206 for (MachineBasicBlock *Succ : NewMBB.successors()) {
207 for (MachineInstr &MI : *Succ) {
208 if (.isPHI())
209 break;
210
213 MachineOperand &OpV = MI.getOperand(OpIdx);
214 MachineOperand &OpMBB = MI.getOperand(OpIdx + 1);
215 assert(OpMBB.isMBB() && "Block operand to a PHI is not a block!");
217 continue;
218
219
220 if (!IsEdgeSplit || Succ != &UnsplitSucc) {
221 OpMBB.setMBB(&NewMBB);
222
223
224
225 continue;
226 }
227
228
229 MI.addOperand(MF, OpV);
231 break;
232 }
233 }
234 }
235
236 return NewMBB;
237}
238
240
243 MI.findRegisterDefOperand(X86::EFLAGS, nullptr);
244 if (!FlagDef)
246
247
248
249
250
251 bool IsWithReloc =
253
256
258}
259
260bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
262 << " **********\n");
263
264 Subtarget = &MF.getSubtarget();
268 PromoteRC = &X86::GR8RegClass;
269
271
272 return false;
273
274 if (none_of(MRI->def_instructions(X86::EFLAGS), [](const MachineInstr &MI) {
275 return MI.getOpcode() == TargetOpcode::COPY;
276 }))
277 return false;
278
279
280
281
282
283
284 auto MDTWrapper = getAnalysisIfAvailable();
285 std::unique_ptr OwnedMDT;
286 if (MDTWrapper) {
287 MDT = &MDTWrapper->getDomTree();
288 } else {
289 OwnedMDT = std::make_unique(MF);
290 MDT = OwnedMDT.get();
291 }
292
293
294
295
296
297 SmallSetVector<MachineInstr *, 4> Copies;
298 ReversePostOrderTraversal<MachineFunction *> RPOT(&MF);
299 for (MachineBasicBlock *MBB : RPOT)
300 for (MachineInstr &MI : *MBB)
301 if (MI.getOpcode() == TargetOpcode::COPY &&
302 MI.getOperand(0).getReg() == X86::EFLAGS)
304
305
306
307
308
309
310
311
312
313
314
315
316
317 if (Subtarget->hasNF()) {
318 SmallSetVector<MachineInstr *, 4> RemovedCopies;
319
320 auto CopyIIt = Copies.begin(), CopyIEnd = Copies.end();
321 while (CopyIIt != CopyIEnd) {
322 auto NCopyIIt = std::next(CopyIIt);
323 SmallSetVector<MachineInstr *, 4> EvitableClobbers;
324 MachineInstr *CopyI = *CopyIIt;
325 MachineOperand &VOp = CopyI->getOperand(1);
326 MachineInstr *CopyDefI = MRI->getVRegDef(VOp.getReg());
327 MachineBasicBlock *CopyIMBB = CopyI->getParent();
328 MachineBasicBlock *CopyDefIMBB = CopyDefI->getParent();
329
330
331
332
333
334 for (auto BI = idf_begin(CopyIMBB), BE = idf_end(CopyDefIMBB); BI != BE;
335 ++BI) {
336 MachineBasicBlock *MBB = *BI;
337 for (auto I = (MBB != CopyDefIMBB)
346 continue;
347
349 goto ProcessNextCopyI;
350
352 EvitableClobbers.insert(&MI);
353 }
354 }
355
356 RemovedCopies.insert(CopyI);
359 RemovedCopies.insert(CopyDefI);
361 }
362 ++NumCopiesEliminated;
363 for (auto *Clobber : EvitableClobbers) {
365 assert(NewOpc && "evitable clobber must have a NF variant");
366 Clobber->setDesc(TII->get(NewOpc));
367 Clobber->removeOperand(
368 Clobber->findRegisterDefOperand(X86::EFLAGS, nullptr)
369 ->getOperandNo());
370 ++NumNFsConvertedTo;
371 }
372
373 for (auto BI = idf_begin(CopyIMBB), BE = idf_end(CopyDefIMBB); BI != BE;
374 ++BI)
375 if (*BI != CopyDefIMBB)
376 BI->addLiveIn(X86::EFLAGS);
377 ProcessNextCopyI:
378 CopyIIt = NCopyIIt;
379 }
380 Copies.set_subtract(RemovedCopies);
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398 for (MachineInstr *CopyI : Copies) {
399 MachineBasicBlock &MBB = *CopyI->getParent();
400
401 MachineOperand &VOp = CopyI->getOperand(1);
403 "The input to the copy for EFLAGS should always be a register!");
404 MachineInstr &CopyDefI = *MRI->getVRegDef(VOp.getReg());
405 if (CopyDefI.getOpcode() != TargetOpcode::COPY) {
406
407
408
409
410
411
412
413
414
415
416
417
418
419
421 dbgs() << "ERROR: Encountered unexpected def of an eflags copy: ";
422 CopyDefI.dump());
424 "Cannot lower EFLAGS copy unless it is defined in turn by a copy!");
425 }
426
428
429
433 ++NumCopiesEliminated;
434 });
435
436 MachineOperand &DOp = CopyI->getOperand(0);
437 assert(DOp.isDef() && "Expected register def!");
438 assert(DOp.getReg() == X86::EFLAGS && "Unexpected copy def register!");
439 if (DOp.isDead())
440 continue;
441
442 MachineBasicBlock *TestMBB = CopyDefI.getParent();
445
447
448
449
450
451
452
453
454
455
456
457
460
461
464
465
466 return &MI != CopyI &&
467 MI.findRegisterDefOperand(X86::EFLAGS, nullptr);
468 });
469 };
470 auto HasEFLAGSClobberPath = [&](MachineBasicBlock *BeginMBB,
471 MachineBasicBlock *EndMBB) {
473 "Only support paths down the dominator tree!");
474 SmallPtrSet<MachineBasicBlock *, 4> Visited;
475 SmallVector<MachineBasicBlock *, 4> Worklist;
476
477 Visited.insert(BeginMBB);
479 do {
482 if (!Visited.insert(PredMBB).second)
483 continue;
484 if (HasEFLAGSClobber(PredMBB->begin(), PredMBB->end()))
485 return true;
486
488 }
489 } while (!Worklist.empty());
490
491 return false;
492 };
494 !HasEFLAGSClobber(TestMBB->begin(), TestPos)) {
495
496
497 MachineBasicBlock *HoistMBB =
498 std::accumulate(std::next(TestMBB->pred_begin()), TestMBB->pred_end(),
500 [&](MachineBasicBlock *LHS, MachineBasicBlock *RHS) {
501 return MDT->findNearestCommonDominator(LHS, RHS);
502 });
503
504
505
506
507 if (HasEFLAGSClobberPath(HoistMBB, TestMBB))
508 break;
509
510
513 break;
514
515
516 TestMBB = HoistMBB;
518
520 }
524 [&](MachineInstr &MI) {
525 return MI.findRegisterDefOperand(X86::EFLAGS, nullptr);
526 });
527 if (DefIt.base() != TestMBB->instr_begin()) {
528 dbgs() << " Using EFLAGS defined by: ";
529 DefIt->dump();
530 } else {
531 dbgs() << " Using live-in flags for BB:\n";
532 TestMBB->dump();
533 }
534 });
535
536
537
538
539 SmallVector<MachineInstr *, 4> JmpIs;
540
541
542
543
544
545
546 CondRegArray CondRegs = collectCondsInRegs(*TestMBB, TestPos);
547
548
549
550
552 SmallPtrSet<MachineBasicBlock *, 2> VisitedBlocks;
554
555 do {
556 MachineBasicBlock &UseMBB = *Blocks.pop_back_val();
557
558
559 bool FlagsKilled = false;
560
561
562
563
564
565
566
567
568
569
574 MII != MIE;) {
575 MachineInstr &MI = *MII++;
576
577
578
579
580 if (&MI == CopyI || &MI == &CopyDefI) {
582 "Should only encounter these on the second pass over the "
583 "original block.");
584 break;
585 }
586
587 MachineOperand *FlagUse =
588 MI.findRegisterUseOperand(X86::EFLAGS, nullptr);
589 FlagsKilled = MI.modifiesRegister(X86::EFLAGS, TRI);
590
591 if (!FlagUse && FlagsKilled)
592 break;
593 else if (!FlagUse)
594 continue;
595
597
598
599 if (FlagUse->isKill())
600 FlagsKilled = true;
601
602
603
604
605
606
607
608
609
611 auto JmpIt = MI.getIterator();
612 do {
613 JmpIs.push_back(&*JmpIt);
614 ++JmpIt;
615 } while (JmpIt != UseMBB.instr_end() &&
617 break;
618 }
619
620
621 unsigned Opc = MI.getOpcode();
622 if (Opc == TargetOpcode::COPY) {
623
624 MRI->replaceRegWith(MI.getOperand(0).getReg(),
626 MI.eraseFromParent();
627 } else if (X86::isSETCC(Opc) || X86::isSETZUCC(Opc)) {
628 rewriteSetCC(*TestMBB, TestPos, TestLoc, MI, CondRegs);
630 rewriteArithmetic(*TestMBB, TestPos, TestLoc, MI, CondRegs);
631 } else {
632 rewriteMI(*TestMBB, TestPos, TestLoc, MI, CondRegs);
633 }
634
635
636 if (FlagsKilled)
637 break;
638 }
639
640
641 if (FlagsKilled)
642 continue;
643
644
645
646 for (MachineBasicBlock *SuccMBB : UseMBB.successors())
647 if (SuccMBB->isLiveIn(X86::EFLAGS) &&
649
650
651
652
653
654
655
656
657
658
659
660
661
662 if (SuccMBB == TestMBB || !MDT->dominates(TestMBB, SuccMBB)) {
665 << "ERROR: Encountered use that is not dominated by our test "
666 "basic block! Rewriting this would require inserting PHI "
667 "nodes to track the flag state across the CFG.\n\nTest "
668 "block:\n";
669 TestMBB->dump();
670 dbgs() << "Use block:\n";
671 SuccMBB->dump();
672 });
674 "Cannot lower EFLAGS copy when original copy def "
675 "does not dominate all uses.");
676 }
677
679
680
681 SuccMBB->removeLiveIn(X86::EFLAGS);
682 }
683 } while (!Blocks.empty());
684
685
686
687
688 MachineBasicBlock *LastJmpMBB = nullptr;
689 for (MachineInstr *JmpI : JmpIs) {
690
691
692 if (JmpI->getParent() == LastJmpMBB)
694 else
696
697 rewriteMI(*TestMBB, TestPos, TestLoc, *JmpI, CondRegs);
698 }
699
700
701
702 }
703
704#ifndef NDEBUG
705 for (MachineBasicBlock &MBB : MF)
706 for (MachineInstr &MI : MBB)
707 if (MI.getOpcode() == TargetOpcode::COPY &&
708 (MI.getOperand(0).getReg() == X86::EFLAGS ||
709 MI.getOperand(1).getReg() == X86::EFLAGS)) {
710 LLVM_DEBUG(dbgs() << "ERROR: Found a COPY involving EFLAGS: ";
713 }
714#endif
715
716 return true;
717}
718
719
720
721CondRegArray X86FlagsCopyLoweringPass::collectCondsInRegs(
723 CondRegArray CondRegs = {};
724
725
726 for (MachineInstr &MI :
730 MI.getOperand(0).isReg() && MI.getOperand(0).getReg().isVirtual()) {
731 assert(MI.getOperand(0).isDef() &&
732 "A non-storing SETcc should always define a register!");
733 CondRegs[Cond] = MI.getOperand(0).getReg();
734 }
735
736
737
738 if (MI.findRegisterDefOperand(X86::EFLAGS, nullptr))
739 break;
740 }
741 return CondRegs;
742}
743
744Register X86FlagsCopyLoweringPass::promoteCondToReg(
747 Register Reg = MRI->createVirtualRegister(PromoteRC);
748 auto SetI = BuildMI(TestMBB, TestPos, TestLoc, TII->get(X86::SETCCr), Reg)
750 (void)SetI;
752 ++NumSetCCsInserted;
753 return Reg;
754}
755
756std::pair<Register, bool> X86FlagsCopyLoweringPass::getCondOrInverseInReg(
761 if (!CondReg && !InvCondReg)
762 CondReg = promoteCondToReg(TestMBB, TestPos, TestLoc, Cond);
763
764 if (CondReg)
765 return {CondReg, false};
766 else
767 return {InvCondReg, true};
768}
769
770void X86FlagsCopyLoweringPass::insertTest(MachineBasicBlock &MBB,
773 auto TestI =
775 (void)TestI;
777 ++NumTestsInserted;
778}
779
780void X86FlagsCopyLoweringPass::rewriteSetCC(MachineBasicBlock &MBB,
783 MachineInstr &MI,
784 CondRegArray &CondRegs) {
786
787
788
790 if (!CondReg)
791 CondReg = promoteCondToReg(MBB, Pos, Loc, Cond);
792
793 if (X86::isSETZUCC(MI.getOpcode())) {
794
795 assert(.mayStore() && "Cannot handle memory variants");
796 assert(MI.getOperand(0).isReg() &&
797 "Cannot have a non-register defined operand to SETZUcc!");
798 Register OldReg = MI.getOperand(0).getReg();
799
800
801 MRI->clearKillFlags(OldReg);
802 for (auto &Use : MRI->use_instructions(OldReg)) {
803 assert(Use.getOpcode() == X86::INSERT_SUBREG &&
804 "SETZUCC should be only used by INSERT_SUBREG");
805 Use.getOperand(2).setReg(CondReg);
806
807 Register ZeroReg = MRI->createVirtualRegister(&X86::GR32RegClass);
808 BuildMI(*Use.getParent(), &Use, Use.getDebugLoc(), TII->get(X86::MOV32r0),
809 ZeroReg);
810 Use.getOperand(1).setReg(ZeroReg);
811 }
812 MI.eraseFromParent();
813 return;
814 }
815
816
817
818 if (.mayStore()) {
819 assert(MI.getOperand(0).isReg() &&
820 "Cannot have a non-register defined operand to SETcc!");
821 Register OldReg = MI.getOperand(0).getReg();
822
823
824 MRI->clearKillFlags(OldReg);
825 MRI->replaceRegWith(OldReg, CondReg);
826 MI.eraseFromParent();
827 return;
828 }
829
830
831 auto MIB = BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),
833
835 MIB.add(MI.getOperand(i));
836
837 MIB.addReg(CondReg);
838 MIB.setMemRefs(MI.memoperands());
839 MI.eraseFromParent();
840}
841
842void X86FlagsCopyLoweringPass::rewriteArithmetic(
844 const DebugLoc &Loc, MachineInstr &MI, CondRegArray &CondRegs) {
845
847
848
849
850 int Addend = 255;
851
852
853
854
856 if (!CondReg)
857 CondReg = promoteCondToReg(MBB, Pos, Loc, Cond);
858
859
860 Register TmpReg = MRI->createVirtualRegister(PromoteRC);
861 auto AddI =
862 BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),
863 TII->get(Subtarget->hasNDD() ? X86::ADD8ri_ND : X86::ADD8ri))
867 (void)AddI;
869 ++NumAddsInserted;
870 MI.findRegisterUseOperand(X86::EFLAGS, nullptr)->setIsKill(true);
871}
872
874#define FROM_TO(A, B) \
875 case X86::CMOV##A##_Fp32: \
876 case X86::CMOV##A##_Fp64: \
877 case X86::CMOV##A##_Fp80: \
878 return X86::COND_##B;
879
880 switch (Opc) {
881 default:
891 }
892#undef FROM_TO
893}
894
897#define CASE(A) \
898 case X86::CMOVB_##A: \
899 case X86::CMOVE_##A: \
900 case X86::CMOVP_##A: \
901 case X86::CMOVBE_##A: \
902 case X86::CMOVNB_##A: \
903 case X86::CMOVNE_##A: \
904 case X86::CMOVNP_##A: \
905 case X86::CMOVNBE_##A: \
906 return (CC == X86::COND_E) ? X86::CMOVE_##A : X86::CMOVNE_##A;
907 switch (Opc) {
908 default:
913 }
914#undef CASE
915}
916
917void X86FlagsCopyLoweringPass::rewriteMI(MachineBasicBlock &MBB,
919 const DebugLoc &Loc, MachineInstr &MI,
920 CondRegArray &CondRegs) {
921
922 bool IsImplicitCC = false;
926 IsImplicitCC = true;
927 }
930 bool Inverted;
931 std::tie(CondReg, Inverted) =
932 getCondOrInverseInReg(MBB, Pos, Loc, CC, CondRegs);
933
934
935 insertTest(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(), CondReg);
936
937
938
940 if (IsImplicitCC)
942 else
943 MI.getOperand(MI.getDesc().getNumOperands() - 1).setImm(NewCC);
944
945 MI.findRegisterUseOperand(X86::EFLAGS, nullptr)->setIsKill(true);
947}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
#define CASE(ATTRNAME, AANAME,...)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
SmallPtrSet< const BasicBlock *, 8 > VisitedBlocks
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static const HTTPClientCleanup Cleanup
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, MachineDominatorTree *MDT)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
#define FROM_TO(FROM, TO)
cl::opt< bool > X86EnableAPXForRelocation
static X86::CondCode getImplicitCondFromMI(unsigned Opc)
Definition X86FlagsCopyLowering.cpp:873
EFLAGSClobber
Definition X86FlagsCopyLowering.cpp:239
@ InevitableClobber
Definition X86FlagsCopyLowering.cpp:239
@ NoClobber
Definition X86FlagsCopyLowering.cpp:239
@ EvitableClobber
Definition X86FlagsCopyLowering.cpp:239
static unsigned getOpcodeWithCC(unsigned Opc, X86::CondCode CC)
Definition X86FlagsCopyLowering.cpp:895
static bool isArithmeticOp(unsigned Opc)
Definition X86FlagsCopyLowering.cpp:134
static EFLAGSClobber getClobberType(const MachineInstr &MI)
Definition X86FlagsCopyLowering.cpp:241
Represent the analysis usage information of a pass.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
FunctionPass class - This class is used to implement most global optimizations.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
instr_iterator instr_begin()
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
succ_iterator succ_begin()
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void dump() const
LLVM_ABI void copySuccessor(const MachineBasicBlock *Orig, succ_iterator I)
Copy a successor (and any probability info) from original block to this block's.
pred_iterator pred_begin()
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
Analysis pass which computes a MachineDominatorTree.
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.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setMBB(MachineBasicBlock *MBB)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
const X86InstrInfo * getInstrInfo() const override
const X86RegisterInfo * getRegisterInfo() const override
self_iterator getIterator()
#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.
CondCode getCondFromBranch(const MachineInstr &MI)
CondCode getCondFromMI(const MachineInstr &MI)
Return the condition code of the instruction.
CondCode GetOppositeBranchCondition(CondCode CC)
GetOppositeBranchCondition - Return the inverse of the specified cond, e.g.
CondCode getCondFromSETCC(const MachineInstr &MI)
unsigned getNFVariant(unsigned Opc)
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
static bool isAddMemInstrWithRelocation(const MachineInstr &MI)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
auto successors(const MachineBasicBlock *BB)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
FunctionPass * createX86FlagsCopyLoweringPass()
Return a pass that lowers EFLAGS copy pseudo instructions.
Definition X86FlagsCopyLowering.cpp:123
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
idf_iterator< T > idf_end(const T &G)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
idf_iterator< T > idf_begin(const T &G)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.