Skip to content

Commit 515b592

Browse files
authored
Merge pull request #6333 from apple/address-non-null
Add a flag to `Address` and `Lvalue` that is used to keep track of whether the pointer is known not to be null
2 parents c67419b + 4086a51 commit 515b592

13 files changed

+203
-152
lines changed

clang/lib/CodeGen/Address.h

Lines changed: 35 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -22,64 +22,23 @@
2222
namespace clang {
2323
namespace CodeGen {
2424

25-
// We try to save some space by using 6 bits over two PointerIntPairs to store
26-
// the alignment. However, some arches don't support 3 bits in a PointerIntPair
27-
// so we fallback to storing the alignment separately.
28-
template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {};
29-
30-
template <typename T> class AddressImpl<T, false> {
31-
llvm::Value *Pointer;
32-
llvm::Type *ElementType;
33-
CharUnits Alignment;
34-
35-
public:
36-
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
37-
CharUnits Alignment)
38-
: Pointer(Pointer), ElementType(ElementType), Alignment(Alignment) {}
39-
llvm::Value *getPointer() const { return Pointer; }
40-
llvm::Type *getElementType() const { return ElementType; }
41-
CharUnits getAlignment() const { return Alignment; }
42-
};
43-
44-
template <typename T> class AddressImpl<T, true> {
45-
// Int portion stores upper 3 bits of the log of the alignment.
46-
llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer;
47-
// Int portion stores lower 3 bits of the log of the alignment.
48-
llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType;
49-
50-
public:
51-
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
52-
CharUnits Alignment)
53-
: Pointer(Pointer), ElementType(ElementType) {
54-
if (Alignment.isZero())
55-
return;
56-
// Currently the max supported alignment is much less than 1 << 63 and is
57-
// guaranteed to be a power of 2, so we can store the log of the alignment
58-
// into 6 bits.
59-
assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero");
60-
auto AlignLog = llvm::Log2_64(Alignment.getQuantity());
61-
assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits");
62-
this->Pointer.setInt(AlignLog >> 3);
63-
this->ElementType.setInt(AlignLog & 7);
64-
}
65-
llvm::Value *getPointer() const { return Pointer.getPointer(); }
66-
llvm::Type *getElementType() const { return ElementType.getPointer(); }
67-
CharUnits getAlignment() const {
68-
unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt();
69-
return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog);
70-
}
71-
};
25+
// Indicates whether a pointer is known not to be null.
26+
enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
7227

7328
/// An aligned address.
7429
class Address {
75-
AddressImpl<void> A;
30+
llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull;
31+
llvm::Type *ElementType;
32+
CharUnits Alignment;
7633

7734
protected:
78-
Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {}
35+
Address(std::nullptr_t) : ElementType(nullptr) {}
7936

8037
public:
81-
Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
82-
: A(Pointer, ElementType, Alignment) {
38+
Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
39+
KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
40+
: PointerAndKnownNonNull(Pointer, IsKnownNonNull),
41+
ElementType(ElementType), Alignment(Alignment) {
8342
assert(Pointer != nullptr && "Pointer cannot be null");
8443
assert(ElementType != nullptr && "Element type cannot be null");
8544
assert(llvm::cast<llvm::PointerType>(Pointer->getType())
@@ -88,11 +47,13 @@ class Address {
8847
}
8948

9049
static Address invalid() { return Address(nullptr); }
91-
bool isValid() const { return A.getPointer() != nullptr; }
50+
bool isValid() const {
51+
return PointerAndKnownNonNull.getPointer() != nullptr;
52+
}
9253

9354
llvm::Value *getPointer() const {
9455
assert(isValid());
95-
return A.getPointer();
56+
return PointerAndKnownNonNull.getPointer();
9657
}
9758

9859
/// Return the type of the pointer value.
@@ -103,7 +64,7 @@ class Address {
10364
/// Return the type of the values stored in this address.
10465
llvm::Type *getElementType() const {
10566
assert(isValid());
106-
return A.getElementType();
67+
return ElementType;
10768
}
10869

10970
/// Return the address space that this address resides in.
@@ -119,19 +80,35 @@ class Address {
11980
/// Return the alignment of this pointer.
12081
CharUnits getAlignment() const {
12182
assert(isValid());
122-
return A.getAlignment();
83+
return Alignment;
12384
}
12485

12586
/// Return address with different pointer, but same element type and
12687
/// alignment.
127-
Address withPointer(llvm::Value *NewPointer) const {
128-
return Address(NewPointer, getElementType(), getAlignment());
88+
Address withPointer(llvm::Value *NewPointer,
89+
KnownNonNull_t IsKnownNonNull) const {
90+
return Address(NewPointer, getElementType(), getAlignment(),
91+
IsKnownNonNull);
12992
}
13093

13194
/// Return address with different alignment, but same pointer and element
13295
/// type.
13396
Address withAlignment(CharUnits NewAlignment) const {
134-
return Address(getPointer(), getElementType(), NewAlignment);
97+
return Address(getPointer(), getElementType(), NewAlignment,
98+
isKnownNonNull());
99+
}
100+
101+
/// Whether the pointer is known not to be null.
102+
KnownNonNull_t isKnownNonNull() const {
103+
assert(isValid());
104+
return (KnownNonNull_t)PointerAndKnownNonNull.getInt();
105+
}
106+
107+
/// Set the non-null bit.
108+
Address setKnownNonNull() {
109+
assert(isValid());
110+
PointerAndKnownNonNull.setInt(true);
111+
return *this;
135112
}
136113
};
137114

clang/lib/CodeGen/CGBuilder.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
160160
assert(cast<llvm::PointerType>(Ty)->isOpaqueOrPointeeTypeMatches(
161161
Addr.getElementType()) &&
162162
"Should not change the element type");
163-
return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name));
163+
return Addr.withPointer(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name),
164+
Addr.isKnownNonNull());
164165
}
165166

166167
/// Cast the element type of the given address to a different type,
@@ -169,7 +170,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
169170
const llvm::Twine &Name = "") {
170171
auto *PtrTy = Ty->getPointerTo(Addr.getAddressSpace());
171172
return Address(CreateBitCast(Addr.getPointer(), PtrTy, Name), Ty,
172-
Addr.getAlignment());
173+
Addr.getAlignment(), Addr.isKnownNonNull());
173174
}
174175

