28 #define DEBUG_TYPE "evaluator"
51 if (
auto *GV = dyn_cast<GlobalValue>(C))
52 return !GV->hasDLLImportStorageClass() && !GV->isThreadLocal();
59 if (isa<ConstantAggregate>(C)) {
71 case Instruction::BitCast:
75 case Instruction::IntToPtr:
76 case Instruction::PtrToInt:
85 case Instruction::GetElementPtr:
105 if (!SimpleConstants.
insert(C).second)
119 if (!cast<PointerType>(C->
getType())->getElementType()->isSingleValueType())
124 return GV->hasUniqueInitializer();
128 if (CE->getOpcode() == Instruction::GetElementPtr &&
129 isa<GlobalVariable>(CE->getOperand(0)) &&
130 cast<GEPOperator>(CE)->isInBounds()) {
139 if (!CI || !CI->
isZero())
return false;
143 if (!CE->isGEPWithNoNotionalOverIndexing())
151 }
else if (CE->getOpcode() == Instruction::BitCast &&
152 isa<GlobalVariable>(CE->getOperand(0))) {
155 return cast<GlobalVariable>(CE->getOperand(0))->hasUniqueInitializer();
168 if (I != MutatedMemory.end())
return I->second;
172 if (GV->hasDefinitiveInitializer())
173 return GV->getInitializer();
179 if (
CE->getOpcode() == Instruction::GetElementPtr &&
180 isa<GlobalVariable>(
CE->getOperand(0))) {
198 DEBUG(
dbgs() <<
"Evaluating Instruction: " << *CurInst <<
"\n");
200 if (
StoreInst *
SI = dyn_cast<StoreInst>(CurInst)) {
201 if (!
SI->isSimple()) {
202 DEBUG(
dbgs() <<
"Store is not simple! Can not evaluate.\n");
207 DEBUG(
dbgs() <<
"Folding constant ptr expression: " << *Ptr);
209 DEBUG(
dbgs() <<
"; To: " << *Ptr <<
"\n");
213 DEBUG(
dbgs() <<
"Pointer is too complex for us to evaluate store.");
222 DEBUG(
dbgs() <<
"Store value is too complex to evaluate store. " << *Val
228 if (CE->getOpcode() == Instruction::BitCast) {
229 DEBUG(
dbgs() <<
"Attempting to resolve bitcast on constant ptr.\n");
233 Ptr = CE->getOperand(0);
235 Type *NewTy = cast<PointerType>(Ptr->
getType())->getElementType();
244 if (
StructType *STy = dyn_cast<StructType>(NewTy)) {
245 NewTy = STy->getTypeAtIndex(0U);
249 Constant *
const IdxList[] = {IdxZero, IdxZero};
258 DEBUG(
dbgs() <<
"Failed to bitcast constant ptr, can not "
268 DEBUG(
dbgs() <<
"Evaluated bitcast: " << *Val <<
"\n");
272 MutatedMemory[
Ptr] = Val;
273 }
else if (
BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
275 getVal(BO->getOperand(0)),
276 getVal(BO->getOperand(1)));
277 DEBUG(
dbgs() <<
"Found a BinaryOperator! Simplifying: " << *InstResult
279 }
else if (
CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
281 getVal(CI->getOperand(0)),
282 getVal(CI->getOperand(1)));
283 DEBUG(
dbgs() <<
"Found a CmpInst! Simplifying: " << *InstResult
285 }
else if (
CastInst *CI = dyn_cast<CastInst>(CurInst)) {
287 getVal(CI->getOperand(0)),
289 DEBUG(
dbgs() <<
"Found a Cast! Simplifying: " << *InstResult
291 }
else if (
SelectInst *
SI = dyn_cast<SelectInst>(CurInst)) {
295 DEBUG(
dbgs() <<
"Found a Select! Simplifying: " << *InstResult
297 }
else if (
auto *EVI = dyn_cast<ExtractValueInst>(CurInst)) {
299 getVal(EVI->getAggregateOperand()), EVI->getIndices());
300 DEBUG(
dbgs() <<
"Found an ExtractValueInst! Simplifying: " << *InstResult
302 }
else if (
auto *IVI = dyn_cast<InsertValueInst>(CurInst)) {
304 getVal(IVI->getAggregateOperand()),
305 getVal(IVI->getInsertedValueOperand()), IVI->getIndices());
306 DEBUG(
dbgs() <<
"Found an InsertValueInst! Simplifying: " << *InstResult
316 cast<GEPOperator>(
GEP)->isInBounds());
317 DEBUG(
dbgs() <<
"Found a GEP! Simplifying: " << *InstResult
319 }
else if (
LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
321 if (!LI->isSimple()) {
322 DEBUG(
dbgs() <<
"Found a Load! Not a simple load, can not evaluate.\n");
329 DEBUG(
dbgs() <<
"Found a constant pointer expression, constant "
330 "folding: " << *Ptr <<
"\n");
332 InstResult = ComputeLoadResult(Ptr);
334 DEBUG(
dbgs() <<
"Failed to compute load result. Can not evaluate load."
339 DEBUG(
dbgs() <<
"Evaluated load: " << *InstResult <<
"\n");
340 }
else if (
AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
341 if (AI->isArrayAllocation()) {
342 DEBUG(
dbgs() <<
"Found an array alloca. Can not evaluate.\n");
345 Type *Ty = AI->getAllocatedType();
346 AllocaTmps.push_back(
349 InstResult = AllocaTmps.back().get();
350 DEBUG(
dbgs() <<
"Found an alloca. Result: " << *InstResult <<
"\n");
351 }
else if (isa<CallInst>(CurInst) || isa<InvokeInst>(CurInst)) {
356 DEBUG(
dbgs() <<
"Ignoring debug info.\n");
363 DEBUG(
dbgs() <<
"Found inline asm, can not evaluate.\n");
368 if (
MemSetInst *MSI = dyn_cast<MemSetInst>(II)) {
369 if (MSI->isVolatile()) {
370 DEBUG(
dbgs() <<
"Can not optimize a volatile memset " <<
377 if (Val->isNullValue() && DestVal && DestVal->isNullValue()) {
379 DEBUG(
dbgs() <<
"Ignoring no-op memset.\n");
385 if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
386 II->getIntrinsicID() == Intrinsic::lifetime_end) {
387 DEBUG(
dbgs() <<
"Ignoring lifetime intrinsic.\n");
392 if (II->getIntrinsicID() == Intrinsic::invariant_start) {
395 if (!II->use_empty()) {
396 DEBUG(
dbgs() <<
"Found unused invariant_start. Can't evaluate.\n");
399 ConstantInt *Size = cast<ConstantInt>(II->getArgOperand(0));
401 Value *
Ptr = PtrArg->stripPointerCasts();
407 Invariants.insert(GV);
408 DEBUG(
dbgs() <<
"Found a global var that is an invariant: " << *GV
411 DEBUG(
dbgs() <<
"Found a global var, but can not treat it as an "
418 }
else if (II->getIntrinsicID() == Intrinsic::assume) {
419 DEBUG(
dbgs() <<
"Skipping assume intrinsic.\n");
424 DEBUG(
dbgs() <<
"Unknown intrinsic. Can not evaluate.\n");
431 DEBUG(
dbgs() <<
"Can not resolve function pointer.\n");
443 DEBUG(
dbgs() <<
"Constant folded function call. Result: " <<
444 *InstResult <<
"\n");
446 DEBUG(
dbgs() <<
"Can not constant fold function call.\n");
451 DEBUG(
dbgs() <<
"Can not constant fold vararg function call.\n");
457 ValueStack.emplace_back();
459 DEBUG(
dbgs() <<
"Failed to evaluate function.\n");
462 ValueStack.pop_back();
466 DEBUG(
dbgs() <<
"Successfully evaluated function. Result: "
467 << *InstResult <<
"\n\n");
469 DEBUG(
dbgs() <<
"Successfully evaluated function. Result: 0\n\n");
472 }
else if (isa<TerminatorInst>(CurInst)) {
473 DEBUG(
dbgs() <<
"Found a terminator instruction.\n");
475 if (
BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
476 if (BI->isUnconditional()) {
477 NextBB = BI->getSuccessor(0);
481 if (!Cond)
return false;
485 }
else if (
SwitchInst *
SI = dyn_cast<SwitchInst>(CurInst)) {
488 if (!Val)
return false;
489 NextBB =
SI->findCaseValue(Val).getCaseSuccessor();
490 }
else if (
IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) {
491 Value *Val =
getVal(IBI->getAddress())->stripPointerCasts();
493 NextBB = BA->getBasicBlock();
496 }
else if (isa<ReturnInst>(CurInst)) {
500 DEBUG(
dbgs() <<
"Can not handle terminator.");
505 DEBUG(
dbgs() <<
"Successfully evaluated block.\n");
509 DEBUG(
dbgs() <<
"Failed to evaluate block due to unhandled instruction."
514 if (!CurInst->use_empty()) {
516 InstResult = FoldedInstResult;
518 setVal(&*CurInst, InstResult);
522 if (
InvokeInst *II = dyn_cast<InvokeInst>(CurInst)) {
523 NextBB = II->getNormalDest();
524 DEBUG(
dbgs() <<
"Found an invoke instruction. Finished Block.\n\n");
543 CallStack.push_back(F);
549 setVal(&*AI, ActualArgs[ArgNo]);
563 DEBUG(
dbgs() <<
"Trying to evaluate BB: " << *CurBB <<
"\n");
574 CallStack.pop_back();
581 if (!ExecutedBlocks.
insert(NextBB).second)
588 for (CurInst = NextBB->
begin();
Return a value (possibly void), from a function.
void push_back(const T &Elt)
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.
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.
unsigned getNumOperands() const
bool EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB)
Evaluate all instructions in block BB, returning true if successful, false if we can't evaluate it...
Type * getValueType() const
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
uint64_t getLimitedValue(uint64_t Limit=~0ULL) const
If this value is smaller than the specified limit, return it, otherwise return the limit value...
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 Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
unsigned getOpcode() const
Return the opcode at the root of this constant expression.
StringRef getName() const
Return a constant reference to the value's name.
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.
This is the base class for all instructions that perform data casts.
const APInt & getValue() const
Return the constant as an APInt value reference.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool canLosslesslyBitCastTo(Type *Ty) const
Return true if this type could be converted with a lossless BitCast to type 'Ty'. ...
Windows NT (Windows on ARM)
bool hasUniqueInitializer() const
hasUniqueInitializer - Whether the global variable has an initializer, and any changes made to the in...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Attempt to fold the constant using the specified DataLayout.
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible. ...
A constant value that is initialized with an expression using other constant values.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
static Constant * getSelect(Constant *C, Constant *V1, Constant *V2, Type *OnlyIfReducedTy=nullptr)
Select constant expr.
An instruction for storing to memory.
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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)
* 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.
This is an important base class in LLVM.
void setVal(Value *V, Constant *C)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isSimpleEnoughValueToCommitHelper(Constant *C, SmallPtrSetImpl< Constant * > &SimpleConstants, const DataLayout &DL)
Return true if the specified constant can be handled by the code generator.
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.
Value * getOperand(unsigned i) const
Class to represent integer types.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static bool isSimpleEnoughValueToCommit(Constant *C, SmallPtrSetImpl< Constant * > &SimpleConstants, const DataLayout &DL)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Iterator for intrusive lists based on ilist_node.
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...
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.
InstrTy * getInstruction() const
Constant * getVal(Value *V)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
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.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
static bool isSimpleEnoughPointerToCommit(Constant *C)
Return true if this constant is simple enough for us to understand.
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
FunctionType * getFunctionType() const
Returns the FunctionType for me.
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 isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time...
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
const BasicBlock & front() const
LLVM Value Representation.
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
static Constant * getExtractValue(Constant *Agg, ArrayRef< unsigned > Idxs, Type *OnlyIfReducedTy=nullptr)
A wrapper class for inspecting calls to intrinsic functions.
Constant * ConstantFoldCall(Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
an instruction to allocate memory on the stack
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.