Skip to content

Commit 160fb11

Browse files
authored
[Clang][NFC] Improve generation of GEP and RecordDecl loop (#101434)
As with other loops, we need only look at a RecordDecl's FieldDecls. Convert to using them. In the meantime, we can improve the generation of the 'counted_by' FieldDecl's GEP by creating one GEP instead of a series of GEPs.
1 parent ea46e20 commit 160fb11

File tree

4 files changed

+28
-29
lines changed

4 files changed

+28
-29
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
996996

997997
// Build a load of the counted_by field.
998998
bool IsSigned = CountedByFD->getType()->isSignedIntegerType();
999-
Value *CountedByInst = EmitCountedByFieldExpr(Base, FAMDecl, CountedByFD);
999+
Value *CountedByInst = EmitLoadOfCountedByField(Base, FAMDecl, CountedByFD);
10001000
if (!CountedByInst)
10011001
return getDefaultBuiltinObjectSizeResult(Type, ResType);
10021002

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,7 @@ class StructAccessBase
10671067

10681068
} // end anonymous namespace
10691069

1070-
using RecIndicesTy =
1071-
SmallVector<std::pair<const RecordDecl *, llvm::Value *>, 8>;
1070+
using RecIndicesTy = SmallVector<llvm::Value *, 8>;
10721071

10731072
static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
10741073
const FieldDecl *Field,
@@ -1083,7 +1082,7 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
10831082

10841083
FieldNo = Layout.getLLVMFieldNo(FD);
10851084
if (FD == Field) {
1086-
Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));
1085+
Indices.emplace_back(CGF.Builder.getInt32(FieldNo));
10871086
return true;
10881087
}
10891088

@@ -1092,7 +1091,7 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
10921091
if (getGEPIndicesToField(CGF, Ty->getAsRecordDecl(), Field, Indices)) {
10931092
if (RD->isUnion())
10941093
FieldNo = 0;
1095-
Indices.emplace_back(std::make_pair(RD, CGF.Builder.getInt32(FieldNo)));
1094+
Indices.emplace_back(CGF.Builder.getInt32(FieldNo));
10961095
return true;
10971096
}
10981097
}
@@ -1109,7 +1108,7 @@ static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD,
11091108
/// - \p FAMDecl: the \p Decl for the flexible array member. It may not be
11101109
/// within the top-level struct.
11111110
/// - \p CountDecl: must be within the same non-anonymous struct as \p FAMDecl.
1112-
llvm::Value *CodeGenFunction::EmitCountedByFieldExpr(
1111+
llvm::Value *CodeGenFunction::EmitLoadOfCountedByField(
11131112
const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) {
11141113
const RecordDecl *RD = CountDecl->getParent()->getOuterLexicalRecordContext();
11151114

@@ -1136,15 +1135,15 @@ llvm::Value *CodeGenFunction::EmitCountedByFieldExpr(
11361135
return nullptr;
11371136
}
11381137

1139-
llvm::Value *Zero = Builder.getInt32(0);
11401138
RecIndicesTy Indices;
1141-
11421139
getGEPIndicesToField(*this, RD, CountDecl, Indices);
1140+
if (Indices.empty())
1141+
return nullptr;
11431142

1144-
for (auto I = Indices.rbegin(), E = Indices.rend(); I != E; ++I)
1145-
Res = Builder.CreateInBoundsGEP(
1146-
ConvertType(QualType(I->first->getTypeForDecl(), 0)), Res,
1147-
{Zero, I->second}, "..counted_by.gep");
1143+
Indices.push_back(Builder.getInt32(0));
1144+
Res = Builder.CreateInBoundsGEP(
1145+
ConvertType(QualType(RD->getTypeForDecl(), 0)), Res,
1146+
RecIndicesTy(llvm::reverse(Indices)), "..counted_by.gep");
11481147

11491148
return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), Res,
11501149
getIntAlign(), "..counted_by.load");
@@ -4108,25 +4107,25 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr,
41084107

41094108
/// The offset of a field from the beginning of the record.
41104109
static bool getFieldOffsetInBits(CodeGenFunction &CGF, const RecordDecl *RD,
4111-
const FieldDecl *FD, int64_t &Offset) {
4110+
const FieldDecl *Field, int64_t &Offset) {
41124111
ASTContext &Ctx = CGF.getContext();
41134112
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
41144113
unsigned FieldNo = 0;
41154114

4116-
for (const Decl *D : RD->decls()) {
4117-
if (const auto *Record = dyn_cast<RecordDecl>(D))
4118-
if (getFieldOffsetInBits(CGF, Record, FD, Offset)) {
4119-
Offset += Layout.getFieldOffset(FieldNo);
4120-
return true;
4121-
}
4115+
for (const FieldDecl *FD : RD->fields()) {
4116+
if (FD == Field) {
4117+
Offset += Layout.getFieldOffset(FieldNo);
4118+
return true;
4119+
}
41224120

4123-
if (const auto *Field = dyn_cast<FieldDecl>(D))
4124-
if (FD == Field) {
4121+
QualType Ty = FD->getType();
4122+
if (Ty->isRecordType())
4123+
if (getFieldOffsetInBits(CGF, Ty->getAsRecordDecl(), Field, Offset)) {
41254124
Offset += Layout.getFieldOffset(FieldNo);
41264125
return true;
41274126
}
41284127

4129-
if (isa<FieldDecl>(D))
4128+
if (!RD->isUnion())
41304129
++FieldNo;
41314130
}
41324131

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3310,9 +3310,9 @@ class CodeGenFunction : public CodeGenTypeCache {
33103310
const FieldDecl *FindCountedByField(const FieldDecl *FD);
33113311

33123312
/// Build an expression accessing the "counted_by" field.
3313-
llvm::Value *EmitCountedByFieldExpr(const Expr *Base,
3314-
const FieldDecl *FAMDecl,
3315-
const FieldDecl *CountDecl);
3313+
llvm::Value *EmitLoadOfCountedByField(const Expr *Base,
3314+
const FieldDecl *FAMDecl,
3315+
const FieldDecl *CountDecl);
33163316

33173317
llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
33183318
bool isInc, bool isPre);

clang/test/CodeGen/attr-counted-by.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -754,11 +754,11 @@ size_t test7_bdos(struct union_of_fams *p) {
754754
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
755755
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
756756
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
757-
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
757+
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
758758
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
759759
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
760760
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
761-
// SANITIZE-WITH-ATTR: cont9:
761+
// SANITIZE-WITH-ATTR: cont7:
762762
// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9
763763
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]]
764764
// SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]]
@@ -908,11 +908,11 @@ size_t test9_bdos(struct union_of_fams *p) {
908908
// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64
909909
// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]]
910910
// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]]
911-
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
911+
// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]]
912912
// SANITIZE-WITH-ATTR: handler.out_of_bounds:
913913
// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR10]], !nosanitize [[META2]]
914914
// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]]
915-
// SANITIZE-WITH-ATTR: cont9:
915+
// SANITIZE-WITH-ATTR: cont7:
916916
// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12
917917
// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]]
918918
// SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0)

0 commit comments

Comments
 (0)