32using namespace PatternMatch;
34#define DEBUG_TYPE "bdce"
36STATISTIC(NumRemoved,
"Number of instructions removed (unused)");
37STATISTIC(NumSimplified,
"Number of instructions trivialized (dead bits)");
39 "Number of sign extension instructions converted to zero extension");
45 assert(
I->getType()->isIntOrIntVectorTy() &&
46 "Trivializing a non-integer value?");
50 if (DB.getDemandedBits(
I).isAllOnes())
56 for (
User *JU :
I->users()) {
57 auto *J = cast<Instruction>(JU);
58 if (J->getType()->isIntOrIntVectorTy()) {
74 while (!WorkList.
empty()) {
85 if (DB.getDemandedBits(J).isAllOnes())
89 auto *K = cast<Instruction>(KU);
90 if (Visited.
insert(K).second && K->getType()->isIntOrIntVectorTy())
103 if (
I.mayHaveSideEffects() &&
I.use_empty())
108 if (DB.isInstructionDead(&
I) ||
109 (
I.getType()->isIntOrIntVectorTy() && DB.getDemandedBits(&
I).isZero() &&
117 if (
SExtInst *SE = dyn_cast<SExtInst>(&
I)) {
118 APInt Demanded = DB.getDemandedBits(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)) {
125 I.replaceAllUsesWith(
126 Builder.
CreateZExt(SE->getOperand(0), DstTy, SE->getName()));
135 if (
auto *BO = dyn_cast<BinaryOperator>(&
I)) {
136 APInt Demanded = DB.getDemandedBits(BO);
140 bool CanBeSimplified =
false;
141 switch (BO->getOpcode()) {
142 case Instruction::Or:
143 case Instruction::Xor:
144 CanBeSimplified = !Demanded.
intersects(*Mask);
146 case Instruction::And:
154 if (CanBeSimplified) {
156 BO->replaceAllUsesWith(BO->getOperand(0));
166 for (
Use &U :
I.operands()) {
168 if (!U->getType()->isIntOrIntVectorTy())
171 if (!isa<Instruction>(U) && !isa<Argument>(U))
174 if (!DB.isUseDead(&U))
177 LLVM_DEBUG(
dbgs() <<
"BDCE: Trivializing: " << U <<
" (all bits dead)\n");
183 U.set(ConstantInt::get(U->getType(), 0));
191 I->dropAllReferences();
196 I->eraseFromParent();
Expand Atomic instructions
static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB)
If an instruction is trivialized (dead), then the chain of users of that instruction may need to be c...
static bool bitTrackingDCE(Function &F, DemandedBits &DB)
This is the interface for a simple mod/ref and alias analysis over globals.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool intersects(const APInt &RHS) const
This operation tests if there are any pairs of corresponding bits between this APInt and RHS that are...
unsigned countl_zero() const
The APInt version of std::countl_zero.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represents analyses that only rely on functions' control flow.
An analysis that produces DemandedBits for a function.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void dropPoisonGeneratingAnnotations()
Drops flags, return attributes and metadata that may generate poison.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
This class represents a sign extension of integer types.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A Use represents the edge between a Value definition and its users.
iterator_range< user_iterator > users()
bool match(Val *V, const Pattern &P)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
This is an optimization pass for GlobalISel generic memory operations.
void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)