| 1 | //===---- BDCE.cpp - Bit-tracking dead code elimination -------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file implements the Bit-Tracking Dead Code Elimination pass. Some |
| 10 | // instructions (shifts, some ands, ors, etc.) kill some of their input bits. |
| 11 | // We track these dead bits and remove instructions that compute only these |
| 12 | // dead bits. We also simplify sext that generates unused extension bits, |
| 13 | // converting it to a zext. |
| 14 | // |
| 15 | //===----------------------------------------------------------------------===// |
| 16 | |
| 17 | #include "llvm/Transforms/Scalar/BDCE.h" |
| 18 | #include "llvm/ADT/SmallPtrSet.h" |
| 19 | #include "llvm/ADT/SmallVector.h" |
| 20 | #include "llvm/ADT/Statistic.h" |
| 21 | #include "llvm/Analysis/DemandedBits.h" |
| 22 | #include "llvm/Analysis/GlobalsModRef.h" |
| 23 | #include "llvm/IR/IRBuilder.h" |
| 24 | #include "llvm/IR/InstIterator.h" |
| 25 | #include "llvm/IR/Instructions.h" |
| 26 | #include "llvm/IR/PatternMatch.h" |
| 27 | #include "llvm/Support/Debug.h" |
| 28 | #include "llvm/Support/raw_ostream.h" |
| 29 | #include "llvm/Transforms/Utils/Local.h" |
| 30 | |
| 31 | using namespace llvm; |
| 32 | using namespace PatternMatch; |
| 33 | |
| 34 | #define DEBUG_TYPE "bdce" |
| 35 | |
| 36 | STATISTIC(NumRemoved, "Number of instructions removed (unused)" ); |
| 37 | STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)" ); |
| 38 | STATISTIC(NumSExt2ZExt, |
| 39 | "Number of sign extension instructions converted to zero extension" ); |
| 40 | |
| 41 | /// If an instruction is trivialized (dead), then the chain of users of that |
| 42 | /// instruction may need to be cleared of assumptions that can no longer be |
| 43 | /// guaranteed correct. |
| 44 | static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) { |
| 45 | assert(I->getType()->isIntOrIntVectorTy() && |
| 46 | "Trivializing a non-integer value?" ); |
| 47 | |
| 48 | // If all bits of a user are demanded, then we know that nothing below that |
| 49 | // in the def-use chain needs to be changed. |
| 50 | if (DB.getDemandedBits(I).isAllOnes()) |
| 51 | return; |
| 52 | |
| 53 | // Initialize the worklist with eligible direct users. |
| 54 | SmallPtrSet<Instruction *, 16> Visited; |
| 55 | SmallVector<Instruction *, 16> WorkList; |
| 56 | for (User *JU : I->users()) { |
| 57 | auto *J = cast<Instruction>(Val: JU); |
| 58 | if (J->getType()->isIntOrIntVectorTy()) { |
| 59 | Visited.insert(Ptr: J); |
| 60 | WorkList.push_back(Elt: J); |
| 61 | } |
| 62 | |
| 63 | // Note that we need to check for non-int types above before asking for |
| 64 | // demanded bits. Normally, the only way to reach an instruction with an |
| 65 | // non-int type is via an instruction that has side effects (or otherwise |
| 66 | // will demand its input bits). However, if we have a readnone function |
| 67 | // that returns an unsized type (e.g., void), we must avoid asking for the |
| 68 | // demanded bits of the function call's return value. A void-returning |
| 69 | // readnone function is always dead (and so we can stop walking the use/def |
| 70 | // chain here), but the check is necessary to avoid asserting. |
| 71 | } |
| 72 | |
| 73 | // DFS through subsequent users while tracking visits to avoid cycles. |
| 74 | while (!WorkList.empty()) { |
| 75 | Instruction *J = WorkList.pop_back_val(); |
| 76 | |
| 77 | // NSW, NUW, and exact are based on operands that might have changed. |
| 78 | J->dropPoisonGeneratingAnnotations(); |
| 79 | |
| 80 | // We do not have to worry about llvm.assume, because it demands its |
| 81 | // operand, so trivializing can't change it. |
| 82 | |
| 83 | // If all bits of a user are demanded, then we know that nothing below |
| 84 | // that in the def-use chain needs to be changed. |
| 85 | if (DB.getDemandedBits(I: J).isAllOnes()) |
| 86 | continue; |
| 87 | |
| 88 | for (User *KU : J->users()) { |
| 89 | auto *K = cast<Instruction>(Val: KU); |
| 90 | if (Visited.insert(Ptr: K).second && K->getType()->isIntOrIntVectorTy()) |
| 91 | WorkList.push_back(Elt: K); |
| 92 | } |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | static bool bitTrackingDCE(Function &F, DemandedBits &DB) { |
| 97 | SmallVector<Instruction*, 128> Worklist; |
| 98 | bool Changed = false; |
| 99 | for (Instruction &I : instructions(F)) { |
| 100 | // If the instruction has side effects and no non-dbg uses, |
| 101 | // skip it. This way we avoid computing known bits on an instruction |
| 102 | // that will not help us. |
| 103 | if (I.mayHaveSideEffects() && I.use_empty()) |
| 104 | continue; |
| 105 | |
| 106 | // Remove instructions that are dead, either because they were not reached |
| 107 | // during analysis or have no demanded bits. |
| 108 | if (DB.isInstructionDead(I: &I) || |
| 109 | (I.getType()->isIntOrIntVectorTy() && DB.getDemandedBits(I: &I).isZero() && |
| 110 | wouldInstructionBeTriviallyDead(I: &I))) { |
| 111 | Worklist.push_back(Elt: &I); |
| 112 | Changed = true; |
| 113 | continue; |
| 114 | } |
| 115 | |
| 116 | // Convert SExt into ZExt if none of the extension bits is required |
| 117 | if (SExtInst *SE = dyn_cast<SExtInst>(Val: &I)) { |
| 118 | APInt Demanded = DB.getDemandedBits(I: SE); |
| 119 | const uint32_t SrcBitSize = SE->getSrcTy()->getScalarSizeInBits(); |
| 120 | auto *const DstTy = SE->getDestTy(); |
| 121 | const uint32_t DestBitSize = DstTy->getScalarSizeInBits(); |
| 122 | if (Demanded.countl_zero() >= (DestBitSize - SrcBitSize)) { |
| 123 | clearAssumptionsOfUsers(I: SE, DB); |
| 124 | IRBuilder<> Builder(SE); |
| 125 | I.replaceAllUsesWith( |
| 126 | V: Builder.CreateZExt(V: SE->getOperand(i_nocapture: 0), DestTy: DstTy, Name: SE->getName())); |
| 127 | Worklist.push_back(Elt: SE); |
| 128 | Changed = true; |
| 129 | NumSExt2ZExt++; |
| 130 | continue; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | // Simplify and, or, xor when their mask does not affect the demanded bits. |
| 135 | if (auto *BO = dyn_cast<BinaryOperator>(Val: &I)) { |
| 136 | APInt Demanded = DB.getDemandedBits(I: BO); |
| 137 | if (!Demanded.isAllOnes()) { |
| 138 | const APInt *Mask; |
| 139 | if (match(V: BO->getOperand(i_nocapture: 1), P: m_APInt(Res&: Mask))) { |
| 140 | bool CanBeSimplified = false; |
| 141 | switch (BO->getOpcode()) { |
| 142 | case Instruction::Or: |
| 143 | case Instruction::Xor: |
| 144 | CanBeSimplified = !Demanded.intersects(RHS: *Mask); |
| 145 | break; |
| 146 | case Instruction::And: |
| 147 | CanBeSimplified = Demanded.isSubsetOf(RHS: *Mask); |
| 148 | break; |
| 149 | default: |
| 150 | // TODO: Handle more cases here. |
| 151 | break; |
| 152 | } |
| 153 | |
| 154 | if (CanBeSimplified) { |
| 155 | clearAssumptionsOfUsers(I: BO, DB); |
| 156 | BO->replaceAllUsesWith(V: BO->getOperand(i_nocapture: 0)); |
| 157 | Worklist.push_back(Elt: BO); |
| 158 | ++NumSimplified; |
| 159 | Changed = true; |
| 160 | continue; |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | for (Use &U : I.operands()) { |
| 167 | // DemandedBits only detects dead integer uses. |
| 168 | if (!U->getType()->isIntOrIntVectorTy()) |
| 169 | continue; |
| 170 | |
| 171 | if (!isa<Instruction>(Val: U) && !isa<Argument>(Val: U)) |
| 172 | continue; |
| 173 | |
| 174 | if (!DB.isUseDead(U: &U)) |
| 175 | continue; |
| 176 | |
| 177 | LLVM_DEBUG(dbgs() << "BDCE: Trivializing: " << U << " (all bits dead)\n" ); |
| 178 | |
| 179 | clearAssumptionsOfUsers(I: &I, DB); |
| 180 | |
| 181 | // Substitute all uses with zero. In theory we could use `freeze poison` |
| 182 | // instead, but that seems unlikely to be profitable. |
| 183 | U.set(ConstantInt::get(Ty: U->getType(), V: 0)); |
| 184 | ++NumSimplified; |
| 185 | Changed = true; |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | for (Instruction *&I : llvm::reverse(C&: Worklist)) { |
| 190 | salvageDebugInfo(I&: *I); |
| 191 | I->dropAllReferences(); |
| 192 | } |
| 193 | |
| 194 | for (Instruction *&I : Worklist) { |
| 195 | ++NumRemoved; |
| 196 | I->eraseFromParent(); |
| 197 | } |
| 198 | |
| 199 | return Changed; |
| 200 | } |
| 201 | |
| 202 | PreservedAnalyses BDCEPass::run(Function &F, FunctionAnalysisManager &AM) { |
| 203 | auto &DB = AM.getResult<DemandedBitsAnalysis>(IR&: F); |
| 204 | if (!bitTrackingDCE(F, DB)) |
| 205 | return PreservedAnalyses::all(); |
| 206 | |
| 207 | PreservedAnalyses PA; |
| 208 | PA.preserveSet<CFGAnalyses>(); |
| 209 | return PA; |
| 210 | } |
| 211 | |