public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] intrinsics: Refactor compilation of intrinsics
@ 2022-08-11 19:18 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-08-11 19:18 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:fc8d5dfe93e80e6d5033dc44ed3eb8220764d8f9

commit fc8d5dfe93e80e6d5033dc44ed3eb8220764d8f9
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Tue Aug 9 15:48:33 2022 +0200

    intrinsics: Refactor compilation of intrinsics
    
    This commit adds helpers around caching, compiling and using intrinsic
    functions before extending them with instructions specific to the
    intrinsic. We can refactor them further, but this is already a bit
    easier to deal with when writing new intrinsics

Diff:
---
 gcc/rust/backend/rust-compile-intrinsic.cc         | 406 +++++++--------------
 gcc/testsuite/rust/compile/torture/intrinsics-2.rs |  22 ++
 2 files changed, 151 insertions(+), 277 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index ebf1ed61f55..a68ccc56a13 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -30,31 +30,32 @@ namespace Rust {
 namespace Compile {
 
 static tree
-offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype);
+offset_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
-sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype);
+sizeof_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
-transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype);
+transmute_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
-rotate_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype, tree_code op);
+rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op);
+
 static inline tree
-rotate_left_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype)
+rotate_left_handler (Context *ctx, TyTy::FnType *fntype)
 {
-  return rotate_intrinsic_handler (ctx, fntype, LROTATE_EXPR);
+  return rotate_handler (ctx, fntype, LROTATE_EXPR);
 }
 static inline tree
-rotate_right_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype)
+rotate_right_handler (Context *ctx, TyTy::FnType *fntype)
 {
-  return rotate_intrinsic_handler (ctx, fntype, RROTATE_EXPR);
+  return rotate_handler (ctx, fntype, RROTATE_EXPR);
 }
 
 static const std::map<std::string,
-		      std::function<tree (Context *, TyTy::BaseType *)>>
-  generic_intrinsics = {{"offset", &offset_intrinsic_handler},
-			{"size_of", &sizeof_intrinsic_handler},
-			{"transmute", &transmute_intrinsic_handler},
-			{"rotate_left", &rotate_left_intrinsic_handler},
-			{"rotate_right", &rotate_right_intrinsic_handler}};
+		      std::function<tree (Context *, TyTy::FnType *)>>
+  generic_intrinsics = {{"offset", &offset_handler},
+			{"size_of", &sizeof_handler},
+			{"transmute", &transmute_handler},
+			{"rotate_left", &rotate_left_handler},
+			{"rotate_right", &rotate_right_handler}};
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
 
@@ -80,44 +81,70 @@ Intrinsics::compile (TyTy::FnType *fntype)
   return error_mark_node;
 }
 
-static tree
-offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
+/**
+ * Items can be forward compiled which means we may not need to invoke this
+ * code. We might also have already compiled this generic function as well.
+ */
+static bool
+check_for_cached_intrinsic (Context *ctx, TyTy::FnType *fntype, tree *lookup)
 {
-  rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-  const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path;
-
-  // items can be forward compiled which means we may not need to invoke this
-  // code. We might also have already compiled this generic function as well.
-  tree lookup = NULL_TREE;
-  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
+  if (ctx->lookup_function_decl (fntype->get_ty_ref (), lookup,
 				 fntype->get_id (), fntype))
     {
-      // has this been added to the list then it must be finished
-      if (ctx->function_completed (lookup))
+      // Has this been added to the list? Then it must be finished
+      if (ctx->function_completed (*lookup))
 	{
 	  tree dummy = NULL_TREE;
 	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	    {
-	      ctx->insert_function_decl (fntype, lookup);
-	    }
-	  return lookup;
+	    ctx->insert_function_decl (fntype, *lookup);
+	  return true;
 	}
     }
 
+  return false;
+}
+
+/**
+ * Maybe override the Hir Lookups for the substituions in this context
+ */
+static void
+maybe_override_ctx (TyTy::FnType *fntype)
+{
   if (fntype->has_subsititions_defined ())
-    {
-      // override the Hir Lookups for the substituions in this context
-      fntype->override_context ();
-    }
+    fntype->override_context ();
+}
 
