Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Scalar/BDCE.cpp
35294 views
//===---- BDCE.cpp - Bit-tracking 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 the Bit-Tracking Dead Code Elimination pass. Some9// instructions (shifts, some ands, ors, etc.) kill some of their input bits.10// We track these dead bits and remove instructions that compute only these11// dead bits. We also simplify sext that generates unused extension bits,12// converting it to a zext.13//14//===----------------------------------------------------------------------===//1516#include "llvm/Transforms/Scalar/BDCE.h"17#include "llvm/ADT/SmallPtrSet.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/ADT/Statistic.h"20#include "llvm/Analysis/DemandedBits.h"21#include "llvm/Analysis/GlobalsModRef.h"22#include "llvm/IR/IRBuilder.h"23#include "llvm/IR/InstIterator.h"24#include "llvm/IR/Instructions.h"25#include "llvm/IR/PatternMatch.h"26#include "llvm/Support/Debug.h"27#include "llvm/Support/raw_ostream.h"28#include "llvm/Transforms/Utils/Local.h"2930using namespace llvm;31using namespace PatternMatch;3233#define DEBUG_TYPE "bdce"3435STATISTIC(NumRemoved, "Number of instructions removed (unused)");36STATISTIC(NumSimplified, "Number of instructions trivialized (dead bits)");37STATISTIC(NumSExt2ZExt,38"Number of sign extension instructions converted to zero extension");3940/// If an instruction is trivialized (dead), then the chain of users of that41/// instruction may need to be cleared of assumptions that can no longer be42/// guaranteed correct.43static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) {44assert(I->getType()->isIntOrIntVectorTy() &&45"Trivializing a non-integer value?");4647// If all bits of a user are demanded, then we know that nothing below that48// in the def-use chain needs to be changed.49if (DB.getDemandedBits(I).isAllOnes())50return;5152// Initialize the worklist with eligible direct users.53SmallPtrSet<Instruction *, 16> Visited;54SmallVector<Instruction *, 16> WorkList;55for (User *JU : I->users()) {56auto *J = cast<Instruction>(JU);57if (J->getType()->isIntOrIntVectorTy()) {58Visited.insert(J);59WorkList.push_back(J);60}6162// Note that we need to check for non-int types above before asking for63// demanded bits. Normally, the only way to reach an instruction with an64// non-int type is via an instruction that has side effects (or otherwise65// will demand its input bits). However, if we have a readnone function66// that returns an unsized type (e.g., void), we must avoid asking for the67// demanded bits of the function call's return value. A void-returning68// readnone function is always dead (and so we can stop walking the use/def69// chain here), but the check is necessary to avoid asserting.70}7172// DFS through subsequent users while tracking visits to avoid cycles.73while (!WorkList.empty()) {74Instruction *J = WorkList.pop_back_val();7576// NSW, NUW, and exact are based on operands that might have changed.77J->dropPoisonGeneratingAnnotations();7879// We do not have to worry about llvm.assume, because it demands its80// operand, so trivializing can't change it.8182// If all bits of a user are demanded, then we know that nothing below83// that in the def-use chain needs to be changed.84if (DB.getDemandedBits(J).isAllOnes())85continue;8687for (User *KU : J->users()) {88auto *K = cast<Instruction>(KU);89if (Visited.insert(K).second && K->getType()->isIntOrIntVectorTy())90WorkList.push_back(K);91}92}93}9495static bool bitTrackingDCE(Function &F, DemandedBits &DB) {96SmallVector<Instruction*, 128> Worklist;97bool Changed = false;98for (Instruction &I : instructions(F)) {99// If the instruction has side effects and no non-dbg uses,100// skip it. This way we avoid computing known bits on an instruction101// that will not help us.102if (I.mayHaveSideEffects() && I.use_empty())103continue;104105// Remove instructions that are dead, either because they were not reached106// during analysis or have no demanded bits.107if (DB.isInstructionDead(&I) ||108(I.getType()->isIntOrIntVectorTy() && DB.getDemandedBits(&I).isZero() &&109wouldInstructionBeTriviallyDead(&I))) {110Worklist.push_back(&I);111Changed = true;112continue;113}114115// Convert SExt into ZExt if none of the extension bits is required116if (SExtInst *SE = dyn_cast<SExtInst>(&I)) {117APInt Demanded = DB.getDemandedBits(SE);118const uint32_t SrcBitSize = SE->getSrcTy()->getScalarSizeInBits();119auto *const DstTy = SE->getDestTy();120const uint32_t DestBitSize = DstTy->getScalarSizeInBits();121if (Demanded.countl_zero() >= (DestBitSize - SrcBitSize)) {122clearAssumptionsOfUsers(SE, DB);123IRBuilder<> Builder(SE);124I.replaceAllUsesWith(125Builder.CreateZExt(SE->getOperand(0), DstTy, SE->getName()));126Worklist.push_back(SE);127Changed = true;128NumSExt2ZExt++;129continue;130}131}132133// Simplify and, or, xor when their mask does not affect the demanded bits.134if (auto *BO = dyn_cast<BinaryOperator>(&I)) {135APInt Demanded = DB.getDemandedBits(BO);136if (!Demanded.isAllOnes()) {137const APInt *Mask;138if (match(BO->getOperand(1), m_APInt(Mask))) {139bool CanBeSimplified = false;140switch (BO->getOpcode()) {141case Instruction::Or:142case Instruction::Xor:143CanBeSimplified = !Demanded.intersects(*Mask);144break;145case Instruction::And:146CanBeSimplified = Demanded.isSubsetOf(*Mask);147break;148default:149// TODO: Handle more cases here.150break;151}152153if (CanBeSimplified) {154clearAssumptionsOfUsers(BO, DB);155BO->replaceAllUsesWith(BO->getOperand(0));156Worklist.push_back(BO);157++NumSimplified;158Changed = true;159continue;160}161}162}163}164165for (Use &U : I.operands()) {166// DemandedBits only detects dead integer uses.167if (!U->getType()->isIntOrIntVectorTy())168continue;169170if (!isa<Instruction>(U) && !isa<Argument>(U))171continue;172173if (!DB.isUseDead(&U))174continue;175176LLVM_DEBUG(dbgs() << "BDCE: Trivializing: " << U << " (all bits dead)\n");177178clearAssumptionsOfUsers(&I, DB);179180// Substitute all uses with zero. In theory we could use `freeze poison`181// instead, but that seems unlikely to be profitable.182U.set(ConstantInt::get(U->getType(), 0));183++NumSimplified;184Changed = true;185}186}187188for (Instruction *&I : llvm::reverse(Worklist)) {189salvageDebugInfo(*I);190I->dropAllReferences();191}192193for (Instruction *&I : Worklist) {194++NumRemoved;195I->eraseFromParent();196}197198return Changed;199}200201PreservedAnalyses BDCEPass::run(Function &F, FunctionAnalysisManager &AM) {202auto &DB = AM.getResult<DemandedBitsAnalysis>(F);203if (!bitTrackingDCE(F, DB))204return PreservedAnalyses::all();205206PreservedAnalyses PA;207PA.preserveSet<CFGAnalyses>();208return PA;209}210211212