Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit ba9f09c

Browse files
committed
NFC. Move isDereferenceable to Loads.h/cpp
This is a part of the refactoring to unify isSafeToLoadUnconditionally and isDereferenceablePointer functions. In subsequent change I'm going to eliminate isDerferenceableAndAlignedPointer from Loads API, leaving isSafeToLoadSpecualtively the only function to check is load instruction can be speculated. Reviewed By: hfinkel Differential Revision: http://reviews.llvm.org/D16180 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261736 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f5b2749 commit ba9f09c

File tree

8 files changed

+228
-222
lines changed

8 files changed

+228
-222
lines changed

include/llvm/Analysis/Loads.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@ namespace llvm {
2323
class DataLayout;
2424
class MDNode;
2525

26+
/// isDereferenceablePointer - Return true if this is always a dereferenceable
27+
/// pointer. If the context instruction is specified perform context-sensitive
28+
/// analysis and return true if the pointer is dereferenceable at the
29+
/// specified instruction.
30+
bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
31+
const Instruction *CtxI = nullptr,
32+
const DominatorTree *DT = nullptr,
33+
const TargetLibraryInfo *TLI = nullptr);
34+
35+
/// Returns true if V is always a dereferenceable pointer with alignment
36+
/// greater or equal than requested. If the context instruction is specified
37+
/// performs context-sensitive analysis and returns true if the pointer is
38+
/// dereferenceable at the specified instruction.
39+
bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
40+
const DataLayout &DL,
41+
const Instruction *CtxI = nullptr,
42+
const DominatorTree *DT = nullptr,
43+
const TargetLibraryInfo *TLI = nullptr);
44+
2645
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
2746
/// from this value cannot trap.
2847
///

include/llvm/Analysis/ValueTracking.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -236,25 +236,6 @@ namespace llvm {
236236
/// are lifetime markers.
237237
bool onlyUsedByLifetimeMarkers(const Value *V);
238238

239-
/// isDereferenceablePointer - Return true if this is always a dereferenceable
240-
/// pointer. If the context instruction is specified perform context-sensitive
241-
/// analysis and return true if the pointer is dereferenceable at the
242-
/// specified instruction.
243-
bool isDereferenceablePointer(const Value *V, const DataLayout &DL,
244-
const Instruction *CtxI = nullptr,
245-
const DominatorTree *DT = nullptr,
246-
const TargetLibraryInfo *TLI = nullptr);
247-
248-
/// Returns true if V is always a dereferenceable pointer with alignment
249-
/// greater or equal than requested. If the context instruction is specified
250-
/// performs context-sensitive analysis and returns true if the pointer is
251-
/// dereferenceable at the specified instruction.
252-
bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
253-
const DataLayout &DL,
254-
const Instruction *CtxI = nullptr,
255-
const DominatorTree *DT = nullptr,
256-
const TargetLibraryInfo *TLI = nullptr);
257-
258239
/// isSafeToSpeculativelyExecute - Return true if the instruction does not
259240
/// have any effects besides calculating the result and does not have
260241
/// undefined behavior.

lib/Analysis/Loads.cpp

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,212 @@
2121
#include "llvm/IR/LLVMContext.h"
2222
#include "llvm/IR/Module.h"
2323
#include "llvm/IR/Operator.h"
24+
#include "llvm/IR/Statepoint.h"
25+
2426
using namespace llvm;
2527

