[Attributor] Introduce an API to delete stuff

Summary:
During the fixpoint iteration, including the manifest stage, we should
not delete stuff as other abstract attributes might have a reference to
the value. Through the API this can now be done safely at the very end.

Reviewers: uenoku, sstefan1

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66779

llvm-svn: 370014
This commit is contained in:
Johannes Doerfert 2019-08-27 04:57:54 +00:00
parent 20650eda99
commit 39681e733c
2 changed files with 37 additions and 0 deletions
llvm
include/llvm/Transforms/IPO
lib/Transforms/IPO

View File

@ -675,6 +675,15 @@ struct Attributor {
void identifyDefaultAbstractAttributes(
Function &F, DenseSet<const char *> *Whitelist = nullptr);
/// Record that \p I is deleted after information was manifested.
void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
/// Record that \p BB is deleted after information was manifested.
void deleteAfterManifest(BasicBlock &BB) { ToBeDeletedBlocks.insert(&BB); }
/// Record that \p F is deleted after information was manifested.
void deleteAfterManifest(Function &F) { ToBeDeletedFunctions.insert(&F); }
/// Return true if \p AA (or its context instruction) is assumed dead.
///
/// If \p LivenessAA is not provided it is queried.
@ -765,6 +774,14 @@ private:
/// The information cache that holds pre-processed (LLVM-IR) information.
InformationCache &InfoCache;
/// Functions, blocks, and instructions we delete after manifest is done.
///
///{
SmallPtrSet<Function *, 8> ToBeDeletedFunctions;
SmallPtrSet<BasicBlock *, 8> ToBeDeletedBlocks;
SmallPtrSet<Instruction *, 8> ToBeDeletedInsts;
///}
};
/// An interface to query the internal state of an abstract attribute.

View File

@ -2641,6 +2641,26 @@ ChangeStatus Attributor::run() {
assert(
NumFinalAAs == AllAbstractAttributes.size() &&
"Expected the final number of abstract attributes to remain unchanged!");
// Delete stuff at the end to avoid invalid references and a nice order.
LLVM_DEBUG(dbgs() << "\n[Attributor] Delete " << ToBeDeletedFunctions.size()
<< " functions and " << ToBeDeletedBlocks.size()
<< " blocks and " << ToBeDeletedInsts.size()
<< " instructions\n");
for (Instruction *I : ToBeDeletedInsts) {
if (I->hasNUsesOrMore(1))
I->replaceAllUsesWith(UndefValue::get(I->getType()));
I->eraseFromParent();
}
for (BasicBlock *BB : ToBeDeletedBlocks) {
// TODO: Check if we need to replace users (PHIs, indirect branches?)
BB->eraseFromParent();
}
for (Function *Fn : ToBeDeletedFunctions) {
Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
Fn->eraseFromParent();
}
return ManifestChange;
}