46#define DEBUG_TYPE "demanded-bits"
49 return I->isTerminator() || isa<DbgInfoIntrinsic>(
I) ||
I->isEHPad() ||
50 I->mayHaveSideEffects();
53void DemandedBits::determineLiveOperandBits(
56 bool &KnownBitsComputed) {
65 auto ComputeKnownBits =
67 if (KnownBitsComputed)
69 KnownBitsComputed =
true;
83 case Instruction::Call:
84 case Instruction::Invoke:
85 if (
const auto *
II = dyn_cast<IntrinsicInst>(UserI)) {
86 switch (
II->getIntrinsicID()) {
88 case Intrinsic::bswap:
93 case Intrinsic::bitreverse:
103 ComputeKnownBits(
BitWidth, Val,
nullptr);
108 case Intrinsic::cttz:
109 if (OperandNo == 0) {
113 ComputeKnownBits(
BitWidth, Val,
nullptr);
118 case Intrinsic::fshl:
119 case Intrinsic::fshr: {
121 if (OperandNo == 2) {
130 if (
II->getIntrinsicID() == Intrinsic::fshr)
135 else if (OperandNo == 1)
140 case Intrinsic::umax:
141 case Intrinsic::umin:
142 case Intrinsic::smax:
143 case Intrinsic::smin:
151 case Instruction::Add:
159 case Instruction::Sub:
167 case Instruction::Mul:
173 case Instruction::Shl:
174 if (OperandNo == 0) {
175 const APInt *ShiftAmtC;
182 const auto *S = cast<ShlOperator>(UserI);
183 if (S->hasNoSignedWrap())
185 else if (S->hasNoUnsignedWrap())
190 case Instruction::LShr:
191 if (OperandNo == 0) {
192 const APInt *ShiftAmtC;
195 AB = AOut.
shl(ShiftAmt);
199 if (cast<LShrOperator>(UserI)->isExact())
204 case Instruction::AShr:
205 if (OperandNo == 0) {
206 const APInt *ShiftAmtC;
209 AB = AOut.
shl(ShiftAmt);
219 if (cast<AShrOperator>(UserI)->isExact())
224 case Instruction::And:
235 AB &= ~(Known.
Zero & ~Known2.Zero);
237 case Instruction::Or:
248 AB &= ~(Known.
One & ~Known2.One);
250 case Instruction::Xor:
251 case Instruction::PHI:
254 case Instruction::Trunc:
257 case Instruction::ZExt:
260 case Instruction::SExt:
270 case Instruction::Select:
274 case Instruction::ExtractElement:
278 case Instruction::InsertElement:
279 case Instruction::ShuffleVector:
280 if (OperandNo == 0 || OperandNo == 1)
286void DemandedBits::performAnalysis() {
309 if (
T->isIntOrIntVectorTy()) {
310 if (AliveBits.try_emplace(&
I,
T->getScalarSizeInBits(), 0).second)
317 for (
Use &OI :
I.operands()) {
318 if (
auto *J = dyn_cast<Instruction>(OI)) {
319 Type *
T = J->getType();
320 if (
T->isIntOrIntVectorTy())
334 while (!Worklist.
empty()) {
339 bool InputIsKnownDead =
false;
341 AOut = AliveBits[UserI];
352 bool KnownBitsComputed =
false;
359 auto *
I = dyn_cast<Instruction>(OI);
360 if (!
I && !isa<Argument>(OI))
363 Type *
T = OI->getType();
364 if (
T->isIntOrIntVectorTy()) {
365 unsigned BitWidth =
T->getScalarSizeInBits();
367 if (InputIsKnownDead) {
372 determineLiveOperandBits(UserI, OI, OI.getOperandNo(), AOut, AB,
373 Known, Known2, KnownBitsComputed);
377 DeadUses.insert(&OI);
386 auto Res = AliveBits.try_emplace(
I);
387 if (Res.second || (AB |= Res.first->second) != Res.first->second) {
388 Res.first->second = std::move(AB);
392 }
else if (
I && Visited.insert(
I).second) {
402 auto Found = AliveBits.find(
I);
403 if (Found != AliveBits.end())
404 return Found->second;
411 Type *
T = (*U)->getType();
412 auto *UserI = cast<Instruction>(U->getUser());
414 unsigned BitWidth =
DL.getTypeSizeInBits(
T->getScalarType());
418 if (!
T->isIntOrIntVectorTy())
429 bool KnownBitsComputed =
false;
431 determineLiveOperandBits(UserI, *U, U->getOperandNo(), AOut, AB, Known,
432 Known2, KnownBitsComputed);
440 return !Visited.count(
I) && !AliveBits.contains(
I) && !
isAlwaysLive(
I);
445 if (!(*U)->getType()->isIntOrIntVectorTy())
449 auto *UserI = cast<Instruction>(U->getUser());
454 if (DeadUses.count(U))
460 auto Found = AliveBits.find(UserI);
461 if (Found != AliveBits.end() && Found->second.isZero())
473 V->printAsOperand(
OS,
false);
479 OS <<
"Printing analysis 'Demanded Bits Analysis' for function '" << F.
getName() <<
"':\n";
481 for (
auto &KV : AliveBits) {
483 PrintDB(
I, KV.second);
485 for (
Use &OI :
I->operands()) {
495 bool CarryZero,
bool CarryOne) {
496 assert(!(CarryZero && CarryOne) &&
497 "Carry can't be zero and one at the same time");
515 APInt RProp = RAOut + (RAOut | ~RBound);
516 APInt RACarry = RProp ^ ~RBound;
520 APInt NeededToMaintainCarryZero;
521 APInt NeededToMaintainCarryOne;
522 if (OperandNo == 0) {
523 NeededToMaintainCarryZero =
LHS.Zero | ~RHS.Zero;
524 NeededToMaintainCarryOne =
LHS.One | ~RHS.One;
526 NeededToMaintainCarryZero =
RHS.Zero | ~LHS.Zero;
527 NeededToMaintainCarryOne =
RHS.One | ~LHS.One;
531 APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero;
532 APInt PossibleSumOne =
LHS.One +
RHS.One + CarryOne;
545 APInt NeededToMaintainCarry = (~PossibleSumZero | NeededToMaintainCarryZero) &
546 (PossibleSumOne | NeededToMaintainCarryOne);
548 APInt AB = AOut | (ACarry & NeededToMaintainCarry);
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool isAlwaysLive(Instruction *I)
static APInt determineLiveOperandBitsAddCarry(unsigned OperandNo, const APInt &AOut, const KnownBits &LHS, const KnownBits &RHS, bool CarryZero, bool CarryOne)
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
APInt zext(unsigned width) const
Zero extend to a new width.
unsigned getActiveBits() const
Compute the number of active bits in the value.
APInt trunc(unsigned width) const
Truncate to new width.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
unsigned getBitWidth() const
Return the number of bits in the APInt.
APInt reverseBits() const
unsigned countr_zero() const
Count the number of trailing zero bits.
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
bool isMask(unsigned numBits) const
APInt shl(unsigned shiftAmt) const
Left-shift function.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getBitsSetFrom(unsigned numBits, unsigned loBit)
Constructs an APInt value that has a contiguous range of bits set.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
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.
A function analysis which provides an AssumptionCache.
A parsed version of the target data layout string in and methods for querying it.
An analysis that produces DemandedBits for a function.
DemandedBits run(Function &F, FunctionAnalysisManager &AM)
Run the analysis pass over a function and produce demanded bits information.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
void print(raw_ostream &OS)
APInt getDemandedBits(Instruction *I)
Return the bits demanded from instruction I.
static APInt determineLiveOperandBitsAdd(unsigned OperandNo, const APInt &AOut, const KnownBits &LHS, const KnownBits &RHS)
Compute alive bits of one addition operand from alive output and known operand bits.
bool isInstructionDead(Instruction *I)
Return true if, during analysis, I could not be reached.
static APInt determineLiveOperandBitsSub(unsigned OperandNo, const APInt &AOut, const KnownBits &LHS, const KnownBits &RHS)
Compute alive bits of one subtraction operand from alive output and known operand bits.
bool isUseDead(Use *U)
Return whether this use is dead by means of not having any demanded bits.
Analysis pass which computes a DominatorTree.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
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.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
A SetVector that performs no allocations if smaller than a certain size.
static Twine utohexstr(const uint64_t &Val)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
constexpr unsigned BitWidth
A special type used by analysis passes to provide an address that identifies that particular analysis...
unsigned countMaxTrailingZeros() const
Returns the maximum number of trailing zero bits possible.
unsigned countMaxLeadingZeros() const
Returns the maximum number of leading zero bits possible.