Skip to content

better early DCE #27547

@JeffBezanson

Description

@JeffBezanson

It would be nice to be able to remove more dead code in the julia-level optimizer. Example case:

julia> function f(A)
           @inbounds for I in 1:length(A)
               view(A, I)
           end
       end
f (generic function with 1 method)

julia> @code_typed f([1])
CodeInfo(
2 1 ── %1  = Base.arraylen(%%A)::Int64                          │╻          length
  │    %2  = Base.sle_int(1, %1)::Bool                          ││╻╷╷╷       Type
  │          Base.sub_int(%1, 1)                                │││╻          unitrange_last
  │    %4  = Base.ifelse(%2, %1, 0)::Int64                      ││││       
  │    %5  = Base.slt_int(%4, 1)::Bool                          ││╻╷╷        isempty
  └───       goto 3 if not %5                                   ││         
  2 ──       goto 4                                             ││         
  3 ──       goto 4                                             ││         
  4 ┄─ %9  = φ (2 => true, 3 => false)::Bool                    │          
  │    %10 = φ (3 => 1)::Int64                                  │          
  │    %11 = φ (3 => 1)::Int64                                  │          
  │    %12 = Base.not_int(%9)::Bool                             │          
  └───       goto 16 if not %12                                 │          
  5 ┄─ %14 = φ (4 => %10, 15 => %35)::Int64                     │          
  │    %15 = φ (4 => %11, 15 => %36)::Int64                     │          
3 └───       goto 10 if not false                               │╻          view
  6 ── %17 = Core.tuple(%14)::Tuple{Int64}                      ││         
  │    %18 = Base.arraysize(%%A, 1)::Int64                      ││╻╷╷╷╷      checkbounds
  │    %19 = Base.slt_int(%18, 0)::Bool                         │││╻╷╷╷       checkbounds
  │    %20 = Base.ifelse(%19, 0, %18)::Int64                    ││││┃││││││    eachindex
  │    %21 = Base.sle_int(1, %14)::Bool                         │││││╻          <=
  │    %22 = Base.sle_int(%14, %20)::Bool                       ││││││     
  │    %23 = Base.and_int(%21, %22)::Bool                       │││││╻          &
  └───       goto 8 if not %23                                  │││        
  7 ──       goto 9                                             │││        
  8 ──       invoke Base.throw_boundserror(%%A::Array{Int64,1}, %17::Tuple{Int64})
  └───       unreachable                                        │││        
  9 ──       nothing                                            │          
  10 ┄       goto 11                                            │╻          view
  11 ─ %30 = Base.:===(%15, %4)::Bool                           ││╻          ==
  └───       goto 13 if not %30                                 ││         
  12 ─       goto 14                                            ││         
  13 ─ %33 = Base.add_int(%15, 1)::Int64                        ││╻          +
  └───       goto 14                                            │╻          iterate
  14 ┄ %35 = φ (13 => %33)::Int64                               │          
  │    %36 = φ (13 => %33)::Int64                               │          
  │    %37 = φ (12 => true, 13 => false)::Bool                  │          
  │    %38 = Base.not_int(%37)::Bool                            │          
  └───       goto 16 if not %38                                 │          
  15 ─       goto 5                                             │          
  16 ┄       return nothing                                     │          
) => Nothing

In this IR there are a couple redundant basic blocks (consisting only of a goto to the next block). There is also unreachable bounds error code (goto 10 if not false). LLVM can remove this code very easily, but it would still be useful for us to remove it (1) to cut down stored IR size, (2) for inlining heuristics, and (3) to spend less time lowering to LLVM.

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:optimizerOptimization passes (mostly in base/compiler/ssair/)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions