Skip to content

Tuples inhibiting optimizations #5923

Closed
@kripken

Description

@kripken

It seems many opts work better without tuples, because tuples hide their components from the optimizations.

Testcase

(module
  (global $g (mut i32) (i32.const 0))

  (export "g" (global $g))

  (func $func (result i32 i32)
    ;; Return an unknown value and 42.
    (return
      (tuple.make
        (global.get $g)
        (i32.const 42)
      )
    )
  )

  (func "caller" (result i32)
    (local $tuple (i32 i32))
    (local $sum i32)

    ;; Get a tuple from a call
    (local.set $tuple
      (call $func)
    )

    ;; Return the sum of the tuple elements.
    (local.set $sum
      (tuple.extract 0
        (local.get $tuple)
      )
    )
    (local.set $sum
      (i32.add
        (local.get $sum)
        (tuple.extract 1
          (local.get $tuple)
        )
      )
    )
    (local.get $sum)
  )
)

After --inlining

(module
 (type $0 (func (result i32 i32)))
 (type $1 (func (result i32)))
 (global $g (mut i32) (i32.const 0))
 (export "g" (global $g))
 (export "caller" (func $1))
 (func $1 (type $1) (result i32)
  (local $tuple (i32 i32))
  (local $sum i32)
  (local.set $tuple
   (block (result i32 i32)
    (block $__inlined_func$func (result i32 i32)
     (br $__inlined_func$func
      (tuple.make
       (global.get $g)
       (i32.const 42)
      )
     )
    )
   )
  )
  (local.set $sum
   (tuple.extract 0
    (local.get $tuple)
   )
  )
  (local.set $sum
   (i32.add
    (local.get $sum)
    (tuple.extract 1
     (local.get $tuple)
    )
   )
  )
  (local.get $sum)
 )
)

Now we have a block with multivalue and a br to it.

After -O3

(module
 (type $0 (func (result i32)))
 (global $g (mut i32) (i32.const 0))
 (export "g" (global $g))
 (export "caller" (func $1))
 (func $1 (type $0) (; has Stack IR ;) (result i32)
  (local $0 (i32 i32))
  (i32.add
   (tuple.extract 1
    (local.tee $0
     (tuple.make
      (global.get $g)
      (i32.const 42)
     )
    )
   )
   (tuple.extract 0
    (local.get $0)
   )
  )
 )
)

The code is simplified somewhat, but still has tuple operations.

After --roundtrip -O3

(module
 (type $0 (func (result i32)))
 (global $g (mut i32) (i32.const 0))
 (export "g" (global $g))
 (export "caller" (func $1))
 (func $1 (type $0) (; has Stack IR ;) (result i32)
  (i32.add
   (global.get $g)
   (i32.const 42)
  )
 )
)

This is the result we wanted before roundtripping.

Roundtripping lowers the tuple locals into normal ones, which optimizations can operate on, so we can do a lot more if we roundtrip atm.

One option here might be to add a pass to lower tuples into normal locals? cc @tlively

@askeksa is this the issue you were seeing?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions