@@ -76,6 +76,7 @@ class Context;
76
76
class Function ;
77
77
class Instruction ;
78
78
class SelectInst ;
79
+ class BranchInst ;
79
80
class LoadInst ;
80
81
class ReturnInst ;
81
82
class StoreInst ;
@@ -179,6 +180,7 @@ class Value {
179
180
friend class User ; // For getting `Val`.
180
181
friend class Use ; // For getting `Val`.
181
182
friend class SelectInst ; // For getting `Val`.
183
+ friend class BranchInst ; // For getting `Val`.
182
184
friend class LoadInst ; // For getting `Val`.
183
185
friend class StoreInst ; // For getting `Val`.
184
186
friend class ReturnInst ; // For getting `Val`.
@@ -343,6 +345,14 @@ class User : public Value {
343
345
virtual unsigned getUseOperandNo (const Use &Use) const = 0;
344
346
friend unsigned Use::getOperandNo () const ; // For getUseOperandNo()
345
347
348
+ void swapOperandsInternal (unsigned OpIdxA, unsigned OpIdxB) {
349
+ assert (OpIdxA < getNumOperands () && " OpIdxA out of bounds!" );
350
+ assert (OpIdxB < getNumOperands () && " OpIdxB out of bounds!" );
351
+ auto UseA = getOperandUse (OpIdxA);
352
+ auto UseB = getOperandUse (OpIdxB);
353
+ UseA.swap (UseB);
354
+ }
355
+
346
356
#ifndef NDEBUG
347
357
void verifyUserOfLLVMUse (const llvm::Use &Use) const ;
348
358
#endif // NDEBUG
@@ -504,6 +514,7 @@ class Instruction : public sandboxir::User {
504
514
// / returns its topmost LLVM IR instruction.
505
515
llvm::Instruction *getTopmostLLVMInstruction () const ;
506
516
friend class SelectInst ; // For getTopmostLLVMInstruction().
517
+ friend class BranchInst ; // For getTopmostLLVMInstruction().
507
518
friend class LoadInst ; // For getTopmostLLVMInstruction().
508
519
friend class StoreInst ; // For getTopmostLLVMInstruction().
509
520
friend class ReturnInst ; // For getTopmostLLVMInstruction().
@@ -617,6 +628,100 @@ class SelectInst : public Instruction {
617
628
#endif
618
629
};
619
630
631
+ class BranchInst : public Instruction {
632
+ // / Use Context::createBranchInst(). Don't call the constructor directly.
633
+ BranchInst (llvm::BranchInst *BI, Context &Ctx)
634
+ : Instruction(ClassID::Br, Opcode::Br, BI, Ctx) {}
635
+ friend Context; // for BranchInst()
636
+ Use getOperandUseInternal (unsigned OpIdx, bool Verify) const final {
637
+ return getOperandUseDefault (OpIdx, Verify);
638
+ }
639
+ SmallVector<llvm::Instruction *, 1 > getLLVMInstrs () const final {
640
+ return {cast<llvm::Instruction>(Val)};
641
+ }
642
+
643
+ public:
644
+ unsigned getUseOperandNo (const Use &Use) const final {
645
+ return getUseOperandNoDefault (Use);
646
+ }
647
+ unsigned getNumOfIRInstrs () const final { return 1u ; }
648
+ static BranchInst *create (BasicBlock *IfTrue, Instruction *InsertBefore,
649
+ Context &Ctx);
650
+ static BranchInst *create (BasicBlock *IfTrue, BasicBlock *InsertAtEnd,
651
+ Context &Ctx);
652
+ static BranchInst *create (BasicBlock *IfTrue, BasicBlock *IfFalse,
653
+ Value *Cond, Instruction *InsertBefore,
654
+ Context &Ctx);
655
+ static BranchInst *create (BasicBlock *IfTrue, BasicBlock *IfFalse,
656
+ Value *Cond, BasicBlock *InsertAtEnd, Context &Ctx);
657
+ // / For isa/dyn_cast.
658
+ static bool classof (const Value *From);
659
+ bool isUnconditional () const {
660
+ return cast<llvm::BranchInst>(Val)->isUnconditional ();
661
+ }
662
+ bool isConditional () const {
663
+ return cast<llvm::BranchInst>(Val)->isConditional ();
664
+ }
665
+ Value *getCondition () const ;
666
+ void setCondition (Value *V) { setOperand (0 , V); }
667
+ unsigned getNumSuccessors () const { return 1 + isConditional (); }
668
+ BasicBlock *getSuccessor (unsigned SuccIdx) const ;
669
+ void setSuccessor (unsigned Idx, BasicBlock *NewSucc);
670
+ void swapSuccessors () { swapOperandsInternal (1 , 2 ); }
671
+
672
+ private:
673
+ struct LLVMBBToSBBB {
674
+ Context &Ctx;
675
+ LLVMBBToSBBB (Context &Ctx) : Ctx(Ctx) {}
676
+ BasicBlock *operator ()(llvm::BasicBlock *BB) const ;
677
+ };
678
+
679
+ struct ConstLLVMBBToSBBB {
680
+ Context &Ctx;
681
+ ConstLLVMBBToSBBB (Context &Ctx) : Ctx(Ctx) {}
682
+ const BasicBlock *operator ()(const llvm::BasicBlock *BB) const ;
683
+ };
684
+
685
+ public:
686
+ using sb_succ_op_iterator =
687
+ mapped_iterator<llvm::BranchInst::succ_op_iterator, LLVMBBToSBBB>;
688
+ iterator_range<sb_succ_op_iterator> successors () {
689
+ iterator_range<llvm::BranchInst::succ_op_iterator> LLVMRange =
690
+ cast<llvm::BranchInst>(Val)->successors ();
691
+ LLVMBBToSBBB BBMap (Ctx);
692
+ sb_succ_op_iterator MappedBegin = map_iterator (LLVMRange.begin (), BBMap);
693
+ sb_succ_op_iterator MappedEnd = map_iterator (LLVMRange.end (), BBMap);
694
+ return make_range (MappedBegin, MappedEnd);
695
+ }
696
+
697
+ using const_sb_succ_op_iterator =
698
+ mapped_iterator<llvm::BranchInst::const_succ_op_iterator,
699
+ ConstLLVMBBToSBBB>;
700
+ iterator_range<const_sb_succ_op_iterator> successors () const {
701
+ iterator_range<llvm::BranchInst::const_succ_op_iterator> ConstLLVMRange =
702
+ static_cast <const llvm::BranchInst *>(cast<llvm::BranchInst>(Val))
703
+ ->successors ();
704
+ ConstLLVMBBToSBBB ConstBBMap (Ctx);
705
+ const_sb_succ_op_iterator ConstMappedBegin =
706
+ map_iterator (ConstLLVMRange.begin (), ConstBBMap);
707
+ const_sb_succ_op_iterator ConstMappedEnd =
708
+ map_iterator (ConstLLVMRange.end (), ConstBBMap);
709
+ return make_range (ConstMappedBegin, ConstMappedEnd);
710
+ }
711
+
712
+ #ifndef NDEBUG
713
+ void verify () const final {
714
+ assert (isa<llvm::BranchInst>(Val) && " Expected BranchInst!" );
715
+ }
716
+ friend raw_ostream &operator <<(raw_ostream &OS, const BranchInst &BI) {
717
+ BI.dump (OS);
718
+ return OS;
719
+ }
720
+ void dump (raw_ostream &OS) const override ;
721
+ LLVM_DUMP_METHOD void dump () const override ;
722
+ #endif
723
+ };
724
+
620
725
class LoadInst final : public Instruction {
621
726
// / Use LoadInst::create() instead of calling the constructor.
622
727
LoadInst (llvm::LoadInst *LI, Context &Ctx)
@@ -870,6 +975,8 @@ class Context {
870
975
871
976
SelectInst *createSelectInst (llvm::SelectInst *SI);
872
977
friend SelectInst; // For createSelectInst()
978
+ BranchInst *createBranchInst (llvm::BranchInst *I);
979
+ friend BranchInst; // For createBranchInst()
873
980
LoadInst *createLoadInst (llvm::LoadInst *LI);
874
981
friend LoadInst; // For createLoadInst()
875
982
StoreInst *createStoreInst (llvm::StoreInst *SI);
0 commit comments