1
0
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:
Johannes Doerfert 2019-08-19 21:56:38 +00:00
parent b1462f01b6
commit 3f511ba363
2 changed files with 26 additions and 15 deletions

View File

@ -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

View File

@ -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;
}
}