Skip to content

Commit

Permalink
[GVN] Basic optimization remark support
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
anemet committed Dec 1, 2016
1 parent d9c0875 commit d53651a
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
1 change: 1 addition & 0 deletions include/llvm/IR/DiagnosticInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase {

explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
Argument(StringRef Key, Value *V);
Argument(StringRef Key, Type *T);
Argument(StringRef Key, int N);
Argument(StringRef Key, unsigned N);
Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
Expand Down
5 changes: 4 additions & 1 deletion include/llvm/Transforms/Scalar/GVN.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "llvm/IR/PassManager.h"

namespace llvm {
class OptimizationRemarkEmitter;

/// A private "module" namespace for types and utilities used by GVN. These
/// are implementation details and should not be used by clients.
Expand Down Expand Up @@ -110,6 +111,7 @@ class GVN : public PassInfoMixin<GVN> {
const TargetLibraryInfo *TLI;
AssumptionCache *AC;
SetVector<BasicBlock *> DeadBlocks;
OptimizationRemarkEmitter *ORE;

ValueTable VN;

Expand All @@ -135,7 +137,8 @@ class GVN : public PassInfoMixin<GVN> {

bool runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
MemoryDependenceResults *RunMD, LoopInfo *LI);
MemoryDependenceResults *RunMD, LoopInfo *LI,
OptimizationRemarkEmitter *ORE);

/// Push a new Value to the LeaderTable onto the list for its value number.
void addToLeaderTable(uint32_t N, Value *V, const BasicBlock *BB) {
Expand Down
6 changes: 6 additions & 0 deletions lib/IR/DiagnosticInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Value *V)
DLoc = I->getDebugLoc();
}

DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, Type *T)
: Key(Key) {
raw_string_ostream OS(Val);
OS << *T;
}

DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
: Key(Key), Val(itostr(N)) {}

Expand Down
23 changes: 20 additions & 3 deletions lib/Transforms/Scalar/GVN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/Analysis/PHITransAddr.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
Expand Down Expand Up @@ -587,7 +588,8 @@ PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
auto &AA = AM.getResult<AAManager>(F);
auto &MemDep = AM.getResult<MemoryDependenceAnalysis>(F);
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI, &ORE);
if (!Changed)
return PreservedAnalyses::all();
PreservedAnalyses PA;
Expand Down Expand Up @@ -1583,10 +1585,18 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock,
if (V->getType()->getScalarType()->isPointerTy())
MD->invalidateCachedPointerInfo(V);
markInstructionForDeletion(LI);
ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadPRE", LI)
<< "load eliminated by PRE");
++NumPRELoad;
return true;
}

static void reportLoadElim(LoadInst *LI, OptimizationRemarkEmitter *ORE) {
ORE->emit(OptimizationRemark(DEBUG_TYPE, "LoadElim", LI)
<< "load of type " << ore::NV("Type", LI->getType())
<< " eliminated");
}

/// Attempt to eliminate a load whose dependencies are
/// non-local by performing PHI construction.
bool GVN::processNonLocalLoad(LoadInst *LI) {
Expand Down Expand Up @@ -1657,6 +1667,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
MD->invalidateCachedPointerInfo(V);
markInstructionForDeletion(LI);
++NumGVNLoad;
reportLoadElim(LI, ORE);
return true;
}

Expand Down Expand Up @@ -1803,6 +1814,7 @@ bool GVN::processLoad(LoadInst *L) {
patchAndReplaceAllUsesWith(L, AvailableValue);
markInstructionForDeletion(L);
++NumGVNLoad;
reportLoadElim(L, ORE);
// Tell MDA to rexamine the reused pointer since we might have more
// information after forwarding it.
if (MD && AvailableValue->getType()->getScalarType()->isPointerTy())
Expand Down Expand Up @@ -2180,14 +2192,16 @@ bool GVN::processInstruction(Instruction *I) {
/// runOnFunction - This is the main transformation entry point for a function.
bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
MemoryDependenceResults *RunMD, LoopInfo *LI) {
MemoryDependenceResults *RunMD, LoopInfo *LI,
OptimizationRemarkEmitter *RunORE) {
AC = &RunAC;
DT = &RunDT;
VN.setDomTree(DT);
TLI = &RunTLI;
VN.setAliasAnalysis(&RunAA);
MD = RunMD;
VN.setMemDep(MD);
ORE = RunORE;

bool Changed = false;
bool ShouldContinue = true;
Expand Down Expand Up @@ -2703,7 +2717,8 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
getAnalysis<AAResultsWrapperPass>().getAAResults(),
NoLoads ? nullptr
: &getAnalysis<MemoryDependenceWrapperPass>().getMemDep(),
LIWP ? &LIWP->getLoopInfo() : nullptr);
LIWP ? &LIWP->getLoopInfo() : nullptr,
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE());
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
Expand All @@ -2716,6 +2731,7 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {

AU.addPreserved<DominatorTreeWrapperPass>();
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
}

private:
Expand All @@ -2737,4 +2753,5 @@ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
59 changes: 59 additions & 0 deletions test/Transforms/GVN/opt-remarks.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
; RUN: opt < %s -gvn -o /dev/null -pass-remarks-output=%t -S -pass-remarks=gvn \
; RUN: 2>&1 | FileCheck %s
; RUN: cat %t | FileCheck -check-prefix=YAML %s

; CHECK: remark: <unknown>:0:0: load of type i32 eliminated{{$}}
; CHECK-NEXT: remark: <unknown>:0:0: load of type i32 eliminated{{$}}
; CHECK-NEXT: remark: <unknown>:0:0: load of type i32 eliminated{{$}}
; CHECK-NOT: remark:

; YAML: --- !Passed
; YAML-NEXT: Pass: gvn
; YAML-NEXT: Name: LoadElim
; YAML-NEXT: Function: arg
; YAML-NEXT: Args:
; YAML-NEXT: - String: 'load of type '
; YAML-NEXT: - Type: i32
; YAML-NEXT: - String: ' eliminated'
; YAML-NEXT: ...
; YAML-NEXT: --- !Passed
; YAML-NEXT: Pass: gvn
; YAML-NEXT: Name: LoadElim
; YAML-NEXT: Function: const
; YAML-NEXT: Args:
; YAML-NEXT: - String: 'load of type '
; YAML-NEXT: - Type: i32
; YAML-NEXT: - String: ' eliminated'
; YAML-NEXT: ...
; YAML-NEXT: --- !Passed
; YAML-NEXT: Pass: gvn
; YAML-NEXT: Name: LoadElim
; YAML-NEXT: Function: inst
; YAML-NEXT: Args:
; YAML-NEXT: - String: 'load of type '
; YAML-NEXT: - Type: i32
; YAML-NEXT: - String: ' eliminated'
; YAML-NEXT: ...


define i32 @arg(i32* %p, i32 %i) {
entry:
store i32 %i, i32* %p
%load = load i32, i32* %p
ret i32 %load
}

define i32 @const(i32* %p) {
entry:
store i32 4, i32* %p
%load = load i32, i32* %p
ret i32 %load
}

define i32 @inst(i32* %p) {
entry:
%load1 = load i32, i32* %p
%load = load i32, i32* %p
%add = add i32 %load1, %load
ret i32 %add
}

0 comments on commit d53651a

Please sign in to comment.