llvm.org GIT mirror llvm / d53651a
[GVN] Basic optimization remark support [recommitting after the fix in r288307] 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@288370 91177308-0d34-0410-b5e6-96231b3b80d8 Adam Nemet 3 years ago
5 changed file(s) with 90 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") {}
2828 #include "llvm/IR/PassManager.h"
2929
3030 namespace llvm {
31 class OptimizationRemarkEmitter;
3132
3233 /// A private "module" namespace for types and utilities used by GVN. These
3334 /// are implementation details and should not be used by clients.
109110 const TargetLibraryInfo *TLI;
110111 AssumptionCache *AC;
111112 SetVector DeadBlocks;
113 OptimizationRemarkEmitter *ORE;
112114
113115 ValueTable VN;
114116
134136
135137 bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
136138 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
137 MemoryDependenceResults *RunMD, LoopInfo *LI);
139 MemoryDependenceResults *RunMD, LoopInfo *LI,
140 OptimizationRemarkEmitter *ORE);
138141
139142 /// Push a new Value to the LeaderTable onto the list for its value number.
140143 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"
586587 auto &AA = AM.getResult(F);
587588 auto &MemDep = AM.getResult(F);
588589 auto *LI = AM.getCachedResult(F);
589 bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI);
590 auto &ORE = AM.getResult(F);
591 bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI, &ORE);
590592 if (!Changed)
591593 return PreservedAnalyses::all();
592594 PreservedAnalyses PA;
15821584 if (V->getType()->getScalarType()->isPointerTy())
15831585 MD->invalidateCachedPointerInfo(V);
15841586 markInstructionForDeletion(LI);
1587 ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadPRE", LI)
1588 << "load eliminated by PRE");
15851589 ++NumPRELoad;
15861590 return true;
1591 }
1592
1593 static void reportLoadElim(LoadInst *LI, OptimizationRemarkEmitter *ORE) {
1594 ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
1595 << "load of type " << ore::NV("Type", LI->getType())
1596 << " eliminated");
15871597 }
15881598
15891599 /// Attempt to eliminate a load whose dependencies are
16561666 MD->invalidateCachedPointerInfo(V);
16571667 markInstructionForDeletion(LI);
16581668 ++NumGVNLoad;
1669 reportLoadElim(LI, ORE);
16591670 return true;
16601671 }
16611672
18021813 patchAndReplaceAllUsesWith(L, AvailableValue);
18031814 markInstructionForDeletion(L);
18041815 ++NumGVNLoad;
1816 reportLoadElim(L, ORE);
18051817 // Tell MDA to rexamine the reused pointer since we might have more
18061818 // information after forwarding it.
18071819 if (MD && AvailableValue->getType()->getScalarType()->isPointerTy())
21792191 /// runOnFunction - This is the main transformation entry point for a function.
21802192 bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
21812193 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
2182 MemoryDependenceResults *RunMD, LoopInfo *LI) {
2194 MemoryDependenceResults *RunMD, LoopInfo *LI,
2195 OptimizationRemarkEmitter *RunORE) {
21832196 AC = &RunAC;
21842197 DT = &RunDT;
21852198 VN.setDomTree(DT);
21872200 VN.setAliasAnalysis(&RunAA);
21882201 MD = RunMD;
21892202 VN.setMemDep(MD);
2203 ORE = RunORE;
21902204
21912205 bool Changed = false;
21922206 bool ShouldContinue = true;
27022716 getAnalysis().getAAResults(),
27032717 NoLoads ? nullptr
27042718 : &getAnalysis().getMemDep(),
2705 LIWP ? &LIWP->getLoopInfo() : nullptr);
2719 LIWP ? &LIWP->getLoopInfo() : nullptr,
2720 &getAnalysis().getORE());
27062721 }
27072722
27082723 void getAnalysisUsage(AnalysisUsage &AU) const override {
27152730
27162731 AU.addPreserved();
27172732 AU.addPreserved();
2733 AU.addRequired();
27182734 }
27192735
27202736 private:
27362752 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
27372753 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
27382754 INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
2755 INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
27392756 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 }