mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 17:02:03 +00:00
[DomTree] Extend update API to allow a post CFG view.
Extend the `applyUpdates` in DominatorTree to allow a post CFG view, different from the current CFG. This patch implements the functionality of updating an already up to date DT, to the desired PostCFGView. Combining a set of updates towards an up to date DT and a PostCFGView is not yet supported. Differential Revision: https://reviews.llvm.org/D85472
This commit is contained in:
parent
bd670142b0
commit
d3e372ea8f
@ -66,9 +66,11 @@ extern template void DeleteEdge<BBPostDomTree>(BBPostDomTree &DT,
|
||||
BasicBlock *To);
|
||||
|
||||
extern template void ApplyUpdates<BBDomTree>(BBDomTree &DT,
|
||||
BBDomTreeGraphDiff &);
|
||||
BBDomTreeGraphDiff &,
|
||||
BBDomTreeGraphDiff *);
|
||||
extern template void ApplyUpdates<BBPostDomTree>(BBPostDomTree &DT,
|
||||
BBPostDomTreeGraphDiff &);
|
||||
BBPostDomTreeGraphDiff &,
|
||||
BBPostDomTreeGraphDiff *);
|
||||
|
||||
extern template bool Verify<BBDomTree>(const BBDomTree &DT,
|
||||
BBDomTree::VerificationLevel VL);
|
||||
|
@ -213,7 +213,9 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
|
||||
template <typename DomTreeT>
|
||||
void ApplyUpdates(DomTreeT &DT,
|
||||
GraphDiff<typename DomTreeT::NodePtr,
|
||||
DomTreeT::IsPostDominator> &PreViewCFG);
|
||||
DomTreeT::IsPostDominator> &PreViewCFG,
|
||||
GraphDiff<typename DomTreeT::NodePtr,
|
||||
DomTreeT::IsPostDominator> *PostViewCFG);
|
||||
|
||||
template <typename DomTreeT>
|
||||
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL);
|
||||
@ -543,7 +545,30 @@ protected:
|
||||
void applyUpdates(ArrayRef<UpdateType> Updates) {
|
||||
GraphDiff<NodePtr, IsPostDominator> PreViewCFG(
|
||||
Updates, /*ReverseApplyUpdates=*/true);
|
||||
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG);
|
||||
DomTreeBuilder::ApplyUpdates(*this, PreViewCFG, nullptr);
|
||||
}
|
||||
|
||||
/// \param Updates An unordered sequence of updates to perform. The current
|
||||
/// CFG and the reverse of these updates provides the pre-view of the CFG.
|
||||
/// \param PostViewUpdates An unordered sequence of update to perform in order
|
||||
/// to obtain a post-view of the CFG. The DT will be updates assuming the
|
||||
/// obtained PostViewCFG is the desired end state.
|
||||
void applyUpdates(ArrayRef<UpdateType> Updates,
|
||||
ArrayRef<UpdateType> PostViewUpdates) {
|
||||
// GraphDiff<NodePtr, IsPostDom> *PostViewCFG = nullptr) {
|
||||
if (Updates.empty()) {
|
||||
GraphDiff<NodePtr, IsPostDom> PostViewCFG(PostViewUpdates);
|
||||
DomTreeBuilder::ApplyUpdates(*this, PostViewCFG, &PostViewCFG);
|
||||
} else {
|
||||
// TODO:
|
||||
// PreViewCFG needs to merge Updates and PostViewCFG. The updates in
|
||||
// Updates need to be reversed, and match the direction in PostViewCFG.
|
||||
// Normally, a PostViewCFG is created without reversing updates, so one
|
||||
// of the internal vectors needs reversing in order to do the
|
||||
// legalization of the merged vector of updates.
|
||||
llvm_unreachable("Currently unsupported to update given a set of "
|
||||
"updates towards a PostView");
|
||||
}
|
||||
}
|
||||
|
||||
/// Inform the dominator tree about a CFG edge insertion and update the tree.
|
||||
|
@ -79,14 +79,15 @@ struct SemiNCAInfo {
|
||||
using UpdateKind = typename DomTreeT::UpdateKind;
|
||||
struct BatchUpdateInfo {
|
||||
// Note: Updates inside PreViewCFG are aleady legalized.
|
||||
BatchUpdateInfo(GraphDiffT &PreViewCFG)
|
||||
: PreViewCFG(PreViewCFG),
|
||||
BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG = nullptr)
|
||||
: PreViewCFG(PreViewCFG), PostViewCFG(PostViewCFG),
|
||||
NumLegalized(PreViewCFG.getNumLegalizedUpdates()) {}
|
||||
|
||||
// Remembers if the whole tree was recalculated at some point during the
|
||||
// current batch update.
|
||||
bool IsRecalculated = false;
|
||||
GraphDiffT &PreViewCFG;
|
||||
GraphDiffT *PostViewCFG;
|
||||
const size_t NumLegalized;
|
||||
};
|
||||
|
||||
@ -560,12 +561,21 @@ struct SemiNCAInfo {
|
||||
auto *Parent = DT.Parent;
|
||||
DT.reset();
|
||||
DT.Parent = Parent;
|
||||
SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree,
|
||||
// there's no point doing it incrementally.
|
||||
// If the update is using the actual CFG, BUI is null. If it's using a view,
|
||||
// BUI is non-null and the PreCFGView is used. When calculating from
|
||||
// scratch, make the PreViewCFG equal to the PostCFGView, so Post is used.
|
||||
BatchUpdatePtr PostViewBUI = nullptr;
|
||||
if (BUI && BUI->PostViewCFG) {
|
||||
BUI->PreViewCFG = *BUI->PostViewCFG;
|
||||
PostViewBUI = BUI;
|
||||
}
|
||||
// This is rebuilding the whole tree, not incrementally, but PostViewBUI is
|
||||
// used in case the caller needs a DT update with a CFGView.
|
||||
SemiNCAInfo SNCA(PostViewBUI);
|
||||
|
||||
// Step #0: Number blocks in depth-first order and initialize variables used
|
||||
// in later stages of the algorithm.
|
||||
DT.Roots = FindRoots(DT, nullptr);
|
||||
DT.Roots = FindRoots(DT, PostViewBUI);
|
||||
SNCA.doFullDFSWalk(DT, AlwaysDescend);
|
||||
|
||||
SNCA.runSemiNCA(DT);
|
||||
@ -1139,7 +1149,10 @@ struct SemiNCAInfo {
|
||||
//===--------------------- DomTree Batch Updater --------------------------===
|
||||
//~~
|
||||
|
||||
static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG) {
|
||||
static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG,
|
||||
GraphDiffT *PostViewCFG) {
|
||||
// Note: the PostViewCFG is only used when computing from scratch. It's data
|
||||
// should already included in the PreViewCFG for incremental updates.
|
||||
const size_t NumUpdates = PreViewCFG.getNumLegalizedUpdates();
|
||||
if (NumUpdates == 0)
|
||||
return;
|
||||
@ -1148,14 +1161,22 @@ struct SemiNCAInfo {
|
||||
// machinery.
|
||||
if (NumUpdates == 1) {
|
||||
UpdateT Update = PreViewCFG.popUpdateForIncrementalUpdates();
|
||||
if (Update.getKind() == UpdateKind::Insert)
|
||||
InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
|
||||
else
|
||||
DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
|
||||
if (!PostViewCFG) {
|
||||
if (Update.getKind() == UpdateKind::Insert)
|
||||
InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
|
||||
else
|
||||
DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
|
||||
} else {
|
||||
BatchUpdateInfo BUI(*PostViewCFG, PostViewCFG);
|
||||
if (Update.getKind() == UpdateKind::Insert)
|
||||
InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
|
||||
else
|
||||
DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BatchUpdateInfo BUI(PreViewCFG);
|
||||
BatchUpdateInfo BUI(PreViewCFG, PostViewCFG);
|
||||
// Recalculate the DominatorTree when the number of updates
|
||||
// exceeds a threshold, which usually makes direct updating slower than
|
||||
// recalculation. We select this threshold proportional to the
|
||||
@ -1571,8 +1592,10 @@ void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
|
||||
template <class DomTreeT>
|
||||
void ApplyUpdates(DomTreeT &DT,
|
||||
GraphDiff<typename DomTreeT::NodePtr,
|
||||
DomTreeT::IsPostDominator> &PreViewCFG) {
|
||||
SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG);
|
||||
DomTreeT::IsPostDominator> &PreViewCFG,
|
||||
GraphDiff<typename DomTreeT::NodePtr,
|
||||
DomTreeT::IsPostDominator> *PostViewCFG) {
|
||||
SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG, PostViewCFG);
|
||||
}
|
||||
|
||||
template <class DomTreeT>
|
||||
|
@ -783,24 +783,32 @@ void MemorySSAUpdater::updateExitBlocksForClonedLoop(
|
||||
void MemorySSAUpdater::applyUpdates(ArrayRef<CFGUpdate> Updates,
|
||||
DominatorTree &DT) {
|
||||
SmallVector<CFGUpdate, 4> DeleteUpdates;
|
||||
SmallVector<CFGUpdate, 4> RevDeleteUpdates;
|
||||
SmallVector<CFGUpdate, 4> InsertUpdates;
|
||||
for (auto &Update : Updates) {
|
||||
if (Update.getKind() == DT.Insert)
|
||||
InsertUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
|
||||
else
|
||||
else {
|
||||
DeleteUpdates.push_back({DT.Delete, Update.getFrom(), Update.getTo()});
|
||||
RevDeleteUpdates.push_back({DT.Insert, Update.getFrom(), Update.getTo()});
|
||||
}
|
||||
}
|
||||
|
||||
if (!DeleteUpdates.empty()) {
|
||||
// Update for inserted edges: use newDT and snapshot CFG as if deletes had
|
||||
// not occurred.
|
||||
// FIXME: This creates a new DT, so it's more expensive to do mix
|
||||
// delete/inserts vs just inserts. We can do an incremental update on the DT
|
||||
// to revert deletes, than re-delete the edges. Teaching DT to do this, is
|
||||
// part of a pending cleanup.
|
||||
DominatorTree NewDT(DT, DeleteUpdates);
|
||||
GraphDiff<BasicBlock *> GD(DeleteUpdates, /*ReverseApplyUpdates=*/true);
|
||||
applyInsertUpdates(InsertUpdates, NewDT, &GD);
|
||||
SmallVector<CFGUpdate, 0> Empty;
|
||||
// Deletes are reversed applied, because this CFGView is pretending the
|
||||
// deletes did not happen yet, hence the edges still exist.
|
||||
DT.applyUpdates(Empty, RevDeleteUpdates);
|
||||
|
||||
// Note: the MSSA update below doesn't distinguish between a GD with
|
||||
// (RevDelete,false) and (Delete, true), but this matters for the DT
|
||||
// updates above; for "children" purposes they are equivalent; but the
|
||||
// updates themselves convey the desired update, used inside DT only.
|
||||
GraphDiff<BasicBlock *> GD(RevDeleteUpdates);
|
||||
applyInsertUpdates(InsertUpdates, DT, &GD);
|
||||
// Update DT to redelete edges; this matches the real CFG so we can perform
|
||||
// the standard update without a postview of the CFG.
|
||||
DT.applyUpdates(DeleteUpdates);
|
||||
} else {
|
||||
GraphDiff<BasicBlock *> GD;
|
||||
applyInsertUpdates(InsertUpdates, DT, &GD);
|
||||
|
@ -90,10 +90,11 @@ template void llvm::DomTreeBuilder::DeleteEdge<DomTreeBuilder::BBPostDomTree>(
|
||||
DomTreeBuilder::BBPostDomTree &DT, BasicBlock *From, BasicBlock *To);
|
||||
|
||||
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBDomTree>(
|
||||
DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &);
|
||||
DomTreeBuilder::BBDomTree &DT, DomTreeBuilder::BBDomTreeGraphDiff &,
|
||||
DomTreeBuilder::BBDomTreeGraphDiff *);
|
||||
template void llvm::DomTreeBuilder::ApplyUpdates<DomTreeBuilder::BBPostDomTree>(
|
||||
DomTreeBuilder::BBPostDomTree &DT,
|
||||
DomTreeBuilder::BBPostDomTreeGraphDiff &);
|
||||
DomTreeBuilder::BBPostDomTree &DT, DomTreeBuilder::BBPostDomTreeGraphDiff &,
|
||||
DomTreeBuilder::BBPostDomTreeGraphDiff *);
|
||||
|
||||
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
|
||||
const DomTreeBuilder::BBDomTree &DT,
|
||||
|
Loading…
Reference in New Issue
Block a user