175176
using CGBuilderBaseTy::CreatePointerBitCastOrAddrSpaceCast;
@@ -178,7 +179,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
178179
const llvm::Twine &Name = "") {
179180
llvm::Value *Ptr =
180181
CreatePointerBitCastOrAddrSpaceCast(Addr.getPointer(), Ty, Name);
181-
return Address(Ptr, ElementTy, Addr.getAlignment());
182+
return Address(Ptr, ElementTy, Addr.getAlignment(), Addr.isKnownNonNull());
182183
}
183184

184185
/// Given
@@ -199,7 +200,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
199200
return Address(
200201
CreateStructGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
201202
ElTy->getElementType(Index),
202-
Addr.getAlignment().alignmentAtOffset(Offset));
203+
Addr.getAlignment().alignmentAtOffset(Offset), Addr.isKnownNonNull());
203204
}
204205

205206
/// Given
@@ -221,7 +222,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
221222
CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
222223
{getSize(CharUnits::Zero()), getSize(Index)}, Name),
223224
ElTy->getElementType(),
224-
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
225+
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
226+
Addr.isKnownNonNull());
225227
}
226228

227229
/// Given
@@ -237,8 +239,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
237239

238240
return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
239241
getSize(Index), Name),
240-
ElTy,
241-
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
242+
ElTy, Addr.getAlignment().alignmentAtOffset(Index * EltSize),
243+
Addr.isKnownNonNull());
242244
}
243245

244246
/// Given
@@ -255,7 +257,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
255257
return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
256258
getSize(Index), Name),
257259
Addr.getElementType(),
258-
Addr.getAlignment().alignmentAtOffset(Index * EltSize));
260+
Addr.getAlignment().alignmentAtOffset(Index * EltSize),
261+
NotKnownNonNull);
259262
}
260263

261264
/// Create GEP with single dynamic index. The address alignment is reduced
@@ -270,7 +273,7 @@ class CGBuilderTy : public CGBuilderBaseTy {
270273
return Address(
271274
CreateGEP(Addr.getElementType(), Addr.getPointer(), Index, Name),
272275
Addr.getElementType(),
273-
Addr.getAlignment().alignmentOfArrayElement(EltSize));
276+
Addr.getAlignment().alignmentOfArrayElement(EltSize), NotKnownNonNull);
274277
}
275278

