|
2 | 2 |
|
3 | 3 | Core.PhiNode() = Core.PhiNode(Int32[], Any[])
|
4 | 4 |
|
5 |
| -isterminator(@nospecialize(stmt)) = isa(stmt, GotoNode) || isa(stmt, GotoIfNot) || isa(stmt, ReturnNode) |
| 5 | +isterminator(@nospecialize(stmt)) = isa(stmt, GotoNode) || isa(stmt, GotoIfNot) || isa(stmt, ReturnNode) || isa(stmt, EnterNode) |
6 | 6 |
|
7 | 7 | struct CFG
|
8 | 8 | blocks::Vector{BasicBlock}
|
@@ -60,16 +60,16 @@ block_for_inst(cfg::CFG, inst::Int) = block_for_inst(cfg.index, inst)
|
60 | 60 | # This is a fake dest to force the next stmt to start a bb
|
61 | 61 | idx < length(stmts) && push!(jump_dests, idx+1)
|
62 | 62 | push!(jump_dests, stmt.label)
|
| 63 | + elseif isa(stmt, EnterNode) |
| 64 | + # :enter starts/ends a BB |
| 65 | + push!(jump_dests, idx) |
| 66 | + push!(jump_dests, idx+1) |
| 67 | + # The catch block is a jump dest |
| 68 | + push!(jump_dests, stmt.catch_dest) |
63 | 69 | elseif isa(stmt, Expr)
|
64 | 70 | if stmt.head === :leave
|
65 | 71 | # :leave terminates a BB
|
66 | 72 | push!(jump_dests, idx+1)
|
67 |
| - elseif stmt.head === :enter |
68 |
| - # :enter starts/ends a BB |
69 |
| - push!(jump_dests, idx) |
70 |
| - push!(jump_dests, idx+1) |
71 |
| - # The catch block is a jump dest |
72 |
| - push!(jump_dests, stmt.args[1]::Int) |
73 | 73 | end
|
74 | 74 | end
|
75 | 75 | if isa(stmt, PhiNode)
|
@@ -125,11 +125,11 @@ function compute_basic_blocks(stmts::Vector{Any})
|
125 | 125 | push!(blocks[block′].preds, num)
|
126 | 126 | push!(b.succs, block′)
|
127 | 127 | end
|
128 |
| - elseif isexpr(terminator, :enter) |
| 128 | + elseif isa(terminator, EnterNode) |
129 | 129 | # :enter gets a virtual edge to the exception handler and
|
130 | 130 | # the exception handler gets a virtual edge from outside
|
131 | 131 | # the function.
|
132 |
| - block′ = block_for_inst(basic_block_index, terminator.args[1]::Int) |
| 132 | + block′ = block_for_inst(basic_block_index, terminator.catch_dest) |
133 | 133 | push!(blocks[block′].preds, num)
|
134 | 134 | push!(blocks[block′].preds, 0)
|
135 | 135 | push!(b.succs, block′)
|
@@ -456,6 +456,10 @@ struct UndefToken end; const UNDEF_TOKEN = UndefToken()
|
456 | 456 | isdefined(stmt, :val) || return OOB_TOKEN
|
457 | 457 | op == 1 || return OOB_TOKEN
|
458 | 458 | return stmt.val
|
| 459 | + elseif isa(stmt, EnterNode) |
| 460 | + isdefined(stmt, :scope) || return OOB_TOKEN |
| 461 | + op == 1 || return OOB_TOKEN |
| 462 | + return stmt.scope |
459 | 463 | elseif isa(stmt, PiNode)
|
460 | 464 | isdefined(stmt, :val) || return OOB_TOKEN
|
461 | 465 | op == 1 || return OOB_TOKEN
|
|
510 | 514 | elseif isa(stmt, GotoIfNot)
|
511 | 515 | op == 1 || throw(BoundsError())
|
512 | 516 | stmt = GotoIfNot(v, stmt.dest)
|
| 517 | + elseif isa(stmt, EnterNode) |
| 518 | + op == 1 || throw(BoundsError()) |
| 519 | + stmt = EnterNode(stmt.catch_dest, v) |
513 | 520 | elseif isa(stmt, ReturnNode)
|
514 | 521 | op == 1 || throw(BoundsError())
|
515 | 522 | stmt = typeof(stmt)(v)
|
|
544 | 551 | function userefs(@nospecialize(x))
|
545 | 552 | relevant = (isa(x, Expr) && is_relevant_expr(x)) ||
|
546 | 553 | isa(x, GotoIfNot) || isa(x, ReturnNode) || isa(x, SSAValue) || isa(x, NewSSAValue) ||
|
547 |
| - isa(x, PiNode) || isa(x, PhiNode) || isa(x, PhiCNode) || isa(x, UpsilonNode) |
| 554 | + isa(x, PiNode) || isa(x, PhiNode) || isa(x, PhiCNode) || isa(x, UpsilonNode) || isa(x, EnterNode) |
548 | 555 | return UseRefIterator(x, relevant)
|
549 | 556 | end
|
550 | 557 |
|
@@ -1379,13 +1386,15 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
|
1379 | 1386 | result[result_idx][:stmt] = GotoIfNot(cond, label)
|
1380 | 1387 | result_idx += 1
|
1381 | 1388 | end
|
| 1389 | + elseif cfg_transforms_enabled && isa(stmt, EnterNode) |
| 1390 | + label = bb_rename_succ[stmt.catch_dest] |
| 1391 | + @assert label > 0 |
| 1392 | + ssa_rename[idx] = SSAValue(result_idx) |
| 1393 | + result[result_idx][:stmt] = EnterNode(stmt, label) |
| 1394 | + result_idx += 1 |
1382 | 1395 | elseif isa(stmt, Expr)
|
1383 | 1396 | stmt = renumber_ssa2!(stmt, ssa_rename, used_ssas, new_new_used_ssas, late_fixup, result_idx, do_rename_ssa, mark_refined!)::Expr
|
1384 |
| - if cfg_transforms_enabled && isexpr(stmt, :enter) |
1385 |
| - label = bb_rename_succ[stmt.args[1]::Int] |
1386 |
| - @assert label > 0 |
1387 |
| - stmt.args[1] = label |
1388 |
| - elseif isexpr(stmt, :throw_undef_if_not) |
| 1397 | + if isexpr(stmt, :throw_undef_if_not) |
1389 | 1398 | cond = stmt.args[2]
|
1390 | 1399 | if isa(cond, Bool) && cond === true
|
1391 | 1400 | # cond was folded to true - this statement
|
@@ -1445,7 +1454,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
|
1445 | 1454 | ssa_rename[idx] = SSAValue(result_idx)
|
1446 | 1455 | result[result_idx][:stmt] = stmt
|
1447 | 1456 | result_idx += 1
|
1448 |
| - elseif isa(stmt, ReturnNode) || isa(stmt, UpsilonNode) || isa(stmt, GotoIfNot) |
| 1457 | + elseif isa(stmt, ReturnNode) || isa(stmt, UpsilonNode) || isa(stmt, GotoIfNot) || isa(stmt, EnterNode) |
1449 | 1458 | ssa_rename[idx] = SSAValue(result_idx)
|
1450 | 1459 | result[result_idx][:stmt] = renumber_ssa2!(stmt, ssa_rename, used_ssas, new_new_used_ssas, late_fixup, result_idx, do_rename_ssa, mark_refined!)
|
1451 | 1460 | result_idx += 1
|
|
0 commit comments