MemoryBuiltins:

- recognize C++ new(std::nothrow) friends
 - ignore ExtractElement and ExtractValue instructions in size/offset analysis (all easy cases are probably folded away before we get here)
 - also recognize realloc as noalias

llvm-svn: 159356
This commit is contained in:
Nuno Lopes 2012-06-28 16:34:03 +00:00
parent 5c8897d37d
commit 181d67ecb1
2 changed files with 41 additions and 15 deletions

View File

@ -37,7 +37,7 @@ class Value;
bool isAllocationFn(const Value *V, bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a function that returns a
/// NoAlias pointer (including malloc/calloc/strdup-like functions).
/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
bool isNoAliasFn(const Value *V, bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
@ -174,6 +174,7 @@ public:
SizeOffsetType visitArgument(Argument &A);
SizeOffsetType visitCallSite(CallSite CS);
SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
@ -233,6 +234,8 @@ public:
SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
SizeOffsetEvalType visitCallSite(CallSite CS);
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
SizeOffsetEvalType visitLoadInst(LoadInst &I);

View File

@ -46,19 +46,25 @@ struct AllocFnsTy {
signed char FstParam, SndParam;
};
// FIXME: certain users need more information. E.g., SimplifyLibCalls needs to
// know which functions are nounwind, noalias, nocapture parameters, etc.
static const AllocFnsTy AllocationFnData[] = {
{"malloc", MallocLike, 1, 0, -1},
{"valloc", MallocLike, 1, 0, -1},
{"_Znwj", MallocLike, 1, 0, -1}, // operator new(unsigned int)
{"_Znwm", MallocLike, 1, 0, -1}, // operator new(unsigned long)
{"_Znaj", MallocLike, 1, 0, -1}, // operator new[](unsigned int)
{"_Znam", MallocLike, 1, 0, -1}, // operator new[](unsigned long)
{"posix_memalign", MallocLike, 3, 2, -1},
{"calloc", CallocLike, 2, 0, 1},
{"realloc", ReallocLike, 2, 1, -1},
{"reallocf", ReallocLike, 2, 1, -1},
{"strdup", StrDupLike, 1, -1, -1},
{"strndup", StrDupLike, 2, -1, -1}
{"malloc", MallocLike, 1, 0, -1},
{"valloc", MallocLike, 1, 0, -1},
{"_Znwj", MallocLike, 1, 0, -1}, // new(unsigned int)
{"_ZnwjRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new(unsigned int, nothrow)
{"_Znwm", MallocLike, 1, 0, -1}, // new(unsigned long)
{"_ZnwmRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new(unsigned long, nothrow)
{"_Znaj", MallocLike, 1, 0, -1}, // new[](unsigned int)
{"_ZnajRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new[](unsigned int, nothrow)
{"_Znam", MallocLike, 1, 0, -1}, // new[](unsigned long)
{"_ZnamRKSt9nothrow_t", MallocLike, 2, 0, -1}, // new[](unsigned long, nothrow)
{"posix_memalign", MallocLike, 3, 2, -1},
{"calloc", CallocLike, 2, 0, 1},
{"realloc", ReallocLike, 2, 1, -1},
{"reallocf", ReallocLike, 2, 1, -1},
{"strdup", StrDupLike, 1, -1, -1},
{"strndup", StrDupLike, 2, -1, -1}
};
@ -131,9 +137,11 @@ bool llvm::isAllocationFn(const Value *V, bool LookThroughBitCast) {
}
/// \brief Tests if a value is a call or invoke to a function that returns a
/// NoAlias pointer (including malloc/calloc/strdup-like functions).
/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
bool llvm::isNoAliasFn(const Value *V, bool LookThroughBitCast) {
return isAllocLikeFn(V, LookThroughBitCast) ||
// it's safe to consider realloc as noalias since accessing the original
// pointer is undefined behavior
return isAllocationFn(V, LookThroughBitCast) ||
hasNoAliasAttr(V, LookThroughBitCast);
}
@ -440,6 +448,11 @@ ObjectSizeOffsetVisitor::visitConstantPointerNull(ConstantPointerNull&) {
return std::make_pair(Zero, Zero);
}
SizeOffsetType
ObjectSizeOffsetVisitor::visitExtractElementInst(ExtractElementInst&) {
return unknown();
}
SizeOffsetType
ObjectSizeOffsetVisitor::visitExtractValueInst(ExtractValueInst&) {
// Easy cases were already folded by previous passes.
@ -616,6 +629,16 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitCallSite(CallSite CS) {
// - memset
}
SizeOffsetEvalType
ObjectSizeOffsetEvaluator::visitExtractElementInst(ExtractElementInst&) {
return unknown();
}
SizeOffsetEvalType
ObjectSizeOffsetEvaluator::visitExtractValueInst(ExtractValueInst&) {
return unknown();
}
SizeOffsetEvalType
ObjectSizeOffsetEvaluator::visitGEPOperator(GEPOperator &GEP) {
SizeOffsetEvalType PtrData = compute_(GEP.getPointerOperand());