Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for setting the inline attribute #3

Closed
wants to merge 16 commits into from

Conversation

antoyo
Copy link

@antoyo antoyo commented Sep 26, 2021

@Commeownist Here's the work I started for rust-lang/rustc_codegen_gcc#87 . There are some issues noted as FIXME in the code, though.

I can't remember if we have access to c-family in libgccjit, so I don't know if we could have a gcc_jit_function_add_attribute function as you suggested.

I still think it's worth having functions specific to inlining because I believe the inline keyword needs to be set separately for #[inline].

antoyo and others added 16 commits May 23, 2021 12:45
2021-05-20  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/96089
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_19): New ABI
            tag.
            * docs/topics/expressions.rst: Add documentation for the
            function gcc_jit_global_set_initializer_value.
            * jit-playback.c: New function (new_global_with_value).
            * jit-playback.h: New function (new_global_with_value).
            * jit-recording.c: Add support for setting a value to a
            global variable.
            * jit-recording.h: New function (set_initializer_value) and
            new field m_initializer_value.
            * libgccjit.c: New macro RETURN_IF_FAIL_PRINTF5 and new
            function (gcc_jit_global_set_initializer_value).
            * libgccjit.h: New function (gcc_jit_global_set_initializer_value).
            * libgccjit.map (LIBGCCJIT_ABI_19): New ABI tag.

    gcc/testsuite/
            PR target/96089
            * jit.dg/test-global-set-initializer.c: Add test for the new
            function (gcc_jit_global_set_initializer_value).

Signed-off-by: Antoni Boucher <[email protected]>
2021-05-19  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/100688
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_18): New ABI
            tag.
            * docs/topics/expressions.rst: Add documentation for the
            function gcc_jit_lvalue_set_link_section.
            * jit-playback.h: New function (set_link_section) and
            rvalue::m_inner protected.
            * jit-recording.c: New function (set_link_section) and
            support for setting the link section.
            * jit-recording.h: New function (set_link_section) and new
            field m_link_section.
            * libgccjit.c: New function (gcc_jit_lvalue_set_link_section).
            * libgccjit.h: New function (gcc_jit_lvalue_set_link_section).
            * libgccjit.map (LIBGCCJIT_ABI_18): New ABI tag.

    gcc/testsuite/
            PR target/100688
            * jit.dg/all-non-failing-tests.h: Add test-link-section.c.
            * jit.dg/test-link_section.c: New test.

Signed-off-by: Antoni Boucher <[email protected]>
…325]

2021-05-18  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/95325
            * docs/topics/types.rst: Add documentation for the new types
            GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
            GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
            GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
            GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T.
            * jit-playback.c: Add support for the sized integer types.
            * jit-recording.c: Add support for the sized integer types.
            * libgccjit.h (GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
            GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
            GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
            GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T):
            New enum variants for gcc_jit_types.
    gcc/testsuite/
            PR target/95325
            * jit.dg/test-types.c: Add tests for sized integer types.

Signed-off-by: Antoni Boucher <[email protected]>
2021-05-18  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/95415
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_17): New ABI
            tag.
            * docs/topics/expressions.rst: Add document for the function
            gcc_jit_lvalue_set_tls_model.
            * jit-playback.h: New function (set_tls_model) and make
            rvalue::m_inner public.
            * jit-recording.c: New function (set_tls_model), new
            variables (tls_models and tls_model_enum_strings) and support
            for setting the tls model.
            * jit-recording.h: New function (set_tls_model) and new
            field m_tls_model.
            * libgccjit.c: New function (gcc_jit_lvalue_set_tls_model).
            * libgccjit.h: New function (gcc_jit_lvalue_set_tls_model)
            and new enum (gcc_jit_tls_model).
            * libgccjit.map (LIBGCCJIT_ABI_17): New ABI tag.

    gcc/testsuite/
            PR target/95415
            * jit.dg/all-non-failing-tests.h: Add test-tls.c.
            * jit.dg/test-tls.c: New test.

Signed-off-by: Antoni Boucher <[email protected]>
2021-05-17  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/PR96066
            PR target/PR96067
            * jit-builtins.c: Implement missing types for builtins.
            * jit-recording.c:: Allow sending a volatile const void * as
            argument.
    gcc/testsuite/
            PR target/PR96066
            PR target/PR96067
            * jit.dg/all-non-failing-tests.h: Add test-builtin-types.c.
            * jit.dg/test-builtin-types.c

Signed-off-by: Antoni Boucher <[email protected]>
2020-09-1  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/96889
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_16): New ABI tag.
            * docs/topics/functions.rst: Add documentation for the
            functions gcc_jit_function_get_return_type and
            gcc_jit_function_get_param_count
            * docs/topics/types.rst: Add documentation for the functions
            gcc_jit_function_type_get_return_type,
            gcc_jit_function_type_get_param_count,
            gcc_jit_function_type_get_param_type,
            gcc_jit_type_unqualified, gcc_jit_type_is_array,
            gcc_jit_type_is_bool,
            gcc_jit_type_is_function_ptr_type,
            gcc_jit_type_is_integral, gcc_jit_type_is_pointer,
            gcc_jit_type_is_vector,
            gcc_jit_vector_type_get_element_type,
            gcc_jit_vector_type_get_num_units,
            gcc_jit_struct_get_field, gcc_jit_type_is_struct,
            and gcc_jit_struct_get_field_count
            * libgccjit.c:
            (gcc_jit_function_get_return_type, gcc_jit_function_get_param_count,
            gcc_jit_function_type_get_return_type,
            gcc_jit_function_type_get_param_count,
            gcc_jit_function_type_get_param_type, gcc_jit_type_unqualified,
            gcc_jit_type_is_array, gcc_jit_type_is_bool,
            gcc_jit_type_is_function_ptr_type, gcc_jit_type_is_integral,
            gcc_jit_type_is_pointer, gcc_jit_type_is_vector,
            gcc_jit_vector_type_get_element_type,
            gcc_jit_vector_type_get_num_units, gcc_jit_struct_get_field,
            gcc_jit_type_is_struct, gcc_jit_struct_get_field_count): New
            functions.
            (struct gcc_jit_function_type, struct gcc_jit_vector_type):
            New types.
            * libgccjit.h:
            (gcc_jit_function_get_return_type, gcc_jit_function_get_param_count,
            gcc_jit_function_type_get_return_type,
            gcc_jit_function_type_get_param_count,
            gcc_jit_function_type_get_param_type, gcc_jit_type_unqualified,
            gcc_jit_type_is_array, gcc_jit_type_is_bool,
            gcc_jit_type_is_function_ptr_type, gcc_jit_type_is_integral,
            gcc_jit_type_is_pointer, gcc_jit_type_is_vector,
            gcc_jit_vector_type_get_element_type,
            gcc_jit_vector_type_get_num_units, gcc_jit_struct_get_field,
            gcc_jit_type_is_struct, gcc_jit_struct_get_field_count): New
            function declarations.
            (struct gcc_jit_function_type, struct gcc_jit_vector_type):
            New types.
            * jit-recording.h: New functions (is_struct and is_vector)
            * libgccjit.map (LIBGCCJIT_ABI_16): New ABI tag.

    gcc/testsuite/
            PR target/96889
            * jit.dg/all-non-failing-tests.h: Add test-reflection.c.
            * jit.dg/test-reflection.c: New test.

Signed-off-by: Antoni Boucher <[email protected]>
2020-07-12  Antoni Boucher  <[email protected]>

gcc/jit/
	PR target/95498
	* jit-playback.c: Add support to handle truncation and extension
	in the convert function.

gcc/testsuite/
	PR target/95498
	* jit.dg/all-non-failing-tests.h: New test.
	* jit.dg/test-cast.c: New test.

Signed-off-by: Antoni Boucher <[email protected]>
Build and upload artifact on GitHub Actions
…325]

