]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add intrinsics::assume
authorOwen Avery <powerboat9.gamer@gmail.com>
Wed, 13 Sep 2023 16:32:33 +0000 (12:32 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:04:36 +0000 (19:04 +0100)
gcc/rust/ChangeLog:

* backend/rust-compile-intrinsic.cc
(get_identifier): Add declaration.
(assume_handler): New.
(generic_intrinsics): Add assume_handler entry.

gcc/testsuite/ChangeLog:

* rust/compile/assume.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/backend/rust-compile-intrinsic.cc
gcc/testsuite/rust/compile/assume.rs [new file with mode: 0644]

index 420ed2dffe093a38b56adab0dd2e8ae07e34bb22..2433b989946a245b69ee0990d52ca94997195639 100644 (file)
 
 #include "print-tree.h"
 
+// declaration taken from "stringpool.h"
+// the get_identifier macro causes compilation issues
+extern tree
+get_identifier (const char *);
+
 namespace Rust {
 namespace Compile {
 
@@ -83,6 +88,8 @@ static tree
 uninit_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
 move_val_init_handler (Context *ctx, TyTy::FnType *fntype);
+static tree
+assume_handler (Context *ctx, TyTy::FnType *fntype);
 
 enum class Prefetch
 {
@@ -231,6 +238,7 @@ static const std::map<std::string,
     {"move_val_init", move_val_init_handler},
     {"likely", expect_handler (true)},
     {"unlikely", expect_handler (false)},
+    {"assume", assume_handler},
 };
 
 Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
@@ -1174,5 +1182,50 @@ expect_handler_inner (Context *ctx, TyTy::FnType *fntype, bool likely)
   return fndecl;
 }
 
+static tree
+assume_handler (Context *ctx, TyTy::FnType *fntype)
+{
+  // TODO: make sure this is actually helping the compiler optimize
+
+  rust_assert (fntype->get_params ().size () == 1);
+  rust_assert (fntype->param_at (0).second->get_kind ()
+              == TyTy::TypeKind::BOOL);
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+    return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  // TODO: make sure these are necessary
+  TREE_READONLY (fndecl) = 0;
+  DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+  DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
+                                       NULL_TREE, DECL_ATTRIBUTES (fndecl));
+
+  std::vector<Bvariable *> param_vars;
+  compile_fn_params (ctx, fntype, fndecl, &param_vars);
+
+  if (!Backend::function_set_parameters (fndecl, param_vars))
+    return error_mark_node;
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  // BUILTIN assume FN BODY BEGIN
+
+  tree val = Backend::var_expression (param_vars[0], UNDEF_LOCATION);
+
+  tree assume_expr = build_call_expr_internal_loc (UNDEF_LOCATION, IFN_ASSUME,
+                                                  void_type_node, 1, val);
+  TREE_SIDE_EFFECTS (assume_expr) = 1;
+
+  ctx->add_statement (assume_expr);
+  // BUILTIN size_of FN BODY END
+
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/testsuite/rust/compile/assume.rs b/gcc/testsuite/rust/compile/assume.rs
new file mode 100644 (file)
index 0000000..4dc2fef
--- /dev/null
@@ -0,0 +1,13 @@
+mod intrinsics {
+    extern "rust-intrinsic" {
+        pub fn assume(value: bool);
+    }
+}
+
+pub fn foo(v: i32) -> i32 {
+    unsafe { intrinsics::assume (v == 12); }
+    v
+}
+
+pub fn main() {
+}