[SLP] Simplify eraseInstruction [NFC]
This simplifies the implementation of eraseInstruction by moving the odd-replace-users-with-undef handling back to the only caller which uses it. This handling was not obviously correct, so add the asserts which make it clear why this is safe to do at all. The result is simpler code and stronger assertions.
This commit is contained in:
parent
a78bd83264
commit
f80aaa675f
|
@ -1964,8 +1964,12 @@ public:
|
||||||
/// Checks if the instruction is marked for deletion.
|
/// Checks if the instruction is marked for deletion.
|
||||||
bool isDeleted(Instruction *I) const { return DeletedInstructions.count(I); }
|
bool isDeleted(Instruction *I) const { return DeletedInstructions.count(I); }
|
||||||
|
|
||||||
/// Marks values operands for later deletion by replacing them with Undefs.
|
/// Removes an instruction from its block and eventually deletes it.
|
||||||
void eraseInstructions(ArrayRef<Value *> AV);
|
/// It's like Instruction::eraseFromParent() except that the actual deletion
|
||||||
|
/// is delayed until BoUpSLP is destructed.
|
||||||
|
void eraseInstruction(Instruction *I) {
|
||||||
|
DeletedInstructions.insert(I);
|
||||||
|
}
|
||||||
|
|
||||||
~BoUpSLP();
|
~BoUpSLP();
|
||||||
|
|
||||||
|
@ -2521,20 +2525,12 @@ private:
|
||||||
// invalidates capture results.
|
// invalidates capture results.
|
||||||
BatchAAResults BatchAA;
|
BatchAAResults BatchAA;
|
||||||
|
|
||||||
/// Removes an instruction from its block and eventually deletes it.
|
|
||||||
/// It's like Instruction::eraseFromParent() except that the actual deletion
|
|
||||||
/// is delayed until BoUpSLP is destructed.
|
|
||||||
/// This is required to ensure that there are no incorrect collisions in the
|
|
||||||
/// AliasCache, which can happen if a new instruction is allocated at the
|
|
||||||
/// same address as a previously deleted instruction.
|
|
||||||
void eraseInstruction(Instruction *I, bool ReplaceOpsWithUndef = false) {
|
|
||||||
auto It = DeletedInstructions.try_emplace(I, ReplaceOpsWithUndef).first;
|
|
||||||
It->getSecond() = It->getSecond() && ReplaceOpsWithUndef;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Temporary store for deleted instructions. Instructions will be deleted
|
/// Temporary store for deleted instructions. Instructions will be deleted
|
||||||
/// eventually when the BoUpSLP is destructed.
|
/// eventually when the BoUpSLP is destructed. The deferral is required to
|
||||||
DenseMap<Instruction *, bool> DeletedInstructions;
|
/// ensure that there are no incorrect collisions in the AliasCache, which
|
||||||
|
/// can happen if a new instruction is allocated at the same address as a
|
||||||
|
/// previously deleted instruction.
|
||||||
|
DenseSet<Instruction *> DeletedInstructions;
|
||||||
|
|
||||||
/// A list of values that need to extracted out of the tree.
|
/// A list of values that need to extracted out of the tree.
|
||||||
/// This list holds pairs of (Internal Scalar : External User). External User
|
/// This list holds pairs of (Internal Scalar : External User). External User
|
||||||
|
@ -3208,19 +3204,12 @@ template <> struct DOTGraphTraits<BoUpSLP *> : public DefaultDOTGraphTraits {
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
BoUpSLP::~BoUpSLP() {
|
BoUpSLP::~BoUpSLP() {
|
||||||
for (const auto &Pair : DeletedInstructions) {
|
for (auto *I : DeletedInstructions)
|
||||||
// Replace operands of ignored instructions with Undefs in case if they were
|
I->dropAllReferences();
|
||||||
// marked for deletion.
|
for (auto *I : DeletedInstructions) {
|
||||||
if (Pair.getSecond()) {
|
assert(I->use_empty() &&
|
||||||
Value *Undef = UndefValue::get(Pair.getFirst()->getType());
|
|
||||||
Pair.getFirst()->replaceAllUsesWith(Undef);
|
|
||||||
}
|
|
||||||
Pair.getFirst()->dropAllReferences();
|
|
||||||
}
|
|
||||||
for (const auto &Pair : DeletedInstructions) {
|
|
||||||
assert(Pair.getFirst()->use_empty() &&
|
|
||||||
"trying to erase instruction with users.");
|
"trying to erase instruction with users.");
|
||||||
Pair.getFirst()->eraseFromParent();
|
I->eraseFromParent();
|
||||||
}
|
}
|
||||||
#ifdef EXPENSIVE_CHECKS
|
#ifdef EXPENSIVE_CHECKS
|
||||||
// If we could guarantee that this call is not extremely slow, we could
|
// If we could guarantee that this call is not extremely slow, we could
|
||||||
|
@ -3229,13 +3218,6 @@ BoUpSLP::~BoUpSLP() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoUpSLP::eraseInstructions(ArrayRef<Value *> AV) {
|
|
||||||
for (auto *V : AV) {
|
|
||||||
if (auto *I = dyn_cast<Instruction>(V))
|
|
||||||
eraseInstruction(I, /*ReplaceOpsWithUndef=*/true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reorders the given \p Reuses mask according to the given \p Mask. \p Reuses
|
/// Reorders the given \p Reuses mask according to the given \p Mask. \p Reuses
|
||||||
/// contains original mask for the scalars reused in the node. Procedure
|
/// contains original mask for the scalars reused in the node. Procedure
|
||||||
/// transform this mask in accordance with the given \p Mask.
|
/// transform this mask in accordance with the given \p Mask.
|
||||||
|
@ -9831,9 +9813,26 @@ public:
|
||||||
|
|
||||||
ReductionRoot->replaceAllUsesWith(VectorizedTree);
|
ReductionRoot->replaceAllUsesWith(VectorizedTree);
|
||||||
|
|
||||||
// Mark all scalar reduction ops for deletion, they are replaced by the
|
// The original scalar reduction is expected to have no remaining
|
||||||
// vector reductions.
|
// uses outside the reduction tree itself. Assert that we got this
|
||||||
V.eraseInstructions(IgnoreList);
|
// correct, replace internal uses with undef, and mark for eventual
|
||||||
|
// deletion.
|
||||||
|
#ifndef NDEBUG
|
||||||
|
SmallSet<Value *, 4> IgnoreSet;
|
||||||
|
IgnoreSet.insert(IgnoreList.begin(), IgnoreList.end());
|
||||||
|
#endif
|
||||||
|
for (auto *Ignore : IgnoreList) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
for (auto *U : Ignore->users()) {
|
||||||
|
assert(IgnoreSet.count(U));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!Ignore->use_empty()) {
|
||||||
|
Value *Undef = UndefValue::get(Ignore->getType());
|
||||||
|
Ignore->replaceAllUsesWith(Undef);
|
||||||
|
}
|
||||||
|
V.eraseInstruction(cast<Instruction>(Ignore));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return VectorizedTree;
|
return VectorizedTree;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue