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 <mo...@google.com> Date: Tue, 28 Nov 2023 17:17:54 -0800 Subject: [PATCH 1/5] [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 <mo...@google.com> Date: Tue, 28 Nov 2023 17:23:10 -0800 Subject: [PATCH 2/5] 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 <mo...@google.com> Date: Wed, 29 Nov 2023 10:01:46 -0800 Subject: [PATCH 3/5] 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 <mo...@google.com> Date: Wed, 29 Nov 2023 10:04:16 -0800 Subject: [PATCH 4/5] 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 <mo...@google.com> Date: Wed, 29 Nov 2023 10:55:49 -0800 Subject: [PATCH 5/5] 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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits