Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR][NFC] Organize emit functions in CIRGenFunction.h #133017

Merged
merged 2 commits into from
Mar 26, 2025

Conversation

andykaylor
Copy link
Contributor

To make rebasing the incubator project easier, we've been trying to place upstreamed code in the same order in which it appears in the incubator project. However, while the upstream implementation is still relatively sparse, it is often difficult to find points of reference for placement of new declarations. To help with that, I refactored CIRGenFunction.h in the incubator to put all the emit* functions in one place and sort them alphabetically.

This change reorganizes the upstream CIRGenFunction.h to match the new incubator ordering.

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Mar 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 25, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: Andy Kaylor (andykaylor)

Changes

To make rebasing the incubator project easier, we've been trying to place upstreamed code in the same order in which it appears in the incubator project. However, while the upstream implementation is still relatively sparse, it is often difficult to find points of reference for placement of new declarations. To help with that, I refactored CIRGenFunction.h in the incubator to put all the emit* functions in one place and sort them alphabetically.

This change reorganizes the upstream CIRGenFunction.h to match the new incubator ordering.


Full diff: https://github.com/llvm/llvm-project/pull/133017.diff

1 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+131-118)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 7d1fa0712c7ac..692a8a0cb8c6d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -108,9 +108,6 @@ class CIRGenFunction : public CIRGenTypeCache {
                bool isParam = false);
 
 public:
-  mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
-                         mlir::Location loc, clang::CharUnits alignment);
-
   mlir::Value createDummyValue(mlir::Location loc, clang::QualType qt);
 
 private:
@@ -133,9 +130,6 @@ class CIRGenFunction : public CIRGenTypeCache {
     ~VarDeclContext() { restore(); }
   };
 
-  void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc,
-                              clang::CharUnits alignment);
-
 public:
   /// Use to track source locations across nested visitor traversals.
   /// Always use a `SourceLocRAIIObject` to change currSrcLoc.
@@ -164,88 +158,12 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   const clang::LangOptions &getLangOpts() const { return cgm.getLangOpts(); }
 
-  /// Emit code to compute the specified expression which can have any type. The
-  /// result is returned as an RValue struct. If this is an aggregate
-  /// expression, the aggloc/agglocvolatile arguments indicate where the result
-  /// should be returned.
-  RValue emitAnyExpr(const clang::Expr *e);
-
   void finishFunction(SourceLocation endLoc);
-  mlir::LogicalResult emitFunctionBody(const clang::Stmt *body);
-
-  /// Build a debug stoppoint if we are emitting debug info.
-  void emitStopPoint(const Stmt *s);
-
-  // Build CIR for a statement. useCurrentScope should be true if no
-  // new scopes need be created when finding a compound statement.
-  mlir::LogicalResult
-  emitStmt(const clang::Stmt *s, bool useCurrentScope,
-           llvm::ArrayRef<const Attr *> attrs = std::nullopt);
-
-  mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s,
-                                     bool useCurrentScope);
-
-  mlir::LogicalResult emitForStmt(const clang::ForStmt &S);
-
-  void emitCompoundStmt(const clang::CompoundStmt &s);
-
-  void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s);
-
-  /// Emit code to compute the specified expression,
-  /// ignoring the result.
-  void emitIgnoredExpr(const clang::Expr *e);
-
-  mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s);
-
-  mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s);
-
-  /// Given an expression that represents a value lvalue, this method emits
-  /// the address of the lvalue, then loads the result as an rvalue,
-  /// returning the rvalue.
-  RValue emitLoadOfLValue(LValue lv, SourceLocation loc);
-
-  /// EmitLoadOfScalar - Load a scalar value from an address, taking
-  /// care to appropriately convert from the memory representation to
-  /// the LLVM value representation.  The l-value must be a simple
-  /// l-value.
-  mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc);
-
-  /// Emit code to compute a designator that specifies the location
-  /// of the expression.
-  /// FIXME: document this function better.
-  LValue emitLValue(const clang::Expr *e);
-
-  void emitDecl(const clang::Decl &d);
-
-  void emitScalarInit(const clang::Expr *init, mlir::Location loc,
-                      LValue lvalue, bool capturedByInit = false);
-
-  LValue emitDeclRefLValue(const clang::DeclRefExpr *e);
-  LValue emitUnaryOpLValue(const clang::UnaryOperator *e);
-  LValue emitBinaryOperatorLValue(const BinaryOperator *e);
 
   /// Determine whether the given initializer is trivial in the sense
   /// that it requires no code to be generated.
   bool isTrivialInitializer(const Expr *init);
 
-  /// Emit an expression as an initializer for an object (variable, field, etc.)
-  /// at the given location.  The expression is not necessarily the normal
-  /// initializer for the object, and the address is not necessarily
-  /// its normal location.
-  ///
-  /// \param init the initializing expression
-  /// \param d the object to act as if we're initializing
-  /// \param lvalue the lvalue to initialize
-  /// \param capturedByInit true if \p d is a __block variable whose address is
-  /// potentially changed by the initializer
-  void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d,
-                      LValue lvalue, bool capturedByInit = false);
-
-  /// Emit code and set up symbol table for a variable declaration with auto,
-  /// register, or no storage class specifier. These turn into simple stack
-  /// objects, globals depending on target.
-  void emitAutoVarDecl(const clang::VarDecl &d);
-
   struct AutoVarEmission {
     const clang::VarDecl *Variable;
     /// The address of the alloca for languages with explicit address space
@@ -291,30 +209,6 @@ class CIRGenFunction : public CIRGenTypeCache {
     }
   };
 
-  AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d);
-  void emitAutoVarInit(const AutoVarEmission &emission);
-  void emitAutoVarCleanups(const AutoVarEmission &emission);
-
-  void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
-                         clang::QualType ty, bool isInit = false,
-                         bool isNontemporal = false);
-  void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
-
-  /// Given a value and its clang type, returns the value casted to its memory
-  /// representation.
-  /// Note: CIR defers most of the special casting to the final lowering passes
-  /// to conserve the high level information.
-  mlir::Value emitToMemory(mlir::Value Value, clang::QualType Ty);
-
-  /// Store the specified rvalue into the specified
-  /// lvalue, where both are guaranteed to the have the same type, and that type
-  /// is 'Ty'.
-  void emitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
-
-  /// This method handles emission of any variable declaration
-  /// inside a function, including static vars etc.
-  void emitVarDecl(const clang::VarDecl &d);
-
   /// Perform the usual unary conversions on the specified expression and
   /// compare the result against zero, returning an Int1Ty value.
   mlir::Value evaluateExprAsBool(const clang::Expr *e);
@@ -326,12 +220,6 @@ class CIRGenFunction : public CIRGenTypeCache {
     // TODO: Add symbol table support
   }
 
-  mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
-                                      bool isInc, bool isPre);
-
-  /// Emit the computation of the specified expression of scalar type.
-  mlir::Value emitScalarExpr(const clang::Expr *e);
-  mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType);
   cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
                            cir::FuncType funcType);
 
@@ -346,12 +234,6 @@ class CIRGenFunction : public CIRGenTypeCache {
                      FunctionArgList args, clang::SourceLocation loc,
                      clang::SourceLocation startLoc);
 
-  /// Emit a conversion from the specified type to the specified destination
-  /// type, both of which are CIR scalar types.
-  mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType,
-                                   clang::QualType dstType,
-                                   clang::SourceLocation loc);
-
   /// Represents a scope, including function bodies, compound statements, and
   /// the substatements of if/while/do/for/switch/try statements.  This class
   /// handles any automatic cleanup, along with the return value.
@@ -482,6 +364,137 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   LexicalScope *curLexScope = nullptr;
 
