llvm.org GIT mirror llvm / dd11fa1
[DomTree] Cleanup Update and LegalizeUpdate API moved to Support header. Summary: Clean-up following D50479. Make Update and LegalizeUpdate refer to the utilities in Support/CFGUpdate. Reviewers: kuhar Subscribers: sanjoy, jlebar, mgrang, llvm-commits Differential Revision: https://reviews.llvm.org/D50669 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339694 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 2 years ago
5 changed file(s) with 28 addition(s) and 117 deletion(s). Raw diff Collapse all Expand all
3636 extern template class DominatorTreeBase; // DomTree
3737 extern template class DominatorTreeBase; // PostDomTree
3838
39 extern template class cfg::Update;
40
3941 namespace DomTreeBuilder {
4042 using BBDomTree = DomTreeBase;
4143 using BBPostDomTree = PostDomTreeBase;
4244
43 extern template struct Update;
44
45 using BBUpdates = ArrayRef<Update>;
45 using BBUpdates = ArrayRef<llvm::cfg::Update>;
4646
4747 extern template void Calculate(BBDomTree &DT);
4848 extern template void Calculate(BBPostDomTree &DT);
2323 #ifndef LLVM_SUPPORT_GENERICDOMTREE_H
2424 #define LLVM_SUPPORT_GENERICDOMTREE_H
2525
26 #include "llvm/ADT/DenseMap.h"
27 #include "llvm/ADT/GraphTraits.h"
28 #include "llvm/ADT/PointerIntPair.h"
29 #include "llvm/ADT/STLExtras.h"
30 #include "llvm/ADT/SmallPtrSet.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/CFGUpdate.h"
33 #include "llvm/Support/raw_ostream.h"
2634 #include
2735 #include
2836 #include
3139 #include
3240 #include
3341 #include
34 #include "llvm/ADT/DenseMap.h"
35 #include "llvm/ADT/GraphTraits.h"
36 #include "llvm/ADT/PointerIntPair.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallPtrSet.h"
39 #include "llvm/ADT/SmallVector.h"
40 #include "llvm/Support/raw_ostream.h"
4142
4243 namespace llvm {
4344
197198 template
198199 void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
199200 typename DomTreeT::NodePtr To);
200
201 // UpdateKind and Update are used by the batch update API and it's easiest to
202 // define them here.
203 enum class UpdateKind : unsigned char { Insert, Delete };
204
205 template
206 struct Update {
207 using NodeKindPair = PointerIntPair;
208
209 NodePtr From;
210 NodeKindPair ToAndKind;
211
212 Update(UpdateKind Kind, NodePtr From, NodePtr To)
213 : From(From), ToAndKind(To, Kind) {}
214
215 UpdateKind getKind() const { return ToAndKind.getInt(); }
216 NodePtr getFrom() const { return From; }
217 NodePtr getTo() const { return ToAndKind.getPointer(); }
218 bool operator==(const Update &RHS) const {
219 return From == RHS.From && ToAndKind == RHS.ToAndKind;
220 }
221
222 friend raw_ostream &operator<<(raw_ostream &OS, const Update &U) {
223 OS << (U.getKind() == UpdateKind::Insert ? "Insert " : "Delete ");
224 U.getFrom()->printAsOperand(OS, false);
225 OS << " -> ";
226 U.getTo()->printAsOperand(OS, false);
227 return OS;
228 }
229 };
230201
231202 template
232203 void ApplyUpdates(DomTreeT &DT,
253224 using ParentType = typename std::remove_pointer::type;
254225 static constexpr bool IsPostDominator = IsPostDom;
255226
256 using UpdateType = DomTreeBuilder::Update;
257 using UpdateKind = DomTreeBuilder::UpdateKind;
227 using UpdateType = cfg::Update;
228 using UpdateKind = cfg::UpdateKind;
258229 static constexpr UpdateKind Insert = UpdateKind::Insert;
259230 static constexpr UpdateKind Delete = UpdateKind::Delete;
260231
7070 DenseMap NodeToInfo;
7171
7272 using UpdateT = typename DomTreeT::UpdateType;
73 using UpdateKind = typename DomTreeT::UpdateKind;
7374 struct BatchUpdateInfo {
7475 SmallVector Updates;
7576 using NodePtrAndKind = PointerIntPair;
11651166 }
11661167
11671168 BatchUpdateInfo BUI;
1168 LegalizeUpdates(Updates, BUI.Updates);
1169 LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1170 cfg::LegalizeUpdates(Updates, BUI.Updates, IsPostDom);
11691171
11701172 const size_t NumLegalized = BUI.Updates.size();
11711173 BUI.FutureSuccessors.reserve(NumLegalized);
11811183
11821184 LLVM_DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n");
11831185 LLVM_DEBUG(if (NumLegalized < 32) for (const auto &U
1184 : reverse(BUI.Updates)) dbgs()
1185 << '\t' << U << "\n");
1186 : reverse(BUI.Updates)) {
1187 dbgs() << "\t";
1188 U.dump();
1189 dbgs() << "\n";
1190 });
11861191 LLVM_DEBUG(dbgs() << "\n");
11871192
11881193 // If the DominatorTree was recalculated at some point, stop the batch
11921197 ApplyNextUpdate(DT, BUI);
11931198 }
11941199
1195 // This function serves double purpose:
1196 // a) It removes redundant updates, which makes it easier to reverse-apply
1197 // them when traversing CFG.
1198 // b) It optimizes away updates that cancel each other out, as the end result
1199 // is the same.
1200 //
1201 // It relies on the property of the incremental updates that says that the
1202 // order of updates doesn't matter. This allows us to reorder them and end up
1203 // with the exact same DomTree every time.
1204 //
1205 // Following the same logic, the function doesn't care about the order of
1206 // input updates, so it's OK to pass it an unordered sequence of updates, that
1207 // doesn't make sense when applied sequentially, eg. performing double
1208 // insertions or deletions and then doing an opposite update.
1209 //
1210 // In the future, it should be possible to schedule updates in way that
1211 // minimizes the amount of work needed done during incremental updates.
1212 static void LegalizeUpdates(ArrayRef AllUpdates,
1213 SmallVectorImpl &Result) {
1214 LLVM_DEBUG(dbgs() << "Legalizing " << AllUpdates.size() << " updates\n");
1215 // Count the total number of inserions of each edge.
1216 // Each insertion adds 1 and deletion subtracts 1. The end number should be
1217 // one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence
1218 // of updates contains multiple updates of the same kind and we assert for
1219 // that case.
1220 SmallDenseMap, int, 4> Operations;
1221 Operations.reserve(AllUpdates.size());
1222
1223 for (const auto &U : AllUpdates) {
1224 NodePtr From = U.getFrom();
1225 NodePtr To = U.getTo();
1226 if (IsPostDom) std::swap(From, To); // Reverse edge for postdominators.
1227
1228 Operations[{From, To}] += (U.getKind() == UpdateKind::Insert ? 1 : -1);
1229 }
1230
1231 Result.clear();
1232 Result.reserve(Operations.size());
1233 for (auto &Op : Operations) {
1234 const int NumInsertions = Op.second;
1235 assert(std::abs(NumInsertions) <= 1 && "Unbalanced operations!");
1236 if (NumInsertions == 0) continue;
1237 const UpdateKind UK =
1238 NumInsertions > 0 ? UpdateKind::Insert : UpdateKind::Delete;
1239 Result.push_back({UK, Op.first.first, Op.first.second});
1240 }
1241
1242 // Make the order consistent by not relying on pointer values within the
1243 // set. Reuse the old Operations map.
1244 // In the future, we should sort by something else to minimize the amount
1245 // of work needed to perform the series of updates.
1246 for (size_t i = 0, e = AllUpdates.size(); i != e; ++i) {
1247 const auto &U = AllUpdates[i];
1248 if (!IsPostDom)
1249 Operations[{U.getFrom(), U.getTo()}] = int(i);
1250 else
1251 Operations[{U.getTo(), U.getFrom()}] = int(i);
1252 }
1253
1254 llvm::sort(Result.begin(), Result.end(),
1255 [&Operations](const UpdateT &A, const UpdateT &B) {
1256 return Operations[{A.getFrom(), A.getTo()}] >
1257 Operations[{B.getFrom(), B.getTo()}];
1258 });
1259 }
1260
12611200 static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
12621201 assert(!BUI.Updates.empty() && "No updates to apply!");
12631202 UpdateT CurrentUpdate = BUI.Updates.pop_back_val();
1264 LLVM_DEBUG(dbgs() << "Applying update: " << CurrentUpdate << "\n");
1203 LLVM_DEBUG(dbgs() << "Applying update: ");
1204 LLVM_DEBUG(CurrentUpdate.dump(); dbgs() << "\n");
12651205
12661206 // Move to the next snapshot of the CFG by removing the reverse-applied
12671207 // current update. Since updates are performed in the same order they are
6666 template class llvm::DominatorTreeBase; // DomTreeBase
6767 template class llvm::DominatorTreeBase; // PostDomTreeBase
6868
69 template struct llvm::DomTreeBuilder::Update;
69 template class llvm::cfg::Update;
7070
7171 template void llvm::DomTreeBuilder::Calculate(
7272 DomTreeBuilder::BBDomTree &DT);
5757 {Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
5858 {Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
5959 SmallVector Legalized;
60 DomSNCA::LegalizeUpdates(Updates, Legalized);
60 cfg::LegalizeUpdates(Updates, Legalized, false);
6161 LLVM_DEBUG(dbgs() << "Legalized updates:\t");
62 LLVM_DEBUG(for (auto &U : Legalized) dbgs() << U << ", ");
62 LLVM_DEBUG(for (auto &U : Legalized) { U.dump(); dbgs() << ", "; });
6363 LLVM_DEBUG(dbgs() << "\n");
6464 EXPECT_EQ(Legalized.size(), 3UL);
6565 EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, B, C}), Legalized.end());
8080 {Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
8181 {Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
8282 SmallVector Legalized;
83 PostDomSNCA::LegalizeUpdates(Updates, Legalized);
83 cfg::LegalizeUpdates(Updates, Legalized, true);
8484 LLVM_DEBUG(dbgs() << "Legalized postdom updates:\t");
85 LLVM_DEBUG(for (auto &U : Legalized) dbgs() << U << ", ");
85 LLVM_DEBUG(for (auto &U : Legalized) { U.dump(); dbgs() << ", "; });
8686 LLVM_DEBUG(dbgs() << "\n");
8787 EXPECT_EQ(Legalized.size(), 3UL);
8888 EXPECT_NE(llvm::find(Legalized, DomUpdate{Insert, C, B}), Legalized.end());