diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-31 13:21:19 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-31 13:21:19 +0000 |
commit | ceb43210f8a6dfec98f634c326964328d1247f57 (patch) | |
tree | 5efa5f7aa3960f67a1ecde67febf9a99760f7a18 /gcc | |
parent | 9b210f1c544ce4b0a4ff330c1e93d3ee83785484 (diff) | |
parent | 5acb1375c9c57b4cc0af13f4ccea0d609942bc0a (diff) | |
download | gcc-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.cc | 103 | ||||
-rw-r--r-- | gcc/rust/backend/rust-tree.cc | 22 |
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); |