[Attributor] Use a pointer value type for the OpcodeInstMap
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: 490390 (320725/s) temporary memory allocations: 84601 (55330/s) peak heap memory consumption: 41.70MB peak RSS (including heaptrack overhead): 131.18MB total memory leaked: 269.04KB ``` After: ``` calls to allocation functions: 489359 (301144/s) temporary memory allocations: 82983 (51066/s) peak heap memory consumption: 36.76MB peak RSS (including heaptrack overhead): 126.48MB total memory leaked: 269.04KB ``` Difference: ``` calls to allocation functions: -1031 (-10739/s) temporary memory allocations: -1618 (-16854/s) peak heap memory consumption: -4.94MB peak RSS (including heaptrack overhead): 0B total memory leaked: 0B ---
This commit is contained in:
parent
99662c22cd
commit
177c065e50
|
@ -573,8 +573,11 @@ struct InformationCache {
|
|||
It.getSecond()->~FunctionInfo();
|
||||
}
|
||||
|
||||
/// A vector type to hold instructions.
|
||||
using InstructionVectorTy = SmallVector<Instruction *, 8>;
|
||||
|
||||
/// A map type from opcodes to instructions with this opcode.
|
||||
using OpcodeInstMapTy = DenseMap<unsigned, SmallVector<Instruction *, 32>>;
|
||||
using OpcodeInstMapTy = DenseMap<unsigned, InstructionVectorTy *>;
|
||||
|
||||
/// Return the map that relates "interesting" opcodes with all instructions
|
||||
/// with that opcode in \p F.
|
||||
|
@ -582,9 +585,6 @@ struct InformationCache {
|
|||
return getFunctionInfo(F).OpcodeInstMap;
|
||||
}
|
||||
|
||||
/// A vector type to hold instructions.
|
||||
using InstructionVectorTy = SmallVector<Instruction *, 4>;
|
||||
|
||||
/// Return the instructions in \p F that may read or write memory.
|
||||
InstructionVectorTy &getReadOrWriteInstsForFunction(const Function &F) {
|
||||
return getFunctionInfo(F).RWInsts;
|
||||
|
@ -633,6 +633,8 @@ struct InformationCache {
|
|||
|
||||
private:
|
||||
struct FunctionInfo {
|
||||
~FunctionInfo();
|
||||
|
||||
/// A nested map that remembers all instructions in a function with a
|
||||
/// certain instruction opcode (Instruction::getOpcode()).
|
||||
OpcodeInstMapTy OpcodeInstMap;
|
||||
|
|
|
@ -832,7 +832,12 @@ static bool checkForAllInstructionsImpl(
|
|||
const AAIsDead *LivenessAA, const ArrayRef<unsigned> &Opcodes,
|
||||
bool CheckBBLivenessOnly = false) {
|
||||
for (unsigned Opcode : Opcodes) {
|
||||
for (Instruction *I : OpcodeInstMap[Opcode]) {
|
||||
// Check if we have instructions with this opcode at all first.
|
||||
auto *Insts = OpcodeInstMap.lookup(Opcode);
|
||||
if (!Insts)
|
||||
continue;
|
||||
|
||||
for (Instruction *I : *Insts) {
|
||||
// Skip dead instructions.
|
||||
if (A && A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
|
||||
CheckBBLivenessOnly))
|
||||
|
@ -1669,8 +1674,12 @@ void InformationCache::initializeInformationCache(const Function &CF,
|
|||
// The alignment of a pointer is interesting for stores.
|
||||
IsInterestingOpcode = true;
|
||||
}
|
||||
if (IsInterestingOpcode)
|
||||
FI.OpcodeInstMap[I.getOpcode()].push_back(&I);
|
||||
if (IsInterestingOpcode) {
|
||||
auto *&Insts = FI.OpcodeInstMap[I.getOpcode()];
|
||||
if (!Insts)
|
||||
Insts = new (Allocator) InstructionVectorTy();
|
||||
Insts->push_back(&I);
|
||||
}
|
||||
if (I.mayReadOrWriteMemory())
|
||||
FI.RWInsts.push_back(&I);
|
||||
}
|
||||
|
@ -1680,6 +1689,13 @@ void InformationCache::initializeInformationCache(const Function &CF,
|
|||
InlineableFunctions.insert(&F);
|
||||
}
|
||||
|
||||
InformationCache::FunctionInfo::~FunctionInfo() {
|
||||
// The instruction vectors are allocated using a BumpPtrAllocator, we need to
|
||||
// manually destroy them.
|
||||
for (auto &It : OpcodeInstMap)
|
||||
It.getSecond()->~InstructionVectorTy();
|
||||
}
|
||||
|
||||
void Attributor::recordDependence(const AbstractAttribute &FromAA,
|
||||
const AbstractAttribute &ToAA,
|
||||
DepClassTy DepClass) {
|
||||
|
|
|
@ -800,8 +800,9 @@ public:
|
|||
for (Argument &Arg : F->args()) {
|
||||
if (Arg.hasReturnedAttr()) {
|
||||
auto &ReturnInstSet = ReturnedValues[&Arg];
|
||||
for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
|
||||
ReturnInstSet.insert(cast<ReturnInst>(RI));
|
||||
if (auto *Insts = OpcodeInstMap.lookup(Instruction::Ret))
|
||||
for (Instruction *RI : *Insts)
|
||||
ReturnInstSet.insert(cast<ReturnInst>(RI));
|
||||
|
||||
indicateOptimisticFixpoint();
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue