Skip to content

Conversation

@aviatesk
Copy link
Owner

@aviatesk aviatesk commented Aug 4, 2020

The final object of this PR is to allow TP to profile even when there are abstract inferred types in profiling.

@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from 16a6e23 to d431350 Compare August 4, 2020 17:35
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from 2cc2cc5 to 89f7c9f Compare August 5, 2020 00:48
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from 588b195 to 9eae440 Compare August 5, 2020 13:42
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch 2 times, most recently from 00da6f5 to 67ad8cb Compare August 6, 2020 12:37
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from 67ad8cb to eeb83f5 Compare August 6, 2020 12:40
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from eeb83f5 to 47fbbc9 Compare August 6, 2020 18:03
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch 3 times, most recently from de449da to a2e121e Compare August 6, 2020 18:25
@aviatesk
Copy link
Owner Author

aviatesk commented Aug 6, 2020

Backedges shouldn't be used for abstract call stack traversal -- it turns out InferenceState.parent is what I need.

use `InferenceState.parent` instead of `MethodInstances.backedges` for 
abstract call stack traversal
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from a2e121e to 41e479c Compare August 7, 2020 16:43
@aviatesk aviatesk force-pushed the avi/newcompilerinterface branch from 41e479c to 4197131 Compare August 7, 2020 16:52
@aviatesk aviatesk merged commit e91e27b into master Aug 7, 2020
@aviatesk aviatesk deleted the avi/newcompilerinterface branch August 7, 2020 16:53
aviatesk added a commit that referenced this pull request May 4, 2021
WIP because I found this is better to be generalized to a control flow
analysis that checks for "never reaching exit points".
For As an example, `sum(a for a in NeverTeminate(::Int))` will come down
to `Base._fold_impl`, which directly uses `iterate(::NeverTeminate, [state])`,
against which the current implementation based on the iteration protocol
can't report an error.

> Adapated from https://github.com/JuliaLang/julia/blob/24d9eab45632bdb3120c9e664503745eb58aa2d6/base/reduce.jl#L53-L65

```julia
function _foldl_impl(op::OP, init, itr) where {OP}
    # Unroll the while loop once; if init is known, the call to op may
    # be evaluated at compile time
    y = iterate(itr)
    y === nothing && return init
    v = op(init, y[1])
    while true
        y = iterate(itr, y[2])
        y === nothing && break
        v = op(v, y[1])
    end
    return v
end
```

> In a lowered representation

```julia
CodeInfo(
1 ─       Core.NewvarNode(:(v))
│         y = Base.iterate(itr)
│   %3  = y === Base.nothing
└──       goto #3 if not %3
2 ─       return init
3 ─ %6  = Base.getindex(y, 1)
└──       v = (op)(init, %6)
4 ┄       goto #8 if not true
5 ─ %9  = Base.getindex(y, 2)
│         y = Base.iterate(itr, %9)
│   %11 = y === Base.nothing
└──       goto #7 if not %11
6 ─       goto #8
7 ─ %14 = v
│   %15 = Base.getindex(y, 1)
│         v = (op)(%14, %15)
└──       goto #4
8 ┄       return v
)
```

We can report infinite iteration by checking both `goto #3 if not %3`
and
`goto #7 if not %11` never happens and thus this function never returns.

---

- closes #135
- closes #179
aviatesk added a commit that referenced this pull request May 6, 2021
WIP because I found this is better to be generalized to a control flow
analysis that checks for "never reaching exit points".
For As an example, `sum(a for a in NeverTeminate(::Int))` will come down
to `Base._fold_impl`, which directly uses `iterate(::NeverTeminate, [state])`,
against which the current implementation based on the iteration protocol
can't report an error.

> Adapated from https://github.com/JuliaLang/julia/blob/24d9eab45632bdb3120c9e664503745eb58aa2d6/base/reduce.jl#L53-L65

```julia
function _foldl_impl(op::OP, init, itr) where {OP}
    # Unroll the while loop once; if init is known, the call to op may
    # be evaluated at compile time
    y = iterate(itr)
    y === nothing && return init
    v = op(init, y[1])
    while true
        y = iterate(itr, y[2])
        y === nothing && break
        v = op(v, y[1])
    end
    return v
end
```

> In a lowered representation

```julia
CodeInfo(
1 ─       Core.NewvarNode(:(v))
│         y = Base.iterate(itr)
│   %3  = y === Base.nothing
└──       goto #3 if not %3
2 ─       return init
3 ─ %6  = Base.getindex(y, 1)
└──       v = (op)(init, %6)
4 ┄       goto #8 if not true
5 ─ %9  = Base.getindex(y, 2)
│         y = Base.iterate(itr, %9)
│   %11 = y === Base.nothing
└──       goto #7 if not %11
6 ─       goto #8
7 ─ %14 = v
│   %15 = Base.getindex(y, 1)
│         v = (op)(%14, %15)
└──       goto #4
8 ┄       return v
)
```

We can report infinite iteration by checking both `goto #3 if not %3` and
`goto #7 if not %11` never happens and thus this function never returns.

---

- closes #135
- closes #179
aviatesk added a commit that referenced this pull request May 10, 2021
WIP because I found this is better to be generalized to a control flow
analysis that checks for "never reaching exit points".
For As an example, `sum(a for a in NeverTeminate(::Int))` will come down
to `Base._fold_impl`, which directly uses `iterate(::NeverTeminate, [state])`,
against which the current implementation based on the iteration protocol
can't report an error.

> Adapated from https://github.com/JuliaLang/julia/blob/24d9eab45632bdb3120c9e664503745eb58aa2d6/base/reduce.jl#L53-L65

```julia
function _foldl_impl(op::OP, init, itr) where {OP}
    # Unroll the while loop once; if init is known, the call to op may
    # be evaluated at compile time
    y = iterate(itr)
    y === nothing && return init
    v = op(init, y[1])
    while true
        y = iterate(itr, y[2])
        y === nothing && break
        v = op(v, y[1])
    end
    return v
end
```

> In a lowered representation

```julia
CodeInfo(
1 ─       Core.NewvarNode(:(v))
│         y = Base.iterate(itr)
│   %3  = y === Base.nothing
└──       goto #3 if not %3
2 ─       return init
3 ─ %6  = Base.getindex(y, 1)
└──       v = (op)(init, %6)
4 ┄       goto #8 if not true
5 ─ %9  = Base.getindex(y, 2)
│         y = Base.iterate(itr, %9)
│   %11 = y === Base.nothing
└──       goto #7 if not %11
6 ─       goto #8
7 ─ %14 = v
│   %15 = Base.getindex(y, 1)
│         v = (op)(%14, %15)
└──       goto #4
8 ┄       return v
)
```

We can report infinite iteration by checking both `goto #3 if not %3` and
`goto #7 if not %11` never happens and thus this function never returns.

---

- closes #135
- closes #179
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