From: Arthur Cohen <[email protected]>
Hey everyone,
I'm posting this and pinging Andrea and Antoni so I can get a review
and make sure I'm doing things properly, but I'll first be merging this
as a series of commits concerning #[used] on our side before pushing
it upstream. If anyone has any comments please let me know!
Best,
Arthur
-------
We now support the full implementation of the #[used] attribute, which
can be used to conserve a static variable even if the compiler deems it
unused. This commit also implements #[used(linker)], which instructs the
linker to not garbage collect the static even if it seems unused.
This behavior is equivalent to the `used` and `retain` attributes in C.
gcc/rust/ChangeLog:
* backend/rust-compile-item.cc (handle_used_attr): New function.
(CompileItem::visit): Call it.
gcc/testsuite/ChangeLog:
* rust/compile/used-attr4.rs: New test.
---
gcc/rust/backend/rust-compile-item.cc | 61 ++++++++++++++++++------
gcc/testsuite/rust/compile/used-attr4.rs | 16 +++++++
2 files changed, 63 insertions(+), 14 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/used-attr4.rs
diff --git a/gcc/rust/backend/rust-compile-item.cc
b/gcc/rust/backend/rust-compile-item.cc
index fa1e8eec99f..d9afdcacc3c 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -23,10 +23,53 @@
#include "rust-substitution-mapper.h"
#include "rust-type-util.h"
#include "rust-finalized-name-resolution-context.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "target.h"
namespace Rust {
namespace Compile {
+static void
+handle_used_attr (HIR::StaticItem &var, tree decl)
+{
+ auto used_compiler = false; /* equivalent to C's used attribute */
+ auto used_linker = false; /* equivalent to C's retain attribute */
+
+ // If the attribute has no argument, then it is equivalent to
`used(compiler)`
+ for (const auto &attr : var.get_outer_attrs ())
+ {
+ if (attr.as_string () == "used")
+ used_compiler = true;
+
+ // We've already checked that the attribute was used properly, so just
+ // fetch the information we need
+ if (attr.has_attr_input ())
+ {
+ auto input
+ = static_cast<const AST::DelimTokenTree &> (attr.get_attr_input ())
+ .parse_to_meta_item ();
+
+ for (const auto &item : input->get_items ())
+ if (item->as_string () == "linker")
+ used_linker = true;
+ }
+ }
+
+ if (used_compiler)
+ {
+ DECL_PRESERVE_P (decl) = 1;
+ DECL_READ_P (decl) = 1;
+ }
+
+ // Check that the linker supports the attribute, and then add it
+ if (SUPPORTS_SHF_GNU_RETAIN && used_linker)
+ {
+ DECL_ATTRIBUTES (decl)
+ = tree_cons (get_identifier ("retain"), NULL, DECL_ATTRIBUTES (decl));
+ }
+}
+
void
CompileItem::visit (HIR::StaticItem &var)
{
@@ -71,24 +114,14 @@ CompileItem::visit (HIR::StaticItem &var)
bool is_hidden = false;
bool in_unique_section = true;
- // NOTE: We currently compile global variables and always mark them as "used"
- // with TREE_USED(tree). I'm not sure this is correct - they should be marked
- // as used only if the `MarkLive` pass reaches them and flags them. However,
- // the `#[used]` built-in attribute can be used here to *force* a static
- // variable to be used by the compiler so that it isn't deleted.
- // We should probably be doing something along the lines of:
- //
- // - Removing the `TREE_USED (decl) = 1` line in `Backend::global_variable`
- // - Check if the static item has a `used` attribute
- // - If it does, check whether it's the default `used` version, or the
version
- // with an argument - `used(compiler)` or `used(linker)`
- // - If we have the attribute or the `compiler` version of the attribute,
then
- // we `TREE_USED` the decl.
-
Bvariable *static_global
= Backend::global_variable (name, asm_name, type, is_external, is_hidden,
in_unique_section, var.get_locus ());
+ // Static items are concerned by the #[used] attribute which needs to be
+ // handled here
+ handle_used_attr (var, static_global->get_decl ());
+
tree init = value == error_mark_node ? error_mark_node : DECL_INITIAL
(value);
Backend::global_variable_set_init (static_global, init);
diff --git a/gcc/testsuite/rust/compile/used-attr4.rs
b/gcc/testsuite/rust/compile/used-attr4.rs
new file mode 100644
index 00000000000..45359481c87
--- /dev/null
+++ b/gcc/testsuite/rust/compile/used-attr4.rs
@@ -0,0 +1,16 @@
+#![feature(no_core)]
+#![feature(used_with_arg)]
+#![no_core]
+
+#[used]
+static FOO0: i32 = 15;
+// { dg-final { scan-assembler "FOO0" } }
+
+#[used(compiler)]
+static FOO1: i32 = 15;
+// { dg-final { scan-assembler "FOO1" } }
+
+#[used(linker)]
+static FOO2: i32 = 15;
+// { dg-final { scan-assembler "FOO2" } }
+// { dg-final { scan-assembler ".section.*awR" } }
--
2.50.1