[TrivialDeadness] Introduce API separating two different usages

The earlier usage of wouldInstructionBeTriviallyDead is based on the
assumption that the use_count of that instruction being checked will be
zero. This patch separates the API into two different ones:

1. The strictly conservative one where the instruction is trivially dead iff the uses are dead.
2. The slightly relaxed form, where an instruction is dead along paths where it is not used.

The second form can be used in identifying instructions that are valid
to sink down to uses (D109917).

Reviewed-By: reames
Differential Revision: https://reviews.llvm.org/D114647
This commit is contained in:
Anna Thomas 2021-12-01 13:53:58 -05:00
parent 0495301293
commit 72750f0012
2 changed files with 20 additions and 0 deletions

View File

@ -89,6 +89,14 @@ bool isInstructionTriviallyDead(Instruction *I,
bool wouldInstructionBeTriviallyDead(Instruction *I,
const TargetLibraryInfo *TLI = nullptr);
/// Return true if the result produced by the instruction has no side effects on
/// any paths other than where it is used. This is less conservative than
/// wouldInstructionBeTriviallyDead which is based on the assumption
/// that the use count will be 0. An example usage of this API is for
/// identifying instructions that can be sunk down to use(s).
bool wouldInstructionBeTriviallyDeadOnUnusedPaths(
Instruction *I, const TargetLibraryInfo *TLI = nullptr);
/// If the specified value is a trivially dead instruction, delete it.
/// If that makes any of its operands trivially dead, delete them too,
/// recursively. Return true if any instructions were deleted.

View File

@ -402,6 +402,18 @@ bool llvm::isInstructionTriviallyDead(Instruction *I,
return wouldInstructionBeTriviallyDead(I, TLI);
}
bool llvm::wouldInstructionBeTriviallyDeadOnUnusedPaths(
Instruction *I, const TargetLibraryInfo *TLI) {
// Instructions that are "markers" and have implied meaning on code around
// them (without explicit uses), are not dead on unused paths.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
if (II->getIntrinsicID() == Intrinsic::stacksave ||
II->getIntrinsicID() == Intrinsic::launder_invariant_group ||
II->isLifetimeStartOrEnd())
return false;
return wouldInstructionBeTriviallyDead(I, TLI);
}
bool llvm::wouldInstructionBeTriviallyDead(Instruction *I,
const TargetLibraryInfo *TLI) {
if (I->isTerminator())