2021-05-18  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/95325
            * docs/topics/types.rst: Add documentation for the new types
            GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
            GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
            GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
            GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T.
            * jit-builtins.c: Add support for BT_UINT128.
            * jit-playback.c: Add support for the sized integer types.
            * jit-recording.c: Add support for the sized integer types.
            * libgccjit.h (GCC_JIT_TYPE_UINT8_T, GCC_JIT_TYPE_UINT16_T,
            GCC_JIT_TYPE_UINT32_T, GCC_JIT_TYPE_UINT64_T,
            GCC_JIT_TYPE_UINT128_T, GCC_JIT_TYPE_INT8_T, GCC_JIT_TYPE_INT16_T,
            GCC_JIT_TYPE_INT32_T, GCC_JIT_TYPE_INT64_T, GCC_JIT_TYPE_INT128_T):
            New enum variants for gcc_jit_types.
    gcc/testsuite/
            PR target/95325
            * jit.dg/test-types.c: Add tests for sized integer types.

Signed-off-by: Antoni Boucher <[email protected]>
TODO: fail if global kind is imported
TODO: doc

2021-05-20  Antoni Boucher  <[email protected]>

    gcc/jit/
            PR target/96089
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_19): New ABI
            tag.
            * docs/topics/expressions.rst: Add documentation for the
            function gcc_jit_global_set_initializer_value.
            * jit-playback.c: New functions (new_global_with_value,
            set_global_initial_value, new_rvalue_from_struct, new_rvalue_from_array).
            * jit-playback.h: New functions (new_global_with_value,
            set_global_initial_value, new_rvalue_from_struct, new_rvalue_from_array).
            * jit-recording.c: Add support for setting a value to a
            global variable and new methods
            (global_initializer::write_reproducer,
            global_initializer::make_debug_string,
            global_initializer::write_to_dump,
            global_initializer::replay_into,
            context::new_global_value_initializer,
            memento_of_new_rvalue_from_struct::write_reproducer,
            memento_of_new_rvalue_from_struct::make_debug_string,
            memento_of_new_rvalue_from_struct::visit_children,
            memento_of_new_rvalue_from_struct::replay_into,
            memento_of_new_rvalue_from_struct::
              memento_of_new_rvalue_from_struct,
            context::new_rvalue_from_struct,
            memento_of_new_rvalue_from_array::write_reproducer,
            memento_of_new_rvalue_from_array::make_debug_string,
            memento_of_new_rvalue_from_array::visit_children,
            memento_of_new_rvalue_from_array::replay_into,
            memento_of_new_rvalue_from_array::
              memento_of_new_rvalue_from_array,
            new_rvalue_from_array).
            * jit-recording.h: New functions (set_initializer_value,
            new_global_value_initializer, new_rvalue_from_struct, new_rvalue_from_array),
            new field m_initializer_value and new classes (global_initializer,
            memento_of_new_rvalue_from_struct, memento_of_new_rvalue_from_array).
            * libgccjit.c: New macro RETURN_IF_FAIL_PRINTF5 and new
            functions (gcc_jit_global_set_initializer_value,
            gcc_jit_context_new_rvalue_from_struct,
            gcc_jit_context_new_rvalue_from_array).
            * libgccjit.h: New functions (gcc_jit_global_set_initializer_value,
            gcc_jit_context_new_rvalue_from_struct,
            gcc_jit_context_new_rvalue_from_array).
            * libgccjit.map (LIBGCCJIT_ABI_19): New ABI tag.

    gcc/testsuite/
            PR target/96089
            * jit.dg/test-global-set-initializer.c: Add test for the new
            function (gcc_jit_global_set_initializer_value).
