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) {
294 APInt
Offset(DL.getIndexTypeSizeInBits(
Ptr->getType()), 0);
297 Offset =
Offset.sextOrTrunc(DL.getIndexTypeSizeInBits(
Ptr->getType()));
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");
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()) {
377 APInt
Offset(DL.getIndexTypeSizeInBits(
Ptr->getType()), 0);
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() >=
437 DL.getTypeStoreSize(ElemTy)) {
438 Invariants.insert(GV);
443 <<
"Found a global var, but can not treat it as an "
450 }
else if (
II->getIntrinsicID() == Intrinsic::assume) {
454 }
else if (
II->getIntrinsicID() == Intrinsic::sideeffect) {
458 }
else if (
II->getIntrinsicID() == Intrinsic::pseudoprobe) {
463 Value *Stripped = CurInst->stripPointerCastsForAliasAnalysis();
467 if (Stripped != &*CurInst) {
468 InstResult = getVal(Stripped);
472 <<
"Stripped pointer casts for alias analysis for "
473 "intrinsic call.\n");
474 StrippedPointerCastsForAliasAnalysis =
true;
487 if (!Callee ||
Callee->isInterposable()) {
492 if (
Callee->isDeclaration()) {
497 << *InstResult <<
"\n");
503 if (
Callee->getFunctionType()->isVarArg()) {
505 <<
"Can not constant fold vararg function call.\n");
511 ValueStack.emplace_back();
516 ValueStack.pop_back();
520 << *InstResult <<
"\n\n");
523 <<
"Successfully evaluated function. Result: 0\n\n");
527 }
else if (CurInst->isTerminator()) {
531 if (BI->isUnconditional()) {
532 NextBB = BI->getSuccessor(0);
536 if (!
Cond)
return false;
538 NextBB = BI->getSuccessor(!
Cond->getZExtValue());
543 if (!Val)
return false;
544 NextBB =
SI->findCaseValue(Val)->getCaseSuccessor();
548 NextBB = BA->getBasicBlock();
564 for (
Value *
Op : CurInst->operands())
565 Ops.push_back(getVal(
Op));
568 LLVM_DEBUG(
dbgs() <<
"Cannot fold instruction: " << *CurInst <<
"\n");
572 << *InstResult <<
"\n");
575 if (!CurInst->use_empty()) {
577 setVal(&*CurInst, InstResult);
582 NextBB =
II->getNormalDest();
583 LLVM_DEBUG(
dbgs() <<
"Found an invoke instruction. Finished Block.\n\n");
597 assert(ActualArgs.
size() ==
F->arg_size() &&
"wrong number of arguments");
604 CallStack.push_back(
F);
608 setVal(&Arg, ActualArgs[ArgNo]);
622 LLVM_DEBUG(
dbgs() <<
"Trying to evaluate BB: " << *CurBB <<
"\n");
624 bool StrippedPointerCastsForAliasAnalysis =
false;
626 if (!EvaluateBlock(CurInst, NextBB, StrippedPointerCastsForAliasAnalysis))
639 if (StrippedPointerCastsForAliasAnalysis &&
645 CallStack.pop_back();
652 if (!ExecutedBlocks.
insert(NextBB).second)
659 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).
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
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 * 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.