Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/DCE.cpp
35269 views
//===- DCE.cpp - Code to perform dead code elimination --------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements dead inst elimination and dead code elimination.9//10// Dead Inst Elimination performs a single pass over the function removing11// instructions that are obviously dead. Dead Code Elimination is similar, but12// it rechecks instructions that were used by removed instructions to see if13// they are newly dead.14//15//===----------------------------------------------------------------------===//1617#include "llvm/Transforms/Scalar/DCE.h"18#include "llvm/ADT/SetVector.h"19#include "llvm/ADT/Statistic.h"20#include "llvm/Analysis/TargetLibraryInfo.h"21#include "llvm/IR/InstIterator.h"22#include "llvm/IR/Instruction.h"23#include "llvm/InitializePasses.h"24#include "llvm/Pass.h"25#include "llvm/Support/DebugCounter.h"26#include "llvm/Transforms/Scalar.h"27#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"28#include "llvm/Transforms/Utils/BasicBlockUtils.h"29#include "llvm/Transforms/Utils/Local.h"30using namespace llvm;3132#define DEBUG_TYPE "dce"3334STATISTIC(DCEEliminated, "Number of insts removed");35DEBUG_COUNTER(DCECounter, "dce-transform",36"Controls which instructions are eliminated");3738PreservedAnalyses39RedundantDbgInstEliminationPass::run(Function &F, FunctionAnalysisManager &AM) {40bool Changed = false;41for (auto &BB : F)42Changed |= RemoveRedundantDbgInstrs(&BB);43if (!Changed)44return PreservedAnalyses::all();45PreservedAnalyses PA;46PA.preserveSet<CFGAnalyses>();47return PA;48}4950//===--------------------------------------------------------------------===//51// DeadCodeElimination pass implementation52//5354static bool DCEInstruction(Instruction *I,55SmallSetVector<Instruction *, 16> &WorkList,56const TargetLibraryInfo *TLI) {57if (isInstructionTriviallyDead(I, TLI)) {58if (!DebugCounter::shouldExecute(DCECounter))59return false;6061salvageDebugInfo(*I);62salvageKnowledge(I);6364// Null out all of the instruction's operands to see if any operand becomes65// dead as we go.66for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {67Value *OpV = I->getOperand(i);68I->setOperand(i, nullptr);6970if (!OpV->use_empty() || I == OpV)71continue;7273// If the operand is an instruction that became dead as we nulled out the74// operand, and if it is 'trivially' dead, delete it in a future loop75// iteration.76if (Instruction *OpI = dyn_cast<Instruction>(OpV))77if (isInstructionTriviallyDead(OpI, TLI))78WorkList.insert(OpI);79}8081I->eraseFromParent();82++DCEEliminated;83return true;84}85return false;86}8788static bool eliminateDeadCode(Function &F, TargetLibraryInfo *TLI) {89bool MadeChange = false;90SmallSetVector<Instruction *, 16> WorkList;91// Iterate over the original function, only adding insts to the worklist92// if they actually need to be revisited. This avoids having to pre-init93// the worklist with the entire function's worth of instructions.94for (Instruction &I : llvm::make_early_inc_range(instructions(F))) {95// We're visiting this instruction now, so make sure it's not in the96// worklist from an earlier visit.97if (!WorkList.count(&I))98MadeChange |= DCEInstruction(&I, WorkList, TLI);99}100101while (!WorkList.empty()) {102Instruction *I = WorkList.pop_back_val();103MadeChange |= DCEInstruction(I, WorkList, TLI);104}105return MadeChange;106}107108PreservedAnalyses DCEPass::run(Function &F, FunctionAnalysisManager &AM) {109if (!eliminateDeadCode(F, &AM.getResult<TargetLibraryAnalysis>(F)))110return PreservedAnalyses::all();111112PreservedAnalyses PA;113PA.preserveSet<CFGAnalyses>();114return PA;115}116117namespace {118struct DCELegacyPass : public FunctionPass {119static char ID; // Pass identification, replacement for typeid120DCELegacyPass() : FunctionPass(ID) {121initializeDCELegacyPassPass(*PassRegistry::getPassRegistry());122}123124bool runOnFunction(Function &F) override {125if (skipFunction(F))126return false;127128TargetLibraryInfo *TLI =129&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);130131return eliminateDeadCode(F, TLI);132}133134void getAnalysisUsage(AnalysisUsage &AU) const override {135AU.addRequired<TargetLibraryInfoWrapperPass>();136AU.setPreservesCFG();137}138};139}140141char DCELegacyPass::ID = 0;142INITIALIZE_PASS(DCELegacyPass, "dce", "Dead Code Elimination", false, false)143144FunctionPass *llvm::createDeadCodeEliminationPass() {145return new DCELegacyPass();146}147148149