break;
case GCC_JIT_INLINE_MODE_ALWAYS_INLINE:
DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1; // FIXME: this line breaks compilation of sysroot, but seems required to make inlining work.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a recursive #[inline(always)] function in libcore. Maybe that is the problem? In rust even #[inline(always)] is just a hint that should be ignored if it is impossible to inline.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a quick workaround, we could check in rustc_cg_gcc if the function is recursive and then refuse to emit any inline attributes for it. I highly doubt that DECL_DISREGARD_INLINE_LIMITS is a good idea here. I'll test tomorrow.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Commeownist Why not? The doc says This is equivalent to using the always_inline attribute without the required diagnostics if the function cannot be inlined., but I'm not sure what it actually means. I'll have to read more code.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antoyo DECL_DISREGARD_INLINE_LIMITS is totally correct here, see this function. My mistake, confused it with something else.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems to actually check whether the function being inlined is recursive.

@ghost
Copy link

ghost commented Sep 26, 2021

I've been secretly working on it yesterday. It's chaotic ATM so I'll publish it tomorrow, but here are my thoughts:

I can't remember if we have access to c-family in libgccjit, so I don't know if we could have a gcc_jit_function_add_attribute function as you suggested.

You don't need this access. If you take a hard look at playback::context::new_function, you'll see that attributes aren't really tied to C that much:

https://github.com/antoyo/gcc/blob/919b622dec9fb8a68ca42ea69bd91521d86da52b/gcc/jit/jit-playback.c#L548-L557

if you look at your own patch, you'll see that you also adding the always_inline attribute this way, so it's clearly an evidence that attributes can be set on demand ;)

So this is how I'd do it:

// C API
void gcc_jit_function_add_attribute (gcc_jit_function *func, const char *attr)
{
  func->add_attribute (attr);
}

// jit-recording.h

class function : public memento
{
public:
  // ... snip ...
  virtual void add_attribute (const char *attr)  // <= add attribute
  { m_attributes.safe_push(attr); }

private:
  location *m_loc;
  enum gcc_jit_function_kind m_kind;
  type *m_return_type;
  auto_vec<string> m_attributes; // <= stored list of attrs
  string *m_name;
  auto_vec<param *> m_params;
  int m_is_variadic;
  enum built_in_function m_builtin_id;
  auto_vec<local *> m_locals;
  auto_vec<block *> m_blocks;
  type *m_fn_ptr_type;
};

// jit-playback.c

playback::function* playback::context::new_function (
              location *loc,
	      enum gcc_jit_function_kind kind,
	      type *return_type,
              auto_vec<string> *attributes, // <= pass stored attrs
	      const char *name,
	      const auto_vec<param *> *params,
	      int is_variadic,
	      enum built_in_function builtin_id)

{
  // ... snip ...

  // apply attributes
  FOR_EACH_VEC_ELT (*attributes, i, attr) {
    DECL_ATTRIBUTES (fndecl) = tree_cons (
           get_identifier (attr), 
 	   NULL, 
 	   DECL_ATTRIBUTES (fndecl)); 
}

 

This was a quick pseudocode, but I think the idea is clear.

I think the attributes-driven approach is more powerful, especially if we'll want to extend this to other attributes in future. Some examples I predict will come up: the cold and hot attributes, maybe noipa, maybe nonnull, noreturn, maybe nothrow, used, and so on.

I still think it's worth having functions specific to inlining because I believe the inline keyword needs to be set separately for #[inline].

Yes, that's right. Keep in mind that always_inline attribute will mark function as inlineable whether it was marked as inline or not, and noinline will conflict with the inline keyword, see https://godbolt.org/z/W76jx5b4d

How about a hybrid approach? You add void set_inline_flag(function *func, bool flag) that's only responsible for the inline keyword, and always/never_inline are set via function attributes. This will resolve the inline topic and it will also open the road for other unresolved topics such as #[used].

@ghost
Copy link

ghost commented Sep 26, 2021

How about a hybrid approach? You add void set_inline_flag(function *func, bool flag) that's only responsible for the inline keyword, and always/never_inline are set via function attributes. This will resolve the inline topic and it will also open the road for other unresolved topics such as #[used].

Alternatively, we could take your current approach - which I like because it prevents the conflicting situation of inline void __attribute((noinline)) foo(); - but still add the add_attribute function.

@antoyo
Copy link
Author

antoyo commented Sep 26, 2021

Alternatively, we could take your current approach - which I like because it prevents the conflicting situation of inline void __attribute((noinline)) foo(); - but still add the add_attribute function.

Yup, I like this.
We might have to add some checks to avoid this scenario of inline noinline.

@antoyo antoyo closed this Jul 5, 2023
antoyo pushed a commit that referenced this pull request Nov 21, 2024
Whenever C1 and C2 are integer constants, X is of a wrapping type, and
cmp is a relational operator, the expression X +- C1 cmp C2 can be
simplified in the following cases:

(a) If cmp is <= and C2 -+ C1 == +INF(1), we can transform the initial
comparison in the following way:
   X +- C1 <= C2
   -INF <= X +- C1 <= C2 (add left hand side which holds for any X, C1)
   -INF -+ C1 <= X <= C2 -+ C1 (add -+C1 to all 3 expressions)
   -INF -+ C1 <= X <= +INF (due to (1))
   -INF -+ C1 <= X (eliminate the right hand side since it holds for any X)

(b) By analogy, if cmp if >= and C2 -+ C1 == -INF(1), use the following
sequence of transformations:

