[llvm] [Support] Use bump ptr allocator for domtree nodes (PR #102516)
Alexis Engelke via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 12 10:54:37 PST 2026
https://github.com/aengelke updated https://github.com/llvm/llvm-project/pull/102516
>From 77c878227671af5143b272f09ee2b260130c9d25 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 | 29 ++++++++++++-------
.../llvm/Support/GenericDomTreeConstruction.h | 15 ++++------
2 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Support/GenericDomTree.h b/llvm/include/llvm/Support/GenericDomTree.h
index b6aae9f7928e3..8b5b7a388529a 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"
@@ -36,6 +37,7 @@
#include <cassert>
#include <cstddef>
#include <memory>
+#include <new>
#include <type_traits>
#include <utility>
@@ -257,8 +259,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.
@@ -268,6 +269,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;
@@ -280,8 +283,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();
}
@@ -293,6 +297,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;
@@ -401,7 +406,7 @@ class DominatorTreeBase {
assert((!BB || Parent == NodeTrait::getParent(const_cast<NodeT *>(BB))) &&
"cannot get DomTreeNode of block with different parent");
if (auto Idx = getNodeIndex(BB); Idx && *Idx < DomTreeNodes.size())
- return DomTreeNodes[*Idx].get();
+ return DomTreeNodes[*Idx];
return nullptr;
}
@@ -737,7 +742,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;
@@ -913,6 +918,7 @@ class DominatorTreeBase {
RootNode = nullptr;
Parent = nullptr;
DFSInfoValid = false;
+ NodeAllocator.DestroyAll();
SlowQueries = 0;
}
@@ -921,13 +927,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
@@ -1012,6 +1018,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 557c9ec319e33..9d520b45f3d88 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