add getUnderlyingObjectSize()

this is similar to getObjectSize(), but doesnt subtract the offset
tweak the BasicAA code accordingly (per PR14988)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176407 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nuno Lopes 2013-03-02 11:23:34 +00:00
parent 5f0d9dbdf4
commit 2bc689c846
3 changed files with 29 additions and 30 deletions

View File

@ -144,6 +144,14 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
/// \brief Compute the size of the underlying object pointed by Ptr. Returns
/// true and the object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
const DataLayout *TD, const TargetLibraryInfo *TLI,
bool RoundToAlign = false);
typedef std::pair<APInt, APInt> SizeOffsetType;

View File

@ -88,7 +88,7 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
const TargetLibraryInfo &TLI,
bool RoundToAlign = false) {
uint64_t Size;
if (getObjectSize(V, Size, &TD, &TLI, RoundToAlign))
if (getUnderlyingObjectSize(V, Size, &TD, &TLI, RoundToAlign))
return Size;
return AliasAnalysis::UnknownSize;
}
@ -98,35 +98,6 @@ static uint64_t getObjectSize(const Value *V, const DataLayout &TD,
static bool isObjectSmallerThan(const Value *V, uint64_t Size,
const DataLayout &TD,
const TargetLibraryInfo &TLI) {
// Note that the meanings of the "object" are slightly different in the
// following contexts:
// c1: llvm::getObjectSize()
// c2: llvm.objectsize() intrinsic
// c3: isObjectSmallerThan()
// c1 and c2 share the same meaning; however, the meaning of "object" in c3
// refers to the "entire object".
//
// Consider this example:
// char *p = (char*)malloc(100)
// char *q = p+80;
//
// In the context of c1 and c2, the "object" pointed by q refers to the
// stretch of memory of q[0:19]. So, getObjectSize(q) should return 20.
//
// However, in the context of c3, the "object" refers to the chunk of memory
// being allocated. So, the "object" has 100 bytes, and q points to the middle
// the "object". In case q is passed to isObjectSmallerThan() as the 1st
// parameter, before the llvm::getObjectSize() is called to get the size of
// entire object, we should:
// - either rewind the pointer q to the base-address of the object in
// question (in this case rewind to p), or
// - just give up. It is up to caller to make sure the pointer is pointing
// to the base address the object.
//
// We go for 2nd option for simplicity.
if (!isIdentifiedObject(V))
return false;
// This function needs to use the aligned object size because we allow
// reads a bit past the end given sufficient alignment.
uint64_t ObjectSize = getObjectSize(V, TD, TLI, /*RoundToAlign*/true);

View File

@ -360,6 +360,26 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
return true;
}
/// \brief Compute the size of the underlying object pointed by Ptr. Returns
/// true and the object size in Size if successful, and false otherwise.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool llvm::getUnderlyingObjectSize(const Value *Ptr, uint64_t &Size,
const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool RoundToAlign) {
if (!TD)
return false;
ObjectSizeOffsetVisitor Visitor(TD, TLI, Ptr->getContext(), RoundToAlign);
SizeOffsetType Data = Visitor.compute(const_cast<Value*>(Ptr));
if (!Visitor.knownSize(Data))
return false;
Size = Data.first.getZExtValue();
return true;
}
STATISTIC(ObjectVisitorArgument,
"Number of arguments with unsolved size and offset");