llvm.org GIT mirror llvm / fe94416
Revert "Emit only A Single Opt Remark When Inlining" Reverting due to clang build failure git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311274 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Elliott 3 years ago
12 changed file(s) with 54 addition(s) and 151 deletion(s). Raw diff Collapse all Expand all
104104 return Cost;
105105 }
106106
107 /// \brief Get the threshold against which the cost was computed
108 int getThreshold() const {
109 assert(isVariable() && "Invalid access of InlineCost");
110 return Threshold;
111 }
112
113107 /// \brief Get the cost delta from the threshold for inlining.
114108 /// Only valid if the cost is of the variable kind. Returns a negative
115109 /// value if the cost is too high to inline.
334334 return false;
335335 }
336336
337 /// Return the cost only if the inliner should attempt to inline at the given
338 /// CallSite. If we return the cost, we will emit an optimisation remark later
339 /// using that cost, so we won't do so from this function.
340 static Optional
341 shouldInline(CallSite CS, function_ref GetInlineCost,
342 OptimizationRemarkEmitter &ORE) {
337 /// Return true if the inliner should attempt to inline at the given CallSite.
338 static bool shouldInline(CallSite CS,
339 function_ref GetInlineCost,
340 OptimizationRemarkEmitter &ORE) {
343341 using namespace ore;
344342 InlineCost IC = GetInlineCost(CS);
345343 Instruction *Call = CS.getInstruction();
349347 if (IC.isAlways()) {
350348 DEBUG(dbgs() << " Inlining: cost=always"
351349 << ", Call: " << *CS.getInstruction() << "\n");
352 return IC;
350 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "AlwaysInline", Call)
351 << NV("Callee", Callee)
352 << " should always be inlined (cost=always)");
353 return true;
353354 }
354355
355356 if (IC.isNever()) {
359360 << NV("Callee", Callee) << " not inlined into "
360361 << NV("Caller", Caller)
361362 << " because it should never be inlined (cost=never)");
362 return None;
363 return false;
363364 }
364365
365366 if (!IC) {
366367 DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost()
367 << ", thres=" << IC.getThreshold()
368 << ", thres=" << (IC.getCostDelta() + IC.getCost())
368369 << ", Call: " << *CS.getInstruction() << "\n");
369370 ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
370371 << NV("Callee", Callee) << " not inlined into "
371372 << NV("Caller", Caller) << " because too costly to inline (cost="
372 << NV("Cost", IC.getCost())
373 << ", threshold=" << NV("Threshold", IC.getThreshold()) << ")");
374 return None;
373 << NV("Cost", IC.getCost()) << ", threshold="
374 << NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")");
375 return false;
375376 }
376377
377378 int TotalSecondaryCost = 0;
384385 << "Not inlining. Cost of inlining " << NV("Callee", Callee)
385386 << " increases the cost of inlining " << NV("Caller", Caller)
386387 << " in other contexts");
387
388 // IC does not bool() to false, so get an InlineCost that will.
389 // This will not be inspected to make an error message.
390 return None;
388 return false;
391389 }
392390
393391 DEBUG(dbgs() << " Inlining: cost=" << IC.getCost()
394 << ", thres=" << IC.getThreshold()
392 << ", thres=" << (IC.getCostDelta() + IC.getCost())
395393 << ", Call: " << *CS.getInstruction() << '\n');
396 return IC;
394 ORE.emit(OptimizationRemarkAnalysis(DEBUG_TYPE, "CanBeInlined", Call)
395 << NV("Callee", Callee) << " can be inlined into "
396 << NV("Caller", Caller) << " with cost=" << NV("Cost", IC.getCost())
397 << " (threshold="
398 << NV("Threshold", IC.getCostDelta() + IC.getCost()) << ")");
399 return true;
397400 }
398401
399402 /// Return true if the specified inline history ID
541544 // just become a regular analysis dependency.
542545 OptimizationRemarkEmitter ORE(Caller);
543546
544 Optional OIC = shouldInline(CS, GetInlineCost, ORE);
545547 // If the policy determines that we should inline this function,
546548 // delete the call instead.
547 if (!OIC)
549 if (!shouldInline(CS, GetInlineCost, ORE))
548550 continue;
549551
550552 // If this call site is dead and it is to a readonly function, we should
559561 ++NumCallsDeleted;
560562 } else {
561563 // Get DebugLoc to report. CS will be invalid after Inliner.
562 DebugLoc DLoc = CS->getDebugLoc();
564 DebugLoc DLoc = Instr->getDebugLoc();
563565 BasicBlock *Block = CS.getParent();
564566
565567 // Attempt to inline the function.
575577 }
576578 ++NumInlined;
577579
578 if (OIC->isAlways())
579 ORE.emit(OptimizationRemark(DEBUG_TYPE, "AlwaysInline", DLoc, Block)
580 << NV("Callee", Callee) << " inlined into "
581 << NV("Caller", Caller) << " with cost=always");
582 else
583 ORE.emit(OptimizationRemark(DEBUG_TYPE, "Inlined", DLoc, Block)
584 << NV("Callee", Callee) << " inlined into "
585 << NV("Caller", Caller)
586 << " with cost=" << NV("Cost", OIC->getCost())
587 << " (threshold=" << NV("Threshold", OIC->getThreshold())
588 << ")");
580 // Report the inline decision.
581 ORE.emit(OptimizationRemark(DEBUG_TYPE, "Inlined", DLoc, Block)
582 << NV("Callee", Callee) << " inlined into "
583 << NV("Caller", Caller));
589584
590585 // If inlining this function gave us any new call sites, throw them
591586 // onto our worklist to process. They are useful inline candidates.
889884 continue;
890885 }
891886
892 Optional OIC = shouldInline(CS, GetInlineCost, ORE);
893887 // Check whether we want to inline this callsite.
894 if (!OIC)
888 if (!shouldInline(CS, GetInlineCost, ORE))
895889 continue;
896890
897891 // Setup the data structure used to plumb customization into the
901895 &FAM.getResult(*(CS.getCaller())),
902896 &FAM.getResult(Callee));
903897
904 // Get DebugLoc to report. CS will be invalid after Inliner.
905 DebugLoc DLoc = CS->getDebugLoc();
906 BasicBlock *Block = CS.getParent();
907
908 using namespace ore;
909 if (!InlineFunction(CS, IFI)) {
910 ORE.emit(
911 OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
912 << NV("Callee", &Callee) << " will not be inlined into "
913 << NV("Caller", &F));
898 if (!InlineFunction(CS, IFI))
914899 continue;
915 }
916900 DidInline = true;
917901 InlinedCallees.insert(&Callee);
918
919 if (OIC->isAlways())
920 ORE.emit(OptimizationRemark(DEBUG_TYPE, "AlwaysInline", DLoc, Block)
921 << NV("Callee", &Callee) << " inlined into "
922 << NV("Caller", &F) << " with cost=always");
923 else
924 ORE.emit(
925 OptimizationRemark(DEBUG_TYPE, "Inlined", DLoc, Block)
926 << NV("Callee", &Callee) << " inlined into " << NV("Caller", &F)
927 << " with cost=" << NV("Cost", OIC->getCost())
928 << " (threshold=" << NV("Threshold", OIC->getThreshold()) << ")");
929902
930903 // Add any new callsites to defined functions to the worklist.
931904 if (!IFI.InlinedCallSites.empty()) {
1616 ; YAML-NEXT: - Callee: tinkywinky
1717 ; YAML-NEXT: - String: ' inlined into '
1818 ; YAML-NEXT: - Caller: main
19 ; YAML-NEXT: - String: ' with cost='
20 ; YAML-NEXT: - Cost: '-15000'
21 ; YAML-NEXT: - String: ' (threshold='
22 ; YAML-NEXT: - Threshold: '337'
23 ; YAML-NEXT: - String: ')'
2419 ; YAML-NEXT: ...
2520
2621 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1414 ; YAML-NEXT: - Callee: tinkywinky
1515 ; YAML-NEXT: - String: ' inlined into '
1616 ; YAML-NEXT: - Caller: main
17 ; YAML-NEXT: - String: ' with cost='
18 ; YAML-NEXT: - Cost: '-15000'
19 ; YAML-NEXT: - String: ' (threshold='
20 ; YAML-NEXT: - Threshold: '337'
21 ; YAML-NEXT: - String: ')'
2217 ; YAML-NEXT: ...
2318
2419 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1616 ; YAML-NEXT: - Callee: foo
1717 ; YAML-NEXT: - String: ' inlined into '
1818 ; YAML-NEXT: - Caller: main
19 ; YAML-NEXT: - String: ' with cost='
20 ; YAML-NEXT: - Cost: '-15000'
21 ; YAML-NEXT: - String: ' (threshold='
22 ; YAML-NEXT: - Threshold: '337'
23 ; YAML-NEXT: - String: ')'
2419 ; YAML-NEXT: ...
2520
2621 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
5252 ; YAML-NEXT: - Callee: foo
5353 ; YAML-NEXT: - String: ' inlined into '
5454 ; YAML-NEXT: - Caller: main
55 ; YAML-NEXT: - String: ' with cost='
56 ; YAML-NEXT: - Cost: '-15000'
57 ; YAML-NEXT: - String: ' (threshold='
58 ; YAML-NEXT: - Threshold: '337'
59 ; YAML-NEXT: - String: ')'
6055 ; YAML-NEXT: ...
6156
6257 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
2424 ; YAML1-NEXT: - Callee: foo
2525 ; YAML1-NEXT: - String: ' inlined into '
2626 ; YAML1-NEXT: - Caller: main
27 ; YAML1-NEXT: - String: ' with cost='
28 ; YAML1-NEXT: - Cost: '-30'
29 ; YAML1-NEXT: - String: ' (threshold='
30 ; YAML1-NEXT: - Threshold: '337'
31 ; YAML1-NEXT: - String: ')'
3227 ; YAML1-NEXT: ...
3328
3429
4237 ; YAML2-NEXT: - Callee: bar
4338 ; YAML2-NEXT: - String: ' inlined into '
4439 ; YAML2-NEXT: - Caller: foo
45 ; YAML2-NEXT: - String: ' with cost='
46 ; YAML2-NEXT: - Cost: '-30'
47 ; YAML2-NEXT: - String: ' (threshold='
48 ; YAML2-NEXT: - Threshold: '337'
49 ; YAML2-NEXT: - String: ')'
5040 ; YAML2-NEXT: ...
5141
5242
2121 ; YAML1-NEXT: - Callee: foo
2222 ; YAML1-NEXT: - String: ' inlined into '
2323 ; YAML1-NEXT: - Caller: main
24 ; YAML1-NEXT: - String: ' with cost='
25 ; YAML1-NEXT: - Cost: '-30'
26 ; YAML1-NEXT: - String: ' (threshold='
27 ; YAML1-NEXT: - Threshold: '337'
28 ; YAML1-NEXT: - String: ')'
2924 ; YAML1-NEXT: ...
3025
3126
3934 ; YAML2-NEXT: - Callee: bar
4035 ; YAML2-NEXT: - String: ' inlined into '
4136 ; YAML2-NEXT: - Caller: foo
42 ; YAML2-NEXT: - String: ' with cost='
43 ; YAML2-NEXT: - Cost: '-30'
44 ; YAML2-NEXT: - String: ' (threshold='
45 ; YAML2-NEXT: - Threshold: '337'
46 ; YAML2-NEXT: - String: ')'
4737 ; YAML2-NEXT: ...
4838
4939
0 ; RUN: opt < %s -S -inline -pass-remarks-output=%t -pass-remarks=inline \
1 ; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \
2 ; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s
3 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
4
5 ; RUN: opt < %s -S -passes=inline -pass-remarks-output=%t -pass-remarks=inline \
61 ; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \
72 ; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s
83 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
1611 ; 4 return foo();
1712 ; 5 }
1813
19 ; CHECK: remark: /tmp/s.c:4:10: foo inlined into bar with cost={{[0-9\-]+}} (threshold={{[0-9]+}}) (hotness: 30)
14 ; CHECK: remark: /tmp/s.c:4:10: foo can be inlined into bar with cost={{[0-9\-]+}} (threshold={{[0-9]+}}) (hotness: 30)
15 ; CHECK-NEXT: remark: /tmp/s.c:4:10: foo inlined into bar (hotness: 30)
2016
21 ; YAML: --- !Passed
17 ; YAML: --- !Analysis
18 ; YAML-NEXT: Pass: inline
19 ; YAML-NEXT: Name: CanBeInlined
20 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 4, Column: 10 }
21 ; YAML-NEXT: Function: bar
22 ; YAML-NEXT: Hotness: 30
23 ; YAML-NEXT: Args:
24 ; YAML-NEXT: - Callee: foo
25 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 1, Column: 0 }
26 ; YAML-NEXT: - String: ' can be inlined into '
27 ; YAML-NEXT: - Caller: bar
28 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 3, Column: 0 }
29 ; YAML-NEXT: - String: ' with cost='
30 ; YAML-NEXT: - Cost: '{{[0-9\-]+}}'
31 ; YAML-NEXT: - String: ' (threshold='
32 ; YAML-NEXT: - Threshold: '{{[0-9]+}}'
33 ; YAML-NEXT: - String: ')'
34 ; YAML-NEXT: ...
35 ; YAML-NEXT: --- !Passed
2236 ; YAML-NEXT: Pass: inline
2337 ; YAML-NEXT: Name: Inlined
2438 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 4, Column: 10 }
3044 ; YAML-NEXT: - String: ' inlined into '
3145 ; YAML-NEXT: - Caller: bar
3246 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 3, Column: 0 }
33 ; YAML-NEXT: - String: ' with cost='
34 ; YAML-NEXT: - Cost: '{{[0-9\-]+}}'
35 ; YAML-NEXT: - String: ' (threshold='
36 ; YAML-NEXT: - Threshold: '{{[0-9]+}}'
37 ; YAML-NEXT: - String: ')'
3847 ; YAML-NEXT: ...
3948
4049 ; ModuleID = '/tmp/s.c'
0 ; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline \
11 ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 \
22 ; RUN: | FileCheck %s
3 ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \
4 ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 \
5 ; RUN: | FileCheck %s
63
7 ; CHECK: foo inlined into bar with cost=always (hotness: 30)
4 ; CHECK: foo should always be inlined (cost=always) (hotness: 30)
5 ; CHECK: foo inlined into bar (hotness: 30)
86 ; CHECK: foz not inlined into bar because it should never be inlined (cost=never) (hotness: 30)
97
108 ; Function Attrs: alwaysinline nounwind uwtable
1111 ; RUN: FileCheck -check-prefix=THRESHOLD %s
1212 ; RUN: test ! -s %t.threshold
1313 ; RUN: opt < %s -S -inline \
14 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 100 \
15 ; RUN: -pass-remarks-output=%t.threshold
16 ; The remarks output file should be empty.
17 ; RUN: test ! -s %t.threshold
18
19 ; NewPM:
20 ; RUN: opt < %s -S -passes=inline -pass-remarks-missed=inline \
21 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 15 \
22 ; RUN: -pass-remarks-output=%t 2>&1 | FileCheck %s -check-prefix=CHECK_NEW
23 ; RUN: test ! -s %t
24 ; RUN: opt < %s -S -passes=inline -pass-remarks-with-hotness -pass-remarks-output=%t
25 ; RUN: test ! -s %t
26 ;
27 ; Verify that remarks that don't meet the hotness threshold are not output.
28 ; RUN: opt < %s -S -passes=inline -pass-remarks-missed=inline \
29 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 100 \
30 ; RUN: -pass-remarks-output=%t.threshold 2>&1 | \
31 ; RUN: FileCheck -check-prefix=THRESHOLD %s
32 ; RUN: test ! -s %t.threshold
33 ; RUN: opt < %s -S -passes=inline \
3414 ; RUN: -pass-remarks-with-hotness -pass-remarks-hotness-threshold 100 \
3515 ; RUN: -pass-remarks-output=%t.threshold
3616 ; The remarks output file should be empty.
7858 ; No remarks should be output, since none meet the threshold.
7959 ; THRESHOLD-NOT: remark
8060
81 ; NewPM does not output this kind of "missed" remark.
82 ; CHECK_NEW-NOT: remark
83
8461 ; ModuleID = '/tmp/s.c'
8562 source_filename = "/tmp/s.c"
8663 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
44 ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \
55 ; RUN: FileCheck -check-prefix=CHECK -check-prefix=HOTNESS %s
66
7 ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \
8 ; RUN: -pass-remarks-analysis=inline -S 2>&1 | \
9 ; RUN: FileCheck -check-prefix=CHECK -check-prefix=NO_HOTNESS %s
10 ; RUN: opt < %s -passes=inline -pass-remarks=inline -pass-remarks-missed=inline \
11 ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \
12 ; RUN: FileCheck -check-prefix=CHECK -check-prefix=HOTNESS_NEW %s
13
147 ; HOTNESS: fox will not be inlined into bar because its definition is unavailable
158 ; NO_HOTNESS-NOT: fox will not be inlined into bar because its definition is unavailable
16 ; NewPM's inliner does not emit the following remark:
17 ; HOTNESS_NEW-NOT: fox will not be inlined into bar because its definition is unavailable
18 ; CHECK: foo inlined into bar with cost=always
9 ; CHECK: foo should always be inlined (cost=always)
10 ; CHECK: foo inlined into bar
1911 ; CHECK: foz not inlined into bar because it should never be inlined (cost=never)
2012
2113 ; Function Attrs: alwaysinline nounwind uwtable