summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/DemandedBits.cpp38
-rw-r--r--llvm/lib/Transforms/Scalar/BDCE.cpp38
2 files changed, 59 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp
index 0382787fbef..4aaa1182116 100644
--- a/llvm/lib/Analysis/DemandedBits.cpp
+++ b/llvm/lib/Analysis/DemandedBits.cpp
@@ -314,6 +314,7 @@ void DemandedBits::performAnalysis() {
Visited.clear();
AliveBits.clear();
+ DeadUses.clear();
SmallVector<Instruction*, 128> Worklist;
@@ -358,7 +359,8 @@ void DemandedBits::performAnalysis() {
APInt AOut;
if (UserI->getType()->isIntOrIntVectorTy()) {
AOut = AliveBits[UserI];
- LLVM_DEBUG(dbgs() << " Alive Out: " << AOut);
+ LLVM_DEBUG(dbgs() << " Alive Out: 0x"
+ << Twine::utohexstr(AOut.getLimitedValue()));
}
LLVM_DEBUG(dbgs() << "\n");
@@ -377,13 +379,20 @@ void DemandedBits::performAnalysis() {
APInt AB = APInt::getAllOnesValue(BitWidth);
if (UserI->getType()->isIntOrIntVectorTy() && !AOut &&
!isAlwaysLive(UserI)) {
+ // If all bits of the output are dead, then all bits of the input
+ // are also dead.
AB = APInt(BitWidth, 0);
} else {
- // If all bits of the output are dead, then all bits of the input
// Bits of each operand that are used to compute alive bits of the
// output are alive, all others are dead.
determineLiveOperandBits(UserI, I, OI.getOperandNo(), AOut, AB,
Known, Known2);
+
+ // Keep track of uses which have no demanded bits.
+ if (AB.isNullValue())
+ DeadUses.insert(&OI);
+ else
+ DeadUses.erase(&OI);
}
// If we've added to the set of alive bits (or the operand has not
@@ -426,6 +435,31 @@ bool DemandedBits::isInstructionDead(Instruction *I) {
!isAlwaysLive(I);
}
+bool DemandedBits::isUseDead(Use *U) {
+ // We only track integer uses, everything else is assumed live.
+ if (!(*U)->getType()->isIntOrIntVectorTy())
+ return false;
+
+ // Uses by always-live instructions are never dead.
+ Instruction *UserI = cast<Instruction>(U->getUser());
+ if (isAlwaysLive(UserI))
+ return false;
+
+ performAnalysis();
+ if (DeadUses.count(U))
+ return true;
+
+ // If no output bits are demanded, no input bits are demanded and the use
+ // is dead. These uses might not be explicitly present in the DeadUses map.
+ if (UserI->getType()->isIntOrIntVectorTy()) {
+ auto Found = AliveBits.find(UserI);
+ if (Found != AliveBits.end() && Found->second.isNullValue())
+ return true;
+ }
+
+ return false;
+}
+
void DemandedBits::print(raw_ostream &OS) {
performAnalysis();
for (auto &KV : AliveBits) {
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index f63182e57c1..65a68c17977 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -96,30 +96,38 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) {
if (I.mayHaveSideEffects() && I.use_empty())
continue;
- if (I.getType()->isIntOrIntVectorTy() &&
- !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 not reached during analysis.
+ if (DB.isInstructionDead(&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;
+
+ // TODO: We could also find dead non-instruction uses, e.g. arguments.
+ if (!isa<Instruction>(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) {
OpenPOWER on IntegriCloud