llvm.org GIT mirror llvm / 36dece4
[GVN, OptDiag] Print the interesting instructions involved in missed load-elimination [recommitting after the fix in r288307] This includes the intervening store and the load/store that we're trying to forward from in the optimization remark for the missed load elimination. This is hooked up under a new mode in ORE that allows for compile-time budget for a bit more analysis to print more insightful messages. This mode is currently enabled for -fsave-optimization-record (-Rpass is trickier since it is controlled in the front-end). With this we can now print the red remark in http://lab.llvm.org:8080/artifacts/opt-view_test-suite/build/SingleSource/Benchmarks/Dhrystone/CMakeFiles/dry.dir/html/_org_test-suite_SingleSource_Benchmarks_Dhrystone_dry.c.html#L446 Differential Revision: https://reviews.llvm.org/D26490 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288381 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 3 years ago
3 changed file(s) with 94 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1717 #include "llvm/ADT/Optional.h"
1818 #include "llvm/Analysis/BlockFrequencyInfo.h"
1919 #include "llvm/IR/DiagnosticInfo.h"
20 #include "llvm/IR/Function.h"
2021 #include "llvm/IR/PassManager.h"
2122 #include "llvm/Pass.h"
2223
2324 namespace llvm {
2425 class DebugLoc;
25 class Function;
2626 class LLVMContext;
2727 class Loop;
2828 class Pass;
193193 void emitOptimizationRemarkAnalysisAliasing(const char *PassName, Loop *L,
194194 const Twine &Msg);
195195
196 /// \brief Whether we allow for extra compile-time budget to perform more
197 /// analysis to produce fewer false positives.
198 ///
199 /// This is useful when reporting missed optimizations. In this case we can
200 /// use the extra analysis (1) to filter trivial false positives or (2) to
201 /// provide more context so that non-trivial false positives can be quickly
202 /// detected by the user.
203 bool allowExtraAnalysis() const {
204 // For now, only allow this with -fsave-optimization-record since the -Rpass
205 // options are handled in the front-end.
206 return F->getContext().getDiagnosticsOutputFile();
207 }
208
196209 private:
197210 Function *F;
198211
12081208 return false;
12091209 }
12101210
1211 /// \brief Try to locate the three instruction involved in a missed
1212 /// load-elimination case that is due to an intervening store.
1213 static void reportMayClobberedLoad(LoadInst *LI, MemDepResult DepInfo,
1214 DominatorTree *DT,
1215 OptimizationRemarkEmitter *ORE) {
1216 using namespace ore;
1217 User *OtherAccess = nullptr;
1218
1219 OptimizationRemarkMissed R(DEBUG_TYPE, "LoadClobbered", LI);
1220 R << "load of type " << NV("Type", LI->getType()) << " not eliminated"
1221 << setExtraArgs();
1222
1223 for (auto *U : LI->getPointerOperand()->users())
1224 if (U != LI && (isa(U) || isa(U)) &&
1225 DT->dominates(cast(U), LI)) {
1226 // FIXME: for now give up if there are multiple memory accesses that
1227 // dominate the load. We need further analysis to decide which one is
1228 // that we're forwarding from.
1229 if (OtherAccess)
1230 OtherAccess = nullptr;
1231 else
1232 OtherAccess = U;
1233 }
1234
1235 if (OtherAccess)
1236 R << " in favor of " << NV("OtherAccess", OtherAccess);
1237
1238 R << " because it is clobbered by " << NV("ClobberedBy", DepInfo.getInst());
1239
1240 ORE->emit(R);
1241 }
1242
12111243 bool GVN::AnalyzeLoadAvailability(LoadInst *LI, MemDepResult DepInfo,
12121244 Value *Address, AvailableValue &Res) {
12131245
12721304 Instruction *I = DepInfo.getInst();
12731305 dbgs() << " is clobbered by " << *I << '\n';
12741306 );
1307
1308 if (ORE->allowExtraAnalysis())
1309 reportMayClobberedLoad(LI, DepInfo, DT, ORE);
1310
12751311 return false;
12761312 }
12771313 assert(DepInfo.isDef() && "follows from above");
3939 ; YAML-NEXT: - String: ' in favor of '
4040 ; YAML-NEXT: - InfavorOfValue: load
4141 ; YAML-NEXT: ...
42
42 ; YAML-NEXT: --- !Missed
43 ; YAML-NEXT: Pass: gvn
44 ; YAML-NEXT: Name: LoadClobbered
45 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 3, Column: 3 }
46 ; YAML-NEXT: Function: may_alias
47 ; YAML-NEXT: Args:
48 ; YAML-NEXT: - String: 'load of type '
49 ; YAML-NEXT: - Type: i32
50 ; YAML-NEXT: - String: ' not eliminated'
51 ; YAML-NEXT: - String: ' in favor of '
52 ; YAML-NEXT: - OtherAccess: load
53 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 1, Column: 13 }
54 ; YAML-NEXT: - String: ' because it is clobbered by '
55 ; YAML-NEXT: - ClobberedBy: store
56 ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 2, Column: 10 }
57 ; YAML-NEXT: ...
4358
4459 define i32 @arg(i32* %p, i32 %i) {
4560 entry:
6277 %add = add i32 %load1, %load
6378 ret i32 %add
6479 }
80
81 define i32 @may_alias(i32* %p, i32* %r) !dbg !7 {
82 entry:
83 %load1 = load i32, i32* %p, !tbaa !13, !dbg !9
84 store i32 4, i32* %r, !tbaa !13, !dbg !10
85 %load = load i32, i32* %p, !tbaa !13, !dbg !11
86 %add = add i32 %load1, %load
87 ret i32 %add
88 }
89 !llvm.dbg.cu = !{!0}
90 !llvm.module.flags = !{!3, !4, !5}
91 !llvm.ident = !{!6}
92
93 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 4.0.0 (trunk 282540) (llvm/trunk 282542)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2)
94 !1 = !DIFile(filename: "/tmp/s.c", directory: "/tmp")
95 !2 = !{}
96 !3 = !{i32 2, !"Dwarf Version", i32 4}
97 !4 = !{i32 2, !"Debug Info Version", i32 3}
98 !5 = !{i32 1, !"PIC Level", i32 2}
99 !6 = !{!"clang version 4.0.0 (trunk 282540) (llvm/trunk 282542)"}
100 !7 = distinct !DISubprogram(name: "may_alias", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, variables: !2)
101 !8 = !DISubroutineType(types: !2)
102 !9 = !DILocation(line: 1, column: 13, scope: !7)
103 !10 = !DILocation(line: 2, column: 10, scope: !7)
104 !11 = !DILocation(line: 3, column: 3, scope: !7)
105
106 !12 = !{ !"tbaa root" }
107 !13 = !{ !"int", !12 }