-  // offset intrinsic has two params dst pointer and offset isize
-  if (fntype->get_params ().size () != 2)
+/**
+ * Compile and setup a function's parameters
+ */
+static void
+compile_fn_params (Context *ctx, TyTy::FnType *fntype, tree fndecl,
+		   std::vector<Bvariable *> *compiled_param_variables,
+		   std::vector<tree_node *> *compiled_param_types = nullptr)
+{
+  for (auto &parm : fntype->get_params ())
     {
-      rust_error_at (fntype->get_ident ().locus,
-		     "invalid number of parameters for offset intrinsic");
-      return error_mark_node;
+      auto &referenced_param = parm.first;
+      auto &param_tyty = parm.second;
+      auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
+
+      Location param_locus = referenced_param->get_locus ();
+      Bvariable *compiled_param_var
+	= CompileFnParam::compile (ctx, fndecl, referenced_param,
+				   compiled_param_type, param_locus);
+
+      compiled_param_variables->push_back (compiled_param_var);
+      if (compiled_param_types)
+	compiled_param_types->push_back (compiled_param_type);
     }
+}
+
+static tree
+compile_intrinsic_function (Context *ctx, TyTy::FnType *fntype)
+{
+  maybe_override_ctx (fntype);
+
+  const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path;
 
   tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
   std::string ir_symbol_name
@@ -128,27 +155,49 @@ offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   tree fndecl
     = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
 				     flags, fntype->get_ident ().locus);
+
   TREE_PUBLIC (fndecl) = 0;
   TREE_READONLY (fndecl) = 1;
   DECL_ARTIFICIAL (fndecl) = 1;
   DECL_EXTERNAL (fndecl) = 0;
   DECL_DECLARED_INLINE_P (fndecl) = 1;
 
-  // setup the params
-  std::vector<Bvariable *> param_vars;
-  for (auto &parm : fntype->get_params ())
-    {
-      auto &referenced_param = parm.first;
-      auto &param_tyty = parm.second;
-      auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
+  return fndecl;
+}
 
-      Location param_locus = referenced_param->get_locus ();
-      Bvariable *compiled_param_var
-	= CompileFnParam::compile (ctx, fndecl, referenced_param,
-				   compiled_param_type, param_locus);
+static void
+enter_intrinsic_block (Context *ctx, tree fndecl)
+{
+  tree enclosing_scope = NULL_TREE;
+  Location start_location = Location ();
+  Location end_location = Location ();
 
-      param_vars.push_back (compiled_param_var);
-    }
+  auto block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
+					   start_location, end_location);
+
+  ctx->push_block (block);
+}
+
+static void
+finalize_intrinsic_block (Context *ctx, tree fndecl)
+{
+  tree bind_tree = ctx->pop_block ();
+
+  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
+  DECL_SAVED_TREE (fndecl) = bind_tree;
+  ctx->push_function (fndecl);
+}
+
+static tree
+offset_handler (Context *ctx, TyTy::FnType *fntype)
+{
+  // offset intrinsic has two params dst pointer and offset isize
+  rust_assert (fntype->get_params ().size () == 2);
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  std::vector<Bvariable *> param_vars;
+  compile_fn_params (ctx, fntype, fndecl, &param_vars);
 
   auto &dst_param = param_vars.at (0);
   auto &size_param = param_vars.at (1);
@@ -156,13 +205,7 @@ offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
     return error_mark_node;
 
-  tree enclosing_scope = NULL_TREE;
-  Location start_location = Location ();
-  Location end_location = Location ();
-
-  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-						start_location, end_location);
-  ctx->push_block (code_block);
+  enter_intrinsic_block (ctx, fndecl);
 
   // BUILTIN offset FN BODY BEGIN
   tree dst = ctx->get_backend ()->var_expression (dst_param, Location ());
