public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
From: Arthur Cohen <arthur.cohen@embecosm.com>
To: gcc-patches@gcc.gnu.org
Cc: gcc-rust@gcc.gnu.org, Philip Herron <philip.herron@embecosm.com>
Subject: [COMMITTED] gccrs: Create canonical process of compiling constant items
Date: Tue, 31 Jan 2023 14:25:38 +0100	[thread overview]
Message-ID: <20230131132538.662296-1-arthur.cohen@embecosm.com> (raw)

From: Philip Herron <philip.herron@embecosm.com>

In order to compile a block expression constant, the simplest way for us
was to reuse what code we have and to generate an artifical function which
does not get added to the translation unit. The constant then becomes
a CALL_EXPR to this artifical function which we can pass to the constexpr
evaluator to resolve the result of this artifical 'CALL_EXPR'.

Before this patch we seperated the difference between block expressions
and non block expressions in constants. So for non block expressions we
simply compiled them as if it was a simple constant but this is not
guaranteed to be the case in rust, for example coercion sites can generate
temporaries during autoderef which we let the constant evaluator resolve
for us. This makes all constants handled in the same way to simplify the
logic here.

gcc/rust/ChangeLog:

	* backend/rust-compile-base.cc: Improve compilation pipeline and simplify
	function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/rust/backend/rust-compile-base.cc | 103 ++++++++++++++------------
 1 file changed, 55 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index e1506b377ce..568abf9ca2c 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -652,65 +652,72 @@ HIRCompileBase::compile_constant_item (
   bool is_block_expr
     = const_value_expr->get_expression_type () == HIR::Expr::ExprType::Block;
 
-  // compile the expression
-  tree folded_expr = error_mark_node;
-  if (!is_block_expr)
-    {
-      tree value = CompileExpr::Compile (const_value_expr, ctx);
-      folded_expr = fold_expr (value);
-    }
-  else
-    {
-      // in order to compile a block expr we want to reuse as much existing
-      // machineary that we already have. This means the best approach is to
-      // make a _fake_ function with a block so it can hold onto temps then
-      // use our constexpr code to fold it completely or error_mark_node
-      Backend::typed_identifier receiver;
-      tree compiled_fn_type = ctx->get_backend ()->function_type (
-	receiver, {}, {Backend::typed_identifier ("_", const_type, locus)},
-	NULL, locus);
-
-      tree fndecl
-	= ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
-      TREE_READONLY (fndecl) = 1;
+  // in order to compile a block expr we want to reuse as much existing
+  // machineary that we already have. This means the best approach is to
+  // make a _fake_ function with a block so it can hold onto temps then
+  // use our constexpr code to fold it completely or error_mark_node
+  Backend::typed_identifier receiver;
+  tree compiled_fn_type = ctx->get_backend ()->function_type (
+    receiver, {}, {Backend::typed_identifier ("_", const_type, locus)}, NULL,
+    locus);
+
+  tree fndecl
+    = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0, locus);
+  TREE_READONLY (fndecl) = 1;
+
+  tree enclosing_scope = NULL_TREE;
 
-      tree enclosing_scope = NULL_TREE;
+  Location start_location = const_value_expr->get_locus ();
+  Location end_location = const_value_expr->get_locus ();
+  if (is_block_expr)
+    {
       HIR::BlockExpr *function_body
 	= static_cast<HIR::BlockExpr *> (const_value_expr);
-      Location start_location = function_body->get_locus ();
-      Location end_location = function_body->get_end_locus ();
+      start_location = function_body->get_locus ();
+      end_location = function_body->get_end_locus ();
+    }
 
-      tree code_block
-	= ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-				      start_location, end_location);
-      ctx->push_block (code_block);
+  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+						start_location, end_location);
+  ctx->push_block (code_block);
 
-      bool address_is_taken = false;
-      tree ret_var_stmt = NULL_TREE;
-      Bvariable *return_address
-	= ctx->get_backend ()->temporary_variable (fndecl, code_block,
-						   const_type, NULL,
-						   address_is_taken, locus,
-						   &ret_var_stmt);
+  bool address_is_taken = false;
+  tree ret_var_stmt = NULL_TREE;
+  Bvariable *return_address
+    = ctx->get_backend ()->temporary_variable (fndecl, code_block, const_type,
+					       NULL, address_is_taken, locus,
+					       &ret_var_stmt);
 
-      ctx->add_statement (ret_var_stmt);
-      ctx->push_fn (fndecl, return_address);
+  ctx->add_statement (ret_var_stmt);
+  ctx->push_fn (fndecl, return_address);
 
+  if (is_block_expr)
+    {
+      HIR::BlockExpr *function_body
+	= static_cast<HIR::BlockExpr *> (const_value_expr);
       compile_function_body (ctx, fndecl, *function_body, true);
-      tree bind_tree = ctx->pop_block ();
+    }
+  else
+    {
+      tree value = CompileExpr::Compile (const_value_expr, ctx);
+      tree return_expr = ctx->get_backend ()->return_statement (
+	fndecl, {value}, const_value_expr->get_locus ());
+      ctx->add_statement (return_expr);
+    }
 
-      gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
-      DECL_SAVED_TREE (fndecl) = bind_tree;
-      DECL_DECLARED_CONSTEXPR_P (fndecl) = 1;
-      maybe_save_constexpr_fundef (fndecl);
+  tree bind_tree = ctx->pop_block ();
+
+  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+  DECL_SAVED_TREE (fndecl) = bind_tree;
+  DECL_DECLARED_CONSTEXPR_P (fndecl) = 1;
+  maybe_save_constexpr_fundef (fndecl);
 
-      ctx->pop_fn ();
+  ctx->pop_fn ();
 
-      // lets fold it into a call expr
-      tree call = build_call_array_loc (locus.gcc_location (), const_type,
-					fndecl, 0, NULL);
-      folded_expr = fold_expr (call);
-    }
+  // lets fold it into a call expr
+  tree call
+    = build_call_array_loc (locus.gcc_location (), const_type, fndecl, 0, NULL);
+  tree folded_expr = fold_expr (call);
 
   return named_constant_expression (const_type, ident, folded_expr, locus);
 }
-- 
2.39.1


                 reply	other threads:[~2023-01-31 13:21 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230131132538.662296-1-arthur.cohen@embecosm.com \
    --to=arthur.cohen@embecosm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc-rust@gcc.gnu.org \
    --cc=philip.herron@embecosm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).