mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[CaptureTracker] Let subclasses provide dereferenceability information
Summary: CaptureTracker subclasses might have better dereferenceability information which allows null pointer checks to be no-capturing. The first user will be D59922. Reviewers: sanjoy, hfinkel, aykevl, sstefan1, uenoku, xbolva00 Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66371 llvm-svn: 369305
This commit is contained in:
parent
b1462f01b6
commit
3f511ba363
@ -17,6 +17,7 @@ namespace llvm {
|
||||
|
||||
class Value;
|
||||
class Use;
|
||||
class DataLayout;
|
||||
class Instruction;
|
||||
class DominatorTree;
|
||||
class OrderedBasicBlock;
|
||||
@ -83,6 +84,11 @@ namespace llvm {
|
||||
/// use U. Return true to stop the traversal or false to continue looking
|
||||
/// for more capturing instructions.
|
||||
virtual bool captured(const Use *U) = 0;
|
||||
|
||||
/// isDereferenceableOrNull - Overload to allow clients with additional
|
||||
/// knowledge about pointer dereferenceability to provide it and thereby
|
||||
/// avoid conservative responses when a pointer is compared to null.
|
||||
virtual bool isDereferenceableOrNull(Value *O, const DataLayout &DL);
|
||||
};
|
||||
|
||||
/// PointerMayBeCaptured - Visit the value and the values derived from it and
|
||||
|
@ -33,6 +33,22 @@ CaptureTracker::~CaptureTracker() {}
|
||||
|
||||
bool CaptureTracker::shouldExplore(const Use *U) { return true; }
|
||||
|
||||
bool CaptureTracker::isDereferenceableOrNull(Value *O, const DataLayout &DL) {
|
||||
// An inbounds GEP can either be a valid pointer (pointing into
|
||||
// or to the end of an allocation), or be null in the default
|
||||
// address space. So for an inbounds GEP there is no way to let
|
||||
// the pointer escape using clever GEP hacking because doing so
|
||||
// would make the pointer point outside of the allocated object
|
||||
// and thus make the GEP result a poison value. Similarly, other
|
||||
// dereferenceable pointers cannot be manipulated without producing
|
||||
// poison.
|
||||
if (auto *GEP = dyn_cast<GetElementPtrInst>(O))
|
||||
if (GEP->isInBounds())
|
||||
return true;
|
||||
bool CanBeNull;
|
||||
return O->getPointerDereferenceableBytes(DL, CanBeNull);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct SimpleCaptureTracker : public CaptureTracker {
|
||||
explicit SimpleCaptureTracker(bool ReturnCaptures)
|
||||
@ -342,21 +358,10 @@ void llvm::PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
|
||||
break;
|
||||
if (!I->getFunction()->nullPointerIsDefined()) {
|
||||
auto *O = I->getOperand(Idx)->stripPointerCastsSameRepresentation();
|
||||
// An inbounds GEP can either be a valid pointer (pointing into
|
||||
// or to the end of an allocation), or be null in the default
|
||||
// address space. So for an inbounds GEPs there is no way to let
|
||||
// the pointer escape using clever GEP hacking because doing so
|
||||
// would make the pointer point outside of the allocated object
|
||||
// and thus make the GEP result a poison value.
|
||||
if (auto *GEP = dyn_cast<GetElementPtrInst>(O))
|
||||
if (GEP->isInBounds())
|
||||
break;
|
||||
// Comparing a dereferenceable_or_null argument against null
|
||||
// cannot lead to pointer escapes, because if it is not null it
|
||||
// must be a valid (in-bounds) pointer.
|
||||
bool CanBeNull;
|
||||
if (O->getPointerDereferenceableBytes(I->getModule()->getDataLayout(),
|
||||
CanBeNull))
|
||||
// Comparing a dereferenceable_or_null pointer against null cannot
|
||||
// lead to pointer escapes, because if it is not null it must be a
|
||||
// valid (in-bounds) pointer.
|
||||
if (Tracker->isDereferenceableOrNull(O, I->getModule()->getDataLayout()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user