12bb61ba2SHal Finkel //===---- BDCE.cpp - Bit-tracking dead code elimination -------------------===// 22bb61ba2SHal Finkel // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 62bb61ba2SHal Finkel // 72bb61ba2SHal Finkel //===----------------------------------------------------------------------===// 82bb61ba2SHal Finkel // 92bb61ba2SHal Finkel // This file implements the Bit-Tracking Dead Code Elimination pass. Some 102bb61ba2SHal Finkel // instructions (shifts, some ands, ors, etc.) kill some of their input bits. 112bb61ba2SHal Finkel // We track these dead bits and remove instructions that compute only these 127bf16839SDiogo Sampaio // dead bits. We also simplify sext that generates unused extension bits, 137bf16839SDiogo Sampaio // converting it to a zext. 142bb61ba2SHal Finkel // 152bb61ba2SHal Finkel //===----------------------------------------------------------------------===// 162bb61ba2SHal Finkel 17655a145eSDavide Italiano #include "llvm/Transforms/Scalar/BDCE.h" 18fe346f9fSSanjay Patel #include "llvm/ADT/SmallPtrSet.h" 192bb61ba2SHal Finkel #include "llvm/ADT/SmallVector.h" 202bb61ba2SHal Finkel #include "llvm/ADT/Statistic.h" 2187405c7fSJames Molloy #include "llvm/Analysis/DemandedBits.h" 22655a145eSDavide Italiano #include "llvm/Analysis/GlobalsModRef.h" 237bf16839SDiogo Sampaio #include "llvm/IR/IRBuilder.h" 242bb61ba2SHal Finkel #include "llvm/IR/InstIterator.h" 252bb61ba2SHal Finkel #include "llvm/IR/Instructions.h" 2605da2fe5SReid Kleckner #include "llvm/InitializePasses.h" 272bb61ba2SHal Finkel #include "llvm/Pass.h" 282bb61ba2SHal Finkel #include "llvm/Support/Debug.h" 292bb61ba2SHal Finkel #include "llvm/Support/raw_ostream.h" 30655a145eSDavide Italiano #include "llvm/Transforms/Scalar.h" 3105da2fe5SReid Kleckner #include "llvm/Transforms/Utils/Local.h" 322bb61ba2SHal Finkel using namespace llvm; 332bb61ba2SHal Finkel 342bb61ba2SHal Finkel #define DEBUG_TYPE "bdce" 352bb61ba2SHal Finkel 362bb61ba2SHal Finkel STATISTIC(NumRemoved, "Number of instructions removed (unused)"); 372bb61ba2SHal Finkel STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)"); 387bf16839SDiogo Sampaio STATISTIC(NumSExt2ZExt, 397bf16839SDiogo Sampaio "Number of sign extension instructions converted to zero extension"); 402bb61ba2SHal Finkel 41fe346f9fSSanjay Patel /// If an instruction is trivialized (dead), then the chain of users of that 42fe346f9fSSanjay Patel /// instruction may need to be cleared of assumptions that can no longer be 43fe346f9fSSanjay Patel /// guaranteed correct. 44fe346f9fSSanjay Patel static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) { 45110cf052SNikita Popov assert(I->getType()->isIntOrIntVectorTy() && 46110cf052SNikita Popov "Trivializing a non-integer value?"); 47fe346f9fSSanjay Patel 48fe346f9fSSanjay Patel // Initialize the worklist with eligible direct users. 49b0f764c7SFangrui Song SmallPtrSet<Instruction *, 16> Visited; 50fe346f9fSSanjay Patel SmallVector<Instruction *, 16> WorkList; 51fe346f9fSSanjay Patel for (User *JU : I->users()) { 52a1067d9bSSanjay Patel // If all bits of a user are demanded, then we know that nothing below that 53a1067d9bSSanjay Patel // in the def-use chain needs to be changed. 54fe346f9fSSanjay Patel auto *J = dyn_cast<Instruction>(JU); 55110cf052SNikita Popov if (J && J->getType()->isIntOrIntVectorTy() && 56b0f764c7SFangrui Song !DB.getDemandedBits(J).isAllOnesValue()) { 57b0f764c7SFangrui Song Visited.insert(J); 58fe346f9fSSanjay Patel WorkList.push_back(J); 59b0f764c7SFangrui Song } 609e54b709SHal Finkel 61110cf052SNikita Popov // Note that we need to check for non-int types above before asking for 629e54b709SHal Finkel // demanded bits. Normally, the only way to reach an instruction with an 63110cf052SNikita Popov // non-int type is via an instruction that has side effects (or otherwise 649e54b709SHal Finkel // will demand its input bits). However, if we have a readnone function 659e54b709SHal Finkel // that returns an unsized type (e.g., void), we must avoid asking for the 669e54b709SHal Finkel // demanded bits of the function call's return value. A void-returning 679e54b709SHal Finkel // readnone function is always dead (and so we can stop walking the use/def 689e54b709SHal Finkel // chain here), but the check is necessary to avoid asserting. 69fe346f9fSSanjay Patel } 70fe346f9fSSanjay Patel 71fe346f9fSSanjay Patel // DFS through subsequent users while tracking visits to avoid cycles. 72fe346f9fSSanjay Patel while (!WorkList.empty()) { 73fe346f9fSSanjay Patel Instruction *J = WorkList.pop_back_val(); 74fe346f9fSSanjay Patel 75fe346f9fSSanjay Patel // NSW, NUW, and exact are based on operands that might have changed. 76fe346f9fSSanjay Patel J->dropPoisonGeneratingFlags(); 77fe346f9fSSanjay Patel 78fe346f9fSSanjay Patel // We do not have to worry about llvm.assume or range metadata: 79fe346f9fSSanjay Patel // 1. llvm.assume demands its operand, so trivializing can't change it. 80fe346f9fSSanjay Patel // 2. range metadata only applies to memory accesses which demand all bits. 81fe346f9fSSanjay Patel 82fe346f9fSSanjay Patel for (User *KU : J->users()) { 83a1067d9bSSanjay Patel // If all bits of a user are demanded, then we know that nothing below 84a1067d9bSSanjay Patel // that in the def-use chain needs to be changed. 85fe346f9fSSanjay Patel auto *K = dyn_cast<Instruction>(KU); 86b0f764c7SFangrui Song if (K && Visited.insert(K).second && K->getType()->isIntOrIntVectorTy() && 879e54b709SHal Finkel !DB.getDemandedBits(K).isAllOnesValue()) 88fe346f9fSSanjay Patel WorkList.push_back(K); 89fe346f9fSSanjay Patel } 90fe346f9fSSanjay Patel } 91fe346f9fSSanjay Patel } 92fe346f9fSSanjay Patel 93655a145eSDavide Italiano static bool bitTrackingDCE(Function &F, DemandedBits &DB) { 942bb61ba2SHal Finkel SmallVector<Instruction*, 128> Worklist; 952bb61ba2SHal Finkel bool Changed = false; 96abbbc480SNikita Popov for (Instruction &I : instructions(F)) { 97043e6613SDavide Italiano // If the instruction has side effects and no non-dbg uses, 981ed53963SDavide Italiano // skip it. This way we avoid computing known bits on an instruction 991ed53963SDavide Italiano // that will not help us. 100043e6613SDavide Italiano if (I.mayHaveSideEffects() && I.use_empty()) 101043e6613SDavide Italiano continue; 102043e6613SDavide Italiano 103cc6ef7f1SNikita Popov // Remove instructions that are dead, either because they were not reached 104cc6ef7f1SNikita Popov // during analysis or have no demanded bits. 105cc6ef7f1SNikita Popov if (DB.isInstructionDead(&I) || 106cc6ef7f1SNikita Popov (I.getType()->isIntOrIntVectorTy() && 107cc6ef7f1SNikita Popov DB.getDemandedBits(&I).isNullValue() && 108cc6ef7f1SNikita Popov wouldInstructionBeTriviallyDead(&I))) { 109bc9986e9SNikita Popov Worklist.push_back(&I); 110bc9986e9SNikita Popov Changed = true; 111bc9986e9SNikita Popov continue; 112bc9986e9SNikita Popov } 113bc9986e9SNikita Popov 1147bf16839SDiogo Sampaio // Convert SExt into ZExt if none of the extension bits is required 1157bf16839SDiogo Sampaio if (SExtInst *SE = dyn_cast<SExtInst>(&I)) { 1167bf16839SDiogo Sampaio APInt Demanded = DB.getDemandedBits(SE); 1177bf16839SDiogo Sampaio const uint32_t SrcBitSize = SE->getSrcTy()->getScalarSizeInBits(); 1187bf16839SDiogo Sampaio auto *const DstTy = SE->getDestTy(); 1197bf16839SDiogo Sampaio const uint32_t DestBitSize = DstTy->getScalarSizeInBits(); 1207bf16839SDiogo Sampaio if (Demanded.countLeadingZeros() >= (DestBitSize - SrcBitSize)) { 1217bf16839SDiogo Sampaio clearAssumptionsOfUsers(SE, DB); 1227bf16839SDiogo Sampaio IRBuilder<> Builder(SE); 1237bf16839SDiogo Sampaio I.replaceAllUsesWith( 1247bf16839SDiogo Sampaio Builder.CreateZExt(SE->getOperand(0), DstTy, SE->getName())); 1257bf16839SDiogo Sampaio Worklist.push_back(SE); 1267bf16839SDiogo Sampaio Changed = true; 1277bf16839SDiogo Sampaio NumSExt2ZExt++; 1287bf16839SDiogo Sampaio continue; 1297bf16839SDiogo Sampaio } 1307bf16839SDiogo Sampaio } 1317bf16839SDiogo Sampaio 132bc9986e9SNikita Popov for (Use &U : I.operands()) { 133bc9986e9SNikita Popov // DemandedBits only detects dead integer uses. 134bc9986e9SNikita Popov if (!U->getType()->isIntOrIntVectorTy()) 135bc9986e9SNikita Popov continue; 136bc9986e9SNikita Popov 1376658fce4SNikita Popov if (!isa<Instruction>(U) && !isa<Argument>(U)) 138bc9986e9SNikita Popov continue; 139bc9986e9SNikita Popov 140bc9986e9SNikita Popov if (!DB.isUseDead(&U)) 141bc9986e9SNikita Popov continue; 142bc9986e9SNikita Popov 143bc9986e9SNikita Popov LLVM_DEBUG(dbgs() << "BDCE: Trivializing: " << U << " (all bits dead)\n"); 144fe346f9fSSanjay Patel 145fe346f9fSSanjay Patel clearAssumptionsOfUsers(&I, DB); 146fe346f9fSSanjay Patel 1472bb61ba2SHal Finkel // FIXME: In theory we could substitute undef here instead of zero. 1482bb61ba2SHal Finkel // This should be reconsidered once we settle on the semantics of 1492bb61ba2SHal Finkel // undef, poison, etc. 150bc9986e9SNikita Popov U.set(ConstantInt::get(U->getType(), 0)); 1512bb61ba2SHal Finkel ++NumSimplified; 1522bb61ba2SHal Finkel Changed = true; 1532bb61ba2SHal Finkel } 1542bb61ba2SHal Finkel } 1552bb61ba2SHal Finkel 156*9232ca47SAdrian Prantl for (Instruction *&I : llvm::reverse(Worklist)) { 157*9232ca47SAdrian Prantl salvageDebugInfo(*I); 158*9232ca47SAdrian Prantl I->dropAllReferences(); 159*9232ca47SAdrian Prantl } 160*9232ca47SAdrian Prantl 1612bb61ba2SHal Finkel for (Instruction *&I : Worklist) { 1622bb61ba2SHal Finkel ++NumRemoved; 1632bb61ba2SHal Finkel I->eraseFromParent(); 1642bb61ba2SHal Finkel } 1652bb61ba2SHal Finkel 1662bb61ba2SHal Finkel return Changed; 1672bb61ba2SHal Finkel } 1682bb61ba2SHal Finkel 169655a145eSDavide Italiano PreservedAnalyses BDCEPass::run(Function &F, FunctionAnalysisManager &AM) { 170655a145eSDavide Italiano auto &DB = AM.getResult<DemandedBitsAnalysis>(F); 171bdc29714SDavide Italiano if (!bitTrackingDCE(F, DB)) 172655a145eSDavide Italiano return PreservedAnalyses::all(); 173bdc29714SDavide Italiano 174ca68a3ecSChandler Carruth PreservedAnalyses PA; 175ca68a3ecSChandler Carruth PA.preserveSet<CFGAnalyses>(); 176bdc29714SDavide Italiano return PA; 1772bb61ba2SHal Finkel } 1782bb61ba2SHal Finkel 179655a145eSDavide Italiano namespace { 180655a145eSDavide Italiano struct BDCELegacyPass : public FunctionPass { 181655a145eSDavide Italiano static char ID; // Pass identification, replacement for typeid 182655a145eSDavide Italiano BDCELegacyPass() : FunctionPass(ID) { 183655a145eSDavide Italiano initializeBDCELegacyPassPass(*PassRegistry::getPassRegistry()); 184655a145eSDavide Italiano } 185655a145eSDavide Italiano 186655a145eSDavide Italiano bool runOnFunction(Function &F) override { 187655a145eSDavide Italiano if (skipFunction(F)) 188655a145eSDavide Italiano return false; 189655a145eSDavide Italiano auto &DB = getAnalysis<DemandedBitsWrapperPass>().getDemandedBits(); 190655a145eSDavide Italiano return bitTrackingDCE(F, DB); 191655a145eSDavide Italiano } 192655a145eSDavide Italiano 193655a145eSDavide Italiano void getAnalysisUsage(AnalysisUsage &AU) const override { 194655a145eSDavide Italiano AU.setPreservesCFG(); 195655a145eSDavide Italiano AU.addRequired<DemandedBitsWrapperPass>(); 196655a145eSDavide Italiano AU.addPreserved<GlobalsAAWrapperPass>(); 197655a145eSDavide Italiano } 198655a145eSDavide Italiano }; 199655a145eSDavide Italiano } 200655a145eSDavide Italiano 201655a145eSDavide Italiano char BDCELegacyPass::ID = 0; 202655a145eSDavide Italiano INITIALIZE_PASS_BEGIN(BDCELegacyPass, "bdce", 203655a145eSDavide Italiano "Bit-Tracking Dead Code Elimination", false, false) 204655a145eSDavide Italiano INITIALIZE_PASS_DEPENDENCY(DemandedBitsWrapperPass) 205655a145eSDavide Italiano INITIALIZE_PASS_END(BDCELegacyPass, "bdce", 206655a145eSDavide Italiano "Bit-Tracking Dead Code Elimination", false, false) 207655a145eSDavide Italiano 208655a145eSDavide Italiano FunctionPass *llvm::createBitTrackingDCEPass() { return new BDCELegacyPass(); } 209