aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-02-10 12:50:30 +0000
committerGitHub <noreply@github.com>2022-02-10 12:50:30 +0000
commitf6ba472caf42db1f5f2f98b73afccf448b36c322 (patch)
tree46d8ef5483a0acc2ee585c8fe176ae7438a5e800 /gcc/rust/backend
parent6d1ff568084ed86e6cf14e709fe6892256be824a (diff)
parentc598bbbcc1eadb178e74d908ce917b7cf4f556c1 (diff)
downloadgcc-f6ba472caf42db1f5f2f98b73afccf448b36c322.zip
gcc-f6ba472caf42db1f5f2f98b73afccf448b36c322.tar.gz
gcc-f6ba472caf42db1f5f2f98b73afccf448b36c322.tar.bz2
Merge #916
916: Support inline attribute by marking as DECL_DECLARED_INLINE_P r=philberty a=philberty This does a refactor by removing more flags for the fndecl construction from the rust-gcc wrapper code in favour of using the tree api directly. The ABI option attributes have also been refactored from the backend interface in favour of their own package. The gccgo wrapper tried to mark inline fns as extern inline but this refactor allows us to control the inline options specificly for the rust semantics. Fixes #857 Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-base.cc92
-rw-r--r--gcc/rust/backend/rust-compile-base.h6
-rw-r--r--gcc/rust/backend/rust-compile-extern.h11
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h17
-rw-r--r--gcc/rust/backend/rust-compile-item.h24
5 files changed, 119 insertions, 31 deletions
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
new file mode 100644
index 0000000..82a38e7
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -0,0 +1,92 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile-base.h"
+#include "stringpool.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+HIRCompileBase::setup_attributes_on_fndecl (
+ tree fndecl, bool is_main_entry_point, bool has_visibility,
+ const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs)
+{
+ // if its the main fn or pub visibility mark its as DECL_PUBLIC
+ // please see https://github.com/Rust-GCC/gccrs/pull/137
+ if (is_main_entry_point || has_visibility)
+ {
+ TREE_PUBLIC (fndecl) = 1;
+ }
+
+ // is it a const fn
+ if (qualifiers.is_const ())
+ {
+ TREE_READONLY (fndecl) = 1;
+ }
+
+ // is it inline?
+ for (const auto &attr : attrs)
+ {
+ bool is_inline = attr.get_path ().as_string ().compare ("inline") == 0;
+ if (is_inline)
+ {
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+
+ // do we want to force inline regardless of optimisation level?
+ // https://gcc.gnu.org/onlinedocs/gcc/Inline.html
+ //
+ // /* Add attribute "always_inline": */
+ // DECL_ATTRIBUTES (fndecl)
+ // = tree_cons (get_identifier ("always_inline"), NULL,
+ // DECL_ATTRIBUTES (fndecl));
+ }
+ }
+}
+
+void
+HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
+{
+ switch (abi)
+ {
+ case Rust::ABI::RUST:
+ case Rust::ABI::INTRINSIC:
+ case Rust::ABI::C:
+ case Rust::ABI::CDECL:
+ DECL_ATTRIBUTES (fndecl)
+ = tree_cons (get_identifier ("cdecl"), NULL, DECL_ATTRIBUTES (fndecl));
+ break;
+
+ case Rust::ABI::STDCALL:
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("stdcall"), NULL,
+ DECL_ATTRIBUTES (fndecl));
+ break;
+
+ case Rust::ABI::FASTCALL:
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("fastcall"), NULL,
+ DECL_ATTRIBUTES (fndecl));
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 902bedc..f318e81 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -71,6 +71,12 @@ protected:
tree resolve_deref_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);
+
+ static void setup_attributes_on_fndecl (
+ tree fndecl, bool is_main_entry_point, bool has_visibility,
+ const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
+
+ static void setup_abi_options (tree fndecl, ABI abi);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 507865a..143b240 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -125,19 +125,16 @@ public:
}
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- compiled_fn_type
- = ctx->get_backend ()->specify_abi_attribute (compiled_fn_type,
- fntype->get_abi ());
-
- const unsigned int flags
- = Backend::function_is_declaration | Backend::function_is_visible;
-
std::string ir_symbol_name = function.get_item_name ();
std::string asm_name = function.get_item_name ();
+ const unsigned int flags = Backend::function_is_declaration;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
+ TREE_PUBLIC (fndecl) = 1;
+ setup_abi_options (fndecl, fntype->get_abi ());
+
ctx->insert_function_decl (fntype, fndecl);
}
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index d646c83..9320276 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -133,13 +133,6 @@ public:
// convert to the actual function type
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- unsigned int flags = 0;
-
- // if its the main fn or pub visibility mark its as DECL_PUBLIC
- // please see https://github.com/Rust-GCC/gccrs/pull/137
- if (function.has_visibility ())
- flags |= Backend::function_is_visible;
-
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_crate_num (),
@@ -150,9 +143,13 @@ public:
= 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, function.get_locus ());
+ setup_attributes_on_fndecl (fndecl, false, function.has_visibility (),
+ function.get_qualifiers (),
+ function.get_outer_attrs ());
ctx->insert_function_decl (fntype, fndecl);
// setup the params
@@ -395,9 +392,7 @@ public:
// convert to the actual function type
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
-
HIR::TraitFunctionDecl &function = func.get_decl ();
- unsigned int flags = 0;
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -408,9 +403,13 @@ public:
std::string fn_identifier = canonical_path->get ();
std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+ unsigned int flags = 0;
tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
asm_name, flags, func.get_locus ());
+ setup_attributes_on_fndecl (fndecl, false, false,
+ func.get_decl ().get_qualifiers (),
+ func.get_outer_attrs ());
ctx->insert_function_decl (fntype, fndecl);
// setup the params
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 73f6967..70b5415 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -144,9 +144,9 @@ public:
NULL, constant.get_locus ());
tree fndecl
- = ctx->get_backend ()->function (compiled_fn_type, ident, "",
- Backend::function_read_only,
+ = ctx->get_backend ()->function (compiled_fn_type, ident, "", 0,
constant.get_locus ());
+ TREE_READONLY (fndecl) = 1;
tree enclosing_scope = NULL_TREE;
HIR::BlockExpr *function_body
@@ -255,18 +255,6 @@ public:
tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
- unsigned int flags = 0;
- bool is_main_fn = function.get_function_name ().compare ("main") == 0;
-
- // if its the main fn or pub visibility mark its as DECL_PUBLIC
- // please see https://github.com/Rust-GCC/gccrs/pull/137
- if (is_main_fn || function.has_visibility ())
- flags |= Backend::function_is_visible;
-
- // is it a const function?
- if (function.get_qualifiers ().is_const ())
- flags |= Backend::function_read_only;
-
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
function.get_mappings ().get_crate_num (),
@@ -275,19 +263,25 @@ public:
std::string ir_symbol_name
= canonical_path->get () + fntype->subst_as_string ();
-
std::string asm_name = function.get_function_name ();
// we don't mangle the main fn since we haven't implemented the main shim
// yet
+ bool is_main_fn = function.get_function_name ().compare ("main") == 0;
if (!is_main_fn)
{
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, function.get_locus ());
+ setup_attributes_on_fndecl (fndecl, is_main_fn, function.has_visibility (),
+ function.get_qualifiers (),
+ function.get_outer_attrs ());
+
+ // insert into the context
ctx->insert_function_decl (fntype, fndecl);
// setup the params