44 #define DEBUG_TYPE "evaluator" 67 if (
auto *GV = dyn_cast<GlobalValue>(C))
68 return !GV->hasDLLImportStorageClass() && !GV->isThreadLocal();
75 if (isa<ConstantAggregate>(C)) {
87 case Instruction::BitCast:
91 case Instruction::IntToPtr:
92 case Instruction::PtrToInt:
101 case Instruction::GetElementPtr:
121 if (!SimpleConstants.
insert(C).second)
135 if (!cast<PointerType>(C->
getType())->getElementType()->isSingleValueType())
140 return GV->hasUniqueInitializer();
144 if (CE->getOpcode() == Instruction::GetElementPtr &&
145 isa<GlobalVariable>(CE->getOperand(0)) &&
146 cast<GEPOperator>(CE)->isInBounds()) {
155 if (!CI || !CI->
isZero())
return false;
159 if (!CE->isGEPWithNoNotionalOverIndexing())
167 }
else if (CE->getOpcode() == Instruction::BitCast &&
168 isa<GlobalVariable>(CE->getOperand(0))) {
171 return cast<GlobalVariable>(CE->getOperand(0))->hasUniqueInitializer();
189 if (I != MutatedMemory.end())
return I->second;
193 if (GV->hasDefinitiveInitializer())
194 return GV->getInitializer();
199 switch (CE->getOpcode()) {
201 case Instruction::GetElementPtr:
206 case Instruction::BitCast:
208 auto MM = MutatedMemory.find(Val);
209 auto *I = (MM != MutatedMemory.end()) ? MM->second
222 if (
auto *Fn = dyn_cast<Function>(C))
225 if (
auto *Alias = dyn_cast<GlobalAlias>(C))
226 if (
auto *Fn = dyn_cast<Function>(Alias->getAliasee()))
239 if (!CE || CE->getOpcode() != Instruction::BitCast ||
259 for (
auto ParI = FTy->param_begin(), ParE = FTy->param_end(); ParI != ParE;
276 if (!RV || !CE || CE->
getOpcode() != Instruction::BitCast)
297 LLVM_DEBUG(
dbgs() <<
"Evaluating Instruction: " << *CurInst <<
"\n");
299 if (
StoreInst *
SI = dyn_cast<StoreInst>(CurInst)) {
300 if (!
SI->isSimple()) {
306 LLVM_DEBUG(
dbgs() <<
"Folding constant ptr expression: " << *Ptr);
313 dbgs() <<
"Pointer is too complex for us to evaluate store.");
322 LLVM_DEBUG(
dbgs() <<
"Store value is too complex to evaluate store. " 328 if (CE->getOpcode() == Instruction::BitCast) {
330 <<
"Attempting to resolve bitcast on constant ptr.\n");
334 Ptr = CE->getOperand(0);
336 Type *NewTy = cast<PointerType>(Ptr->
getType())->getElementType();
346 if (
StructType *STy = dyn_cast<StructType>(NewTy)) {
347 NewTy = STy->getTypeAtIndex(0U);
351 Constant *
const IdxList[] = {IdxZero, IdxZero};
371 MutatedMemory[Ptr] = Val;
372 }
else if (
BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
374 getVal(BO->getOperand(0)),
375 getVal(BO->getOperand(1)));
377 << *InstResult <<
"\n");
378 }
else if (
CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
380 getVal(CI->getOperand(0)),
381 getVal(CI->getOperand(1)));
382 LLVM_DEBUG(
dbgs() <<
"Found a CmpInst! Simplifying: " << *InstResult
384 }
else if (
CastInst *CI = dyn_cast<CastInst>(CurInst)) {
386 getVal(CI->getOperand(0)),
390 }
else if (
SelectInst *
SI = dyn_cast<SelectInst>(CurInst)) {
394 LLVM_DEBUG(
dbgs() <<
"Found a Select! Simplifying: " << *InstResult
396 }
else if (
auto *EVI = dyn_cast<ExtractValueInst>(CurInst)) {
398 getVal(EVI->getAggregateOperand()), EVI->getIndices());
400 << *InstResult <<
"\n");
401 }
else if (
auto *IVI = dyn_cast<InsertValueInst>(CurInst)) {
403 getVal(IVI->getAggregateOperand()),
404 getVal(IVI->getInsertedValueOperand()), IVI->getIndices());
406 << *InstResult <<
"\n");
415 cast<GEPOperator>(
GEP)->isInBounds());
416 LLVM_DEBUG(
dbgs() <<
"Found a GEP! Simplifying: " << *InstResult <<
"\n");
417 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
418 if (!LI->isSimple()) {
420 dbgs() <<
"Found a Load! Not a simple load, can not evaluate.\n");
427 LLVM_DEBUG(
dbgs() <<
"Found a constant pointer expression, constant " 431 InstResult = ComputeLoadResult(Ptr);
434 dbgs() <<
"Failed to compute load result. Can not evaluate load." 440 }
else if (
AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
441 if (AI->isArrayAllocation()) {
442 LLVM_DEBUG(
dbgs() <<
"Found an array alloca. Can not evaluate.\n");
445 Type *Ty = AI->getAllocatedType();
446 AllocaTmps.push_back(llvm::make_unique<GlobalVariable>(
449 AI->getType()->getPointerAddressSpace()));
450 InstResult = AllocaTmps.back().get();
451 LLVM_DEBUG(
dbgs() <<
"Found an alloca. Result: " << *InstResult <<
"\n");
452 }
else if (isa<CallInst>(CurInst) || isa<InvokeInst>(CurInst)) {
469 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(II)) {
470 if (MSI->isVolatile()) {
478 if (Val->isNullValue() && DestVal && DestVal->isNullValue()) {
486 if (II->isLifetimeStartOrEnd()) {
495 if (!II->use_empty()) {
497 <<
"Found unused invariant_start. Can't evaluate.\n");
504 Type *ElemTy = GV->getValueType();
508 Invariants.insert(GV);
513 <<
"Found a global var, but can not treat it as an " 549 << *InstResult <<
"\n");
556 LLVM_DEBUG(
dbgs() <<
"Can not constant fold vararg function call.\n");
562 ValueStack.emplace_back();
567 ValueStack.pop_back();
569 if (RetVal && !InstResult)
574 << *InstResult <<
"\n\n");
577 <<
"Successfully evaluated function. Result: 0\n\n");
580 }
else if (CurInst->isTerminator()) {
583 if (
BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
584 if (BI->isUnconditional()) {
585 NextBB = BI->getSuccessor(0);
589 if (!Cond)
return false;
593 }
else if (
SwitchInst *
SI = dyn_cast<SwitchInst>(CurInst)) {
596 if (!Val)
return false;
597 NextBB =
SI->findCaseValue(Val)->getCaseSuccessor();
598 }
else if (
IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) {
599 Value *Val =
getVal(IBI->getAddress())->stripPointerCasts();
601 NextBB = BA->getBasicBlock();
604 }
else if (isa<ReturnInst>(CurInst)) {
618 dbgs() <<
"Failed to evaluate block due to unhandled instruction." 623 if (!CurInst->use_empty()) {
625 InstResult = FoldedInstResult;
627 setVal(&*CurInst, InstResult);
631 if (
InvokeInst *II = dyn_cast<InvokeInst>(CurInst)) {
632 NextBB = II->getNormalDest();
633 LLVM_DEBUG(
dbgs() <<
"Found an invoke instruction. Finished Block.\n\n");
652 CallStack.push_back(F);
658 setVal(&*AI, ActualArgs[ArgNo]);
672 LLVM_DEBUG(
dbgs() <<
"Trying to evaluate BB: " << *CurBB <<
"\n");
683 CallStack.pop_back();
690 if (!ExecutedBlocks.
insert(NextBB).second)
697 for (CurInst = NextBB->
begin();
Return a value (possibly void), from a function.
A parsed version of the target data layout string in and methods for querying it. ...
This class is the base class for the comparison instructions.
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
This class represents an incoming formal argument to a Function.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This class represents lattice values for constants.
Constant * ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE)
ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a getelementptr constantexpr, return the constant value being addressed by the constant expression, or null if something is funny and we can't decide.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant *> IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
void push_back(const T &Elt)
bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB)
Evaluate all instructions in block BB, returning true if successful, false if we can't evaluate it...
bool getFormalParams(CallSite &CS, Function *F, SmallVector< Constant *, 8 > &Formals)
Given call site and callee returns list of callee formal argument values converting them when necessa...
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time...
This class wraps the llvm.memset intrinsic.
An instruction for reading from memory.
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
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 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...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
The address of a basic block.
This class represents the LLVM 'select' instruction.
Type * getPointerElementType() const
This is the base class for all instructions that perform data casts.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
InstrTy * getInstruction() const
ValTy * getCalledValue() const
Return the pointer to function that is being called.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Attempt to fold the constant using the specified DataLayout.
A constant value that is initialized with an expression using other constant values.
Type * getType() const
All values are typed, get the type of this value.
static Constant * getSelect(Constant *C, Constant *V1, Constant *V2, Type *OnlyIfReducedTy=nullptr)
Select constant expr.
const APInt & getValue() const
Return the constant as an APInt value reference.
An instruction for storing to memory.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static Function * getFunction(Constant *C)
amdgpu Simplify well known AMD library false Value * Callee
Value * getOperand(unsigned i) const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
static Constant * getInsertValue(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs, Type *OnlyIfReducedTy=nullptr)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Conditional or Unconditional Branch instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
void setVal(Value *V, Constant *C)
Value * getIncomingValueForBlock(const BasicBlock *BB) const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Indirect Branch Instruction.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool hasUniqueInitializer() const
hasUniqueInitializer - Whether the global variable has an initializer, and any changes made to the in...
static bool isSimpleEnoughValueToCommit(Constant *C, SmallPtrSetImpl< Constant *> &SimpleConstants, const DataLayout &DL)
static bool isSimpleEnoughValueToCommitHelper(Constant *C, SmallPtrSetImpl< Constant *> &SimpleConstants, const DataLayout &DL)
Return true if the specified constant can be handled by the code generator.
Class to represent integer types.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
unsigned getNumArgOperands() const
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
Constant * getVal(Value *V)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static Constant * getInitializer(Constant *C)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
static bool isSimpleEnoughPointerToCommit(Constant *C)
Return true if this constant is simple enough for us to understand.
InstListType::iterator iterator
Instruction iterators...
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
Function * getCalleeWithFormalArgs(CallSite &CS, SmallVector< Constant *, 8 > &Formals)
Given call site return callee and list of its formal arguments.
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...
StringRef getName() const
Return a constant reference to the value's name.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
Constant * castCallResultIfNeeded(Value *CallExpr, Constant *RV)
Casts call result to a type of bitcast call expression.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Rename collisions when linking (static functions).
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
const BasicBlock & front() const
LLVM Value Representation.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Constant * ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, const DataLayout &DL)
ConstantFoldLoadThroughBitcast - try to cast constant to destination type returning null if unsuccess...
static Constant * getExtractValue(Constant *Agg, ArrayRef< unsigned > Idxs, Type *OnlyIfReducedTy=nullptr)
Constant * ConstantFoldCall(ImmutableCallSite CS, Function *F, ArrayRef< Constant *> Operands, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
A wrapper class for inspecting calls to intrinsic functions.
an instruction to allocate memory on the stack
static Constant * get(unsigned Opcode, Constant *C1, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a unary operator constant expression, folding if possible.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.