+  /// ----------------------
+  /// CIR emit functions
+  /// ----------------------
+private:
+  void emitAndUpdateRetAlloca(clang::QualType type, mlir::Location loc,
+                              clang::CharUnits alignment);
+
+public:
+  mlir::Value emitAlloca(llvm::StringRef name, mlir::Type ty,
+                         mlir::Location loc, clang::CharUnits alignment);
+
+  /// Emit code to compute the specified expression which can have any type. The
+  /// result is returned as an RValue struct. If this is an aggregate
+  /// expression, the aggloc/agglocvolatile arguments indicate where the result
+  /// should be returned.
+  RValue emitAnyExpr(const clang::Expr *e);
+
+  AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d);
+
+  /// Emit code and set up symbol table for a variable declaration with auto,
+  /// register, or no storage class specifier. These turn into simple stack
+  /// objects, globals depending on target.
+  void emitAutoVarDecl(const clang::VarDecl &d);
+
+  void emitAutoVarCleanups(const AutoVarEmission &emission);
+  void emitAutoVarInit(const AutoVarEmission &emission);
+
+  LValue emitBinaryOperatorLValue(const BinaryOperator *e);
+
+  /// Emit an expression as an initializer for an object (variable, field, etc.)
+  /// at the given location.  The expression is not necessarily the normal
+  /// initializer for the object, and the address is not necessarily
+  /// its normal location.
+  ///
+  /// \param init the initializing expression
+  /// \param d the object to act as if we're initializing
+  /// \param lvalue the lvalue to initialize
+  /// \param capturedByInit true if \p d is a __block variable whose address is
+  /// potentially changed by the initializer
+  void emitExprAsInit(const clang::Expr *init, const clang::ValueDecl *d,
+                      LValue lvalue, bool capturedByInit = false);
+
+  mlir::LogicalResult emitFunctionBody(const clang::Stmt *body);
+
+  mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType);
+
+  /// Emit the computation of the specified expression of scalar type.
+  mlir::Value emitScalarExpr(const clang::Expr *e);
+
+  mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv,
+                                      bool isInc, bool isPre);
+
+  /// Build a debug stoppoint if we are emitting debug info.
+  void emitStopPoint(const Stmt *s);
+
+  // Build CIR for a statement. useCurrentScope should be true if no
+  // new scopes need be created when finding a compound statement.
+  mlir::LogicalResult
+  emitStmt(const clang::Stmt *s, bool useCurrentScope,
+           llvm::ArrayRef<const Attr *> attrs = std::nullopt);
+
+  mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s,
+                                     bool useCurrentScope);
+
+  mlir::LogicalResult emitForStmt(const clang::ForStmt &S);
+
+  void emitCompoundStmt(const clang::CompoundStmt &s);
+
+  void emitCompoundStmtWithoutScope(const clang::CompoundStmt &s);
+
+  void emitDecl(const clang::Decl &d);
+  mlir::LogicalResult emitDeclStmt(const clang::DeclStmt &s);
+  LValue emitDeclRefLValue(const clang::DeclRefExpr *e);
+
+  /// Emit code to compute the specified expression,
+  /// ignoring the result.
+  void emitIgnoredExpr(const clang::Expr *e);
+
+  /// Given an expression that represents a value lvalue, this method emits
+  /// the address of the lvalue, then loads the result as an rvalue,
+  /// returning the rvalue.
+  RValue emitLoadOfLValue(LValue lv, SourceLocation loc);
+
+  /// EmitLoadOfScalar - Load a scalar value from an address, taking
+  /// care to appropriately convert from the memory representation to
+  /// the LLVM value representation.  The l-value must be a simple
+  /// l-value.
+  mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc);
+
+  /// Emit code to compute a designator that specifies the location
+  /// of the expression.
+  /// FIXME: document this function better.
+  LValue emitLValue(const clang::Expr *e);
+
+  mlir::LogicalResult emitReturnStmt(const clang::ReturnStmt &s);
+
+  /// Emit a conversion from the specified type to the specified destination
+  /// type, both of which are CIR scalar types.
+  mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType,
+                                   clang::QualType dstType,
+                                   clang::SourceLocation loc);
+
+  void emitScalarInit(const clang::Expr *init, mlir::Location loc,
+                      LValue lvalue, bool capturedByInit = false);
+
+  void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile,
+                         clang::QualType ty, bool isInit = false,
+                         bool isNontemporal = false);
+  void emitStoreOfScalar(mlir::Value value, LValue lvalue, bool isInit);
+
+  /// Store the specified rvalue into the specified
+  /// lvalue, where both are guaranteed to the have the same type, and that type
+  /// is 'Ty'.
+  void emitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
+
+  /// Given a value and its clang type, returns the value casted to its memory
+  /// representation.
+  /// Note: CIR defers most of the special casting to the final lowering passes
+  /// to conserve the high level information.
+  mlir::Value emitToMemory(mlir::Value Value, clang::QualType Ty);
+
+  LValue emitUnaryOpLValue(const clang::UnaryOperator *e);
+
+  /// This method handles emission of any variable declaration
+  /// inside a function, including static vars etc.
+  void emitVarDecl(const clang::VarDecl &d);
+
+  /// ----------------------
+  /// CIR build helpers
+  /// -----------------
+public:
   Address createTempAlloca(mlir::Type ty, CharUnits align, mlir::Location loc,
                            const Twine &name = "tmp");
 };

