Skip to content

Commit

Permalink
[CGSCC] Add -abort-on-max-devirt-iterations-reached option
Browse files Browse the repository at this point in the history
Aborts if we hit the max devirtualization iteration.
Will be useful for testing that changes to devirtualization don't cause
devirtualization to repeat passes more times than necessary.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D89519
  • Loading branch information
aeubanks committed Oct 16, 2020
1 parent f2897b8 commit faf5210
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
5 changes: 5 additions & 0 deletions llvm/include/llvm/Analysis/CGSCCPassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,10 @@ createCGSCCToFunctionPassAdaptor(FunctionPassT Pass) {
return CGSCCToFunctionPassAdaptor<FunctionPassT>(std::move(Pass));
}

/// Checks -abort-on-max-devirt-iterations-reached to see if we should report an
/// error.
void maxDevirtIterationsReached();

/// A helper that repeats an SCC pass each time an indirect call is refined to
/// a direct call by that pass.
///
Expand Down Expand Up @@ -711,6 +715,7 @@ class DevirtSCCRepeatedPass

// Otherwise, if we've already hit our max, we're done.
if (Iteration >= MaxIterations) {
maxDevirtIterationsReached();
LLVM_DEBUG(
dbgs() << "Found another devirtualization after hitting the max "
"number of repetitions ("
Expand Down
14 changes: 13 additions & 1 deletion llvm/lib/Analysis/CGSCCPassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PassManagerImpl.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <iterator>
Expand All @@ -36,6 +38,11 @@ using namespace llvm;
// template typedefs.
namespace llvm {

static cl::opt<bool> AbortOnMaxDevirtIterationsReached(
"abort-on-max-devirt-iterations-reached",
cl::desc("Abort when the max iterations for devirtualization CGSCC repeat "
"pass is reached"));

// Explicit instantiations for the core proxy templates.
template class AllAnalysesOn<LazyCallGraph::SCC>;
template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
Expand Down Expand Up @@ -362,6 +369,11 @@ static void updateNewSCCFunctionAnalyses(LazyCallGraph::SCC &C,
}
}

void llvm::maxDevirtIterationsReached() {
if (AbortOnMaxDevirtIterationsReached)
report_fatal_error("Max devirtualization iterations reached");
}

/// Helper function to update both the \c CGSCCAnalysisManager \p AM and the \c
/// CGSCCPassManager's \c CGSCCUpdateResult \p UR based on a range of newly
/// added SCCs.
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/Other/cgscc-devirt-iteration.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(devirt<1>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER1
; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(devirt<2>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2
;
; RUN: not --crash opt -abort-on-max-devirt-iterations-reached -aa-pipeline=basic-aa -passes='cgscc(devirt<1>(function-attrs,function(gvn,instcombine)))' -S < %s
; RUN: opt -abort-on-max-devirt-iterations-reached -aa-pipeline=basic-aa -passes='cgscc(devirt<2>(function-attrs,function(gvn,instcombine)))' -S < %s
;
; We also verify that the real O2 pipeline catches these cases.
; RUN: opt -aa-pipeline=basic-aa -passes='default<O2>' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2

Expand Down

0 comments on commit faf5210

Please sign in to comment.