Skip to content

Commit c7275a7

Browse files
bors[bot]philberty
andauthored
Merge #922
922: Support inline never and always options r=philberty a=philberty This maps over to DECL_UNINLINEABLE and to use the GCC attribute always_inline. Fixes #921 Co-authored-by: Philip Herron <[email protected]>
2 parents b71cc52 + 112f284 commit c7275a7

File tree

5 files changed

+82
-14
lines changed

5 files changed

+82
-14
lines changed

gcc/rust/backend/rust-compile-base.cc

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ namespace Compile {
3030

3131
void
3232
HIRCompileBase::setup_attributes_on_fndecl (
33-
tree fndecl, bool is_main_entry_point, bool has_visibility,
33+
tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility,
3434
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs)
3535
{
3636
// if its the main fn or pub visibility mark its as DECL_PUBLIC
3737
// please see https://github.com/Rust-GCC/gccrs/pull/137
38-
if (is_main_entry_point || has_visibility)
38+
bool is_pub
39+
= visibility.get_vis_type () != HIR::Visibility::PublicVisType::NONE;
40+
if (is_main_entry_point || is_pub)
3941
{
4042
TREE_PUBLIC (fndecl) = 1;
4143
}
@@ -52,19 +54,59 @@ HIRCompileBase::setup_attributes_on_fndecl (
5254
bool is_inline = attr.get_path ().as_string ().compare ("inline") == 0;
5355
if (is_inline)
5456
{
55-
DECL_DECLARED_INLINE_P (fndecl) = 1;
56-
57-
// do we want to force inline regardless of optimisation level?
58-
// https://gcc.gnu.org/onlinedocs/gcc/Inline.html
59-
//
60-
// /* Add attribute "always_inline": */
61-
// DECL_ATTRIBUTES (fndecl)
62-
// = tree_cons (get_identifier ("always_inline"), NULL,
63-
// DECL_ATTRIBUTES (fndecl));
57+
handle_inline_attribute_on_fndecl (fndecl, attr);
6458
}
6559
}
6660
}
6761

62+
void
63+
HIRCompileBase::handle_inline_attribute_on_fndecl (tree fndecl,
64+
const AST::Attribute &attr)
65+
{
66+
// simple #[inline]
67+
if (!attr.has_attr_input ())
68+
{
69+
DECL_DECLARED_INLINE_P (fndecl) = 1;
70+
return;
71+
}
72+
73+
const AST::AttrInput &input = attr.get_attr_input ();
74+
bool is_token_tree
75+
= input.get_attr_input_type () == AST::AttrInput::AttrInputType::TOKEN_TREE;
76+
rust_assert (is_token_tree);
77+
const auto &option = static_cast<const AST::DelimTokenTree &> (input);
78+
AST::AttrInputMetaItemContainer *meta_item = option.parse_to_meta_item ();
79+
if (meta_item->get_items ().size () != 1)
80+
{
81+
rust_error_at (attr.get_locus (), "invalid number of arguments");
82+
return;
83+
}
84+
85+
const std::string inline_option
86+
= meta_item->get_items ().at (0)->as_string ();
87+
88+
// we only care about NEVER and ALWAYS else its an error
89+
bool is_always = inline_option.compare ("always") == 0;
90+
bool is_never = inline_option.compare ("never") == 0;
91+
92+
// #[inline(never)]
93+
if (is_never)
94+
{
95+
DECL_UNINLINABLE (fndecl) = 1;
96+
}
97+
// #[inline(always)]
98+
else if (is_always)
99+
{
100+
DECL_DECLARED_INLINE_P (fndecl) = 1;
101+
DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("always_inline"),
102+
NULL, DECL_ATTRIBUTES (fndecl));
103+
}
104+
else
105+
{
106+
rust_error_at (attr.get_locus (), "unknown inline option");
107+
}
108+
}
109+
68110
void
69111
HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
70112
{
@@ -278,8 +320,8 @@ HIRCompileBase::compile_function (
278320
unsigned int flags = 0;
279321
tree fndecl = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
280322
asm_name, flags, locus);
281-
setup_attributes_on_fndecl (fndecl, is_main_fn, !visibility.is_error (),
282-
qualifiers, outer_attrs);
323+
setup_attributes_on_fndecl (fndecl, is_main_fn, visibility, qualifiers,
324+
outer_attrs);
283325
setup_abi_options (fndecl, fntype->get_abi ());
284326

285327
// insert into the context

gcc/rust/backend/rust-compile-base.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,12 @@ class HIRCompileBase : public HIR::HIRFullVisitorBase
7171
tree expression, Location locus);
7272

7373
static void setup_attributes_on_fndecl (
74-
tree fndecl, bool is_main_entry_point, bool has_visibility,
74+
tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility,
7575
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
7676

77+
static void handle_inline_attribute_on_fndecl (tree fndecl,
78+
const AST::Attribute &attr);
79+
7780
static void setup_abi_options (tree fndecl, ABI abi);
7881

7982
static tree address_expression (tree, Location);

gcc/rust/hir/tree/rust-hir-item.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ struct Visibility
632632
return Visibility (IN_PATH, std::move (in_path));
633633
}
634634

635+
PublicVisType get_vis_type () const { return public_vis_type; }
636+
635637
std::string as_string () const;
636638

637639
protected:
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#[inline]
2+
fn test_a() {}
3+
4+
// { dg-final { scan-tree-dump-times {always_inline} 1 gimple } }
5+
#[inline(always)]
6+
fn test_b() {}
7+
8+
#[inline(never)]
9+
fn test_c() {}
10+
11+
fn main() {
12+
test_a();
13+
test_b();
14+
test_c();
15+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// { dg-additional-options "-w" }
2+
#[inline(A)] // { dg-error "unknown inline option" }
3+
fn test_a() {}
4+
5+
#[inline(A, B)] // { dg-error "invalid number of arguments" }
6+
fn test_b() {}

0 commit comments

Comments
 (0)