To make rebasing the incubator project easier, we've been trying to place
upstreamed code in the same order in which it appears in the incubator
project. However, while the upstream implementation is still relatively
sparse, it is often difficult to find points of reference for placement
of new declarations. To help with that, I refactored CIRGenFunction.h in
the incubator to put all the emit* functions in one place and sort them
alphabetically.

This change reorganizes the upstream CIRGenFunction.h to match the new
incubator ordering.
@andykaylor andykaylor force-pushed the cir-refactor-cirgenfn branch from 66fc5f0 to ea61ece Compare March 25, 2025 23:32
mlir::LogicalResult emitSimpleStmt(const clang::Stmt *s,
bool useCurrentScope);

mlir::LogicalResult emitForStmt(const clang::ForStmt &S);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mlir::LogicalResult emitForStmt(const clang::ForStmt &S);
mlir::LogicalResult emitForStmt(const clang::ForStmt &s);

/// Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void emitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void emitStoreThroughLValue(RValue Src, LValue Dst, bool isInit = false);
void emitStoreThroughLValue(RValue src, LValue dst, bool isInit = false);

/// representation.
/// Note: CIR defers most of the special casting to the final lowering passes
/// to conserve the high level information.
mlir::Value emitToMemory(mlir::Value Value, clang::QualType Ty);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
mlir::Value emitToMemory(mlir::Value Value, clang::QualType Ty);
mlir::Value emitToMemory(mlir::Value value, clang::QualType ty);

Copy link
Contributor

xlauko commented Mar 26, 2025

LGTM with minor nits

@andykaylor
Copy link
Contributor Author

@mmha I should have copied you on this earlier.

Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@andykaylor andykaylor merged commit 6d1184d into llvm:main Mar 26, 2025
11 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 26, 2025

LLVM Buildbot has detected a new failure on builder clang-aarch64-quick running on linaro-clang-aarch64-quick while building clang at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/14464

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
******************** TEST 'Clangd Unit Tests :: ./ClangdTests/57/161' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests-Clangd Unit Tests-2438688-57-161.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=161 GTEST_SHARD_INDEX=57 /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests
--

Script:
--
/home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests --gtest_filter=ClangdServerTest.FallbackWhenWaitingForCompileCommand
--
Build for file /clangd-test/foo.cpp is not ready. Enter fallback mode.
Code complete: 0 results from Sema, 0 from Index, 0 matched, 1 from identifiers, 1 returned.
ASTWorker building file /clangd-test/foo.cpp version null with command 
[/clangd-test]
clangd -ffreestanding /clangd-test/foo.cpp
Driver produced command: cc1 -cc1 -triple aarch64-unknown-linux-gnu -fsyntax-only -disable-free -clear-ast-before-backend -main-file-name foo.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=non-leaf -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -enable-tlsdesc -target-cpu generic -target-feature +v8a -target-feature +fp-armv8 -target-feature +neon -target-abi aapcs -debugger-tuning=gdb -fdebug-compilation-dir=/clangd-test -fcoverage-compilation-dir=/clangd-test -resource-dir lib/clang/21 -internal-isystem lib/clang/21/include -internal-isystem /usr/local/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -no-round-trip-args -target-feature -fmv -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -x c++ /clangd-test/foo.cpp
Building first preamble for /clangd-test/foo.cpp version null
../llvm/clang-tools-extra/clangd/unittests/ClangdTests.cpp:1157: Failure
Value of: Server.blockUntilIdleForTest()
  Actual: false
Expected: true

Built preamble of size 722640 for file /clangd-test/foo.cpp version null in 11.01 seconds

../llvm/clang-tools-extra/clangd/unittests/ClangdTests.cpp:1157
Value of: Server.blockUntilIdleForTest()
  Actual: false
Expected: true



********************


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants