diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-03-16 21:03:34 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-03-18 00:15:08 +0000 |
commit | 6b77eb316cdfb394fdea443d61605e72683c4ec4 (patch) | |
tree | 5a609127ddc3f6d0a0231be612f906ce9fe525d3 /gcc/rust/backend | |
parent | 858fd17fcf9aeddd9392d480c19471aaac891e5f (diff) | |
download | gcc-6b77eb316cdfb394fdea443d61605e72683c4ec4.zip gcc-6b77eb316cdfb394fdea443d61605e72683c4ec4.tar.gz gcc-6b77eb316cdfb394fdea443d61605e72683c4ec4.tar.bz2 |
gccrs: Add move_val_init intrinsic
This implements it as a builtin memcpy using the generic param T for the
size hint.
Fixes #1902
gcc/rust/ChangeLog:
* backend/rust-compile-intrinsic.cc (move_val_init_handler): new intrinsice
(uninit_handler): use a builtin memcpy
gcc/testsuite/ChangeLog:
* rust/compile/issue-1981.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r-- | gcc/rust/backend/rust-compile-intrinsic.cc | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 85f6e1c..b9951a0 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -83,6 +83,8 @@ static tree op_with_overflow_inner (Context *ctx, TyTy::FnType *fntype, tree_code op); static tree uninit_handler (Context *ctx, TyTy::FnType *fntype); +static tree +move_val_init_handler (Context *ctx, TyTy::FnType *fntype); enum class Prefetch { @@ -205,6 +207,7 @@ static const std::map<std::string, {"unchecked_shl", unchecked_op_handler (LSHIFT_EXPR)}, {"unchecked_shr", unchecked_op_handler (RSHIFT_EXPR)}, {"uninit", uninit_handler}, + {"move_val_init", move_val_init_handler}, }; Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {} @@ -1001,7 +1004,7 @@ uninit_handler (Context *ctx, TyTy::FnType *fntype) auto fndecl = compile_intrinsic_function (ctx, fntype); - // get the template parameter type tree fn size_of<T>(); + // get the template parameter type tree fn uninit<T>(); rust_assert (fntype->get_num_substitutions () == 1); auto ¶m_mapping = fntype->get_substs ().at (0); const TyTy::ParamType *param_tyty = param_mapping.get_param_ty (); @@ -1042,5 +1045,56 @@ uninit_handler (Context *ctx, TyTy::FnType *fntype) return fndecl; } +static tree +move_val_init_handler (Context *ctx, TyTy::FnType *fntype) +{ + rust_assert (fntype->get_params ().size () == 2); + + tree lookup = NULL_TREE; + if (check_for_cached_intrinsic (ctx, fntype, &lookup)) + return lookup; + + auto fndecl = compile_intrinsic_function (ctx, fntype); + + // get the template parameter type tree fn size_of<T>(); + rust_assert (fntype->get_num_substitutions () == 1); + auto ¶m_mapping = fntype->get_substs ().at (0); + const TyTy::ParamType *param_tyty = param_mapping.get_param_ty (); + TyTy::BaseType *resolved_tyty = param_tyty->resolve (); + tree template_parameter_type + = TyTyResolveCompile::compile (ctx, resolved_tyty); + + std::vector<Bvariable *> param_vars; + compile_fn_params (ctx, fntype, fndecl, ¶m_vars); + + if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars)) + return error_mark_node; + + enter_intrinsic_block (ctx, fndecl); + + // BUILTIN size_of FN BODY BEGIN + + tree dst = ctx->get_backend ()->var_expression (param_vars[0], Location ()); + tree src = ctx->get_backend ()->var_expression (param_vars[1], Location ()); + tree size = TYPE_SIZE_UNIT (template_parameter_type); + + tree memcpy_builtin = error_mark_node; + BuiltinsContext::get ().lookup_simple_builtin ("memcpy", &memcpy_builtin); + rust_assert (memcpy_builtin != error_mark_node); + + src = build_fold_addr_expr_loc (BUILTINS_LOCATION, src); + tree memset_call = build_call_expr_loc (BUILTINS_LOCATION, memcpy_builtin, 3, + dst, src, size); + TREE_READONLY (memset_call) = 0; + TREE_SIDE_EFFECTS (memset_call) = 1; + + ctx->add_statement (memset_call); + // BUILTIN size_of FN BODY END + + finalize_intrinsic_block (ctx, fndecl); + + return fndecl; +} + } // namespace Compile } // namespace Rust |