39#define DEBUG_TYPE "evaluator"
63 return !GV->hasDLLImportStorageClass() && !GV->isThreadLocal();
83 switch (CE->getOpcode()) {
84 case Instruction::BitCast:
88 case Instruction::IntToPtr:
89 case Instruction::PtrToInt:
92 if (
DL.getTypeSizeInBits(CE->getType()) !=
93 DL.getTypeSizeInBits(CE->getOperand(0)->getType()))
98 case Instruction::GetElementPtr:
99 for (
unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
104 case Instruction::Add:
118 if (!SimpleConstants.
insert(
C).second)
124void Evaluator::MutableValue::clear() {
131 const DataLayout &DL)
const {
132 TypeSize TySize = DL.getTypeStoreSize(Ty);
133 const MutableValue *
V =
this;
135 Type *AggTy = Agg->Ty;
136 std::optional<APInt>
Index = DL.getGEPIndexForOffset(AggTy,
Offset);
137 if (!Index ||
Index->uge(Agg->Elements.size()) ||
141 V = &Agg->Elements[
Index->getZExtValue()];
147bool Evaluator::MutableValue::makeMutable() {
149 Type *Ty =
C->getType();
150 unsigned NumElements;
152 NumElements = VT->getNumElements();
154 NumElements = AT->getNumElements();
156 NumElements =
ST->getNumElements();
160 MutableAggregate *MA =
new MutableAggregate(Ty);
161 MA->Elements.reserve(NumElements);
162 for (
unsigned I = 0;
I < NumElements; ++
I)
163 MA->Elements.push_back(
C->getAggregateElement(
I));
168bool Evaluator::MutableValue::write(Constant *V, APInt
Offset,
169 const DataLayout &DL) {
170 Type *Ty =
V->getType();
171 TypeSize TySize = DL.getTypeStoreSize(Ty);
172 MutableValue *MV =
this;
179 Type *AggTy = Agg->Ty;
180 std::optional<APInt>
Index = DL.getGEPIndexForOffset(AggTy,
Offset);
181 if (!Index ||
Index->uge(Agg->Elements.size()) ||
185 MV = &Agg->Elements[
Index->getZExtValue()];
188 Type *MVType = MV->getType();
194 else if (Ty != MVType)
201Constant *Evaluator::MutableAggregate::toConstant()
const {
203 for (
const MutableValue &MV : Elements)
216Constant *Evaluator::ComputeLoadResult(Constant *
P,
Type *Ty) {
217 APInt
Offset(DL.getIndexTypeSizeInBits(
P->getType()), 0);
220 Offset =
Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(
P->getType()));
222 return ComputeLoadResult(GV, Ty,
Offset);
226Constant *Evaluator::ComputeLoadResult(GlobalVariable *GV,
Type *Ty,
228 auto It = MutatedMemory.find(GV);
229 if (It != MutatedMemory.end())
230 return It->second.read(Ty,
Offset, DL);
248Evaluator::getCalleeWithFormalArgs(CallBase &CB,
249 SmallVectorImpl<Constant *> &Formals) {
252 return getFormalParams(CB, Fn, Formals) ? Fn :
nullptr;
256bool Evaluator::getFormalParams(CallBase &CB, Function *
F,
257 SmallVectorImpl<Constant *> &Formals) {
258 auto *FTy =
F->getFunctionType();
274 bool &StrippedPointerCastsForAliasAnalysis) {
279 LLVM_DEBUG(
dbgs() <<
"Evaluating Instruction: " << *CurInst <<
"\n");
282 if (
SI->isVolatile()) {
288 if (Ptr != FoldedPtr) {
289 LLVM_DEBUG(
dbgs() <<
"Folding constant ptr expression: " << *Ptr);
300 LLVM_DEBUG(
dbgs() <<
"Store is not to global with unique initializer: "
309 LLVM_DEBUG(
dbgs() <<
"Store value is too complex to evaluate store. "
315 if (!Res.first->second.write(Val,
Offset, DL))
318 if (LI->isVolatile()) {
320 dbgs() <<
"Found a Load! Volatile load, can not evaluate.\n");
324 Constant *Ptr = getVal(LI->getOperand(0));
326 if (Ptr != FoldedPtr) {
328 LLVM_DEBUG(
dbgs() <<
"Found a constant pointer expression, constant "
332 InstResult = ComputeLoadResult(Ptr, LI->getType());
335 dbgs() <<
"Failed to compute load result. Can not evaluate load."
342 if (AI->isArrayAllocation()) {
343 LLVM_DEBUG(
dbgs() <<
"Found an array alloca. Can not evaluate.\n");
346 Type *Ty = AI->getAllocatedType();
347 AllocaTmps.push_back(std::make_unique<GlobalVariable>(
350 AI->getType()->getPointerAddressSpace()));
351 InstResult = AllocaTmps.back().get();
352 LLVM_DEBUG(
dbgs() <<
"Found an alloca. Result: " << *InstResult <<
"\n");
364 if (MSI->isVolatile()) {
376 Constant *Ptr = getVal(MSI->getDest());
386 Constant *Val = getVal(MSI->getValue());
389 if (!Val->
isNullValue() || MutatedMemory.contains(GV) ||
392 APInt
Len = LenC->getValue();
393 if (
Len.ugt(64 * 1024)) {
401 if (DestVal != Val) {
403 <<
Offset <<
" of " << *GV <<
".\n");
416 if (
II->isLifetimeStartOrEnd()) {
422 if (
II->getIntrinsicID() == Intrinsic::invariant_start) {
425 if (!
II->use_empty()) {
427 <<
"Found unused invariant_start. Can't evaluate.\n");
431 Value *PtrArg = getVal(
II->getArgOperand(1));
435 if (!
Size->isMinusOne() &&
436 Size->getValue().getLimitedValue() >= MinGVSize) {
437 Invariants.insert(GV);
442 <<
"Found a global var, but can not treat it as an "
449 }
else if (
II->getIntrinsicID() == Intrinsic::assume) {
453 }
else if (
II->getIntrinsicID() == Intrinsic::sideeffect) {
457 }
else if (
II->getIntrinsicID() == Intrinsic::pseudoprobe) {
462 Value *Stripped = CurInst->stripPointerCastsForAliasAnalysis();
466 if (Stripped != &*CurInst) {
467 InstResult = getVal(Stripped);
471 <<
"Stripped pointer casts for alias analysis for "
472 "intrinsic call.\n");
473 StrippedPointerCastsForAliasAnalysis =
true;
486 if (!Callee ||
Callee->isInterposable()) {
491 if (
Callee->isDeclaration()) {
496 << *InstResult <<
"\n");
502 if (
Callee->getFunctionType()->isVarArg()) {
504 <<
"Can not constant fold vararg function call.\n");
510 ValueStack.emplace_back();
515 ValueStack.pop_back();
519 << *InstResult <<
"\n\n");
522 <<
"Successfully evaluated function. Result: 0\n\n");
526 }
else if (CurInst->isTerminator()) {
530 if (BI->isUnconditional()) {
531 NextBB = BI->getSuccessor(0);
535 if (!
Cond)
return false;
537 NextBB = BI->getSuccessor(!
Cond->getZExtValue());
542 if (!Val)
return false;
543 NextBB =
SI->findCaseValue(Val)->getCaseSuccessor();
547 NextBB = BA->getBasicBlock();
563 for (
Value *
Op : CurInst->operands())
564 Ops.push_back(getVal(
Op));
567 LLVM_DEBUG(
dbgs() <<
"Cannot fold instruction: " << *CurInst <<
"\n");
571 << *InstResult <<
"\n");
574 if (!CurInst->use_empty()) {
576 setVal(&*CurInst, InstResult);
581 NextBB =
II->getNormalDest();
582 LLVM_DEBUG(
dbgs() <<
"Found an invoke instruction. Finished Block.\n\n");
596 assert(ActualArgs.
size() ==
F->arg_size() &&
"wrong number of arguments");
603 CallStack.push_back(
F);
607 setVal(&Arg, ActualArgs[ArgNo]);
621 LLVM_DEBUG(
dbgs() <<
"Trying to evaluate BB: " << *CurBB <<
"\n");
623 bool StrippedPointerCastsForAliasAnalysis =
false;
625 if (!EvaluateBlock(CurInst, NextBB, StrippedPointerCastsForAliasAnalysis))
638 if (StrippedPointerCastsForAliasAnalysis &&
644 CallStack.pop_back();
651 if (!ExecutedBlocks.
insert(NextBB).second)
658 for (CurInst = NextBB->
begin();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool isSimpleEnoughValueToCommitHelper(Constant *C, SmallPtrSetImpl< Constant * > &SimpleConstants, const DataLayout &DL)
Return true if the specified constant can be handled by the code generator.
static bool isSimpleEnoughValueToCommit(Constant *C, SmallPtrSetImpl< Constant * > &SimpleConstants, const DataLayout &DL)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static Function * getFunction(FunctionType *Ty, const Twine &Name, Module *M)
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isInlineAsm() const
Check if this call is an inline asm statement.
Value * getCalledOperand() const
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
static LLVM_ABI bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
const Constant * stripPointerCasts() const
LLVM_ABI bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
A parsed version of the target data layout string in and methods for querying it.
bool EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl< Constant * > &ActualArgs)
Evaluate a call to function F, returning true if successful, false if we can't evaluate it.
@ InternalLinkage
Rename collisions when linking (static functions).
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
bool hasUniqueInitializer() const
hasUniqueInitializer - Whether the global variable has an initializer, and any changes made to the in...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
bool isPointerTy() const
True if this is an instance of PointerType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
LLVM_ABI Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
LLVM_ABI Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.