aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-31 13:21:19 +0000
committerGitHub <noreply@github.com>2022-08-31 13:21:19 +0000
commitceb43210f8a6dfec98f634c326964328d1247f57 (patch)
tree5efa5f7aa3960f67a1ecde67febf9a99760f7a18 /gcc
parent9b210f1c544ce4b0a4ff330c1e93d3ee83785484 (diff)
parent5acb1375c9c57b4cc0af13f4ccea0d609942bc0a (diff)
downloadgcc-ceb43210f8a6dfec98f634c326964328d1247f57.zip
gcc-ceb43210f8a6dfec98f634c326964328d1247f57.tar.gz
gcc-ceb43210f8a6dfec98f634c326964328d1247f57.tar.bz2
Merge #1505
1505: Create canonical process of compiling constant items r=philberty a=philberty 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. Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-base.cc103
-rw-r--r--gcc/rust/backend/rust-tree.cc22
2 files changed, 56 insertions, 69 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index c56a0ea..a5643d2 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);
}
diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 9dac0dce..f587835 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -2916,27 +2916,7 @@ comptypes (tree t1, tree t2, int strict)
perform a deep check. */
return structural_comptypes (t1, t2, strict);
- if (flag_checking && param_use_canonical_types)
- {
- bool result = structural_comptypes (t1, t2, strict);
-
- if (result && TYPE_CANONICAL (t1) != TYPE_CANONICAL (t2))
- /* The two types are structurally equivalent, but their
- canonical types were different. This is a failure of the
- canonical type propagation code.*/
- internal_error (
- "canonical types differ for identical types %qT and %qT", t1, t2);
- else if (!result && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
- /* Two types are structurally different, but the canonical
- types are the same. This means we were over-eager in
- assigning canonical types. */
- internal_error (
- "same canonical type node for different types %qT and %qT", t1,
- t2);
-
- return result;
- }
- if (!flag_checking && param_use_canonical_types)
+ if (!flag_checking)
return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
else
return structural_comptypes (t1, t2, strict);