@@ -76,6 +76,7 @@ class Context;
7676class Function ;
7777class Instruction ;
7878class SelectInst ;
79+ class BranchInst ;
7980class LoadInst ;
8081class ReturnInst ;
8182class StoreInst ;
@@ -179,6 +180,7 @@ class Value {
179180 friend class User ; // For getting `Val`.
180181 friend class Use ; // For getting `Val`.
181182 friend class SelectInst ; // For getting `Val`.
183+ friend class BranchInst ; // For getting `Val`.
182184 friend class LoadInst ; // For getting `Val`.
183185 friend class StoreInst ; // For getting `Val`.
184186 friend class ReturnInst ; // For getting `Val`.
@@ -343,6 +345,14 @@ class User : public Value {
343345 virtual unsigned getUseOperandNo (const Use &Use) const = 0;
344346 friend unsigned Use::getOperandNo () const ; // For getUseOperandNo()
345347
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+
346356#ifndef NDEBUG
347357 void verifyUserOfLLVMUse (const llvm::Use &Use) const ;
348358#endif // NDEBUG
@@ -504,6 +514,7 @@ class Instruction : public sandboxir::User {
504514 // / returns its topmost LLVM IR instruction.
505515 llvm::Instruction *getTopmostLLVMInstruction () const ;
506516 friend class SelectInst ; // For getTopmostLLVMInstruction().
517+ friend class BranchInst ; // For getTopmostLLVMInstruction().
507518 friend class LoadInst ; // For getTopmostLLVMInstruction().
508519 friend class StoreInst ; // For getTopmostLLVMInstruction().
509520 friend class ReturnInst ; // For getTopmostLLVMInstruction().
@@ -617,6 +628,100 @@ class SelectInst : public Instruction {
617628#endif
618629};
619630
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+
620725class LoadInst final : public Instruction {
621726 // / Use LoadInst::create() instead of calling the constructor.
622727 LoadInst (llvm::LoadInst *LI, Context &Ctx)
@@ -870,6 +975,8 @@ class Context {
870975
871976 SelectInst *createSelectInst (llvm::SelectInst *SI);
872977 friend SelectInst; // For createSelectInst()
978+ BranchInst *createBranchInst (llvm::BranchInst *I);
979+ friend BranchInst; // For createBranchInst()
873980 LoadInst *createLoadInst (llvm::LoadInst *LI);
874981 friend LoadInst; // For createLoadInst()
875982 StoreInst *createStoreInst (llvm::StoreInst *SI);
0 commit comments