[Attributor] Use a pointer value type for the AAMap

This reduces memory consumption and the need to copy complex data
structures repeatedly.

No functional change is intended.

---

Single run of the Attributor module and then CGSCC pass (oldPM)
for SPASS/clause.c (~10k LLVM-IR loc):

Before:
```
calls to allocation functions: 613353 (376521/s)
temporary memory allocations: 83636 (51341/s)
peak heap memory consumption: 75.64MB
peak RSS (including heaptrack overhead): 162.97MB
total memory leaked: 269.04KB
```

After:
```
calls to allocation functions: 616575 (349929/s)
temporary memory allocations: 83650 (47474/s)
peak heap memory consumption: 72.15MB
peak RSS (including heaptrack overhead): 159.81MB
total memory leaked: 269.04KB
```

Difference:
```
calls to allocation functions: 3222 (24225/s)
temporary memory allocations: 14 (105/s)
peak heap memory consumption: -3.49MB
peak RSS (including heaptrack overhead): 0B
total memory leaked: 0B

---
This commit is contained in:
Johannes Doerfert 2020-04-16 18:23:01 -05:00
parent 128d72751f
commit 91a6c88349
2 changed files with 26 additions and 17 deletions

View File

@ -803,10 +803,13 @@ struct Attributor {
// Put the attribute in the lookup map structure and the container we use to
// keep track of all attributes.
const IRPosition &IRP = AA.getIRPosition();
auto &KindToAbstractAttributeMap = AAMap[IRP];
assert(!KindToAbstractAttributeMap.count(&AAType::ID) &&
"Attribute already in map!");
KindToAbstractAttributeMap[&AAType::ID] = &AA;
Kind2AAMapTy *&Kind2AA = AAMap[IRP];
if (!Kind2AA)
Kind2AA = new (Allocator) Kind2AAMapTy();
assert(!(*Kind2AA)[&AAType::ID] && "Attribute already in map!");
(*Kind2AA)[&AAType::ID] = &AA;
AllAbstractAttributes.push_back(&AA);
return AA;
}
@ -1185,18 +1188,19 @@ private:
// Lookup the abstract attribute of type AAType. If found, return it after
// registering a dependence of QueryingAA on the one returned attribute.
auto KindToAbstractAttributeMapIt = AAMap.find(IRP);
if ( KindToAbstractAttributeMapIt == AAMap.end())
Kind2AAMapTy *Kind2AA = AAMap.lookup(IRP);
if (!Kind2AA)
return nullptr;
if (AAType *AA = static_cast<AAType *>(
KindToAbstractAttributeMapIt->second.lookup(&AAType::ID))) {
// Do not register a dependence on an attribute with an invalid state.
if (TrackDependence && AA->getState().isValidState())
recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
DepClass);
return AA;
}
return nullptr;
AAType *AA = static_cast<AAType *>((*Kind2AA)[&AAType::ID]);
if (!AA)
return nullptr;
// Do not register a dependence on an attribute with an invalid state.
if (TrackDependence && AA->getState().isValidState())
recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
DepClass);
return AA;
}
/// Apply all requested function signature rewrites
@ -1215,9 +1219,9 @@ private:
/// on the outer level, and the addresses of the static member (AAType::ID) on
/// the inner level.
///{
using KindToAbstractAttributeMap =
using Kind2AAMapTy =
SmallDenseMap<const char *, AbstractAttribute *, /*InlineBuckets=*/32>;
DenseMap<IRPosition, KindToAbstractAttributeMap> AAMap;
DenseMap<IRPosition, Kind2AAMapTy*> AAMap;
///}
/// A map from abstract attributes to the ones that queried them through calls

View File

@ -487,6 +487,11 @@ Attributor::~Attributor() {
for (AbstractAttribute *AA : AllAbstractAttributes)
AA->~AbstractAttribute();
// The Kind2AAMap objects are allocated via a BumpPtrAllocator, we call
// the destructor manually.
for (auto &It : AAMap)
It.getSecond()->~Kind2AAMapTy();
for (auto &It : ArgumentReplacementMap)
DeleteContainerPointers(It.second);
}