summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2017-12-04 20:36:01 +0000
committerHiroshi Yamauchi <yamauchi@google.com>2017-12-04 20:36:01 +0000
commit07f4dc367b2fe397d356114da57ed58556ad231c (patch)
tree10e5f7885aecfb7ebd5468e730ac605281a1d0e7 /include
parentca3a90446b9745705c871aa9ea941da0535a506c (diff)
Move splitIndirectCriticalEdges() to BasicBlockUtils.h.
Summary: Move splitIndirectCriticalEdges() from CodeGenPrepare to BasicBlockUtils.h so that it can be called from other places. Reviewers: davidxl Reviewed By: davidxl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40750 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319689 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h20
1 files changed, 20 insertions, 0 deletions
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index 88873a991d5..d42c11f1d9f 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -283,6 +283,26 @@ void SplitBlockAndInsertIfThenElse(Value *Cond, Instruction *SplitBefore,
Value *GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue,
BasicBlock *&IfFalse);
+// Split critical edges where the source of the edge is an indirectbr
+// instruction. This isn't always possible, but we can handle some easy cases.
+// This is useful because MI is unable to split such critical edges,
+// which means it will not be able to sink instructions along those edges.
+// This is especially painful for indirect branches with many successors, where
+// we end up having to prepare all outgoing values in the origin block.
+//
+// Our normal algorithm for splitting critical edges requires us to update
+// the outgoing edges of the edge origin block, but for an indirectbr this
+// is hard, since it would require finding and updating the block addresses
+// the indirect branch uses. But if a block only has a single indirectbr
+// predecessor, with the others being regular branches, we can do it in a
+// different way.
+// Say we have A -> D, B -> D, I -> D where only I -> D is an indirectbr.
+// We can split D into D0 and D1, where D0 contains only the PHIs from D,
+// and D1 is the D block body. We can then duplicate D0 as D0A and D0B, and
+// create the following structure:
+// A -> D0A, B -> D0A, I -> D0B, D0A -> D1, D0B -> D1
+bool SplitIndirectBrCriticalEdges(Function &F);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H