diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/Transforms/Scalar/BDCE.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/Scalar/BDCE.cpp')
| -rw-r--r-- | lib/Transforms/Scalar/BDCE.cpp | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/lib/Transforms/Scalar/BDCE.cpp b/lib/Transforms/Scalar/BDCE.cpp index 3a8ef073cb48..d3c9b9a270aa 100644 --- a/lib/Transforms/Scalar/BDCE.cpp +++ b/lib/Transforms/Scalar/BDCE.cpp @@ -38,7 +38,8 @@ STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)"); /// instruction may need to be cleared of assumptions that can no longer be /// guaranteed correct. static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) { - assert(I->getType()->isIntegerTy() && "Trivializing a non-integer value?"); + assert(I->getType()->isIntOrIntVectorTy() && + "Trivializing a non-integer value?"); // Initialize the worklist with eligible direct users. SmallVector<Instruction *, 16> WorkList; @@ -46,13 +47,13 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) { // If all bits of a user are demanded, then we know that nothing below that // in the def-use chain needs to be changed. auto *J = dyn_cast<Instruction>(JU); - if (J && J->getType()->isSized() && + if (J && J->getType()->isIntOrIntVectorTy() && !DB.getDemandedBits(J).isAllOnesValue()) WorkList.push_back(J); - // Note that we need to check for unsized types above before asking for + // Note that we need to check for non-int types above before asking for // demanded bits. Normally, the only way to reach an instruction with an - // unsized type is via an instruction that has side effects (or otherwise + // non-int type is via an instruction that has side effects (or otherwise // will demand its input bits). However, if we have a readnone function // that returns an unsized type (e.g., void), we must avoid asking for the // demanded bits of the function call's return value. A void-returning @@ -78,7 +79,7 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) { // If all bits of a user are demanded, then we know that nothing below // that in the def-use chain needs to be changed. auto *K = dyn_cast<Instruction>(KU); - if (K && !Visited.count(K) && K->getType()->isSized() && + if (K && !Visited.count(K) && K->getType()->isIntOrIntVectorTy() && !DB.getDemandedBits(K).isAllOnesValue()) WorkList.push_back(K); } @@ -95,30 +96,41 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) { if (I.mayHaveSideEffects() && I.use_empty()) continue; - if (I.getType()->isIntegerTy() && - !DB.getDemandedBits(&I).getBoolValue()) { - // For live instructions that have all dead bits, first make them dead by - // replacing all uses with something else. Then, if they don't need to - // remain live (because they have side effects, etc.) we can remove them. - LLVM_DEBUG(dbgs() << "BDCE: Trivializing: " << I << " (all bits dead)\n"); + // Remove instructions that are dead, either because they were not reached + // during analysis or have no demanded bits. + if (DB.isInstructionDead(&I) || + (I.getType()->isIntOrIntVectorTy() && + DB.getDemandedBits(&I).isNullValue() && + wouldInstructionBeTriviallyDead(&I))) { + salvageDebugInfo(I); + Worklist.push_back(&I); + I.dropAllReferences(); + Changed = true; + continue; + } + + for (Use &U : I.operands()) { + // DemandedBits only detects dead integer uses. + if (!U->getType()->isIntOrIntVectorTy()) + continue; + + if (!isa<Instruction>(U) && !isa<Argument>(U)) + continue; + + if (!DB.isUseDead(&U)) + continue; + + LLVM_DEBUG(dbgs() << "BDCE: Trivializing: " << U << " (all bits dead)\n"); clearAssumptionsOfUsers(&I, DB); // FIXME: In theory we could substitute undef here instead of zero. // This should be reconsidered once we settle on the semantics of // undef, poison, etc. - Value *Zero = ConstantInt::get(I.getType(), 0); + U.set(ConstantInt::get(U->getType(), 0)); ++NumSimplified; - I.replaceNonMetadataUsesWith(Zero); Changed = true; } - if (!DB.isInstructionDead(&I)) - continue; - - salvageDebugInfo(I); - Worklist.push_back(&I); - I.dropAllReferences(); - Changed = true; } for (Instruction *&I : Worklist) { |
