public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
* Unit Type for Rust
@ 2021-06-28 13:49 Philip Herron
  2021-06-28 13:51 ` Philip Herron
  0 siblings, 1 reply; 3+ messages in thread
From: Philip Herron @ 2021-06-28 13:49 UTC (permalink / raw)
  To: gcc-rust


[-- Attachment #1.1: Type: text/plain, Size: 4035 bytes --]

Hi everyone,

In Rust the language has the notion of the unit type '()', so for example:

 fn foo ->i32 { ... }
 fn bar() { ... }

Foo has the return type i32, and bar has no return type, which means it
is unit-type so that it can be a value assignable just like any other
function call. You can also declare unit-structs or unit as a type on
variables:

 struct foobar; // empty unit struct
 let a:() = (); // unit type

I thought I could use GCC's void_type_node to represent the unit type
and void_node for the value when assigning or using it, but this causes
the ICE:

```
In function ‘test’:
rust1: internal compiler error: in create_tmp_var, at gimple-expr.c:482
0x13fd3bf create_tmp_var(tree_node*, char const*)
        ../../gccrs/gcc/gimple-expr.c:482
0xe5d195 Gcc_backend::temporary_variable(Bfunction*, Bblock*, Btype*,
Bexpression*, bool, Location, Bstatement**)
        ../../gccrs/gcc/rust/rust-gcc.cc:2889
0xfe3479 Rust::HIR::Function::accept_vis(Rust::HIR::HIRVisitor&)
        ../../gccrs/gcc/rust/hir/tree/rust-hir-full-test.cc:4414
0xf95cdb Rust::Compile::CompileCrate::go()
        ../../gccrs/gcc/rust/backend/rust-compile.cc:49
0xf95b8b Rust::Compile::CompileCrate::Compile(Rust::HIR::Crate&,
Rust::Compile::Context*)
        ../../gccrs/gcc/rust/backend/rust-compile.cc:39
0xee92e7 Rust::Session::parse_file(char const*)
        ../../gccrs/gcc/rust/rust-session-manager.cc:596
0xee8d76 Rust::Session::parse_files(int, char const**)
        ../../gccrs/gcc/rust/rust-session-manager.cc:459
0xe45264 grs_langhook_parse_file
        ../../gccrs/gcc/rust/rust-lang.cc:171

