Skip to content

Commit 55d51b7

Browse files
authored
Closure specialization might create functions with lots of arguments. (#77629)
Increase inlining benefits for functions with more than 5 arguments and / or results. We assume that each argument beyond these 5 would be passed on stack and therefore would incur a pair of load and store.
1 parent a8fd757 commit 55d51b7

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,16 @@ bool SILPerformanceInliner::isProfitableToInline(
471471
int BaseBenefit = isa<BeginApplyInst>(AI) ? RemovedCoroutineCallBenefit
472472
: RemovedCallBenefit;
473473

474+
// If function has more than 5 parameters / results, then increase base
475+
// benefit for each additional parameter. We assume that for each extra
476+
// parameter or result we'd eliminate extra pair of loads and stores used to
477+
// pass / return value via stack.
478+
unsigned numParameters = AI->getNumRealOperands(), numResults = AI->getNumResults();
479+
if (numParameters > 5)
480+
BaseBenefit += (RemovedLoadBenefit + RemovedStoreBenefit) * (numParameters - 5);
481+
if (numResults > 5)
482+
BaseBenefit += (RemovedLoadBenefit + RemovedStoreBenefit) * (numResults - 5);
483+
474484
// Osize heuristic.
475485
//
476486
// As a hack, don't apply this at all to coroutine inlining; avoiding

test/SILOptimizer/inline_heuristics.sil

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,3 +470,130 @@ bb0:
470470
// TODO:
471471
// Check that the inlining heuristic takes into account the possibility
472472
// of performing a devirtualization after inlining.
473+
474+
// Test of inlining functions with many parameters
475+
476+
// CHECK-LABEL: sil @testManyParams : $@convention(thin) (Float,
477+
// CHECK-NOT: apply
478+
// CHECK: return
479+
// CHECK: end sil function 'testManyParams'
480+
481+
sil @manyParamsCallee1 : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float {
482+
bb0(%0 : $Float, %1 : $Float, %2 : $Float, %3 : $Float, %4 : $Float, %5 : $Float, %6 : $Float, %7 : $Float, %8 : $Float, %9 : $Float, %10 : $Float, %11 : $Float, %12 : $Float, %13 : $Float, %14 : $Float, %15 : $Float, %16 : $Float, %17 : $Float, %18 : $Float):
483+
%19 = struct_extract %10 : $Float, #Float._value // user: %21
484+
%20 = struct_extract %0 : $Float, #Float._value // users: %65, %67, %60, %53, %55, %23, %21
485+
%21 = builtin "fmul_FPIEEE32"(%19 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %27, %25
486+
%22 = struct_extract %11 : $Float, #Float._value // user: %23
487+
%23 = builtin "fmul_FPIEEE32"(%22 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %28
488+
%24 = struct_extract %8 : $Float, #Float._value // user: %25
489+
%25 = builtin "fmul_FPIEEE32"(%24 : $Builtin.FPIEEE32, %21 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %29
490+
%26 = struct_extract %9 : $Float, #Float._value // user: %27
491+
%27 = builtin "fmul_FPIEEE32"(%26 : $Builtin.FPIEEE32, %21 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %28
492+
%28 = builtin "fadd_FPIEEE32"(%27 : $Builtin.FPIEEE32, %23 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %50
493+
%29 = builtin "fneg_FPIEEE32"(%25 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %31
494+
%30 = struct_extract %18 : $Float, #Float._value // user: %31
495+
%31 = builtin "fdiv_FPIEEE32"(%29 : $Builtin.FPIEEE32, %30 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %34, %32
496+
%33 = struct_extract %17 : $Float, #Float._value // user: %34
497+
%34 = builtin "fdiv_FPIEEE32"(%31 : $Builtin.FPIEEE32, %33 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %36
498+
%35 = struct_extract %16 : $Float, #Float._value // user: %36
499+
%36 = builtin "fmul_FPIEEE32"(%35 : $Builtin.FPIEEE32, %34 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %43, %37
500+
%38 = struct_extract %14 : $Float, #Float._value // users: %41, %41
501+
%39 = struct_extract %15 : $Float, #Float._value // user: %40
502+
%40 = builtin "fneg_FPIEEE32"(%39 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %42
503+
%41 = builtin "fmul_FPIEEE32"(%38 : $Builtin.FPIEEE32, %38 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %42
504+
%42 = builtin "fdiv_FPIEEE32"(%40 : $Builtin.FPIEEE32, %41 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %43
505+
%43 = builtin "fmul_FPIEEE32"(%42 : $Builtin.FPIEEE32, %36 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %46, %44
506+
%45 = struct_extract %13 : $Float, #Float._value // user: %46
507+
%46 = builtin "fdiv_FPIEEE32"(%43 : $Builtin.FPIEEE32, %45 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %48
508+
%47 = struct_extract %12 : $Float, #Float._value // user: %48
509+
%48 = builtin "fmul_FPIEEE32"(%47 : $Builtin.FPIEEE32, %46 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %49, %50
510+
%50 = builtin "fadd_FPIEEE32"(%48 : $Builtin.FPIEEE32, %28 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %51, %63
511+
%52 = struct_extract %6 : $Float, #Float._value // user: %53
512+
%53 = builtin "fmul_FPIEEE32"(%52 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %57
513+
%54 = struct_extract %7 : $Float, #Float._value // user: %55
514+
%55 = builtin "fmul_FPIEEE32"(%54 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %58
515+
%56 = struct_extract %5 : $Float, #Float._value // user: %57
516+
%57 = builtin "fmul_FPIEEE32"(%56 : $Builtin.FPIEEE32, %53 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %58
517+
%58 = builtin "fadd_FPIEEE32"(%57 : $Builtin.FPIEEE32, %55 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %61
518+
%59 = struct_extract %4 : $Float, #Float._value // user: %60
519+
%60 = builtin "fmul_FPIEEE32"(%59 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %61
520+
%61 = builtin "fadd_FPIEEE32"(%60 : $Builtin.FPIEEE32, %58 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %62, %63
521+
%63 = builtin "fadd_FPIEEE32"(%61 : $Builtin.FPIEEE32, %50 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %75
522+
%64 = struct_extract %2 : $Float, #Float._value // user: %65
523+
%65 = builtin "fmul_FPIEEE32"(%64 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %69
524+
%66 = struct_extract %3 : $Float, #Float._value // user: %67
525+
%67 = builtin "fmul_FPIEEE32"(%66 : $Builtin.FPIEEE32, %20 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %70
526+
%68 = struct_extract %1 : $Float, #Float._value // user: %69
527+
%69 = builtin "fmul_FPIEEE32"(%68 : $Builtin.FPIEEE32, %65 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %70
528+
%70 = builtin "fadd_FPIEEE32"(%69 : $Builtin.FPIEEE32, %67 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %73
529+
%71 = integer_literal $Builtin.Int64, 0 // user: %72
530+
%72 = builtin "sitofp_Int64_FPIEEE32"(%71 : $Builtin.Int64) : $Builtin.FPIEEE32 // user: %73
531+
%73 = builtin "fadd_FPIEEE32"(%72 : $Builtin.FPIEEE32, %70 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %74, %75
532+
%75 = builtin "fadd_FPIEEE32"(%73 : $Builtin.FPIEEE32, %63 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %76
533+
%76 = struct $Float (%75 : $Builtin.FPIEEE32) // users: %78, %77
534+
return %76 : $Float // id: %78
535+
}
536+
537+
sil @manyParamsCallee2 : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float {
538+
bb0(%0 : $Float, %1 : $Float, %2 : $Float, %3 : $Float, %4 : $Float, %5 : $Float, %6 : $Float, %7 : $Float, %8 : $Float, %9 : $Float, %10 : $Float, %11 : $Float, %12 : $Float, %13 : $Float, %14 : $Float, %15 : $Float, %16 : $Float, %17 : $Float, %18 : $Float, %19 : $Float, %20 : $Float, %21 : $Float, %22 : $Float, %23 : $Float, %24 : $Float, %25 : $Float, %26 : $Float):
539+
%27 = function_ref @manyParamsCallee1 : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float
540+
%28 = apply %27(%0, %2, %3, %4, %6, %8, %9, %10, %11, %12, %13, %14, %15, %17, %19, %20, %21, %23, %25) : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float
541+
return %28 : $Float
542+
}
543+
544+
sil @testManyParams : $@convention(thin) (Float, Builtin.FPIEEE32, Builtin.FPIEEE32, Builtin.FPIEEE32) -> (Float, Float) {
545+
bb0(%0 : $Float, %1 : @closureCapture $Builtin.FPIEEE32, %2 : @closureCapture $Builtin.FPIEEE32, %3 : @closureCapture $Builtin.FPIEEE32):
546+
%4 = struct $Float (%3 : $Builtin.FPIEEE32)
547+
%5 = struct $Float (%2 : $Builtin.FPIEEE32)
548+
%11 = float_literal $Builtin.FPIEEE32, 0x47C35000 // 1.0E+5 // user: %12
549+
%12 = builtin "fneg_FPIEEE32"(%11 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %15, %13
550+
%13 = struct $Float (%12 : $Builtin.FPIEEE32) // user: %67
551+
%14 = struct_extract %0 : $Float, #Float._value // users: %60, %58, %34, %23, %21, %19, %17, %15
552+
%15 = builtin "fmul_FPIEEE32"(%12 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %17, %16
553+
%16 = struct $Float (%15 : $Builtin.FPIEEE32) // user: %67
554+
%17 = builtin "fmul_FPIEEE32"(%15 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %25
555+
%19 = builtin "fmul_FPIEEE32"(%2 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %20
556+
%20 = builtin "fadd_FPIEEE32"(%1 : $Builtin.FPIEEE32, %19 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %24
557+
%21 = builtin "fmul_FPIEEE32"(%3 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %23, %22
558+
%22 = struct $Float (%21 : $Builtin.FPIEEE32) // user: %67
559+
%23 = builtin "fmul_FPIEEE32"(%21 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %24
560+
%24 = builtin "fadd_FPIEEE32"(%20 : $Builtin.FPIEEE32, %23 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %25
561+
%25 = builtin "fadd_FPIEEE32"(%17 : $Builtin.FPIEEE32, %24 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %61
562+
%28 = float_literal $Builtin.FPIEEE32, 0x3C9C0EBF // 0.0190500002 // users: %50, %34, %29
563+
%29 = struct $Float (%28 : $Builtin.FPIEEE32) // users: %67, %67, %30
564+
%31 = float_literal $Builtin.FPIEEE32, 0x425AA3D7 // 54.6599998 // users: %48, %32
565+
%32 = struct $Float (%31 : $Builtin.FPIEEE32) // users: %67, %33
566+
%34 = builtin "fmul_FPIEEE32"(%14 : $Builtin.FPIEEE32, %28 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %38, %35
567+
%35 = struct $Float (%34 : $Builtin.FPIEEE32) // user: %67
568+
%36 = float_literal $Builtin.FPIEEE32, 0x34883033 // 2.53670436E-7 // users: %38, %37
569+
%37 = struct $Float (%36 : $Builtin.FPIEEE32) // user: %67
570+
%38 = builtin "fdiv_FPIEEE32"(%34 : $Builtin.FPIEEE32, %36 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %43, %39
571+
%40 = float_literal $Builtin.FPIEEE32, 0x42800000 // 64 // users: %45, %41
572+
%41 = struct $Float (%40 : $Builtin.FPIEEE32) // user: %67
573+
%42 = float_literal $Builtin.FPIEEE32, 0x3C23D70A // 0.00999999977 // user: %43
574+
%43 = builtin "fadd_FPIEEE32"(%38 : $Builtin.FPIEEE32, %42 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %45, %44
575+
%44 = struct $Float (%43 : $Builtin.FPIEEE32) // user: %67
576+
%45 = builtin "fdiv_FPIEEE32"(%40 : $Builtin.FPIEEE32, %43 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %48, %46
577+
%46 = struct $Float (%45 : $Builtin.FPIEEE32) // users: %67, %47
578+
%48 = builtin "fmul_FPIEEE32"(%45 : $Builtin.FPIEEE32, %31 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %50, %49
579+
%49 = struct $Float (%48 : $Builtin.FPIEEE32) // user: %67
580+
%50 = builtin "fdiv_FPIEEE32"(%48 : $Builtin.FPIEEE32, %28 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %55, %51
581+
%51 = struct $Float (%50 : $Builtin.FPIEEE32) // users: %67, %52
582+
%53 = float_literal $Builtin.FPIEEE32, 0x3929844A // 1.61663775E-4 // users: %55, %54
583+
%54 = struct $Float (%53 : $Builtin.FPIEEE32) // user: %67
584+
%55 = builtin "fdiv_FPIEEE32"(%50 : $Builtin.FPIEEE32, %53 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %56
585+
%56 = builtin "fneg_FPIEEE32"(%55 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %58, %57
586+
%57 = struct $Float (%56 : $Builtin.FPIEEE32) // user: %67
587+
%58 = builtin "fmul_FPIEEE32"(%56 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // users: %60, %59
588+
%59 = struct $Float (%58 : $Builtin.FPIEEE32) // user: %67
589+
%60 = builtin "fmul_FPIEEE32"(%58 : $Builtin.FPIEEE32, %14 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %61
590+
%61 = builtin "fadd_FPIEEE32"(%25 : $Builtin.FPIEEE32, %60 : $Builtin.FPIEEE32) : $Builtin.FPIEEE32 // user: %62
591+
%62 = struct $Float (%61 : $Builtin.FPIEEE32) // user: %69
592+
%63 = integer_literal $Builtin.Int64, 1 // user: %64
593+
%64 = builtin "sitofp_Int64_FPIEEE32"(%63 : $Builtin.Int64) : $Builtin.FPIEEE32
594+
%65 = struct $Float (%64 : $Builtin.FPIEEE32)
595+
%66 = function_ref @manyParamsCallee2 : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float
596+
%67 = apply %66(%65, %0, %13, %0, %16, %0, %5, %0, %4, %0, %22, %0, %57, %0, %59, %29, %0, %37, %35, %44, %41, %32, %46, %29, %49, %54, %51) : $@convention(thin) (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) -> Float // users: %69, %68
597+
%69 = tuple (%62 : $Float, %67 : $Float) // user: %70
598+
return %69 : $(Float, Float) // id: %70
599+
}

0 commit comments

Comments
 (0)