[llvm] [Support] Use bump ptr allocator for domtree nodes (PR #102516)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 8 11:16:36 PDT 2024
https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/102516
Avoids one heap allocation per basic block per dominator tree and improves data locality.
[c-t-t](http://llvm-compile-time-tracker.com/compare.php?from=fbb0619fe2acea4ac8764d13b754505ed8f1b578&to=7d6bcb79154bac9d4df6559535cc8c310b1617c2&stat=instructions:u) stage2-O3 -0.52%
>From 7d6bcb79154bac9d4df6559535cc8c310b1617c2 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Thu, 8 Aug 2024 15:25:40 +0000
Subject: [PATCH] [Support] Use bump ptr allocator for domtree nodes
---
llvm/include/llvm/Support/GenericDomTree.h | 28 +++++++++++--------
.../llvm/Support/GenericDomTreeConstruction.h | 15 ++++------
2 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h
index 7e2b68e6faea29..00ce3df9c99f1b 100644
--- a/llvm/include/llvm/Support/GenericDomTree.h
+++ b/llvm/include/llvm/Support/GenericDomTree.h
@@ -29,6 +29,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/CFGDiff.h"
#include "llvm/Support/CFGUpdate.h"
#include "llvm/Support/raw_ostream.h"
@@ -37,6 +38,7 @@
#include <cstddef>
#include <iterator>
#include <memory>
+#include <new>
#include <type_traits>
#include <utility>
@@ -258,8 +260,7 @@ class DominatorTreeBase {
// Dominators always have a single root, postdominators can have more.
SmallVector<NodeT *, IsPostDom ? 4 : 1> Roots;
- using DomTreeNodeStorageTy =
- SmallVector<std::unique_ptr<DomTreeNodeBase<NodeT>>>;
+ using DomTreeNodeStorageTy = SmallVector<DomTreeNodeBase<NodeT> *>;
DomTreeNodeStorageTy DomTreeNodes;
// For graphs where blocks don't have numbers, create a numbering here.
// TODO: use an empty struct with [[no_unique_address]] in C++20.
@@ -269,6 +270,8 @@ class DominatorTreeBase {
DomTreeNodeBase<NodeT> *RootNode = nullptr;
ParentPtr Parent = nullptr;
+ SpecificBumpPtrAllocator<DomTreeNodeBase<NodeT>> NodeAllocator;
+
mutable bool DFSInfoValid = false;
mutable unsigned int SlowQueries = 0;
unsigned BlockNumberEpoch = 0;
@@ -281,8 +284,9 @@ class DominatorTreeBase {
DominatorTreeBase(DominatorTreeBase &&Arg)
: Roots(std::move(Arg.Roots)), DomTreeNodes(std::move(Arg.DomTreeNodes)),
NodeNumberMap(std::move(Arg.NodeNumberMap)), RootNode(Arg.RootNode),
- Parent(Arg.Parent), DFSInfoValid(Arg.DFSInfoValid),
- SlowQueries(Arg.SlowQueries), BlockNumberEpoch(Arg.BlockNumberEpoch) {
+ Parent(Arg.Parent), NodeAllocator(std::move(Arg.NodeAllocator)),
+ DFSInfoValid(Arg.DFSInfoValid), SlowQueries(Arg.SlowQueries),
+ BlockNumberEpoch(Arg.BlockNumberEpoch) {
Arg.wipe();
}
@@ -292,6 +296,7 @@ class DominatorTreeBase {
NodeNumberMap = std::move(RHS.NodeNumberMap);
RootNode = RHS.RootNode;
Parent = RHS.Parent;
+ NodeAllocator = std::move(RHS.NodeAllocator);
DFSInfoValid = RHS.DFSInfoValid;
SlowQueries = RHS.SlowQueries;
BlockNumberEpoch = RHS.BlockNumberEpoch;
@@ -398,7 +403,7 @@ class DominatorTreeBase {
/// statically unreachable block.
DomTreeNodeBase<NodeT> *getNode(const NodeT *BB) const {
if (auto Idx = getNodeIndex(BB); Idx && *Idx < DomTreeNodes.size())
- return DomTreeNodes[*Idx].get();
+ return DomTreeNodes[*Idx];
return nullptr;
}
@@ -718,7 +723,7 @@ class DominatorTreeBase {
std::optional<unsigned> IdxOpt = getNodeIndex(BB);
assert(IdxOpt && DomTreeNodes[*IdxOpt] &&
"Removing node that isn't in dominator tree.");
- DomTreeNodeBase<NodeT> *Node = DomTreeNodes[*IdxOpt].get();
+ DomTreeNodeBase<NodeT> *Node = DomTreeNodes[*IdxOpt];
assert(Node->isLeaf() && "Node is not a leaf node.");
DFSInfoValid = false;
@@ -902,13 +907,13 @@ class DominatorTreeBase {
DomTreeNodeBase<NodeT> *createNode(NodeT *BB,
DomTreeNodeBase<NodeT> *IDom = nullptr) {
- auto Node = std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom);
- auto *NodePtr = Node.get();
+ auto *Node =
+ new (NodeAllocator.Allocate()) DomTreeNodeBase<NodeT>(BB, IDom);
unsigned NodeIdx = getNodeIndexForInsert(BB);
- DomTreeNodes[NodeIdx] = std::move(Node);
+ DomTreeNodes[NodeIdx] = Node;
if (IDom)
- IDom->addChild(NodePtr);
- return NodePtr;
+ IDom->addChild(Node);
+ return Node;
}
// NewBB is split and now it has one successor. Update dominator tree to
@@ -993,6 +998,7 @@ class DominatorTreeBase {
NodeNumberMap.clear();
RootNode = nullptr;
Parent = nullptr;
+ NodeAllocator.DestroyAll();
}
};
diff --git a/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 9aab5ec60f4a25..6f2a798135e800 100644
--- a/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -1246,8 +1246,7 @@ struct SemiNCAInfo {
clear();
doFullDFSWalk(DT, AlwaysDescend);
- for (auto &NodeToTN : DT.DomTreeNodes) {
- const TreeNodePtr TN = NodeToTN.get();
+ for (auto *TN : DT.DomTreeNodes) {
if (!TN)
continue;
const NodePtr BB = TN->getBlock();
@@ -1281,8 +1280,7 @@ struct SemiNCAInfo {
// have level L + 1.
// Running time: O(N).
static bool VerifyLevels(const DomTreeT &DT) {
- for (auto &NodeToTN : DT.DomTreeNodes) {
- const TreeNodePtr TN = NodeToTN.get();
+ for (auto *TN : DT.DomTreeNodes) {
if (!TN)
continue;
const NodePtr BB = TN->getBlock();
@@ -1338,8 +1336,7 @@ struct SemiNCAInfo {
// For each tree node verify if children's DFS numbers cover their parent's
// DFS numbers with no gaps.
- for (const auto &NodeToTN : DT.DomTreeNodes) {
- const TreeNodePtr Node = NodeToTN.get();
+ for (auto *Node : DT.DomTreeNodes) {
if (!Node)
continue;
@@ -1453,8 +1450,7 @@ struct SemiNCAInfo {
// This means that if a node gets disconnected from the graph, then all of
// the nodes it dominated previously will now become unreachable.
bool verifyParentProperty(const DomTreeT &DT) {
- for (auto &NodeToTN : DT.DomTreeNodes) {
- const TreeNodePtr TN = NodeToTN.get();
+ for (auto *TN : DT.DomTreeNodes) {
if (!TN)
continue;
const NodePtr BB = TN->getBlock();
@@ -1489,8 +1485,7 @@ struct SemiNCAInfo {
// This means that if a node gets disconnected from the graph, then all of its
// siblings will now still be reachable.
bool verifySiblingProperty(const DomTreeT &DT) {
- for (auto &NodeToTN : DT.DomTreeNodes) {
- const TreeNodePtr TN = NodeToTN.get();
+ for (auto *TN : DT.DomTreeNodes) {
if (!TN)
continue;
const NodePtr BB = TN->getBlock();
More information about the llvm-commits
mailing list