@@ -1288,6 +1288,22 @@ function handle_any_const_result!(cases::Vector{InliningCase}, @nospecialize(res
1288
1288
end
1289
1289
end
1290
1290
1291
+ function info_effects (@nospecialize (result), match:: MethodMatch , state:: InliningState )
1292
+ if isa (result, Union{ConcreteResult, SemiConcreteResult})
1293
+ return result. effects
1294
+ elseif isa (result, ConstPropResult)
1295
+ return result. result. ipo_effects
1296
+ else
1297
+ mi = specialize_method (match; preexisting= true )
1298
+ code = get (state. mi_cache, mi, nothing )
1299
+ if code isa CodeInstance
1300
+ return decode_effects (code. ipo_purity_bits)
1301
+ else
1302
+ return Effects ()
1303
+ end
1304
+ end
1305
+ end
1306
+
1291
1307
function compute_inlining_cases (info:: Union{ConstCallInfo, Vector{MethodMatchInfo}} ,
1292
1308
flag:: UInt8 , sig:: Signature , state:: InliningState )
1293
1309
argtypes = sig. argtypes
@@ -1306,6 +1322,7 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
1306
1322
local meth:: MethodLookupResult
1307
1323
local all_result_count = 0
1308
1324
1325
+ joint_effects = EFFECTS_TOTAL
1309
1326
for i in 1 : length (infos)
1310
1327
meth = infos[i]. results
1311
1328
if meth. ambig
@@ -1331,6 +1348,7 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
1331
1348
all_result_count += 1
1332
1349
result = results === nothing ? nothing : results[all_result_count]
1333
1350
any_fully_covered |= match. fully_covers
1351
+ joint_effects = merge_effects (joint_effects, info_effects (result, match, state))
1334
1352
if ! validate_sparams (match. sparams)
1335
1353
if ! match. fully_covers
1336
1354
handled_all_cases = false
@@ -1348,6 +1366,10 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
1348
1366
end
1349
1367
end
1350
1368
1369
+ if ! any_fully_covered
1370
+ joint_effects = Effects ()
1371
+ end
1372
+
1351
1373
if handled_all_cases && revisit_idx != = nothing
1352
1374
# we handled everything except one match with unmatched sparams,
1353
1375
# so try to handle it by bypassing validate_sparams
@@ -1377,17 +1399,17 @@ function compute_inlining_cases(info::Union{ConstCallInfo, Vector{MethodMatchInf
1377
1399
filter! (case:: InliningCase -> isdispatchtuple (case. sig), cases)
1378
1400
end
1379
1401
1380
- return cases, handled_all_cases & any_fully_covered
1402
+ return cases, handled_all_cases & any_fully_covered, joint_effects
1381
1403
end
1382
1404
1383
1405
function handle_call! (
1384
1406
ir:: IRCode , idx:: Int , stmt:: Expr , infos:: Vector{MethodMatchInfo} , flag:: UInt8 ,
1385
1407
sig:: Signature , state:: InliningState , todo:: Vector{Pair{Int, Any}} )
1386
1408
cases = compute_inlining_cases (infos, flag, sig, state)
1387
1409
cases === nothing && return nothing
1388
- cases, all_covered = cases
1410
+ cases, all_covered, joint_effects = cases
1389
1411
handle_cases! (ir, idx, stmt, argtypes_to_type (sig. argtypes), cases,
1390
- all_covered, todo, state. params)
1412
+ all_covered, todo, state. params, joint_effects )
1391
1413
end
1392
1414
1393
1415
function handle_const_call! (
@@ -1397,7 +1419,7 @@ function handle_const_call!(
1397
1419
cases === nothing && return nothing
1398
1420
cases, all_covered = cases
1399
1421
handle_cases! (ir, idx, stmt, argtypes_to_type (sig. argtypes), cases,
1400
- all_covered, todo, state. params)
1422
+ all_covered, todo, state. params, joint_effects )
1401
1423
end
1402
1424
1403
1425
function handle_match! (
@@ -1452,7 +1474,7 @@ end
1452
1474
1453
1475
function handle_cases! (ir:: IRCode , idx:: Int , stmt:: Expr , @nospecialize (atype),
1454
1476
cases:: Vector{InliningCase} , fully_covered:: Bool , todo:: Vector{Pair{Int, Any}} ,
1455
- params:: OptimizationParams )
1477
+ params:: OptimizationParams , joint_effects :: Effects )
1456
1478
# If we only have one case and that case is fully covered, we may either
1457
1479
# be able to do the inlining now (for constant cases), or push it directly
1458
1480
# onto the todo list
@@ -1464,6 +1486,8 @@ function handle_cases!(ir::IRCode, idx::Int, stmt::Expr, @nospecialize(atype),
1464
1486
isa (case. sig, DataType) || return nothing
1465
1487
end
1466
1488
push! (todo, idx=> UnionSplit (fully_covered, atype, cases))
1489
+ else
1490
+ ir[SSAValue (idx)][:flag ] |= flags_for_effects (joint_effects)
1467
1491
end
1468
1492
return nothing
1469
1493
end
0 commit comments