Skip to content

Commit 2897dab

Browse files
committed
[CodeGen] Add a flag to Address and Lvalue that is used to keep
track of whether the pointer is known not to be null The flag will be used for the arm64e work we plan to upstream in the future (see https://lists.llvm.org/pipermail/llvm-dev/2019-October/136091.html). Currently the flag has no effect on code generation. Differential Revision: https://reviews.llvm.org/D142584 (cherry picked from commit 57865bc)
1 parent 27c1daf commit 2897dab

13 files changed

+221
-112
lines changed

clang/lib/CodeGen/Address.h

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

25+
// Indicates whether a pointer is known not to be null.
26+
enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
27+
2528
// We try to save some space by using 6 bits over two PointerIntPairs to store
2629
// the alignment. However, some arches don't support 3 bits in a PointerIntPair
2730
// so we fallback to storing the alignment separately.
2831
template <typename T, bool = alignof(llvm::Value *) >= 8> class AddressImpl {};
2932

3033
template <typename T> class AddressImpl<T, false> {
31-
llvm::Value *Pointer;
34+
llvm::PointerIntPair<llvm::Value *, 1, bool> PointerAndKnownNonNull;
3235
llvm::Type *ElementType;
3336
CharUnits Alignment;
3437

3538
public:
3639
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+
CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
41+
: PointerAndKnownNonNull(Pointer, IsKnownNonNull),
42+
ElementType(ElementType), Alignment(Alignment) {}
43+
llvm::Value *getPointer() const {
44+
return PointerAndKnownNonNull.getPointer();
45+
}
4046
llvm::Type *getElementType() const { return ElementType; }
4147
CharUnits getAlignment() const { return Alignment; }
48+
KnownNonNull_t isKnownNonNull() const {
49+
return (KnownNonNull_t)PointerAndKnownNonNull.getInt();
50+
}
51+
void setKnownNonNull() { PointerAndKnownNonNull.setInt(true); }
4252
};
4353

4454
template <typename T> class AddressImpl<T, true> {
45-
// Int portion stores upper 3 bits of the log of the alignment.
55+
// Int portion stores the non-null bit and the upper 2 bits of the log of the
56+
// alignment.
4657
llvm::PointerIntPair<llvm::Value *, 3, unsigned> Pointer;
4758
// Int portion stores lower 3 bits of the log of the alignment.
4859
llvm::PointerIntPair<llvm::Type *, 3, unsigned> ElementType;
4960

5061
public:
5162
AddressImpl(llvm::Value *Pointer, llvm::Type *ElementType,
52-
CharUnits Alignment)
63+
CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
5364
: Pointer(Pointer), ElementType(ElementType) {
54-
if (Alignment.isZero())
65+
if (Alignment.isZero()) {
66+
this->Pointer.setInt(IsKnownNonNull << 2);
5567
return;
56-
// Currently the max supported alignment is much less than 1 << 63 and is
68+
}
69+
// Currently the max supported alignment is exactly 1 << 32 and is
5770
// guaranteed to be a power of 2, so we can store the log of the alignment
58-
// into 6 bits.
71+
// into 5 bits.
5972
assert(Alignment.isPowerOfTwo() && "Alignment cannot be zero");
6073
auto AlignLog = llvm::Log2_64(Alignment.getQuantity());
61-
assert(AlignLog < (1 << 6) && "cannot fit alignment into 6 bits");
62-
this->Pointer.setInt(AlignLog >> 3);
74+
assert(AlignLog < (1 << 5) && "cannot fit alignment into 5 bits");
75+
this->Pointer.setInt(IsKnownNonNull << 2 | AlignLog >> 3);
6376
this->ElementType.setInt(AlignLog & 7);
6477
}
6578
llvm::Value *getPointer() const { return Pointer.getPointer(); }
6679
llvm::Type *getElementType() const { return ElementType.getPointer(); }
6780
CharUnits getAlignment() const {
68-
unsigned AlignLog = (Pointer.getInt() << 3) | ElementType.getInt();
81+
unsigned AlignLog = ((Pointer.getInt() & 0x3) << 3) | ElementType.getInt();
6982
return CharUnits::fromQuantity(CharUnits::QuantityType(1) << AlignLog);
7083
}
84+
KnownNonNull_t isKnownNonNull() const {
85+
return (KnownNonNull_t)(!!(Pointer.getInt() & 0x4));
86+
}
87+
void setKnownNonNull() { Pointer.setInt(Pointer.getInt() | 0x4); }
7188
};
7289

7390
/// An aligned address.
7491
class Address {
7592
AddressImpl<void> A;
7693

7794
protected:
78-
Address(std::nullptr_t) : A(nullptr, nullptr, CharUnits::Zero()) {}
95+
Address(std::nullptr_t)
96+
: A(nullptr, nullptr, CharUnits::Zero(), NotKnownNonNull) {}
7997

8098
public:
81-
Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment)
82-
: A(Pointer, ElementType, Alignment) {
99+
Address(llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
100+
KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
101+
: A(Pointer, ElementType, Alignment, IsKnownNonNull) {
83102
assert(Pointer != nullptr && "Pointer cannot be null");
84103
assert(ElementType != nullptr && "Element type cannot be null");
85104
assert(llvm::cast<llvm::PointerType>(Pointer->getType())
@@ -124,14 +143,30 @@ class Address {
124143

125144
/// Return address with different pointer, but same element type and
126145
/// alignment.
127-
Address withPointer(llvm::Value *NewPointer) const {
128-
return Address(NewPointer, getElementType(), getAlignment());
146+
Address withPointer(llvm::Value *NewPointer,
147+
KnownNonNull_t IsKnownNonNull) const {
148+
return Address(NewPointer, getElementType(), getAlignment(),
149+
IsKnownNonNull);
129150
}
130151

131152
/// Return address with different alignment, but same pointer and element
132153
/// type.
133154
Address withAlignment(CharUnits NewAlignment) const {
134-
return Address(getPointer(), getElementType(), NewAlignment);
155+
return Address(getPointer(), getElementType(), NewAlignment,
156+
isKnownNonNull());
157+
}
158+
159+
/// Whether the pointer is known not to be null.
160+
KnownNonNull_t isKnownNonNull() const {
161+
assert(isValid());
162+
return A.isKnownNonNull();
163+
}
164+
165+
/// Set the non-null bit.
166+
Address setKnownNonNull() {
167+
assert(isValid());
168+
A.setKnownNonNull();
169+
return *this;
135170
}
136171
};
137172

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)