#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueLattice.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
usingnamespacellvm;
usingnamespacePatternMatch;
#define DEBUG_TYPE …
static const unsigned MaxProcessedPerValue = …;
char LazyValueInfoWrapperPass::ID = …;
LazyValueInfoWrapperPass::LazyValueInfoWrapperPass() : … { … }
INITIALIZE_PASS_BEGIN(LazyValueInfoWrapperPass, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_END(LazyValueInfoWrapperPass, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
namespace llvm {
FunctionPass *createLazyValueInfoPass() { … }
}
AnalysisKey LazyValueAnalysis::Key;
static bool hasSingleValue(const ValueLatticeElement &Val) { … }
namespace {
class LazyValueInfoCache;
struct LVIValueHandle final : public CallbackVH { … };
}
namespace {
NonNullPointerSet;
class LazyValueInfoCache { … };
}
void LazyValueInfoCache::eraseValue(Value *V) { … }
void LVIValueHandle::deleted() { … }
void LazyValueInfoCache::eraseBlock(BasicBlock *BB) { … }
void LazyValueInfoCache::threadEdgeImpl(BasicBlock *OldSucc,
BasicBlock *NewSucc) { … }
namespace llvm {
namespace {
class LazyValueInfoAnnotatedWriter : public AssemblyAnnotationWriter { … };
}
class LazyValueInfoImpl { … };
}
void LazyValueInfoImpl::solve() { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::getBlockValue(Value *Val, BasicBlock *BB,
Instruction *CxtI) { … }
static ValueLatticeElement getFromRangeMetadata(Instruction *BBI) { … }
bool LazyValueInfoImpl::solveBlockValue(Value *Val, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueImpl(Value *Val, BasicBlock *BB) { … }
static void AddNonNullPointer(Value *Ptr, NonNullPointerSet &PtrSet) { … }
static void AddNonNullPointersByInstruction(
Instruction *I, NonNullPointerSet &PtrSet) { … }
bool LazyValueInfoImpl::isNonNullAtEndOfBlock(Value *Val, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValuePHINode(PHINode *PN, BasicBlock *BB) { … }
void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
Value *Val, ValueLatticeElement &BBLV, Instruction *BBI) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueSelect(SelectInst *SI, BasicBlock *BB) { … }
std::optional<ConstantRange>
LazyValueInfoImpl::getRangeFor(Value *V, Instruction *CxtI, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueCast(CastInst *CI, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueBinaryOpImpl(
Instruction *I, BasicBlock *BB,
std::function<ConstantRange(const ConstantRange &, const ConstantRange &)>
OpFn) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueBinaryOp(BinaryOperator *BO, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueOverflowIntrinsic(WithOverflowInst *WO,
BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueIntrinsic(IntrinsicInst *II, BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueInsertElement(InsertElementInst *IEI,
BasicBlock *BB) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueExtractValue(ExtractValueInst *EVI,
BasicBlock *BB) { … }
static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val,
ICmpInst::Predicate Pred) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::getValueFromSimpleICmpCondition(CmpInst::Predicate Pred,
Value *RHS,
const APInt &Offset,
Instruction *CxtI,
bool UseBlockValue) { … }
static std::optional<ConstantRange>
getRangeViaSLT(CmpInst::Predicate Pred, APInt RHS,
function_ref<std::optional<ConstantRange>(const APInt &)> Fn) { … }
std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
Value *Val, ICmpInst *ICI, bool isTrueDest, bool UseBlockValue) { … }
static ValueLatticeElement getValueFromOverflowCondition(
Value *Val, WithOverflowInst *WO, bool IsTrueDest) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::getValueFromCondition(Value *Val, Value *Cond,
bool IsTrueDest, bool UseBlockValue,
unsigned Depth) { … }
static bool usesOperand(User *Usr, Value *Op) { … }
static bool isOperationFoldable(User *Usr) { … }
static ValueLatticeElement constantFoldUser(User *Usr, Value *Op,
const APInt &OpConstVal,
const DataLayout &DL) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
BasicBlock *BBTo, bool UseBlockValue) { … }
std::optional<ValueLatticeElement>
LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
BasicBlock *BBTo, Instruction *CxtI) { … }
ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
Instruction *CxtI) { … }
ValueLatticeElement LazyValueInfoImpl::getValueAt(Value *V, Instruction *CxtI) { … }
ValueLatticeElement LazyValueInfoImpl::
getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
Instruction *CxtI) { … }
ValueLatticeElement LazyValueInfoImpl::getValueAtUse(const Use &U) { … }
void LazyValueInfoImpl::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
BasicBlock *NewSucc) { … }
bool LazyValueInfoWrapperPass::runOnFunction(Function &F) { … }
void LazyValueInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { … }
LazyValueInfo &LazyValueInfoWrapperPass::getLVI() { … }
LazyValueInfoImpl &LazyValueInfo::getOrCreateImpl(const Module *M) { … }
LazyValueInfoImpl *LazyValueInfo::getImpl() { … }
LazyValueInfo::~LazyValueInfo() { … }
void LazyValueInfo::releaseMemory() { … }
bool LazyValueInfo::invalidate(Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &Inv) { … }
void LazyValueInfoWrapperPass::releaseMemory() { … }
LazyValueInfo LazyValueAnalysis::run(Function &F,
FunctionAnalysisManager &FAM) { … }
static bool isKnownNonConstant(Value *V) { … }
Constant *LazyValueInfo::getConstant(Value *V, Instruction *CxtI) { … }
ConstantRange LazyValueInfo::getConstantRange(Value *V, Instruction *CxtI,
bool UndefAllowed) { … }
ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
bool UndefAllowed) { … }
Constant *LazyValueInfo::getConstantOnEdge(Value *V, BasicBlock *FromBB,
BasicBlock *ToBB,
Instruction *CxtI) { … }
ConstantRange LazyValueInfo::getConstantRangeOnEdge(Value *V,
BasicBlock *FromBB,
BasicBlock *ToBB,
Instruction *CxtI) { … }
static Constant *getPredicateResult(CmpInst::Predicate Pred, Constant *C,
const ValueLatticeElement &Val,
const DataLayout &DL) { … }
Constant *LazyValueInfo::getPredicateOnEdge(CmpInst::Predicate Pred, Value *V,
Constant *C, BasicBlock *FromBB,
BasicBlock *ToBB,
Instruction *CxtI) { … }
Constant *LazyValueInfo::getPredicateAt(CmpInst::Predicate Pred, Value *V,
Constant *C, Instruction *CxtI,
bool UseBlockValue) { … }
Constant *LazyValueInfo::getPredicateAt(CmpInst::Predicate Pred, Value *LHS,
Value *RHS, Instruction *CxtI,
bool UseBlockValue) { … }
void LazyValueInfo::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc,
BasicBlock *NewSucc) { … }
void LazyValueInfo::forgetValue(Value *V) { … }
void LazyValueInfo::eraseBlock(BasicBlock *BB) { … }
void LazyValueInfo::clear() { … }
void LazyValueInfo::printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS) { … }
void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
const BasicBlock *BB, formatted_raw_ostream &OS) { … }
void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
const Instruction *I, formatted_raw_ostream &OS) { … }
PreservedAnalyses LazyValueInfoPrinterPass::run(Function &F,
FunctionAnalysisManager &AM) { … }