@@ -175,53 +218,22 @@ offset_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   ctx->add_statement (return_statement);
   // BUILTIN offset FN BODY END
 
-  tree bind_tree = ctx->pop_block ();
-
-  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
-  DECL_SAVED_TREE (fndecl) = bind_tree;
-  ctx->push_function (fndecl);
+  finalize_intrinsic_block (ctx, fndecl);
 
   return fndecl;
 }
 
 static tree
-sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
+sizeof_handler (Context *ctx, TyTy::FnType *fntype)
 {
-  rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-  const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path;
+  // size_of has _zero_ parameters its parameter is the generic one
+  rust_assert (fntype->get_params ().size () == 0);
 
-  // items can be forward compiled which means we may not need to invoke this
-  // code. We might also have already compiled this generic function as well.
   tree lookup = NULL_TREE;
-  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				 fntype->get_id (), fntype))
-    {
-      // has this been added to the list then it must be finished
-      if (ctx->function_completed (lookup))
-	{
-	  tree dummy = NULL_TREE;
-	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	    {
-	      ctx->insert_function_decl (fntype, lookup);
-	    }
-	  return lookup;
-	}
-    }
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
 
-  if (fntype->has_subsititions_defined ())
-    {
-      // override the Hir Lookups for the substituions in this context
-      fntype->override_context ();
-    }
-
-  // size_of has _zero_ parameters its parameter is the generic one
-  if (fntype->get_params ().size () != 0)
-    {
-      rust_error_at (fntype->get_ident ().locus,
-		     "invalid number of parameters for size of intrinsic");
-      return error_mark_node;
-    }
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
 
   // get the template parameter type tree fn size_of<T>();
   rust_assert (fntype->get_num_substitutions () == 1);
@@ -231,29 +243,7 @@ sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   tree template_parameter_type
     = TyTyResolveCompile::compile (ctx, resolved_tyty);
 
-  // build the intrinsic function
-  tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-  std::string ir_symbol_name
-    = canonical_path.get () + fntype->subst_as_string ();
-  std::string asm_name = ctx->mangle_item (fntype, canonical_path);
-
-  unsigned int flags = 0;
-  tree fndecl
-    = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
-				     flags, fntype->get_ident ().locus);
-  TREE_PUBLIC (fndecl) = 0;
-  TREE_READONLY (fndecl) = 1;
-  DECL_ARTIFICIAL (fndecl) = 1;
-  DECL_EXTERNAL (fndecl) = 0;
-  DECL_DECLARED_INLINE_P (fndecl) = 1;
-
-  tree enclosing_scope = NULL_TREE;
-  Location start_location = Location ();
-  Location end_location = Location ();
-
-  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-						start_location, end_location);
-  ctx->push_block (code_block);
+  enter_intrinsic_block (ctx, fndecl);
 
   // BUILTIN size_of FN BODY BEGIN
   tree size_expr = TYPE_SIZE_UNIT (template_parameter_type);
@@ -262,89 +252,27 @@ sizeof_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   ctx->add_statement (return_statement);
   // BUILTIN size_of FN BODY END
 
-  tree bind_tree = ctx->pop_block ();
-
-  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
-  DECL_SAVED_TREE (fndecl) = bind_tree;
-  ctx->push_function (fndecl);
+  finalize_intrinsic_block (ctx, fndecl);
 
   return fndecl;
 }
 
 static tree
-transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
+transmute_handler (Context *ctx, TyTy::FnType *fntype)
 {
-  rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-  const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path;
+  // transmute intrinsic has one parameter
+  rust_assert (fntype->get_params ().size () == 1);
 
-  // items can be forward compiled which means we may not need to invoke this
-  // code. We might also have already compiled this generic function as well.
   tree lookup = NULL_TREE;
-  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				 fntype->get_id (), fntype))
-    {
-      // has this been added to the list then it must be finished
-      if (ctx->function_completed (lookup))
-	{
-	  tree dummy = NULL_TREE;
-	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	    {
-	      ctx->insert_function_decl (fntype, lookup);
-	    }
-	  return lookup;
-	}
-    }
-
-  if (fntype->has_subsititions_defined ())
-    {
-      // override the Hir Lookups for the substituions in this context
-      fntype->override_context ();
-    }
-
-  // transmute intrinsic has one parameter
-  if (fntype->get_params ().size () != 1)
-    {
-      rust_error_at (fntype->get_ident ().locus,
-		     "invalid number of parameters for transmute intrinsic");
-      return error_mark_node;
-    }
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
 
-  // build the intrinsic function
-  tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-  std::string ir_symbol_name
-    = canonical_path.get () + fntype->subst_as_string ();
-  std::string asm_name = ctx->mangle_item (fntype, canonical_path);
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
 
-  unsigned int flags = 0;
-  tree fndecl
-    = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
-				     flags, fntype->get_ident ().locus);
-  TREE_PUBLIC (fndecl) = 0;
-  TREE_READONLY (fndecl) = 1;
-  DECL_ARTIFICIAL (fndecl) = 1;
-  DECL_EXTERNAL (fndecl) = 0;
-  DECL_DECLARED_INLINE_P (fndecl) = 1;
-
-  // setup the params
   std::vector<Bvariable *> param_vars;
   std::vector<tree_node *> compiled_types;
-  for (auto &parm : fntype->get_params ())
-    {
-      auto &referenced_param = parm.first;
-      auto &param_tyty = parm.second;
-      auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
+  compile_fn_params (ctx, fntype, fndecl, &param_vars, &compiled_types);
 
-      Location param_locus = referenced_param->get_locus ();
-      Bvariable *compiled_param_var
-	= CompileFnParam::compile (ctx, fndecl, referenced_param,
-				   compiled_param_type, param_locus);
-
-      param_vars.push_back (compiled_param_var);
-      compiled_types.push_back (compiled_param_type);
-    }
-
-  rust_assert (param_vars.size () == 1);
   if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
     return error_mark_node;
 
@@ -381,13 +309,7 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
 		   (unsigned long) target_size);
     }
 
-  tree enclosing_scope = NULL_TREE;
-  Location start_location = Location ();
-  Location end_location = Location ();
-
-  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-						start_location, end_location);
-  ctx->push_block (code_block);
+  enter_intrinsic_block (ctx, fndecl);
 
   // BUILTIN transmute FN BODY BEGIN
   tree result_type_tree = TREE_TYPE (DECL_RESULT (fndecl));
@@ -424,86 +346,26 @@ transmute_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty)
   ctx->add_statement (return_statement);
   // BUILTIN transmute FN BODY END
 
-  tree bind_tree = ctx->pop_block ();
-
-  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
-  DECL_SAVED_TREE (fndecl) = bind_tree;
-  ctx->push_function (fndecl);
+  finalize_intrinsic_block (ctx, fndecl);
 
   return fndecl;
 }
 
 static tree
-rotate_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty,
-			  tree_code op)
+rotate_handler (Context *ctx, TyTy::FnType *fntype, tree_code op)
 {
-  rust_assert (fntype_tyty->get_kind () == TyTy::TypeKind::FNDEF);
-  TyTy::FnType *fntype = static_cast<TyTy::FnType *> (fntype_tyty);
-  const Resolver::CanonicalPath &canonical_path = fntype->get_ident ().path;
-
-  // items can be forward compiled which means we may not need to invoke this
-  // code. We might also have already compiled this generic function as well.
-  tree lookup = NULL_TREE;
-  if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				 fntype->get_id (), fntype))
-    {
-      // has this been added to the list then it must be finished
-      if (ctx->function_completed (lookup))
-	{
-	  tree dummy = NULL_TREE;
-	  if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
-	    {
-	      ctx->insert_function_decl (fntype, lookup);
-	    }
-	  return lookup;
-	}
-    }
-
-  if (fntype->has_subsititions_defined ())
-    {
-      // override the Hir Lookups for the substitutions in this context
-      fntype->override_context ();
-    }
-
   // rotate intrinsic has two parameter
