[clang] [Clang] Generate the GEP instead of adding AST nodes (PR #73730)
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 29 11:04:44 PST 2023
https://github.com/bwendling updated https://github.com/llvm/llvm-project/pull/73730
>From 3e500c2a7c6b7895ebe292a1ed50e04409ba149c Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Tue, 28 Nov 2023 17:17:54 -0800
Subject: [PATCH 1/6] [Clang] Generate the GEP instead of adding AST nodes
---
clang/lib/CodeGen/CGBuiltin.cpp | 3 +-
clang/lib/CodeGen/CGExpr.cpp | 99 +++++++++++++++++++----------
clang/lib/CodeGen/CodeGenFunction.h | 4 +-
3 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index c83ea966fdeadc6..487bd14244e531c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -916,8 +916,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
// Build a load of the counted_by field.
bool IsSigned = CountedByFD->getType()->isSignedIntegerType();
- const Expr *CountedByExpr = BuildCountedByFieldExpr(Base, CountedByFD);
- Value *CountedByInst = EmitAnyExprToTemp(CountedByExpr).getScalarVal();
+ Value *CountedByInst = BuildCountedByFieldExpr(Base, CountedByFD);
llvm::Type *CountedByTy = CountedByInst->getType();
// Build a load of the index and subtract it from the count.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 9fe8f1d7da780c8..b77d9d8904dfc2d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -26,6 +26,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/NSAPI.h"
+#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/SourceManager.h"
@@ -940,8 +941,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
if (const ValueDecl *VD = CGF.FindCountedByField(Base)) {
IndexedType = Base->getType();
- const Expr *E = CGF.BuildCountedByFieldExpr(Base, VD);
- return CGF.EmitAnyExprToTemp(E).getScalarVal();
+ return CGF.BuildCountedByFieldExpr(Base, VD);
}
}
@@ -956,42 +956,77 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
return nullptr;
}
-const Expr *
+namespace {
+
+struct MemberExprBaseVisitor
+ : public StmtVisitor<MemberExprBaseVisitor, Expr *> {
+ MemberExprBaseVisitor() = default;
+
+ //===--------------------------------------------------------------------===//
+ // Visitor Methods
+ //===--------------------------------------------------------------------===//
+
+ Expr *Visit(Expr *E) {
+ return StmtVisitor<MemberExprBaseVisitor, Expr *>::Visit(E);
+ }
+
+ Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+ return Visit(E->getBase());
+ }
+ Expr *VisitCastExpr(CastExpr *E) {
+ return Visit(E->getSubExpr());
+ }
+ Expr *VisitDeclRefExpr(DeclRefExpr *E) {
+ return E;
+ }
+ Expr *VisitMemberExpr(MemberExpr *E) {
+ return Visit(E->getBase());
+ }
+ Expr *VisitParenExpr(ParenExpr *E) {
+ return Visit(E->getSubExpr());
+ }
+ Expr *VisitUnaryOperator(UnaryOperator *E) {
+ return Visit(E->getSubExpr());
+ }
+};
+
+} // end anonymous namespace
+
+llvm::Value *
CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
const ValueDecl *CountedByVD) {
// Find the outer struct expr (i.e. p in p->a.b.c.d).
- Expr *CountedByExpr = const_cast<Expr *>(Base)->IgnoreParenImpCasts();
-
- // Work our way up the expression until we reach the DeclRefExpr.
- while (!isa<DeclRefExpr>(CountedByExpr))
- if (const auto *ME = dyn_cast<MemberExpr>(CountedByExpr))
- CountedByExpr = ME->getBase()->IgnoreParenImpCasts();
-
- // Add back an implicit cast to create the required pr-value.
- CountedByExpr = ImplicitCastExpr::Create(
- getContext(), CountedByExpr->getType(), CK_LValueToRValue, CountedByExpr,
- nullptr, VK_PRValue, FPOptionsOverride());
-
- if (const auto *IFD = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
- // The counted_by field is inside an anonymous struct / union. The
- // IndirectFieldDecl has the correct order of FieldDecls to build this
- // easily. (Yay!)
- for (NamedDecl *ND : IFD->chain()) {
- auto *VD = cast<ValueDecl>(ND);
- CountedByExpr =
- MemberExpr::CreateImplicit(getContext(), CountedByExpr,
- CountedByExpr->getType()->isPointerType(),
- VD, VD->getType(), VK_LValue, OK_Ordinary);
+ Expr *CountedByExpr = MemberExprBaseVisitor().Visit(const_cast<Expr *>(Base));
+
+ llvm::Value *Res =
+ CountedByExpr->getType()->isPointerType()
+ ? EmitPointerWithAlignment(CountedByExpr).getPointer()
+ : EmitDeclRefLValue(cast<DeclRefExpr>(CountedByExpr)).getPointer(*this);
+
+ auto *Zero = llvm::ConstantInt::get(Int32Ty, 0);
+ SmallVector<llvm::Value *, 4> Indices{Zero};
+ if (const auto *FD = dyn_cast<FieldDecl>(CountedByVD)) {
+ Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
+ } else if (const auto *I = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
+ for (auto *ND : I->chain()) {
+ if (auto *FD = dyn_cast<FieldDecl>(ND)) {
+ Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
+ }
}
- } else {
- CountedByExpr = MemberExpr::CreateImplicit(
- getContext(), const_cast<Expr *>(CountedByExpr),
- CountedByExpr->getType()->isPointerType(),
- const_cast<ValueDecl *>(CountedByVD), CountedByVD->getType(), VK_LValue,
- OK_Ordinary);
}
- return CountedByExpr;
+ const DeclContext *DC = CountedByVD->getLexicalDeclContext();
+ const auto *CountedByRD = cast<RecordDecl>(DC);
+
+ llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(CountedByRD->getTypeForDecl(), 0));
+ Res = Builder.CreateGEP(Ty, Res, Indices, "bork");
+
+ QualType CountedByTy(CountedByVD->getType());
+ TypeInfo TI = getContext().getTypeInfo(CountedByTy);
+ Ty = CGM.getTypes().ConvertType(CountedByTy);
+ Address Addr(Res, Ty, CharUnits::fromQuantity(TI.Align / getContext().getCharWidth()));
+
+ return Builder.CreateLoad(Addr, Res, "fork");
}
const ValueDecl *
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 618e78809db408b..e3137eb65dbad23 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3032,8 +3032,8 @@ class CodeGenFunction : public CodeGenTypeCache {
const ValueDecl *FindCountedByField(const Expr *Base);
/// Build an expression accessing the "counted_by" field.
- const Expr *BuildCountedByFieldExpr(const Expr *Base,
- const ValueDecl *CountedByVD);
+ llvm::Value *BuildCountedByFieldExpr(const Expr *Base,
+ const ValueDecl *CountedByVD);
llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre);
>From 47d6daf6ba01d284cbee13e790394ac63f564b34 Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Tue, 28 Nov 2023 17:23:10 -0800
Subject: [PATCH 2/6] Reformat.
---
clang/lib/CodeGen/CGExpr.cpp | 39 +++++++++++++++---------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index b77d9d8904dfc2d..2708aa8b273ab67 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -956,7 +956,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
return nullptr;
}
-namespace {
+namespace {
struct MemberExprBaseVisitor
: public StmtVisitor<MemberExprBaseVisitor, Expr *> {
@@ -973,21 +973,11 @@ struct MemberExprBaseVisitor
Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
return Visit(E->getBase());
}
- Expr *VisitCastExpr(CastExpr *E) {
- return Visit(E->getSubExpr());
- }
- Expr *VisitDeclRefExpr(DeclRefExpr *E) {
- return E;
- }
- Expr *VisitMemberExpr(MemberExpr *E) {
- return Visit(E->getBase());
- }
- Expr *VisitParenExpr(ParenExpr *E) {
- return Visit(E->getSubExpr());
- }
- Expr *VisitUnaryOperator(UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
+ Expr *VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); }
+ Expr *VisitDeclRefExpr(DeclRefExpr *E) { return E; }
+ Expr *VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); }
+ Expr *VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
+ Expr *VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
};
} // end anonymous namespace
@@ -998,10 +988,10 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
// Find the outer struct expr (i.e. p in p->a.b.c.d).
Expr *CountedByExpr = MemberExprBaseVisitor().Visit(const_cast<Expr *>(Base));
- llvm::Value *Res =
- CountedByExpr->getType()->isPointerType()
- ? EmitPointerWithAlignment(CountedByExpr).getPointer()
- : EmitDeclRefLValue(cast<DeclRefExpr>(CountedByExpr)).getPointer(*this);
+ llvm::Value *Res = CountedByExpr->getType()->isPointerType()
+ ? EmitPointerWithAlignment(CountedByExpr).getPointer()
+ : EmitDeclRefLValue(cast<DeclRefExpr>(CountedByExpr))
+ .getPointer(*this);
auto *Zero = llvm::ConstantInt::get(Int32Ty, 0);
SmallVector<llvm::Value *, 4> Indices{Zero};
@@ -1010,7 +1000,8 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
} else if (const auto *I = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
for (auto *ND : I->chain()) {
if (auto *FD = dyn_cast<FieldDecl>(ND)) {
- Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
+ Indices.emplace_back(
+ llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
}
}
}
@@ -1018,13 +1009,15 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
const DeclContext *DC = CountedByVD->getLexicalDeclContext();
const auto *CountedByRD = cast<RecordDecl>(DC);
- llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(CountedByRD->getTypeForDecl(), 0));
+ llvm::Type *Ty =
+ CGM.getTypes().ConvertType(QualType(CountedByRD->getTypeForDecl(), 0));
Res = Builder.CreateGEP(Ty, Res, Indices, "bork");
QualType CountedByTy(CountedByVD->getType());
TypeInfo TI = getContext().getTypeInfo(CountedByTy);
Ty = CGM.getTypes().ConvertType(CountedByTy);
- Address Addr(Res, Ty, CharUnits::fromQuantity(TI.Align / getContext().getCharWidth()));
+ Address Addr(Res, Ty,
+ CharUnits::fromQuantity(TI.Align / getContext().getCharWidth()));
return Builder.CreateLoad(Addr, Res, "fork");
}
>From 54199ea769cf0656d4c162cacaf7906365b700ae Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Wed, 29 Nov 2023 10:01:46 -0800
Subject: [PATCH 3/6] Remove Swedish Chef references and use the correct type
in the for-each loop.
---
clang/lib/CodeGen/CGExpr.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 2708aa8b273ab67..aecc671b3cd3a5b 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -998,7 +998,7 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
if (const auto *FD = dyn_cast<FieldDecl>(CountedByVD)) {
Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
} else if (const auto *I = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
- for (auto *ND : I->chain()) {
+ for (NamedDecl *ND : I->chain()) {
if (auto *FD = dyn_cast<FieldDecl>(ND)) {
Indices.emplace_back(
llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
@@ -1011,7 +1011,7 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
llvm::Type *Ty =
CGM.getTypes().ConvertType(QualType(CountedByRD->getTypeForDecl(), 0));
- Res = Builder.CreateGEP(Ty, Res, Indices, "bork");
+ Res = Builder.CreateGEP(Ty, Res, Indices);
QualType CountedByTy(CountedByVD->getType());
TypeInfo TI = getContext().getTypeInfo(CountedByTy);
@@ -1019,7 +1019,7 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
Address Addr(Res, Ty,
CharUnits::fromQuantity(TI.Align / getContext().getCharWidth()));
- return Builder.CreateLoad(Addr, Res, "fork");
+ return Builder.CreateLoad(Addr, Res);
}
const ValueDecl *
>From b915f62882b9e42bd60341681b4a438f2a82c49f Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Wed, 29 Nov 2023 10:04:16 -0800
Subject: [PATCH 4/6] Check that we have a real counted_by expression.
---
clang/lib/CodeGen/CGExpr.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index aecc671b3cd3a5b..9ae0f858bb6f295 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -987,6 +987,8 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
const ValueDecl *CountedByVD) {
// Find the outer struct expr (i.e. p in p->a.b.c.d).
Expr *CountedByExpr = MemberExprBaseVisitor().Visit(const_cast<Expr *>(Base));
+ if (!CountedByExpr || !isa<DeclRefExpr>(CountedByExpr))
+ return nullptr;
llvm::Value *Res = CountedByExpr->getType()->isPointerType()
? EmitPointerWithAlignment(CountedByExpr).getPointer()
>From d19cc51bd998f3e9c3bfcc11bae05bd9b45c7730 Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Wed, 29 Nov 2023 10:55:49 -0800
Subject: [PATCH 5/6] Use the correct indices for the fields. Also generate an
'inbounds' GEP and non-volatile load.
---
clang/lib/CodeGen/CGBuiltin.cpp | 2 +-
clang/lib/CodeGen/CGExpr.cpp | 20 ++++++++++----------
clang/lib/CodeGen/CodeGenFunction.h | 4 ++--
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 487bd14244e531c..9f1b5e5f6ecb5ae 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -916,7 +916,7 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type,
// Build a load of the counted_by field.
bool IsSigned = CountedByFD->getType()->isSignedIntegerType();
- Value *CountedByInst = BuildCountedByFieldExpr(Base, CountedByFD);
+ Value *CountedByInst = EmitCountedByFieldExpr(Base, CountedByFD);
llvm::Type *CountedByTy = CountedByInst->getType();
// Build a load of the index and subtract it from the count.
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 9ae0f858bb6f295..11df3f0c804b34e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -941,7 +941,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
if (const ValueDecl *VD = CGF.FindCountedByField(Base)) {
IndexedType = Base->getType();
- return CGF.BuildCountedByFieldExpr(Base, VD);
+ return CGF.EmitCountedByFieldExpr(Base, VD);
}
}
@@ -958,6 +958,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
namespace {
+/// \p MemberExprBaseVisitor returns the base \p DeclRefExpr of a field access.
struct MemberExprBaseVisitor
: public StmtVisitor<MemberExprBaseVisitor, Expr *> {
MemberExprBaseVisitor() = default;
@@ -983,7 +984,7 @@ struct MemberExprBaseVisitor
} // end anonymous namespace
llvm::Value *
-CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
+CodeGenFunction::EmitCountedByFieldExpr(const Expr *Base,
const ValueDecl *CountedByVD) {
// Find the outer struct expr (i.e. p in p->a.b.c.d).
Expr *CountedByExpr = MemberExprBaseVisitor().Visit(const_cast<Expr *>(Base));
@@ -999,13 +1000,13 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
SmallVector<llvm::Value *, 4> Indices{Zero};
if (const auto *FD = dyn_cast<FieldDecl>(CountedByVD)) {
Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
- } else if (const auto *I = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
- for (NamedDecl *ND : I->chain()) {
+ } else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(CountedByVD)) {
+ for (NamedDecl *ND : IFD->chain())
if (auto *FD = dyn_cast<FieldDecl>(ND)) {
- Indices.emplace_back(
- llvm::ConstantInt::get(Int32Ty, FD->getFieldIndex()));
+ const RecordDecl *RD = FD->getParent();
+ unsigned Idx = CGM.getTypes().getCGRecordLayout(RD).getLLVMFieldNo(FD);
+ Indices.emplace_back(llvm::ConstantInt::get(Int32Ty, Idx));
}
- }
}
const DeclContext *DC = CountedByVD->getLexicalDeclContext();
@@ -1013,15 +1014,14 @@ CodeGenFunction::BuildCountedByFieldExpr(const Expr *Base,
llvm::Type *Ty =
CGM.getTypes().ConvertType(QualType(CountedByRD->getTypeForDecl(), 0));
- Res = Builder.CreateGEP(Ty, Res, Indices);
+ Res = Builder.CreateInBoundsGEP(Ty, Res, Indices);
QualType CountedByTy(CountedByVD->getType());
TypeInfo TI = getContext().getTypeInfo(CountedByTy);
Ty = CGM.getTypes().ConvertType(CountedByTy);
Address Addr(Res, Ty,
CharUnits::fromQuantity(TI.Align / getContext().getCharWidth()));
-
- return Builder.CreateLoad(Addr, Res);
+ return Builder.CreateLoad(Addr, /*IsVolatile=*/false);
}
const ValueDecl *
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index e3137eb65dbad23..053718e74f2460f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -3032,8 +3032,8 @@ class CodeGenFunction : public CodeGenTypeCache {
const ValueDecl *FindCountedByField(const Expr *Base);
/// Build an expression accessing the "counted_by" field.
- llvm::Value *BuildCountedByFieldExpr(const Expr *Base,
- const ValueDecl *CountedByVD);
+ llvm::Value *EmitCountedByFieldExpr(const Expr *Base,
+ const ValueDecl *CountedByVD);
llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
bool isInc, bool isPre);
>From 279ca2e16d0a58f7ceb0631355d9b6ebbb31a126 Mon Sep 17 00:00:00 2001
From: Bill Wendling <morbo at google.com>
Date: Wed, 29 Nov 2023 11:04:27 -0800
Subject: [PATCH 6/6] Reformat
---
clang/lib/CodeGen/CGExpr.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 11df3f0c804b34e..e42942602a7fcda 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -985,7 +985,7 @@ struct MemberExprBaseVisitor
llvm::Value *
CodeGenFunction::EmitCountedByFieldExpr(const Expr *Base,
- const ValueDecl *CountedByVD) {
+ const ValueDecl *CountedByVD) {
// Find the outer struct expr (i.e. p in p->a.b.c.d).
Expr *CountedByExpr = MemberExprBaseVisitor().Visit(const_cast<Expr *>(Base));
if (!CountedByExpr || !isa<DeclRefExpr>(CountedByExpr))
More information about the cfe-commits
mailing list