276279
/// Given a pointer to i8, adjust it by a given constant offset.
@@ -280,15 +283,17 @@ class CGBuilderTy : public CGBuilderBaseTy {
280283
return Address(CreateInBoundsGEP(Addr.getElementType(), Addr.getPointer(),
281284
getSize(Offset), Name),
282285
Addr.getElementType(),
283-
Addr.getAlignment().alignmentAtOffset(Offset));
286+
Addr.getAlignment().alignmentAtOffset(Offset),
287+
Addr.isKnownNonNull());
284288
}
285289
Address CreateConstByteGEP(Address Addr, CharUnits Offset,
286290
const llvm::Twine &Name = "") {
287291
assert(Addr.getElementType() == TypeCache.Int8Ty);
288292
return Address(CreateGEP(Addr.getElementType(), Addr.getPointer(),
289293
getSize(Offset), Name),
290294
Addr.getElementType(),
291-
Addr.getAlignment().alignmentAtOffset(Offset));
295+
Addr.getAlignment().alignmentAtOffset(Offset),
296+
NotKnownNonNull);
292297
}
293298

294299
using CGBuilderBaseTy::CreateConstInBoundsGEP2_32;
@@ -305,7 +310,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
305310
llvm_unreachable("offset of GEP with constants is always computable");
306311
return Address(GEP, GEP->getResultElementType(),
307312
Addr.getAlignment().alignmentAtOffset(
308-
CharUnits::fromQuantity(Offset.getSExtValue())));
313+
CharUnits::fromQuantity(Offset.getSExtValue())),
314+
Addr.isKnownNonNull());
309315
}
310316

311317
using CGBuilderBaseTy::CreateMemCpy;
@@ -369,7 +375,8 @@ class CGBuilderTy : public CGBuilderBaseTy {
369375

370376
using CGBuilderBaseTy::CreateLaunderInvariantGroup;
371377
Address CreateLaunderInvariantGroup(Address Addr) {
372-
return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()));
378+
return Addr.withPointer(CreateLaunderInvariantGroup(Addr.getPointer()),
379+
Addr.isKnownNonNull());
373380
}
374381
};
375382

clang/lib/CodeGen/CGCall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2791,7 +2791,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
27912791
case ABIArgInfo::IndirectAliased: {
27922792
assert(NumIRArgs == 1);
27932793
Address ParamAddr = Address(Fn->getArg(FirstIRArg), ConvertTypeForMem(Ty),
2794-
ArgI.getIndirectAlign());
2794+
ArgI.getIndirectAlign(), KnownNonNull);
27952795

27962796
if (!hasScalarEvaluationKind(Ty)) {
27972797
// Aggregates and complex variables are accessed by reference. All we

clang/lib/CodeGen/CGClass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Address CodeGenFunction::LoadCXXThisAddress() {
138138
}
139139

140140
llvm::Type *Ty = ConvertType(MD->getThisType()->getPointeeType());
141-
return Address(LoadCXXThis(), Ty, CXXThisAlignment);
141+
return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull);
142142
}
143143

144144
/// Emit the address of a field using a member data pointer.
@@ -391,7 +391,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
391391
llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result");
392392
PHI->addIncoming(Value.getPointer(), notNullBB);
393393
PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
394-
Value = Value.withPointer(PHI);
394+
Value = Value.withPointer(PHI, NotKnownNonNull);
395395
}
396396

397397
return Value;

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,8 +2503,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
25032503
CGM.getDataLayout().getAllocaAddrSpace());
25042504
auto DestAS = getContext().getTargetAddressSpace(DestLangAS);
25052505
auto *T = DeclPtr.getElementType()->getPointerTo(DestAS);
2506-
DeclPtr = DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast(
2507-
*this, V, SrcLangAS, DestLangAS, T, true));
2506+
DeclPtr =
2507+
DeclPtr.withPointer(getTargetHooks().performAddrSpaceCast(
2508+
*this, V, SrcLangAS, DestLangAS, T, true),
2509+
DeclPtr.isKnownNonNull());
25082510
}
25092511

25102512
// For truly ABI indirect arguments -- those that are not `byval` -- store

clang/lib/CodeGen/CGException.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,7 @@ Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
18451845
llvm::Value *ChildVar =
18461846
Builder.CreateBitCast(RecoverCall, ParentVar.getType());
18471847
ChildVar->setName(ParentVar.getName());
1848-
return ParentVar.withPointer(ChildVar);
1848+
return ParentVar.withPointer(ChildVar, KnownNonNull);
18491849
}
18501850

18511851
void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,

0 commit comments

Comments
 (0)