-  if (fntype->get_params ().size () != 2)
-    {
-      rust_error_at (fntype->get_ident ().locus,
-		     "invalid number of parameters for rotate intrinsic");
-      return error_mark_node;
-    }
+  rust_assert (fntype->get_params ().size () == 2);
 
-  // build the intrinsic function
-  tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-  std::string ir_symbol_name
-    = canonical_path.get () + fntype->subst_as_string ();
-  std::string asm_name = ctx->mangle_item (fntype, canonical_path);
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
 
-  unsigned int flags = 0;
-  tree fndecl
-    = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name,
-				     flags, fntype->get_ident ().locus);
-  TREE_PUBLIC (fndecl) = 0;
-  TREE_READONLY (fndecl) = 1;
-  DECL_ARTIFICIAL (fndecl) = 1;
-  DECL_EXTERNAL (fndecl) = 0;
-  DECL_DECLARED_INLINE_P (fndecl) = 1;
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
 
   // setup the params
   std::vector<Bvariable *> param_vars;
-  for (auto &parm : fntype->get_params ())
-    {
-      auto &referenced_param = parm.first;
-      auto &param_tyty = parm.second;
-      auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
-
-      Location param_locus = referenced_param->get_locus ();
-      Bvariable *compiled_param_var
-	= CompileFnParam::compile (ctx, fndecl, referenced_param,
-				   compiled_param_type, param_locus);
-
-      param_vars.push_back (compiled_param_var);
-    }
+  compile_fn_params (ctx, fntype, fndecl, &param_vars);
 
   auto &x_param = param_vars.at (0);
   auto &y_param = param_vars.at (1);
@@ -511,13 +373,7 @@ rotate_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty,
   if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
     return error_mark_node;
 
-  tree enclosing_scope = NULL_TREE;
-  Location start_location = Location ();
-  Location end_location = Location ();
-
-  tree code_block = ctx->get_backend ()->block (fndecl, enclosing_scope, {},
-						start_location, end_location);
-  ctx->push_block (code_block);
+  enter_intrinsic_block (ctx, fndecl);
 
   // BUILTIN rotate FN BODY BEGIN
   tree x = ctx->get_backend ()->var_expression (x_param, Location ());
@@ -530,11 +386,7 @@ rotate_intrinsic_handler (Context *ctx, TyTy::BaseType *fntype_tyty,
   ctx->add_statement (return_statement);
   // BUILTIN rotate FN BODY END
 
-  tree bind_tree = ctx->pop_block ();
-
-  gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
-  DECL_SAVED_TREE (fndecl) = bind_tree;
-  ctx->push_function (fndecl);
+  finalize_intrinsic_block (ctx, fndecl);
 
   return fndecl;
 }
diff --git a/gcc/testsuite/rust/compile/torture/intrinsics-2.rs b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
new file mode 100644
index 00000000000..6b2339f38f3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/intrinsics-2.rs
@@ -0,0 +1,22 @@
+// { dg-additional-options -fdump-tree-original }
+
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+    pub fn size_of<T>() -> usize;
+}
+
+fn main() -> i32 {
+    unsafe fn foo() -> usize {
+        let f: f32;
+
+        let s_f32 = size_of::<f32>();
+        let s_f64 = size_of::<f64>();
+        let s_f32_again = size_of::<f32>();
+
+        s_f32 + s_f64 + s_f32_again
+    }
+
+    // useless code, just used for function compilation caching
+    unsafe { foo() as i32 }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-08-11 19:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-11 19:18 [gcc/devel/rust/master] intrinsics: Refactor compilation of intrinsics Thomas Schwinge

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).