   X +- C1 >= C2
   +INF >= X +- C1 >= C2 (add left hand side which holds for any X, C1)
   +INF -+ C1 >= X >= C2 -+ C1 (add -+C1 to all 3 expressions)
   +INF -+ C1 >= X >= -INF (due to (1))
   +INF -+ C1 >= X (eliminate the right hand side since it holds for any X)

(c) The > and < cases are negations of (a) and (b), respectively.

This transformation allows to occasionally save add / sub instructions,
for instance the expression

3 + (uint32_t)f() < 2

compiles to

cmn     w0, #4
cset    w0, ls

instead of

add     w0, w0, 3
cmp     w0, 2
cset    w0, ls

on aarch64.

Testcases that go together with this patch have been split into two
separate files, one containing testcases for unsigned variables and the
other for wrapping signed ones (and thus compiled with -fwrapv).
Additionally, one aarch64 test has been adjusted since the patch has
caused the generated code to change from

cmn     w0, #2
csinc   w0, w1, wzr, cc   (x < -2)

to

cmn     w0, #3
csinc   w0, w1, wzr, cs   (x <= -3)

This patch has been bootstrapped and regtested on aarch64, x86_64, and
i386, and additionally regtested on riscv32.

gcc/ChangeLog:

	PR tree-optimization/116024
	* match.pd: New transformation around integer comparison.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/pr116024-2.c: New test.
	* gcc.dg/tree-ssa/pr116024-2-fwrapv.c: Ditto.
	* gcc.target/aarch64/gtu_to_ltu_cmp_1.c: Adjust.
antoyo pushed a commit that referenced this pull request Nov 21, 2024
This patch folds svindex with constant arguments into a vector series.
We implemented this in svindex_impl::fold using the function build_vec_series.
For example,
svuint64_t f1 ()
{
  return svindex_u642 (10, 3);
}
compiled with -O2 -march=armv8.2-a+sve, is folded to {10, 13, 16, ...}
in the gimple pass lower.
This optimization benefits cases where svindex is used in combination with
other gimple-level optimizations.
For example,
svuint64_t f2 ()
{
    return svmul_x (svptrue_b64 (), svindex_u64 (10, 3), 5);
}
has previously been compiled to
f2:
        index   z0.d, #10, #3
        mul     z0.d, z0.d, #5
        ret
Now, it is compiled to
f2:
        mov     x0, 50
        index   z0.d, x0, #15
        ret

We added test cases checking
- the application of the transform during gimple for constant arguments,
- the interaction with another gimple-level optimization.

The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression.
OK for mainline?

Signed-off-by: Jennifer Schmitz <[email protected]>

gcc/
	* config/aarch64/aarch64-sve-builtins-base.cc
	(svindex_impl::fold): Add constant folding.

gcc/testsuite/
	* gcc.target/aarch64/sve/index_const_fold.c: New test.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants