12bb61ba2SHal Finkel //===---- BDCE.cpp - Bit-tracking dead code elimination -------------------===// 22bb61ba2SHal Finkel // 32bb61ba2SHal Finkel // The LLVM Compiler Infrastructure 42bb61ba2SHal Finkel // 52bb61ba2SHal Finkel // This file is distributed under the University of Illinois Open Source 62bb61ba2SHal Finkel // License. See LICENSE.TXT for details. 72bb61ba2SHal Finkel // 82bb61ba2SHal Finkel //===----------------------------------------------------------------------===// 92bb61ba2SHal Finkel // 102bb61ba2SHal Finkel // This file implements the Bit-Tracking Dead Code Elimination pass. Some 112bb61ba2SHal Finkel // instructions (shifts, some ands, ors, etc.) kill some of their input bits. 122bb61ba2SHal Finkel // We track these dead bits and remove instructions that compute only these 132bb61ba2SHal Finkel // dead bits. 142bb61ba2SHal Finkel // 152bb61ba2SHal Finkel //===----------------------------------------------------------------------===// 162bb61ba2SHal Finkel 172bb61ba2SHal Finkel #include "llvm/Transforms/Scalar.h" 182bb61ba2SHal Finkel #include "llvm/ADT/SmallVector.h" 192bb61ba2SHal Finkel #include "llvm/ADT/Statistic.h" 20*87405c7fSJames Molloy #include "llvm/Analysis/DemandedBits.h" 212bb61ba2SHal Finkel #include "llvm/IR/CFG.h" 222bb61ba2SHal Finkel #include "llvm/IR/InstIterator.h" 232bb61ba2SHal Finkel #include "llvm/IR/Instructions.h" 242bb61ba2SHal Finkel #include "llvm/IR/IntrinsicInst.h" 252bb61ba2SHal Finkel #include "llvm/IR/Operator.h" 262bb61ba2SHal Finkel #include "llvm/Pass.h" 272bb61ba2SHal Finkel #include "llvm/Support/Debug.h" 282bb61ba2SHal Finkel #include "llvm/Support/raw_ostream.h" 292bb61ba2SHal Finkel using namespace llvm; 302bb61ba2SHal Finkel 312bb61ba2SHal Finkel #define DEBUG_TYPE "bdce" 322bb61ba2SHal Finkel 332bb61ba2SHal Finkel STATISTIC(NumRemoved, "Number of instructions removed (unused)"); 342bb61ba2SHal Finkel STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)"); 352bb61ba2SHal Finkel 362bb61ba2SHal Finkel namespace { 372bb61ba2SHal Finkel struct BDCE : public FunctionPass { 382bb61ba2SHal Finkel static char ID; // Pass identification, replacement for typeid 392bb61ba2SHal Finkel BDCE() : FunctionPass(ID) { 402bb61ba2SHal Finkel initializeBDCEPass(*PassRegistry::getPassRegistry()); 412bb61ba2SHal Finkel } 422bb61ba2SHal Finkel 432bb61ba2SHal Finkel bool runOnFunction(Function& F) override; 442bb61ba2SHal Finkel 452bb61ba2SHal Finkel void getAnalysisUsage(AnalysisUsage& AU) const override { 462bb61ba2SHal Finkel AU.setPreservesCFG(); 47*87405c7fSJames Molloy AU.addRequired<DemandedBits>(); 482bb61ba2SHal Finkel } 492bb61ba2SHal Finkel }; 50f00654e3SAlexander Kornienko } 512bb61ba2SHal Finkel 522bb61ba2SHal Finkel char BDCE::ID = 0; 532bb61ba2SHal Finkel INITIALIZE_PASS_BEGIN(BDCE, "bdce", "Bit-Tracking Dead Code Elimination", 542bb61ba2SHal Finkel false, false) 55*87405c7fSJames Molloy INITIALIZE_PASS_DEPENDENCY(DemandedBits) 562bb61ba2SHal Finkel INITIALIZE_PASS_END(BDCE, "bdce", "Bit-Tracking Dead Code Elimination", 572bb61ba2SHal Finkel false, false) 582bb61ba2SHal Finkel 592bb61ba2SHal Finkel bool BDCE::runOnFunction(Function& F) { 602bb61ba2SHal Finkel if (skipOptnoneFunction(F)) 612bb61ba2SHal Finkel return false; 62*87405c7fSJames Molloy DemandedBits &DB = getAnalysis<DemandedBits>(); 632bb61ba2SHal Finkel 642bb61ba2SHal Finkel SmallVector<Instruction*, 128> Worklist; 652bb61ba2SHal Finkel bool Changed = false; 6678199518SNico Rieck for (Instruction &I : instructions(F)) { 67*87405c7fSJames Molloy if (I.getType()->isIntegerTy() && 68*87405c7fSJames Molloy !DB.getDemandedBits(&I).getBoolValue()) { 692bb61ba2SHal Finkel // For live instructions that have all dead bits, first make them dead by 702bb61ba2SHal Finkel // replacing all uses with something else. Then, if they don't need to 712bb61ba2SHal Finkel // remain live (because they have side effects, etc.) we can remove them. 722bb61ba2SHal Finkel DEBUG(dbgs() << "BDCE: Trivializing: " << I << " (all bits dead)\n"); 732bb61ba2SHal Finkel // FIXME: In theory we could substitute undef here instead of zero. 742bb61ba2SHal Finkel // This should be reconsidered once we settle on the semantics of 752bb61ba2SHal Finkel // undef, poison, etc. 762bb61ba2SHal Finkel Value *Zero = ConstantInt::get(I.getType(), 0); 772bb61ba2SHal Finkel ++NumSimplified; 782bb61ba2SHal Finkel I.replaceAllUsesWith(Zero); 792bb61ba2SHal Finkel Changed = true; 802bb61ba2SHal Finkel } 81*87405c7fSJames Molloy if (!DB.isInstructionDead(&I)) 822bb61ba2SHal Finkel continue; 832bb61ba2SHal Finkel 842bb61ba2SHal Finkel Worklist.push_back(&I); 852bb61ba2SHal Finkel I.dropAllReferences(); 862bb61ba2SHal Finkel Changed = true; 872bb61ba2SHal Finkel } 882bb61ba2SHal Finkel 892bb61ba2SHal Finkel for (Instruction *&I : Worklist) { 902bb61ba2SHal Finkel ++NumRemoved; 912bb61ba2SHal Finkel I->eraseFromParent(); 922bb61ba2SHal Finkel } 932bb61ba2SHal Finkel 942bb61ba2SHal Finkel return Changed; 952bb61ba2SHal Finkel } 962bb61ba2SHal Finkel 972bb61ba2SHal Finkel FunctionPass *llvm::createBitTrackingDCEPass() { 982bb61ba2SHal Finkel return new BDCE(); 992bb61ba2SHal Finkel } 1002bb61ba2SHal Finkel 101