[unroll] Use a small set to de-duplicate operands prior to putting them

into the worklist. This avoids allocating lots of worklist memory for
them when there are large numbers of repeated operands.

llvm-svn: 229052
This commit is contained in:
Chandler Carruth 2015-02-13 03:48:38 +00:00
parent 8e19879f5a
commit 8c86375a10
1 changed files with 12 additions and 2 deletions

View File

@ -503,6 +503,12 @@ public:
SmallVector<Instruction *, 8> Worklist; SmallVector<Instruction *, 8> Worklist;
SmallPtrSet<Instruction *, 16> DeadInstructions; SmallPtrSet<Instruction *, 16> DeadInstructions;
// We keep a very small set of operands that we use to de-duplicate things
// when inserting into the worklist. This lets us handle duplicates within
// a single instruction's operands without buring lots of memory on the
// worklist.
SmallPtrSet<Instruction *, 4> OperandSet;
// Start by initializing worklist with simplified instructions. // Start by initializing worklist with simplified instructions.
for (auto &FoldedKeyValue : SimplifiedValues) for (auto &FoldedKeyValue : SimplifiedValues)
if (auto *FoldedInst = dyn_cast<Instruction>(FoldedKeyValue.first)) { if (auto *FoldedInst = dyn_cast<Instruction>(FoldedKeyValue.first)) {
@ -510,9 +516,11 @@ public:
// Add each instruction operand of this dead instruction to the // Add each instruction operand of this dead instruction to the
// worklist. // worklist.
OperandSet.clear();
for (auto *Op : FoldedInst->operand_values()) for (auto *Op : FoldedInst->operand_values())
if (auto *OpI = dyn_cast<Instruction>(Op)) if (auto *OpI = dyn_cast<Instruction>(Op))
Worklist.push_back(OpI); if (OperandSet.insert(OpI).second)
Worklist.push_back(OpI);
} }
// If a definition of an insn is only used by simplified or dead // If a definition of an insn is only used by simplified or dead
@ -537,9 +545,11 @@ public:
if (AllUsersFolded) { if (AllUsersFolded) {
NumberOfOptimizedInstructions += TTI.getUserCost(I); NumberOfOptimizedInstructions += TTI.getUserCost(I);
DeadInstructions.insert(I); DeadInstructions.insert(I);
OperandSet.clear();
for (auto *Op : I->operand_values()) for (auto *Op : I->operand_values())
if (auto *OpI = dyn_cast<Instruction>(Op)) if (auto *OpI = dyn_cast<Instruction>(Op))
Worklist.push_back(OpI); if (OperandSet.insert(OpI).second)
Worklist.push_back(OpI);
} }
} }
return NumberOfOptimizedInstructions; return NumberOfOptimizedInstructions;