28+
static bool isDereferenceableFromAttribute(const Value *BV, APInt Offset,
29+
Type *Ty, const DataLayout &DL,
30+
const Instruction *CtxI,
31+
const DominatorTree *DT,
32+
const TargetLibraryInfo *TLI) {
33+
assert(Offset.isNonNegative() && "offset can't be negative");
34+
assert(Ty->isSized() && "must be sized");
35+
36+
APInt DerefBytes(Offset.getBitWidth(), 0);
37+
bool CheckForNonNull = false;
38+
if (const Argument *A = dyn_cast<Argument>(BV)) {
39+
DerefBytes = A->getDereferenceableBytes();
40+
if (!DerefBytes.getBoolValue()) {
41+
DerefBytes = A->getDereferenceableOrNullBytes();
42+
CheckForNonNull = true;
43+
}
44+
} else if (auto CS = ImmutableCallSite(BV)) {
45+
DerefBytes = CS.getDereferenceableBytes(0);
46+
if (!DerefBytes.getBoolValue()) {
47+
DerefBytes = CS.getDereferenceableOrNullBytes(0);
48+
CheckForNonNull = true;
49+
}
50+
} else if (const LoadInst *LI = dyn_cast<LoadInst>(BV)) {
51+
if (MDNode *MD = LI->getMetadata(LLVMContext::MD_dereferenceable)) {
52+
ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
53+
DerefBytes = CI->getLimitedValue();
54+
}
55+
if (!DerefBytes.getBoolValue()) {
56+
if (MDNode *MD =
57+
LI->getMetadata(LLVMContext::MD_dereferenceable_or_null)) {
58+
ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
59+
DerefBytes = CI->getLimitedValue();
60+
}
61+
CheckForNonNull = true;
62+
}
63+
}
64+
65+
if (DerefBytes.getBoolValue())
66+
if (DerefBytes.uge(Offset + DL.getTypeStoreSize(Ty)))
67+
if (!CheckForNonNull || isKnownNonNullAt(BV, CtxI, DT, TLI))
68+
return true;
69+
70+
return false;
71+
}
72+
73+
static bool isDereferenceableFromAttribute(const Value *V, const DataLayout &DL,
74+
const Instruction *CtxI,
75+
const DominatorTree *DT,
76+
const TargetLibraryInfo *TLI) {
77+
Type *VTy = V->getType();
78+
Type *Ty = VTy->getPointerElementType();
79+
if (!Ty->isSized())
80+
return false;
81+
82+
APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0);
83+
return isDereferenceableFromAttribute(V, Offset, Ty, DL, CtxI, DT, TLI);
84+
}
85+
86+
static bool isAligned(const Value *Base, APInt Offset, unsigned Align,
87+
const DataLayout &DL) {
88+
APInt BaseAlign(Offset.getBitWidth(), Base->getPointerAlignment(DL));
89+
90+
if (!BaseAlign) {
91+
Type *Ty = Base->getType()->getPointerElementType();
92+
if (!Ty->isSized())
93+
return false;
94+
BaseAlign = DL.getABITypeAlignment(Ty);
95+
}
96+
97+
APInt Alignment(Offset.getBitWidth(), Align);
98+
99+
assert(Alignment.isPowerOf2() && "must be a power of 2!");
100+
return BaseAlign.uge(Alignment) && !(Offset & (Alignment-1));
101+
}
102+
103+
static bool isAligned(const Value *Base, unsigned Align, const DataLayout &DL) {
104+
Type *Ty = Base->getType();
105+
assert(Ty->isSized() && "must be sized");
106+
APInt Offset(DL.getTypeStoreSizeInBits(Ty), 0);
107+
return isAligned(Base, Offset, Align, DL);
108+
}
109+
110+
/// Test if V is always a pointer to allocated and suitably aligned memory for
111+
/// a simple load or store.
112+
static bool isDereferenceableAndAlignedPointer(
113+
const Value *V, unsigned Align, const DataLayout &DL,
114+
const Instruction *CtxI, const DominatorTree *DT,
115+
const TargetLibraryInfo *TLI, SmallPtrSetImpl<const Value *> &Visited) {
116+
// Note that it is not safe to speculate into a malloc'd region because
117+
// malloc may return null.
118+
119+
// These are obviously ok if aligned.
120+
if (isa<AllocaInst>(V))
121+
return isAligned(V, Align, DL);
122+
123+
// It's not always safe to follow a bitcast, for example:
124+
// bitcast i8* (alloca i8) to i32*
125+
// would result in a 4-byte load from a 1-byte alloca. However,
126+
// if we're casting from a pointer from a type of larger size
127+
// to a type of smaller size (or the same size), and the alignment
128+
// is at least as large as for the resulting pointer type, then
129+
// we can look through the bitcast.
130+
if (const BitCastOperator *BC = dyn_cast<BitCastOperator>(V)) {
131+
Type *STy = BC->getSrcTy()->getPointerElementType(),
132+
*DTy = BC->getDestTy()->getPointerElementType();
133+
if (STy->isSized() && DTy->isSized() &&
134+
(DL.getTypeStoreSize(STy) >= DL.getTypeStoreSize(DTy)) &&
135+
(DL.getABITypeAlignment(STy) >= DL.getABITypeAlignment(DTy)))
136+
return isDereferenceableAndAlignedPointer(BC->getOperand(0), Align, DL,
137+
CtxI, DT, TLI, Visited);
138+
}
139+
140+
// Global variables which can't collapse to null are ok.
141+
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
142+
if (!GV->hasExternalWeakLinkage())
143+
return isAligned(V, Align, DL);
144+
145+
// byval arguments are okay.
146+
if (const Argument *A = dyn_cast<Argument>(V))
147+
if (A->hasByValAttr())
148+
return isAligned(V, Align, DL);
149+
150+
if (isDereferenceableFromAttribute(V, DL, CtxI, DT, TLI))
151+
return isAligned(V, Align, DL);
152+
153+
// For GEPs, determine if the indexing lands within the allocated object.
154+
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
155+
Type *Ty = GEP->getResultElementType();
156+
const Value *Base = GEP->getPointerOperand();
157+
158+
// Conservatively require that the base pointer be fully dereferenceable
159+
// and aligned.
160+
if (!Visited.insert(Base).second)
161+
return false;
162+
if (!isDereferenceableAndAlignedPointer(Base, Align, DL, CtxI, DT, TLI,
163+
Visited))
164+
return false;
165+
166+
APInt Offset(DL.getPointerTypeSizeInBits(GEP->getType()), 0);
167+
if (!GEP->accumulateConstantOffset(DL, Offset))
168+
return false;
169+
170+
// Check if the load is within the bounds of the underlying object
171+
// and offset is aligned.
172+
uint64_t LoadSize = DL.getTypeStoreSize(Ty);
173+
Type *BaseType = GEP->getSourceElementType();
174+
assert(isPowerOf2_32(Align) && "must be a power of 2!");
175+
return (Offset + LoadSize).ule(DL.getTypeAllocSize(BaseType)) &&
176+
!(Offset & APInt(Offset.getBitWidth(), Align-1));
177+
}
178+
179+
// For gc.relocate, look through relocations
180+
if (const GCRelocateInst *RelocateInst = dyn_cast<GCRelocateInst>(V))
181+
return isDereferenceableAndAlignedPointer(
182+
RelocateInst->getDerivedPtr(), Align, DL, CtxI, DT, TLI, Visited);
183+
184+
if (const AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(V))
185+
return isDereferenceableAndAlignedPointer(ASC->getOperand(0), Align, DL,
186+
CtxI, DT, TLI, Visited);
187+
188+
// If we don't know, assume the worst.
189+
return false;
190+
}
191+
192+
bool llvm::isDereferenceableAndAlignedPointer(const Value *V, unsigned Align,
193+
const DataLayout &DL,
194+
const Instruction *CtxI,
195+
const DominatorTree *DT,
196+
const TargetLibraryInfo *TLI) {
197+
// When dereferenceability information is provided by a dereferenceable
198+
// attribute, we know exactly how many bytes are dereferenceable. If we can
199+
// determine the exact offset to the attributed variable, we can use that
200+
// information here.
201+
Type *VTy = V->getType();
202+
Type *Ty = VTy->getPointerElementType();
203+
204+
// Require ABI alignment for loads without alignment specification
205+
if (Align == 0)
206+
Align = DL.getABITypeAlignment(Ty);
207+
208+
if (Ty->isSized()) {
209+
APInt Offset(DL.getTypeStoreSizeInBits(VTy), 0);
210+
const Value *BV = V->stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
211+
212+
if (Offset.isNonNegative())
213+
if (isDereferenceableFromAttribute(BV, Offset, Ty, DL, CtxI, DT, TLI) &&
214+
isAligned(BV, Offset, Align, DL))
215+
return true;
216+
}
217+
218+
SmallPtrSet<const Value *, 32> Visited;
219+
return ::isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT, TLI,
220+
Visited);
221+
}
222+
223+
bool llvm::isDereferenceablePointer(const Value *V, const DataLayout &DL,
224+
const Instruction *CtxI,
225+
const DominatorTree *DT,
226+
const TargetLibraryInfo *TLI) {
227+
return isDereferenceableAndAlignedPointer(V, 1, DL, CtxI, DT, TLI);
228+
}
229+
26230
/// \brief Test if A and B will obviously have the same value.
27231
///
28232
/// This includes recognizing that %t0 and %t1 will have the same

lib/Analysis/MemDerefPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "llvm/Analysis/Passes.h"
1111
#include "llvm/ADT/SetVector.h"
1212
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
13-
#include "llvm/Analysis/ValueTracking.h"
13+
#include "llvm/Analysis/Loads.h"
1414
#include "llvm/IR/CallSite.h"
1515
#include "llvm/IR/DataLayout.h"
1616
#include "llvm/IR/InstIterator.h"

0 commit comments

Comments
 (0)