```

I think because void_node is likely not COMPLETE_TYPE_P which means it
hits the assertion when you need temporary's.


Then Tom Tromey suggested I try a zero precision integer so I called:
make_unsigned_type (0) for the type and then use integer_zero_node for
the value, and this solves the problem; however, if I use this zero
precision integer type for the return type on functions and turn
optimizations on I get the ICE:

   ```
   test.rs: In function ‘main’:
   test.rs:16:1: internal compiler error: in min_value, at wide-int.cc:346
      16 | fn main() {
         | ^
   0x1d551d5 wi::min_value(unsigned int, signop)
           ../../gccrs/gcc/wide-int.cc:346
   0x1146ca5 irange::set_varying(tree_node*)
           ../../gccrs/gcc/value-range.h:476
   0x1ce5970 value_range_equiv::set_varying(tree_node*)
           ../../gccrs/gcc/value-range-equiv.cc:71
   0x1d3da07 vr_values::set_def_to_varying(tree_node const*)
           ../../gccrs/gcc/vr-values.c:230
   0x1d3da70 vr_values::set_defs_to_varying(gimple*)
           ../../gccrs/gcc/vr-values.c:241
   0x1c78b2f vrp_prop::visit_stmt(gimple*, edge_def**, tree_node**)
           ../../gccrs/gcc/tree-vrp.c:4001
   0x1ad8519 ssa_propagation_engine::simulate_stmt(gimple*)
           ../../gccrs/gcc/tree-ssa-propagate.c:230
   0x1ad8a0e ssa_propagation_engine::simulate_block(basic_block_def*)
           ../../gccrs/gcc/tree-ssa-propagate.c:337
   0x1ad9f2e ssa_propagation_engine::ssa_propagate()
           ../../gccrs/gcc/tree-ssa-propagate.c:800
   0x1c7a0b0 execute_vrp
           ../../gccrs/gcc/tree-vrp.c:4512
   0x1c7a3e4 execute
           ../../gccrs/gcc/tree-vrp.c:4620
   Please submit a full bug report,
   ```

The backtrace looks as though the optimizer is looking for min value for
a default for the return value, but it's a zero precision integer that
hits the assertion. Note running with -O0, the assertion does not get hit.


At the moment, I have left functions with return type unit to keep using
void_type_node and everywhere else, use this new zero precision integer.
I am not sure what the best approach is here; I was hoping to solicit
feedback on what I am doing with the folks here on the mailing list.

Thanks

--Phil

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 665 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Unit Type for Rust
  2021-06-28 13:49 Unit Type for Rust Philip Herron
@ 2021-06-28 13:51 ` Philip Herron
  2021-06-28 17:37   ` Segher Boessenkool
  0 siblings, 1 reply; 3+ messages in thread
From: Philip Herron @ 2021-06-28 13:51 UTC (permalink / raw)
  To: gcc-rust, gcc Mailing List


[-- Attachment #1.1: Type: text/plain, Size: 4318 bytes --]

On 28/06/2021 14:49, Philip Herron wrote:
> Hi everyone,
>
> In Rust the language has the notion of the unit type '()', so for example:
>
>  fn foo ->i32 { ... }
>  fn bar() { ... }
>
> Foo has the return type i32, and bar has no return type, which means it
> is unit-type so that it can be a value assignable just like any other
> function call. You can also declare unit-structs or unit as a type on
> variables:
>
>  struct foobar; // empty unit struct
>  let a:() = (); // unit type
>
> I thought I could use GCC's void_type_node to represent the unit type
> and void_node for the value when assigning or using it, but this causes
> the ICE:
>
> ```
> In function ‘test’:
> rust1: internal compiler error: in create_tmp_var, at gimple-expr.c:482
> 0x13fd3bf create_tmp_var(tree_node*, char const*)
>         ../../gccrs/gcc/gimple-expr.c:482
> 0xe5d195 Gcc_backend::temporary_variable(Bfunction*, Bblock*, Btype*,
> Bexpression*, bool, Location, Bstatement**)
>         ../../gccrs/gcc/rust/rust-gcc.cc:2889
> 0xfe3479 Rust::HIR::Function::accept_vis(Rust::HIR::HIRVisitor&)
>         ../../gccrs/gcc/rust/hir/tree/rust-hir-full-test.cc:4414
> 0xf95cdb Rust::Compile::CompileCrate::go()
>         ../../gccrs/gcc/rust/backend/rust-compile.cc:49
> 0xf95b8b Rust::Compile::CompileCrate::Compile(Rust::HIR::Crate&,
> Rust::Compile::Context*)
>         ../../gccrs/gcc/rust/backend/rust-compile.cc:39
> 0xee92e7 Rust::Session::parse_file(char const*)
>         ../../gccrs/gcc/rust/rust-session-manager.cc:596
> 0xee8d76 Rust::Session::parse_files(int, char const**)
>         ../../gccrs/gcc/rust/rust-session-manager.cc:459
> 0xe45264 grs_langhook_parse_file
>         ../../gccrs/gcc/rust/rust-lang.cc:171
>
> ```
>
> I think because void_node is likely not COMPLETE_TYPE_P which means it
> hits the assertion when you need temporary's.
>
>
> Then Tom Tromey suggested I try a zero precision integer so I called:
> make_unsigned_type (0) for the type and then use integer_zero_node for
> the value, and this solves the problem; however, if I use this zero
> precision integer type for the return type on functions and turn
> optimizations on I get the ICE:
>
>    ```
>    test.rs: In function ‘main’:
>    test.rs:16:1: internal compiler error: in min_value, at wide-int.cc:346
>       16 | fn main() {
>          | ^
>    0x1d551d5 wi::min_value(unsigned int, signop)
>            ../../gccrs/gcc/wide-int.cc:346
>    0x1146ca5 irange::set_varying(tree_node*)
>            ../../gccrs/gcc/value-range.h:476
>    0x1ce5970 value_range_equiv::set_varying(tree_node*)
>            ../../gccrs/gcc/value-range-equiv.cc:71
>    0x1d3da07 vr_values::set_def_to_varying(tree_node const*)
>            ../../gccrs/gcc/vr-values.c:230
>    0x1d3da70 vr_values::set_defs_to_varying(gimple*)
>            ../../gccrs/gcc/vr-values.c:241
>    0x1c78b2f vrp_prop::visit_stmt(gimple*, edge_def**, tree_node**)
>            ../../gccrs/gcc/tree-vrp.c:4001
>    0x1ad8519 ssa_propagation_engine::simulate_stmt(gimple*)
>            ../../gccrs/gcc/tree-ssa-propagate.c:230
>    0x1ad8a0e ssa_propagation_engine::simulate_block(basic_block_def*)
>            ../../gccrs/gcc/tree-ssa-propagate.c:337
>    0x1ad9f2e ssa_propagation_engine::ssa_propagate()
>            ../../gccrs/gcc/tree-ssa-propagate.c:800
>    0x1c7a0b0 execute_vrp
>            ../../gccrs/gcc/tree-vrp.c:4512
>    0x1c7a3e4 execute
>            ../../gccrs/gcc/tree-vrp.c:4620
>    Please submit a full bug report,
>    ```
>
> The backtrace looks as though the optimizer is looking for min value for
> a default for the return value, but it's a zero precision integer that
> hits the assertion. Note running with -O0, the assertion does not get hit.
>
>
> At the moment, I have left functions with return type unit to keep using
> void_type_node and everywhere else, use this new zero precision integer.
> I am not sure what the best approach is here; I was hoping to solicit
> feedback on what I am doing with the folks here on the mailing list.
>
> Thanks
>
> --Phil
>

Adding in the GCC mailing list for feedback.

Thanks

--Phil


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 665 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Unit Type for Rust
  2021-06-28 13:51 ` Philip Herron
@ 2021-06-28 17:37   ` Segher Boessenkool
  0 siblings, 0 replies; 3+ messages in thread
From: Segher Boessenkool @ 2021-06-28 17:37 UTC (permalink / raw)
  To: Philip Herron; +Cc: gcc-rust, gcc Mailing List

On Mon, Jun 28, 2021 at 02:51:22PM +0100, Philip Herron wrote:
> On 28/06/2021 14:49, Philip Herron wrote:
> > In Rust the language has the notion of the unit type '()', so for example:
> >
> >  fn foo ->i32 { ... }
> >  fn bar() { ... }
> >
> > Foo has the return type i32, and bar has no return type, which means it
> > is unit-type so that it can be a value assignable just like any other
> > function call. You can also declare unit-structs or unit as a type on
> > variables:
> >
> >  struct foobar; // empty unit struct
> >  let a:() = (); // unit type

So you probably should have the unit type only in the language code, and
use an actual type for anything later?  Or can the actual type stay
unknown as well?  That is new territory for GCC.

> > I thought I could use GCC's void_type_node to represent the unit type
> > and void_node for the value when assigning or using it, but this causes
> > the ICE:

"void" already has a meaning, and it is not this.

> > Then Tom Tromey suggested I try a zero precision integer so I called:
> > make_unsigned_type (0) for the type and then use integer_zero_node for
> > the value, and this solves the problem; however, if I use this zero
> > precision integer type for the return type on functions and turn
> > optimizations on I get the ICE:
> >
> >    ```
> >    test.rs: In function ‘main’:
> >    test.rs:16:1: internal compiler error: in min_value, at wide-int.cc:346

So you'll need to update the max/min code to know about this.  Or, don't
expose unit type in generic code at all?  Can the language code not
always lower it to an actual type instead of the placeholder it is?

There will be many more places things will break after vrp1.  Including
many RTL passes.


Segher

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-06-28 17:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-28 13:49 Unit Type for Rust Philip Herron
2021-06-28 13:51 ` Philip Herron
2021-06-28 17:37   ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).