43 #define DEBUG_TYPE "demanded-bits"
47 "Demanded bits analysis",
false,
false)
69 return isa<TerminatorInst>(
I) || isa<DbgInfoIntrinsic>(I) ||
73 void DemandedBits::determineLiveOperandBits(
85 auto ComputeKnownBits =
86 [&](
unsigned BitWidth,
const Value *V1,
const Value *
V2) {
88 KnownZero =
APInt(BitWidth, 0);
89 KnownOne =
APInt(BitWidth, 0);
94 KnownZero2 =
APInt(BitWidth, 0);
95 KnownOne2 =
APInt(BitWidth, 0);
104 case Instruction::Invoke:
105 if (
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(UserI))
106 switch (II->getIntrinsicID()) {
108 case Intrinsic::bswap:
113 case Intrinsic::ctlz:
114 if (OperandNo == 0) {
118 ComputeKnownBits(BitWidth, I,
nullptr);
123 case Intrinsic::cttz:
124 if (OperandNo == 0) {
128 ComputeKnownBits(BitWidth, I,
nullptr);
136 case Instruction::Sub:
137 case Instruction::Mul:
143 case Instruction::Shl:
146 dyn_cast<ConstantInt>(UserI->
getOperand(1))) {
148 AB = AOut.
lshr(ShiftAmt);
159 case Instruction::LShr:
162 dyn_cast<ConstantInt>(UserI->
getOperand(1))) {
164 AB = AOut.
shl(ShiftAmt);
168 if (cast<LShrOperator>(UserI)->isExact())
172 case Instruction::AShr:
175 dyn_cast<ConstantInt>(UserI->
getOperand(1))) {
176 uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1);
177 AB = AOut.
shl(ShiftAmt);
187 if (cast<AShrOperator>(UserI)->isExact())
198 if (OperandNo == 0) {
199 ComputeKnownBits(BitWidth, I, UserI->
getOperand(1));
203 ComputeKnownBits(BitWidth, UserI->
getOperand(0),
I);
204 AB &= ~(KnownZero & ~KnownZero2);
214 if (OperandNo == 0) {
215 ComputeKnownBits(BitWidth, I, UserI->
getOperand(1));
219 ComputeKnownBits(BitWidth, UserI->
getOperand(0),
I);
220 AB &= ~(KnownOne & ~KnownOne2);
224 case Instruction::PHI:
227 case Instruction::Trunc:
228 AB = AOut.
zext(BitWidth);
230 case Instruction::ZExt:
231 AB = AOut.
trunc(BitWidth);
233 case Instruction::SExt:
234 AB = AOut.
trunc(BitWidth);
251 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
252 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
253 DB.emplace(F, AC, DT);
261 void DemandedBits::performAnalysis() {
277 DEBUG(
dbgs() <<
"DemandedBits: Root: " << I <<
"\n");
283 if (AliveBits.try_emplace(&I,
IT->getBitWidth(), 0).second)
304 while (!Worklist.
empty()) {
307 DEBUG(
dbgs() <<
"DemandedBits: Visiting: " << *UserI);
310 AOut = AliveBits[UserI];
316 Visited.insert(UserI);
318 APInt KnownZero, KnownOne, KnownZero2, KnownOne2;
325 unsigned BitWidth =
IT->getBitWidth();
329 AB =
APInt(BitWidth, 0);
334 determineLiveOperandBits(UserI, I, OI.getOperandNo(), AOut, AB,
336 KnownZero2, KnownOne2);
342 APInt ABPrev(BitWidth, 0);
343 auto ABI = AliveBits.find(I);
344 if (ABI != AliveBits.end())
345 ABPrev = ABI->second;
347 APInt ABNew = AB | ABPrev;
348 if (ABNew != ABPrev || ABI == AliveBits.end()) {
349 AliveBits[
I] = std::move(ABNew);
352 }
else if (!Visited.count(I)) {
364 auto Found = AliveBits.find(I);
365 if (Found != AliveBits.end())
366 return Found->second;
373 return !Visited.count(I) && AliveBits.find(I) == AliveBits.end() &&
379 for (
auto &KV : AliveBits) {
380 OS <<
"DemandedBits: 0x" <<
utohexstr(KV.second.getLimitedValue()) <<
" for "
381 << *KV.first <<
"\n";
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7")))
void computeKnownBits(const Value *V, APInt &KnownZero, APInt &KnownOne, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
void initializeDemandedBitsWrapperPassPass(PassRegistry &)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
A Module instance is used to store all the information related to an LLVM module. ...
bool isInstructionDead(Instruction *I)
Return true if, during analysis, I could not be reached.
void setBit(unsigned bitPosition)
Set a given bit to 1.
bool hasNoSignedWrap() const
Test whether this operation is known to never undergo signed overflow, aka the nsw property...
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
An immutable pass that tracks lazily created AssumptionCache objects.
bool mayHaveSideEffects() const
Return true if the instruction may have side effects.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
If this value is smaller than the specified limit, return it, otherwise return the limit value...
Analysis pass which computes a DominatorTree.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
A Use represents the edge between a Value definition and its users.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
An analysis that produces DemandedBits for a function.
LLVM_NODISCARD bool empty() const
APInt shl(unsigned shiftAmt) const
Left-shift function.
demanded Demanded bits false
unsigned getActiveBits() const
Compute the number of active bits in the value.
DemandedBits run(Function &F, FunctionAnalysisManager &AM)
Run the analysis pass over a function and produce demanded bits information.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
APInt trunc(unsigned width) const
Truncate to new width.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
unsigned getBitWidth() const
Return the number of bits in the APInt.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Class to represent integer types.
demanded Demanded bits analysis
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
A function analysis which provides an AssumptionCache.
INITIALIZE_PASS_BEGIN(DemandedBitsWrapperPass,"demanded-bits","Demanded bits analysis", false, false) INITIALIZE_PASS_END(DemandedBitsWrapperPass
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This is the shared class of boolean and integer constants.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
LLVM_NODISCARD T pop_back_val()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
APInt getDemandedBits(Instruction *I)
Return the bits demanded from instruction I.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
bool isIntegerTy() const
True if this is an instance of IntegerType.
void setPreservesAll()
Set by analyses that do not transform their input at all.
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
void print(raw_ostream &OS, const Module *M) const override
print - Print out the internal state of the pass.
static std::string utohexstr(uint64_t X, bool LowerCase=false)
LLVM Value Representation.
static bool isAlwaysLive(Instruction *I)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
This class implements an extremely fast bulk output stream that can only output to a stream...
unsigned countLeadingZeros() const
The APInt version of the countLeadingZeros functions in MathExtras.h.
inst_range instructions(Function *F)
APInt zext(unsigned width) const
Zero extend to a new width.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
FunctionPass * createDemandedBitsWrapperPass()
Create a demanded bits analysis pass.
A special type used by analysis passes to provide an address that identifies that particular analysis...
const BasicBlock * getParent() const
void releaseMemory() override
Clean up memory in between runs.
bool hasNoUnsignedWrap() const
Test whether this operation is known to never undergo unsigned overflow, aka the nuw property...
void print(raw_ostream &OS)
A wrapper class for inspecting calls to intrinsic functions.