llvm.org GIT mirror llvm / ae45a93
[GVN] Basic optimization remark support [recommiting patches one-by-one to see which breaks the stage2 LTO bot] Follow-on patches will add more interesting cases. The goal of this patch-set is to get the GVN messages printed in opt-viewer from Dhrystone as was presented in my Dev Meeting talk. This is the optimization view for the function (the last remark in the function has a bug which is fixed in this series): 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#L430 Differential Revision: https://reviews.llvm.org/D26488 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288210 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 3 years ago
5 changed file(s) with 89 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
391391
392392 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
393393 Argument(StringRef Key, Value *V);
394 Argument(StringRef Key, Type *T);
394395 Argument(StringRef Key, int N);
395396 Argument(StringRef Key, unsigned N);
396397 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
2727 #include "llvm/IR/PassManager.h"
2828
2929 namespace llvm {
30 class OptimizationRemarkEmitter;
3031
3132 /// A private "module" namespace for types and utilities used by GVN. These
3233 /// are implementation details and should not be used by clients.
108109 const TargetLibraryInfo *TLI;
109110 AssumptionCache *AC;
110111 SetVector DeadBlocks;
112 OptimizationRemarkEmitter *ORE;
111113
112114 ValueTable VN;
113115
133135
134136 bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
135137 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
136 MemoryDependenceResults *RunMD);
138 MemoryDependenceResults *RunMD, OptimizationRemarkEmitter *ORE);
137139
138140 /// Push a new Value to the LeaderTable onto the list for its value number.
139141 void addToLeaderTable(uint32_t N, Value *V, const BasicBlock *BB) {
179179 DLoc = I->getDebugLoc();
180180 }
181181
182 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Type *T)
183 : Key(Key) {
184 raw_string_ostream OS(Val);
185 OS << *T;
186 }
187
182188 DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
183189 : Key(Key), Val(itostr(N)) {}
184190
3232 #include "llvm/Analysis/Loads.h"
3333 #include "llvm/Analysis/MemoryBuiltins.h"
3434 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
35 #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
3536 #include "llvm/Analysis/PHITransAddr.h"
3637 #include "llvm/Analysis/TargetLibraryInfo.h"
3738 #include "llvm/Analysis/ValueTracking.h"
585586 auto &TLI = AM.getResult(F);
586587 auto &AA = AM.getResult(F);
587588 auto &MemDep = AM.getResult(F);
588 bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep);
589 auto &ORE = AM.getResult(F);
590 bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, &ORE);
589591 if (!Changed)
590592 return PreservedAnalyses::all();
591593 PreservedAnalyses PA;
15811583 if (V->getType()->getScalarType()->isPointerTy())
15821584 MD->invalidateCachedPointerInfo(V);
15831585 markInstructionForDeletion(LI);
1586 ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadPRE", LI)
1587 << "load eliminated by PRE");
15841588 ++NumPRELoad;
15851589 return true;
1590 }
1591
1592 static void reportLoadElim(LoadInst *LI, OptimizationRemarkEmitter *ORE) {
1593 ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
1594 << "load of type " << ore::NV("Type", LI->getType())
1595 << " eliminated");
15861596 }
15871597
15881598 /// Attempt to eliminate a load whose dependencies are
16551665 MD->invalidateCachedPointerInfo(V);
16561666 markInstructionForDeletion(LI);
16571667 ++NumGVNLoad;
1668 reportLoadElim(LI, ORE);
16581669 return true;
16591670 }
16601671
18011812 patchAndReplaceAllUsesWith(L, AvailableValue);
18021813 markInstructionForDeletion(L);
18031814 ++NumGVNLoad;
1815 reportLoadElim(L, ORE);
18041816 // Tell MDA to rexamine the reused pointer since we might have more
18051817 // information after forwarding it.
18061818 if (MD && AvailableValue->getType()->getScalarType()->isPointerTy())
21782190 /// runOnFunction - This is the main transformation entry point for a function.
21792191 bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
21802192 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
2181 MemoryDependenceResults *RunMD) {
2193 MemoryDependenceResults *RunMD,
2194 OptimizationRemarkEmitter *RunORE) {
21822195 AC = &RunAC;
21832196 DT = &RunDT;
21842197 VN.setDomTree(DT);
21862199 VN.setAliasAnalysis(&RunAA);
21872200 MD = RunMD;
21882201 VN.setMemDep(MD);
2202 ORE = RunORE;
21892203
21902204 bool Changed = false;
21912205 bool ShouldContinue = true;
26982712 getAnalysis().getTLI(),
26992713 getAnalysis().getAAResults(),
27002714 NoLoads ? nullptr
2701 : &getAnalysis().getMemDep());
2715 : &getAnalysis().getMemDep(),
2716 &getAnalysis().getORE());
27022717 }
27032718
27042719 void getAnalysisUsage(AnalysisUsage &AU) const override {
27112726
27122727 AU.addPreserved();
27132728 AU.addPreserved();
2729 AU.addRequired();
27142730 }
27152731
27162732 private:
27322748 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
27332749 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
27342750 INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
2751 INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
27352752 INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
0 ; RUN: opt < %s -gvn -o /dev/null -pass-remarks-output=%t -S -pass-remarks=gvn \
1 ; RUN: 2>&1 | FileCheck %s
2 ; RUN: cat %t | FileCheck -check-prefix=YAML %s
3
4 ; CHECK: remark: :0:0: load of type i32 eliminated{{$}}
5 ; CHECK-NEXT: remark: :0:0: load of type i32 eliminated{{$}}
6 ; CHECK-NEXT: remark: :0:0: load of type i32 eliminated{{$}}
7 ; CHECK-NOT: remark:
8
9 ; YAML: --- !Passed
10 ; YAML-NEXT: Pass: gvn
11 ; YAML-NEXT: Name: LoadElim
12 ; YAML-NEXT: Function: arg
13 ; YAML-NEXT: Args:
14 ; YAML-NEXT: - String: 'load of type '
15 ; YAML-NEXT: - Type: i32
16 ; YAML-NEXT: - String: ' eliminated'
17 ; YAML-NEXT: ...
18 ; YAML-NEXT: --- !Passed
19 ; YAML-NEXT: Pass: gvn
20 ; YAML-NEXT: Name: LoadElim
21 ; YAML-NEXT: Function: const
22 ; YAML-NEXT: Args:
23 ; YAML-NEXT: - String: 'load of type '
24 ; YAML-NEXT: - Type: i32
25 ; YAML-NEXT: - String: ' eliminated'
26 ; YAML-NEXT: ...
27 ; YAML-NEXT: --- !Passed
28 ; YAML-NEXT: Pass: gvn
29 ; YAML-NEXT: Name: LoadElim
30 ; YAML-NEXT: Function: inst
31 ; YAML-NEXT: Args:
32 ; YAML-NEXT: - String: 'load of type '
33 ; YAML-NEXT: - Type: i32
34 ; YAML-NEXT: - String: ' eliminated'
35 ; YAML-NEXT: ...
36
37
38 define i32 @arg(i32* %p, i32 %i) {
39 entry:
40 store i32 %i, i32* %p
41 %load = load i32, i32* %p
42 ret i32 %load
43 }
44
45 define i32 @const(i32* %p) {
46 entry:
47 store i32 4, i32* %p
48 %load = load i32, i32* %p
49 ret i32 %load
50 }
51
52 define i32 @inst(i32* %p) {
53 entry:
54 %load1 = load i32, i32* %p
55 %load = load i32, i32* %p
56 %add = add i32 %load1, %load
57 ret i32 %add
58 }