diff --git a/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h b/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h --- a/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h +++ b/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h @@ -16,6 +16,7 @@ namespace llvm { +class BasicBlock; class DependenceInfo; class DominatorTree; class Instruction; @@ -30,6 +31,15 @@ const DominatorTree &DT, const PostDominatorTree &PDT); +/// Return true if \p BB0 and \p BB1 are control flow equivalent. +/// Two basic blocks are control flow equivalent if when one executes, the other +/// is guaranteed to execute. This is determined using dominators and +/// post-dominators: if A dominates B and B post-dominates A then A and B are +/// control-flow equivalent. +bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1, + const DominatorTree &DT, + const PostDominatorTree &PDT); + /// Return true if \p I can be safely moved before \p InsertPoint. bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint, const DominatorTree &DT, const PostDominatorTree &PDT, diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp --- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp +++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp @@ -63,6 +63,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/CodeMoverUtils.h" using namespace llvm; @@ -593,16 +594,8 @@ const FusionCandidate &FC1) const { assert(FC0.Preheader && FC1.Preheader && "Expecting valid preheaders"); - BasicBlock *FC0EntryBlock = FC0.getEntryBlock(); - BasicBlock *FC1EntryBlock = FC1.getEntryBlock(); - - if (DT.dominates(FC0EntryBlock, FC1EntryBlock)) - return PDT.dominates(FC1EntryBlock, FC0EntryBlock); - - if (DT.dominates(FC1EntryBlock, FC0EntryBlock)) - return PDT.dominates(FC0EntryBlock, FC1EntryBlock); - - return false; + return ::isControlFlowEquivalent(*FC0.getEntryBlock(), *FC1.getEntryBlock(), + DT, PDT); } /// Iterate over all loops in the given loop set and identify the loops that diff --git a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp --- a/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp +++ b/llvm/lib/Transforms/Utils/CodeMoverUtils.cpp @@ -33,10 +33,14 @@ bool llvm::isControlFlowEquivalent(const Instruction &I0, const Instruction &I1, const DominatorTree &DT, const PostDominatorTree &PDT) { - const BasicBlock *BB0 = I0.getParent(); - const BasicBlock *BB1 = I1.getParent(); - return ((DT.dominates(BB0, BB1) && PDT.dominates(BB1, BB0)) || - (PDT.dominates(BB0, BB1) && DT.dominates(BB1, BB0))); + return isControlFlowEquivalent(*I0.getParent(), *I1.getParent(), DT, PDT); +} + +bool llvm::isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1, + const DominatorTree &DT, + const PostDominatorTree &PDT) { + return ((DT.dominates(&BB0, &BB1) && PDT.dominates(&BB1, &BB0)) || + (PDT.dominates(&BB0, &BB1) && DT.dominates(&BB1, &BB0))); } static bool reportInvalidCandidate(const Instruction &I,