Index: llvm/include/llvm/Transforms/Utils/Cloning.h =================================================================== --- llvm/include/llvm/Transforms/Utils/Cloning.h +++ llvm/include/llvm/Transforms/Utils/Cloning.h @@ -233,6 +233,17 @@ void remapInstructionsInBlocks(const SmallVectorImpl &Blocks, ValueToValueMapTy &VMap); +/// Returns true of the region formed by [Entry, Exit] is a +/// single-entry-single-exit (SESE) region. All the traces from \p Entry to +/// \p Exit should be dominated by \p Entry and post-dominated by \p Exit. +bool isSingleEntrySingleExit(const BasicBlock *Entry, const BasicBlock *Exit, + DominatorTree *DT, DominatorTree *PDT); + +/// Returns true of the region formed by [Entry, Exit] is a +/// single-entry-multiple-exit (SEME) region. All the traces from \p Entry +/// which leads to the \p Exit are analyzed. +bool isSingleEntryMultipleExit(const BasicBlock *Entry, const BasicBlock *Exit, + DominatorTree *DT); } // End llvm namespace #endif Index: llvm/lib/Transforms/Utils/CloneFunction.cpp =================================================================== --- llvm/lib/Transforms/Utils/CloneFunction.cpp +++ llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -747,3 +747,44 @@ return NewLoop; } + +bool llvm::isSingleEntrySingleExit(const BasicBlock *Entry, + const BasicBlock *Exit, + DominatorTree *DT, DominatorTree *PDT) { + if (!DT->dominates(Entry, Exit)) + return false; + + if (!PDT->dominates(Exit, Entry)) + return false; + + for (auto I = df_begin(Entry), E = df_end(Entry); I != E;) { + if (*I == Exit) { + I.skipChildren(); + continue; + } + if (!DT->dominates(Entry, *I)) + return false; + ++I; + } + return true; +} + +bool llvm::isSingleEntryMultipleExit(const BasicBlock *Entry, + const BasicBlock *Exit, + DominatorTree *DT) { + if (!DT->dominates(Entry, Exit)) + return false; + + for (auto I = idf_begin(Exit), E = idf_end(Exit); I != E;) { + if (*I == Entry) { + I.skipChildren(); + continue; + } + + if (!DT->dominates(Entry, *I)) + return false; + + ++I; + } + return true; +}