OSDN Git Service

[MachineOutliner] Add missed optimization remarks for the outliner.
authorJessica Paquette <jpaquette@apple.com>
Wed, 30 Aug 2017 23:31:49 +0000 (23:31 +0000)
committerJessica Paquette <jpaquette@apple.com>
Wed, 30 Aug 2017 23:31:49 +0000 (23:31 +0000)
This adds missed optimization remarks which report viable candidates that
were not outlined because they would increase code size.

Other remarks will come in separate commits.

This will help to diagnose code size regressions and changes in outliner
behaviour in projects using the outliner.

https://reviews.llvm.org/D37085

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312194 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineOutliner.cpp
test/CodeGen/AArch64/machine-outliner-remarks.ll [new file with mode: 0644]

index 9a8eebf..c120354 100644 (file)
@@ -46,6 +46,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/Support/Allocator.h"
@@ -64,6 +65,7 @@
 #define DEBUG_TYPE "machine-outliner"
 
 using namespace llvm;
+using namespace ore;
 
 STATISTIC(NumOutlined, "Number of candidates outlined");
 STATISTIC(FunctionsCreated, "Number of functions created");
@@ -895,8 +897,41 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
     size_t OutliningCost = CallOverhead + FrameOverhead + SequenceOverhead;
     size_t NotOutliningCost = SequenceOverhead * Parent.OccurrenceCount;
 
-    if (NotOutliningCost <= OutliningCost)
+    // Is it better to outline this candidate than not?
+    if (NotOutliningCost <= OutliningCost) {
+      // Outlining this candidate would take more instructions than not
+      // outlining.
+      // Emit a remark explaining why we didn't outline this candidate.
+      std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator> C =
+          CandidateClass[0];
+      MachineOptimizationRemarkEmitter MORE(
+          *(C.first->getParent()->getParent()), nullptr);
+      MachineOptimizationRemarkMissed R(DEBUG_TYPE, "NotOutliningCheaper",
+                                        C.first->getDebugLoc(),
+                                        C.first->getParent());
+      R << "Did not outline " << NV("Length", StringLen) << " instructions"
+        << " from " << NV("NumOccurrences", CandidateClass.size())
+        << " locations."
+        << " Instructions from outlining all occurrences ("
+        << NV("OutliningCost", OutliningCost) << ")"
+        << " >= Unoutlined instruction count ("
+        << NV("NotOutliningCost", NotOutliningCost) << ")"
+        << " (Also found at: ";
+
+      // Tell the user the other places the candidate was found.
+      for (size_t i = 1, e = CandidateClass.size(); i < e; i++) {
+        R << NV((Twine("OtherStartLoc") + Twine(i)).str(),
+                CandidateClass[i].first->getDebugLoc());
+        if (i != e - 1)
+          R << ", ";
+      }
+
+      R << ")";
+      MORE.emit(R);
+
+      // Move to the next candidate.
       continue;
+    }
 
     size_t Benefit = NotOutliningCost - OutliningCost;
 
diff --git a/test/CodeGen/AArch64/machine-outliner-remarks.ll b/test/CodeGen/AArch64/machine-outliner-remarks.ll
new file mode 100644 (file)
index 0000000..113f343
--- /dev/null
@@ -0,0 +1,73 @@
+; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -pass-remarks-missed=machine-outliner -o /dev/null 2>&1 | FileCheck %s
+; CHECK: machine-outliner-remarks.ll:5:9:
+; CHECK-SAME: Did not outline 2 instructions from 2 locations.
+; CHECK-SAME: Instructions from outlining all occurrences (9) >=
+; CHECK-SAME: Unoutlined instruction count (4)
+; CHECK-SAME: (Also found at: machine-outliner-remarks.ll:13:9)
+; RUN: llc %s -enable-machine-outliner -mtriple=aarch64-unknown-unknown -o /dev/null -pass-remarks-missed=machine-outliner -pass-remarks-output=%t.yaml
+; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
+; YAML: --- !Missed
+; YAML-NEXT: Pass:            machine-outliner
+; YAML-NEXT: Name:            NotOutliningCheaper
+; YAML-NEXT: DebugLoc:        { File: machine-outliner-remarks.ll, Line: 5, Column: 9 }
+; YAML-NEXT: Function:        dog
+; YAML-NEXT: Args:            
+; YAML-NEXT:   - String:          'Did not outline '
+; YAML-NEXT:   - Length:          '2'
+; YAML-NEXT:   - String:          ' instructions'
+; YAML-NEXT:   - String:          ' from '
+; YAML-NEXT:   - NumOccurrences:  '2'
+; YAML-NEXT:   - String:          ' locations.'
+; YAML-NEXT:   - String:          ' Instructions from outlining all occurrences ('
+; YAML-NEXT:   - OutliningCost:   '9'
+; YAML-NEXT:   - String:          ')'
+; YAML-NEXT:   - String:          ' >= Unoutlined instruction count ('
+; YAML-NEXT:   - NotOutliningCost: '4'
+; YAML-NEXT:   - String:          ')'
+; YAML-NEXT:   - String:          ' (Also found at: '
+; YAML-NEXT:   - OtherStartLoc1:  'machine-outliner-remarks.ll:13:9'
+; YAML-NEXT:     DebugLoc:        { File: machine-outliner-remarks.ll, Line: 13, Column: 9 }
+; YAML-NEXT:   - String:          ')'
+
+define void @dog() #0 !dbg !8 {
+entry:
+  %x = alloca i32, align 4
+  %y = alloca i32, align 4
+  store i32 0, i32* %x, align 4, !dbg !11
+  store i32 1, i32* %y, align 4, !dbg !12
+  ret void, !dbg !13
+}
+
+define void @cat() #0 !dbg !14 {
+entry:
+  %x = alloca i32, align 4
+  %y = alloca i32, align 4
+  store i32 0, i32* %x, align 4, !dbg !15
+  store i32 1, i32* %y, align 4, !dbg !16
+  ret void, !dbg !17
+}
+
+attributes #0 = { noredzone nounwind ssp uwtable "no-frame-pointer-elim"="false" "target-cpu"="cyclone" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "machine-outliner-remarks.ll", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 7, !"PIC Level", i32 2}
+!7 = !{!""}
+!8 = distinct !DISubprogram(name: "dog", scope: !1, file: !1, line: 2, type: !9, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!9 = !DISubroutineType(types: !10)
+!10 = !{null}
+!11 = !DILocation(line: 4, column: 9, scope: !8)
+!12 = !DILocation(line: 5, column: 9, scope: !8)
+!13 = !DILocation(line: 6, column: 1, scope: !8)
+!14 = distinct !DISubprogram(name: "cat", scope: !1, file: !1, line: 10, type: !9, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
+!15 = !DILocation(line: 12, column: 9, scope: !14)
+!16 = !DILocation(line: 13, column: 9, scope: !14)
+!17 = !DILocation(line: 14, column: 1, scope: !14)