2002-08-03 00:43:03 +08:00
|
|
|
//===- Dominators.cpp - Dominator Calculation -----------------------------===//
|
2005-04-22 07:48:37 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-30 04:36:04 +08:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-22 07:48:37 +08:00
|
|
|
//
|
2003-10-21 03:43:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2001-07-02 13:46:38 +08:00
|
|
|
//
|
2002-08-03 00:43:03 +08:00
|
|
|
// This file implements simple dominator construction algorithms for finding
|
|
|
|
// forward dominators. Postdominators are available in libanalysis, but are not
|
|
|
|
// included in libvmcore, because it's not needed. Forward dominators are
|
|
|
|
// needed to support the Verifier pass.
|
2001-07-02 13:46:38 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-01-13 17:26:24 +08:00
|
|
|
#include "llvm/IR/Dominators.h"
|
2004-09-02 06:55:40 +08:00
|
|
|
#include "llvm/ADT/DepthFirstIterator.h"
|
2007-03-28 04:50:46 +08:00
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
2014-03-04 19:45:46 +08:00
|
|
|
#include "llvm/IR/CFG.h"
|
2018-01-13 05:06:48 +08:00
|
|
|
#include "llvm/IR/Constants.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Instructions.h"
|
2015-01-14 18:19:28 +08:00
|
|
|
#include "llvm/IR/PassManager.h"
|
2009-09-28 08:27:48 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2014-01-13 18:52:56 +08:00
|
|
|
#include "llvm/Support/GenericDomTreeConstruction.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2004-06-05 08:24:59 +08:00
|
|
|
#include <algorithm>
|
2003-11-22 04:23:48 +08:00
|
|
|
using namespace llvm;
|
2003-11-12 06:41:34 +08:00
|
|
|
|
2017-01-24 13:52:07 +08:00
|
|
|
bool llvm::VerifyDomInfo = false;
|
2017-12-01 08:53:10 +08:00
|
|
|
static cl::opt<bool, true>
|
|
|
|
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo), cl::Hidden,
|
|
|
|
cl::desc("Verify dominator info (time consuming)"));
|
2009-09-28 08:27:48 +08:00
|
|
|
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
#ifdef EXPENSIVE_CHECKS
|
|
|
|
static constexpr bool ExpensiveChecksEnabled = true;
|
|
|
|
#else
|
|
|
|
static constexpr bool ExpensiveChecksEnabled = false;
|
|
|
|
#endif
|
|
|
|
|
2012-08-16 23:09:43 +08:00
|
|
|
bool BasicBlockEdge::isSingleEdge() const {
|
|
|
|
const TerminatorInst *TI = Start->getTerminator();
|
|
|
|
unsigned NumEdgesToEnd = 0;
|
|
|
|
for (unsigned int i = 0, n = TI->getNumSuccessors(); i < n; ++i) {
|
|
|
|
if (TI->getSuccessor(i) == End)
|
|
|
|
++NumEdgesToEnd;
|
|
|
|
if (NumEdgesToEnd >= 2)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
assert(NumEdgesToEnd == 1);
|
|
|
|
return true;
|
2012-08-10 22:05:55 +08:00
|
|
|
}
|
|
|
|
|
2003-12-07 08:38:08 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2007-04-15 16:47:27 +08:00
|
|
|
// DominatorTree Implementation
|
2003-12-07 08:38:08 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2007-09-24 05:31:44 +08:00
|
|
|
// Provide public access to DominatorTree information. Implementation details
|
2014-01-13 18:52:56 +08:00
|
|
|
// can be found in Dominators.h, GenericDomTree.h, and
|
|
|
|
// GenericDomTreeConstruction.h.
|
2003-12-07 08:38:08 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-07-14 01:21:31 +08:00
|
|
|
template class llvm::DomTreeNodeBase<BasicBlock>;
|
2017-07-15 02:26:09 +08:00
|
|
|
template class llvm::DominatorTreeBase<BasicBlock, false>; // DomTreeBase
|
|
|
|
template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
|
2007-10-17 03:59:25 +08:00
|
|
|
|
2017-08-17 00:12:52 +08:00
|
|
|
template struct llvm::DomTreeBuilder::Update<BasicBlock *>;
|
|
|
|
|
2017-07-27 02:07:40 +08:00
|
|
|
template void llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBDomTree>(
|
|
|
|
DomTreeBuilder::BBDomTree &DT);
|
|
|
|
template void llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBPostDomTree>(
|
|
|
|
DomTreeBuilder::BBPostDomTree &DT);
|
2017-07-14 04:45:32 +08:00
|
|
|
|
2017-07-15 05:17:33 +08:00
|
|
|
template void llvm::DomTreeBuilder::InsertEdge<DomTreeBuilder::BBDomTree>(
|
|
|
|
DomTreeBuilder::BBDomTree &DT, BasicBlock *From, BasicBlock *To);
|
|
|
|
template void llvm::DomTreeBuilder::InsertEdge<DomTreeBuilder::BBPostDomTree>(
|
|
|
|
DomTreeBuilder::BBPostDomTree &DT, BasicBlock *From, BasicBlock *To);
|
|
|
|
|
2017-07-15 05:58:53 +08:00
|
|
|
template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBDomTree>(
|
|
|
|
DomTreeBuilder::BBDomTree &DT, BasicBlock *From, BasicBlock *To);
|
|
|
|
template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBPostDomTree>(
|
|
|
|
DomTreeBuilder::BBPostDomTree &DT, BasicBlock *From, BasicBlock *To);
|
|
|
|
|
2017-08-17 00:12:52 +08:00
|
|
|
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBDomTree>(
|
|
|
|
DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBUpdates);
|
|
|
|
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBPostDomTree>(
|
|
|
|
DomTreeBuilder::BBPostDomTree &DT, DomTreeBuilder::BBUpdates);
|
|
|
|
|
2017-07-14 04:45:32 +08:00
|
|
|
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
const DomTreeBuilder::BBDomTree &DT,
|
|
|
|
DomTreeBuilder::BBDomTree::VerificationLevel VL);
|
2017-07-15 02:26:09 +08:00
|
|
|
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBPostDomTree>(
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
const DomTreeBuilder::BBPostDomTree &DT,
|
|
|
|
DomTreeBuilder::BBPostDomTree::VerificationLevel VL);
|
2014-02-15 06:36:16 +08:00
|
|
|
|
2017-01-15 14:32:49 +08:00
|
|
|
bool DominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
|
|
|
|
FunctionAnalysisManager::Invalidator &) {
|
|
|
|
// Check whether the analysis, all analyses on functions, or the function's
|
|
|
|
// CFG have been preserved.
|
|
|
|
auto PAC = PA.getChecker<DominatorTreeAnalysis>();
|
|
|
|
return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
|
|
|
|
PAC.preservedSet<CFGAnalyses>());
|
|
|
|
}
|
|
|
|
|
2012-02-26 10:19:19 +08:00
|
|
|
// dominates - Return true if Def dominates a use in User. This performs
|
|
|
|
// the special checks necessary if Def and User are in the same basic block.
|
|
|
|
// Note that Def doesn't dominate a use in Def itself!
|
|
|
|
bool DominatorTree::dominates(const Instruction *Def,
|
|
|
|
const Instruction *User) const {
|
|
|
|
const BasicBlock *UseBB = User->getParent();
|
|
|
|
const BasicBlock *DefBB = Def->getParent();
|
|
|
|
|
2012-03-31 00:46:21 +08:00
|
|
|
// Any unreachable use is dominated, even if Def == User.
|
|
|
|
if (!isReachableFromEntry(UseBB))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Unreachable definitions don't dominate anything.
|
|
|
|
if (!isReachableFromEntry(DefBB))
|
|
|
|
return false;
|
2012-02-26 10:19:19 +08:00
|
|
|
|
|
|
|
// An instruction doesn't dominate a use in itself.
|
|
|
|
if (Def == User)
|
|
|
|
return false;
|
|
|
|
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
// The value defined by an invoke dominates an instruction only if it
|
|
|
|
// dominates every instruction in UseBB.
|
|
|
|
// A PHI is dominated only if the instruction dominates every possible use in
|
|
|
|
// the UseBB.
|
|
|
|
if (isa<InvokeInst>(Def) || isa<PHINode>(User))
|
2012-02-26 10:19:19 +08:00
|
|
|
return dominates(Def, UseBB);
|
|
|
|
|
|
|
|
if (DefBB != UseBB)
|
|
|
|
return dominates(DefBB, UseBB);
|
2012-02-19 03:46:02 +08:00
|
|
|
|
2012-02-26 10:19:19 +08:00
|
|
|
// Loop through the basic block until we find Def or User.
|
|
|
|
BasicBlock::const_iterator I = DefBB->begin();
|
|
|
|
for (; &*I != Def && &*I != User; ++I)
|
|
|
|
/*empty*/;
|
|
|
|
|
|
|
|
return &*I == Def;
|
|
|
|
}
|
2012-02-19 03:46:02 +08:00
|
|
|
|
2012-02-26 10:19:19 +08:00
|
|
|
// true if Def would dominate a use in any instruction in UseBB.
|
|
|
|
// note that dominates(Def, Def->getParent()) is false.
|
|
|
|
bool DominatorTree::dominates(const Instruction *Def,
|
|
|
|
const BasicBlock *UseBB) const {
|
|
|
|
const BasicBlock *DefBB = Def->getParent();
|
2012-02-19 03:46:02 +08:00
|
|
|
|
2012-03-31 00:46:21 +08:00
|
|
|
// Any unreachable use is dominated, even if DefBB == UseBB.
|
|
|
|
if (!isReachableFromEntry(UseBB))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Unreachable definitions don't dominate anything.
|
|
|
|
if (!isReachableFromEntry(DefBB))
|
|
|
|
return false;
|
2012-02-26 10:19:19 +08:00
|
|
|
|
|
|
|
if (DefBB == UseBB)
|
2009-09-22 06:30:50 +08:00
|
|
|
return false;
|
2012-02-19 03:46:02 +08:00
|
|
|
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
// Invoke results are only usable in the normal destination, not in the
|
|
|
|
// exceptional destination.
|
2015-08-15 10:46:08 +08:00
|
|
|
if (const auto *II = dyn_cast<InvokeInst>(Def)) {
|
|
|
|
BasicBlock *NormalDest = II->getNormalDest();
|
|
|
|
BasicBlockEdge E(DefBB, NormalDest);
|
|
|
|
return dominates(E, UseBB);
|
|
|
|
}
|
2012-02-19 03:46:02 +08:00
|
|
|
|
2015-08-15 10:46:08 +08:00
|
|
|
return dominates(DefBB, UseBB);
|
2012-08-08 01:30:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool DominatorTree::dominates(const BasicBlockEdge &BBE,
|
|
|
|
const BasicBlock *UseBB) const {
|
|
|
|
// If the BB the edge ends in doesn't dominate the use BB, then the
|
|
|
|
// edge also doesn't.
|
|
|
|
const BasicBlock *Start = BBE.getStart();
|
|
|
|
const BasicBlock *End = BBE.getEnd();
|
|
|
|
if (!dominates(End, UseBB))
|
2012-02-26 10:19:19 +08:00
|
|
|
return false;
|
|
|
|
|
2012-08-08 01:30:46 +08:00
|
|
|
// Simple case: if the end BB has a single predecessor, the fact that it
|
|
|
|
// dominates the use block implies that the edge also does.
|
|
|
|
if (End->getSinglePredecessor())
|
2012-02-26 10:19:19 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// The normal edge from the invoke is critical. Conceptually, what we would
|
|
|
|
// like to do is split it and check if the new block dominates the use.
|
|
|
|
// With X being the new block, the graph would look like:
|
|
|
|
//
|
|
|
|
// DefBB
|
|
|
|
// /\ . .
|
|
|
|
// / \ . .
|
|
|
|
// / \ . .
|
|
|
|
// / \ | |
|
|
|
|
// A X B C
|
|
|
|
// | \ | /
|
|
|
|
// . \|/
|
|
|
|
// . NormalDest
|
|
|
|
// .
|
|
|
|
//
|
2012-09-27 18:14:43 +08:00
|
|
|
// Given the definition of dominance, NormalDest is dominated by X iff X
|
2012-02-26 10:19:19 +08:00
|
|
|
// dominates all of NormalDest's predecessors (X, B, C in the example). X
|
|
|
|
// trivially dominates itself, so we only have to find if it dominates the
|
|
|
|
// other predecessors. Since the only way out of X is via NormalDest, X can
|
|
|
|
// only properly dominate a node if NormalDest dominates that node too.
|
2017-06-06 00:27:09 +08:00
|
|
|
int IsDuplicateEdge = 0;
|
2014-07-22 01:06:51 +08:00
|
|
|
for (const_pred_iterator PI = pred_begin(End), E = pred_end(End);
|
|
|
|
PI != E; ++PI) {
|
|
|
|
const BasicBlock *BB = *PI;
|
2017-06-06 00:27:09 +08:00
|
|
|
if (BB == Start) {
|
|
|
|
// If there are multiple edges between Start and End, by definition they
|
|
|
|
// can't dominate anything.
|
|
|
|
if (IsDuplicateEdge++)
|
|
|
|
return false;
|
2012-02-26 10:19:19 +08:00
|
|
|
continue;
|
2017-06-06 00:27:09 +08:00
|
|
|
}
|
2012-02-26 10:19:19 +08:00
|
|
|
|
2012-08-08 01:30:46 +08:00
|
|
|
if (!dominates(End, BB))
|
2012-02-26 10:19:19 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2009-09-22 06:30:50 +08:00
|
|
|
}
|
2012-04-13 07:31:46 +08:00
|
|
|
|
2014-01-13 21:07:17 +08:00
|
|
|
bool DominatorTree::dominates(const BasicBlockEdge &BBE, const Use &U) const {
|
2012-08-08 01:30:46 +08:00
|
|
|
Instruction *UserInst = cast<Instruction>(U.getUser());
|
|
|
|
// A PHI in the end of the edge is dominated by it.
|
|
|
|
PHINode *PN = dyn_cast<PHINode>(UserInst);
|
|
|
|
if (PN && PN->getParent() == BBE.getEnd() &&
|
|
|
|
PN->getIncomingBlock(U) == BBE.getStart())
|
|
|
|
return true;
|
2012-04-13 07:31:46 +08:00
|
|
|
|
2012-08-08 01:30:46 +08:00
|
|
|
// Otherwise use the edge-dominates-block query, which
|
|
|
|
// handles the crazy critical edge cases properly.
|
|
|
|
const BasicBlock *UseBB;
|
|
|
|
if (PN)
|
|
|
|
UseBB = PN->getIncomingBlock(U);
|
|
|
|
else
|
|
|
|
UseBB = UserInst->getParent();
|
|
|
|
return dominates(BBE, UseBB);
|
|
|
|
}
|
2012-04-13 07:31:46 +08:00
|
|
|
|
2014-01-13 21:07:17 +08:00
|
|
|
bool DominatorTree::dominates(const Instruction *Def, const Use &U) const {
|
2012-08-08 01:30:46 +08:00
|
|
|
Instruction *UserInst = cast<Instruction>(U.getUser());
|
2012-04-13 07:31:46 +08:00
|
|
|
const BasicBlock *DefBB = Def->getParent();
|
|
|
|
|
|
|
|
// Determine the block in which the use happens. PHI nodes use
|
|
|
|
// their operands on edges; simulate this by thinking of the use
|
|
|
|
// happening at the end of the predecessor block.
|
|
|
|
const BasicBlock *UseBB;
|
|
|
|
if (PHINode *PN = dyn_cast<PHINode>(UserInst))
|
|
|
|
UseBB = PN->getIncomingBlock(U);
|
|
|
|
else
|
|
|
|
UseBB = UserInst->getParent();
|
|
|
|
|
|
|
|
// Any unreachable use is dominated, even if Def == User.
|
|
|
|
if (!isReachableFromEntry(UseBB))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Unreachable definitions don't dominate anything.
|
|
|
|
if (!isReachableFromEntry(DefBB))
|
|
|
|
return false;
|
|
|
|
|
[IR] Reformulate LLVM's EH funclet IR
While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
but they are difficult to explain to others, even to seasoned LLVM
experts.
- catchendpad and cleanupendpad are optimization barriers. They cannot
be split and force all potentially throwing call-sites to be invokes.
This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
It is unsplittable, starts a funclet, and has control flow to other
funclets.
- The nesting relationship between funclets is currently a property of
control flow edges. Because of this, we are forced to carefully
analyze the flow graph to see if there might potentially exist illegal
nesting among funclets. While we have logic to clone funclets when
they are illegally nested, it would be nicer if we had a
representation which forbade them upfront.
Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
flow, just a bunch of simple operands; catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad. Their presence can be inferred
implicitly using coloring information.
N.B. The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for. An expert should take a
look to make sure the results are reasonable.
Reviewers: rnk, JosephTremoulet, andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D15139
llvm-svn: 255422
2015-12-12 13:38:55 +08:00
|
|
|
// Invoke instructions define their return values on the edges to their normal
|
|
|
|
// successors, so we have to handle them specially.
|
2012-04-13 07:31:46 +08:00
|
|
|
// Among other things, this means they don't dominate anything in
|
|
|
|
// their own block, except possibly a phi, so we don't need to
|
|
|
|
// walk the block in any case.
|
|
|
|
if (const InvokeInst *II = dyn_cast<InvokeInst>(Def)) {
|
2012-08-08 01:30:46 +08:00
|
|
|
BasicBlock *NormalDest = II->getNormalDest();
|
|
|
|
BasicBlockEdge E(DefBB, NormalDest);
|
|
|
|
return dominates(E, U);
|
2012-04-13 07:31:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If the def and use are in different blocks, do a simple CFG dominator
|
|
|
|
// tree query.
|
|
|
|
if (DefBB != UseBB)
|
|
|
|
return dominates(DefBB, UseBB);
|
|
|
|
|
|
|
|
// Ok, def and use are in the same block. If the def is an invoke, it
|
|
|
|
// doesn't dominate anything in the block. If it's a PHI, it dominates
|
|
|
|
// everything in the block.
|
|
|
|
if (isa<PHINode>(UserInst))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise, just loop through the basic block until we find Def or User.
|
|
|
|
BasicBlock::const_iterator I = DefBB->begin();
|
|
|
|
for (; &*I != Def && &*I != UserInst; ++I)
|
|
|
|
/*empty*/;
|
|
|
|
|
|
|
|
return &*I != UserInst;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DominatorTree::isReachableFromEntry(const Use &U) const {
|
|
|
|
Instruction *I = dyn_cast<Instruction>(U.getUser());
|
|
|
|
|
|
|
|
// ConstantExprs aren't really reachable from the entry block, but they
|
|
|
|
// don't need to be treated like unreachable code either.
|
|
|
|
if (!I) return true;
|
|
|
|
|
|
|
|
// PHI nodes use their operands on their incoming edges.
|
|
|
|
if (PHINode *PN = dyn_cast<PHINode>(I))
|
|
|
|
return isReachableFromEntry(PN->getIncomingBlock(U));
|
|
|
|
|
|
|
|
// Everything else uses their operands in their own block.
|
|
|
|
return isReachableFromEntry(I->getParent());
|
|
|
|
}
|
2014-01-13 21:07:17 +08:00
|
|
|
|
|
|
|
void DominatorTree::verifyDomTree() const {
|
2017-07-01 00:33:04 +08:00
|
|
|
// Perform the expensive checks only when VerifyDomInfo is set.
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
VerificationLevel VL = VerificationLevel::Fast;
|
|
|
|
if (VerifyDomInfo)
|
|
|
|
VL = VerificationLevel::Full;
|
|
|
|
else if (ExpensiveChecksEnabled)
|
|
|
|
VL = VerificationLevel::Basic;
|
2014-01-13 21:07:17 +08:00
|
|
|
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
if (!verify(VL)) {
|
|
|
|
errs() << "\n~~~~~~~~~~~\n\t\tDomTree verification failed!\n~~~~~~~~~~~\n";
|
2017-08-17 00:12:52 +08:00
|
|
|
errs() << "\nCFG:\n";
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
getRoot()->getParent()->print(errs());
|
2017-08-17 00:12:52 +08:00
|
|
|
errs().flush();
|
2014-01-13 21:07:17 +08:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-14 18:19:28 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DominatorTreeAnalysis and related pass implementations
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This implements the DominatorTreeAnalysis which is used with the new pass
|
|
|
|
// manager. It also implements some methods from utility passes.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-06-17 08:11:01 +08:00
|
|
|
DominatorTree DominatorTreeAnalysis::run(Function &F,
|
2016-08-09 08:28:15 +08:00
|
|
|
FunctionAnalysisManager &) {
|
2015-01-14 18:19:28 +08:00
|
|
|
DominatorTree DT;
|
|
|
|
DT.recalculate(F);
|
|
|
|
return DT;
|
|
|
|
}
|
|
|
|
|
2016-11-24 01:53:26 +08:00
|
|
|
AnalysisKey DominatorTreeAnalysis::Key;
|
2016-02-29 01:17:00 +08:00
|
|
|
|
2015-01-14 18:19:28 +08:00
|
|
|
DominatorTreePrinterPass::DominatorTreePrinterPass(raw_ostream &OS) : OS(OS) {}
|
|
|
|
|
|
|
|
PreservedAnalyses DominatorTreePrinterPass::run(Function &F,
|
2016-03-11 19:05:24 +08:00
|
|
|
FunctionAnalysisManager &AM) {
|
2015-01-14 18:19:28 +08:00
|
|
|
OS << "DominatorTree for function: " << F.getName() << "\n";
|
2016-03-11 19:05:24 +08:00
|
|
|
AM.getResult<DominatorTreeAnalysis>(F).print(OS);
|
2015-01-14 18:19:28 +08:00
|
|
|
|
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
|
|
|
|
|
|
|
PreservedAnalyses DominatorTreeVerifierPass::run(Function &F,
|
2016-03-11 19:05:24 +08:00
|
|
|
FunctionAnalysisManager &AM) {
|
|
|
|
AM.getResult<DominatorTreeAnalysis>(F).verifyDomTree();
|
2015-01-14 18:19:28 +08:00
|
|
|
|
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
|
|
|
|
2014-01-13 21:07:17 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DominatorTreeWrapperPass Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2015-01-14 18:19:28 +08:00
|
|
|
// The implementation details of the wrapper pass that holds a DominatorTree
|
|
|
|
// suitable for use with the legacy pass manager.
|
2014-01-13 21:07:17 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
char DominatorTreeWrapperPass::ID = 0;
|
|
|
|
INITIALIZE_PASS(DominatorTreeWrapperPass, "domtree",
|
|
|
|
"Dominator Tree Construction", true, true)
|
|
|
|
|
|
|
|
bool DominatorTreeWrapperPass::runOnFunction(Function &F) {
|
|
|
|
DT.recalculate(F);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-05-06 16:18:41 +08:00
|
|
|
void DominatorTreeWrapperPass::verifyAnalysis() const {
|
[Dominators] Introduce DomTree verification levels
Summary:
Currently, there are 2 ways to verify a DomTree:
* `DT.verify()` -- runs full tree verification and checks all the properties and gives a reason why the tree is incorrect. This is run by when EXPENSIVE_CHECKS are enabled or when `-verify-dom-info` flag is set.
* `DT.verifyDominatorTree()` -- constructs a fresh tree and compares it against the old one. This does not check any other tree properties (DFS number, levels), nor ensures that the construction algorithm is correct. Used by some passes inside assertions.
This patch introduces DomTree verification levels, that try to close the gape between the two ways of checking trees by introducing 3 verification levels:
- Full -- checks all properties, but can be slow (O(N^3)). Used when manually requested (e.g. `assert(DT.verify())`) or when `-verify-dom-info` is set.
- Basic -- checks all properties except the sibling property, and compares the current tree with a freshly constructed one instead. This should catch almost all errors, but does not guarantee that the construction algorithm is correct. Used when EXPENSIVE checks are enabled.
- Fast -- checks only basic properties (reachablility, dfs numbers, levels, roots), and compares with a fresh tree. This is meant to replace the legacy `DT.verifyDominatorTree()` and in my tests doesn't cause any noticeable performance impact even in the most pessimistic examples.
When used to verify dom tree wrapper pass analysis on sqlite3, the 3 new levels make `opt -O3` take the following amount of time on my machine:
- no verification: 8.3s
- `DT.verify(VerificationLevel::Fast)`: 10.1s
- `DT.verify(VerificationLevel::Basic)`: 44.8s
- `DT.verify(VerificationLevel::Full)`: 1m 46.2s
(and the previous `DT.verifyDominatorTree()` is within the noise of the Fast level)
This patch makes `DT.verifyDominatorTree()` pick between the 3 verification levels depending on EXPENSIVE_CHECKS and `-verify-dom-info`.
Reviewers: dberlin, brzycki, davide, grosser, dmgreen
Reviewed By: dberlin, brzycki
Subscribers: MatzeB, llvm-commits
Differential Revision: https://reviews.llvm.org/D42337
llvm-svn: 323298
2018-01-24 10:40:35 +08:00
|
|
|
if (ExpensiveChecksEnabled || VerifyDomInfo)
|
|
|
|
DT.verifyDomTree();
|
2015-05-06 16:18:41 +08:00
|
|
|
}
|
2014-01-13 21:07:17 +08:00
|
|
|
|
|
|
|
void DominatorTreeWrapperPass::print(raw_ostream &OS, const Module *) const {
|
|
|
|
DT.print(OS);
|
|
|
|
}
|
|
|
|
|
2018-01-13 05:06:48 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// DeferredDominance Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The implementation details of the DeferredDominance class which allows
|
|
|
|
// one to queue updates to a DominatorTree.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// \brief Queues multiple updates and discards duplicates.
|
|
|
|
void DeferredDominance::applyUpdates(
|
|
|
|
ArrayRef<DominatorTree::UpdateType> Updates) {
|
|
|
|
SmallVector<DominatorTree::UpdateType, 8> Seen;
|
|
|
|
for (auto U : Updates)
|
|
|
|
// Avoid duplicates to applyUpdate() to save on analysis.
|
|
|
|
if (std::none_of(Seen.begin(), Seen.end(),
|
|
|
|
[U](DominatorTree::UpdateType S) { return S == U; })) {
|
|
|
|
Seen.push_back(U);
|
|
|
|
applyUpdate(U.getKind(), U.getFrom(), U.getTo());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Helper method for a single edge insertion. It's almost always better
|
|
|
|
/// to batch updates and call applyUpdates to quickly remove duplicate edges.
|
|
|
|
/// This is best used when there is only a single insertion needed to update
|
|
|
|
/// Dominators.
|
|
|
|
void DeferredDominance::insertEdge(BasicBlock *From, BasicBlock *To) {
|
|
|
|
applyUpdate(DominatorTree::Insert, From, To);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Helper method for a single edge deletion. It's almost always better
|
|
|
|
/// to batch updates and call applyUpdates to quickly remove duplicate edges.
|
|
|
|
/// This is best used when there is only a single deletion needed to update
|
|
|
|
/// Dominators.
|
|
|
|
void DeferredDominance::deleteEdge(BasicBlock *From, BasicBlock *To) {
|
|
|
|
applyUpdate(DominatorTree::Delete, From, To);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Delays the deletion of a basic block until a flush() event.
|
|
|
|
void DeferredDominance::deleteBB(BasicBlock *DelBB) {
|
|
|
|
assert(DelBB && "Invalid push_back of nullptr DelBB.");
|
|
|
|
assert(pred_empty(DelBB) && "DelBB has one or more predecessors.");
|
|
|
|
// DelBB is unreachable and all its instructions are dead.
|
|
|
|
while (!DelBB->empty()) {
|
|
|
|
Instruction &I = DelBB->back();
|
|
|
|
// Replace used instructions with an arbitrary value (undef).
|
|
|
|
if (!I.use_empty())
|
|
|
|
I.replaceAllUsesWith(llvm::UndefValue::get(I.getType()));
|
|
|
|
DelBB->getInstList().pop_back();
|
|
|
|
}
|
|
|
|
// Make sure DelBB has a valid terminator instruction. As long as DelBB is a
|
|
|
|
// Child of Function F it must contain valid IR.
|
|
|
|
new UnreachableInst(DelBB->getContext(), DelBB);
|
|
|
|
DeletedBBs.insert(DelBB);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Returns true if DelBB is awaiting deletion at a flush() event.
|
|
|
|
bool DeferredDominance::pendingDeletedBB(BasicBlock *DelBB) {
|
|
|
|
if (DeletedBBs.empty())
|
|
|
|
return false;
|
|
|
|
return DeletedBBs.count(DelBB) != 0;
|
|
|
|
}
|
|
|
|
|
2018-02-17 00:35:17 +08:00
|
|
|
/// \brief Returns true if pending DT updates are queued for a flush() event.
|
|
|
|
bool DeferredDominance::pending() { return !PendUpdates.empty(); }
|
|
|
|
|
2018-01-13 05:06:48 +08:00
|
|
|
/// \brief Flushes all pending updates and block deletions. Returns a
|
|
|
|
/// correct DominatorTree reference to be used by the caller for analysis.
|
|
|
|
DominatorTree &DeferredDominance::flush() {
|
|
|
|
// Updates to DT must happen before blocks are deleted below. Otherwise the
|
|
|
|
// DT traversal will encounter badref blocks and assert.
|
|
|
|
if (!PendUpdates.empty()) {
|
|
|
|
DT.applyUpdates(PendUpdates);
|
|
|
|
PendUpdates.clear();
|
|
|
|
}
|
|
|
|
flushDelBB();
|
|
|
|
return DT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Drops all internal state and forces a (slow) recalculation of the
|
|
|
|
/// DominatorTree based on the current state of the LLVM IR in F. This should
|
|
|
|
/// only be used in corner cases such as the Entry block of F being deleted.
|
|
|
|
void DeferredDominance::recalculate(Function &F) {
|
|
|
|
// flushDelBB must be flushed before the recalculation. The state of the IR
|
|
|
|
// must be consistent before the DT traversal algorithm determines the
|
|
|
|
// actual DT.
|
|
|
|
if (flushDelBB() || !PendUpdates.empty()) {
|
|
|
|
DT.recalculate(F);
|
|
|
|
PendUpdates.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Debug method to help view the state of pending updates.
|
|
|
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
|
|
LLVM_DUMP_METHOD void DeferredDominance::dump() const {
|
|
|
|
raw_ostream &OS = llvm::dbgs();
|
|
|
|
OS << "PendUpdates:\n";
|
|
|
|
int I = 0;
|
|
|
|
for (auto U : PendUpdates) {
|
|
|
|
OS << " " << I << " : ";
|
|
|
|
++I;
|
|
|
|
if (U.getKind() == DominatorTree::Insert)
|
|
|
|
OS << "Insert, ";
|
|
|
|
else
|
|
|
|
OS << "Delete, ";
|
|
|
|
BasicBlock *From = U.getFrom();
|
|
|
|
if (From) {
|
|
|
|
auto S = From->getName();
|
|
|
|
if (!From->hasName())
|
|
|
|
S = "(no name)";
|
|
|
|
OS << S << "(" << From << "), ";
|
|
|
|
} else {
|
|
|
|
OS << "(badref), ";
|
|
|
|
}
|
|
|
|
BasicBlock *To = U.getTo();
|
|
|
|
if (To) {
|
|
|
|
auto S = To->getName();
|
|
|
|
if (!To->hasName())
|
|
|
|
S = "(no_name)";
|
|
|
|
OS << S << "(" << To << ")\n";
|
|
|
|
} else {
|
|
|
|
OS << "(badref)\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OS << "DeletedBBs:\n";
|
|
|
|
I = 0;
|
|
|
|
for (auto BB : DeletedBBs) {
|
|
|
|
OS << " " << I << " : ";
|
|
|
|
++I;
|
|
|
|
if (BB->hasName())
|
|
|
|
OS << BB->getName() << "(";
|
|
|
|
else
|
|
|
|
OS << "(no_name)(";
|
|
|
|
OS << BB << ")\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/// Apply an update (Kind, From, To) to the internal queued updates. The
|
|
|
|
/// update is only added when determined to be necessary. Checks for
|
|
|
|
/// self-domination, unnecessary updates, duplicate requests, and balanced
|
|
|
|
/// pairs of requests are all performed. Returns true if the update is
|
|
|
|
/// queued and false if it is discarded.
|
|
|
|
bool DeferredDominance::applyUpdate(DominatorTree::UpdateKind Kind,
|
|
|
|
BasicBlock *From, BasicBlock *To) {
|
|
|
|
if (From == To)
|
|
|
|
return false; // Cannot dominate self; discard update.
|
|
|
|
|
|
|
|
// Discard updates by inspecting the current state of successors of From.
|
|
|
|
// Since applyUpdate() must be called *after* the Terminator of From is
|
|
|
|
// altered we can determine if the update is unnecessary.
|
|
|
|
bool HasEdge = std::any_of(succ_begin(From), succ_end(From),
|
|
|
|
[To](BasicBlock *B) { return B == To; });
|
|
|
|
if (Kind == DominatorTree::Insert && !HasEdge)
|
|
|
|
return false; // Unnecessary Insert: edge does not exist in IR.
|
|
|
|
if (Kind == DominatorTree::Delete && HasEdge)
|
|
|
|
return false; // Unnecessary Delete: edge still exists in IR.
|
|
|
|
|
|
|
|
// Analyze pending updates to determine if the update is unnecessary.
|
|
|
|
DominatorTree::UpdateType Update = {Kind, From, To};
|
|
|
|
DominatorTree::UpdateType Invert = {Kind != DominatorTree::Insert
|
|
|
|
? DominatorTree::Insert
|
|
|
|
: DominatorTree::Delete,
|
|
|
|
From, To};
|
|
|
|
for (auto I = PendUpdates.begin(), E = PendUpdates.end(); I != E; ++I) {
|
|
|
|
if (Update == *I)
|
|
|
|
return false; // Discard duplicate updates.
|
|
|
|
if (Invert == *I) {
|
|
|
|
// Update and Invert are both valid (equivalent to a no-op). Remove
|
|
|
|
// Invert from PendUpdates and discard the Update.
|
|
|
|
PendUpdates.erase(I);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PendUpdates.push_back(Update); // Save the valid update.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Performs all pending basic block deletions. We have to defer the deletion
|
|
|
|
/// of these blocks until after the DominatorTree updates are applied. The
|
|
|
|
/// internal workings of the DominatorTree code expect every update's From
|
|
|
|
/// and To blocks to exist and to be a member of the same Function.
|
|
|
|
bool DeferredDominance::flushDelBB() {
|
|
|
|
if (DeletedBBs.empty())
|
|
|
|
return false;
|
|
|
|
for (auto *BB : DeletedBBs)
|
|
|
|
BB->eraseFromParent();
|
|
|
|
DeletedBBs.clear();
|
|
|
|
return true;
|
|
|
|
}
|