Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions clang/include/clang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
DiagnosticsEngine *Diags = nullptr,
bool DefaultDiagColor = true);

unsigned getOptimizationLevel(llvm::opt::ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags);

unsigned getOptimizationLevelSize(llvm::opt::ArgList &Args);

/// The base class of CompilerInvocation. It keeps individual option objects
/// behind reference-counted pointers, which is useful for clients that want to
/// keep select option objects alive (even after CompilerInvocation gets
Expand Down
113 changes: 56 additions & 57 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,52 +703,6 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
// Deserialization (from args)
//===----------------------------------------------------------------------===//

static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
unsigned DefaultOpt = 0;
if ((IK.getLanguage() == Language::OpenCL ||
IK.getLanguage() == Language::OpenCLCXX) &&
!Args.hasArg(OPT_cl_opt_disable))
DefaultOpt = 2;

if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O0))
return 0;

if (A->getOption().matches(options::OPT_Ofast))
return 3;

assert(A->getOption().matches(options::OPT_O));

StringRef S(A->getValue());
if (S == "s" || S == "z")
return 2;

if (S == "g")
return 1;

return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
}

return DefaultOpt;
}

static unsigned getOptimizationLevelSize(ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O)) {
switch (A->getValue()[0]) {
default:
return 0;
case 's':
return 1;
case 'z':
return 2;
}
}
}
return 0;
}

static void GenerateArg(ArgumentConsumer Consumer,
llvm::opt::OptSpecifier OptSpecifier) {
Option Opt = getDriverOptTable().getOption(OptSpecifier);
Expand Down Expand Up @@ -1859,17 +1813,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
const LangOptions &LangOptsRef) {
unsigned NumErrorsBefore = Diags.getNumErrors();

unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
// TODO: This could be done in Driver
unsigned MaxOptLevel = 3;
if (OptimizationLevel > MaxOptLevel) {
// If the optimization level is not supported, fall back on the default
// optimization
Diags.Report(diag::warn_drv_optimization_value)
<< Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
OptimizationLevel = MaxOptLevel;
}
Opts.OptimizationLevel = OptimizationLevel;
Opts.OptimizationLevel = getOptimizationLevel(Args, IK, Diags);

// The key paths of codegen options defined in Options.td start with
// "CodeGenOpts.". Let's provide the expected variable name and type.
Expand Down Expand Up @@ -2728,6 +2672,61 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
return Diags->getNumErrors() == NumErrorsBefore;
}

unsigned clang::getOptimizationLevel(ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
unsigned DefaultOpt = 0;
if ((IK.getLanguage() == Language::OpenCL ||
IK.getLanguage() == Language::OpenCLCXX) &&
!Args.hasArg(OPT_cl_opt_disable))
DefaultOpt = 2;

if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O0))
return 0;

if (A->getOption().matches(options::OPT_Ofast))
return 3;

assert(A->getOption().matches(options::OPT_O));

StringRef S(A->getValue());
if (S == "s" || S == "z")
return 2;

if (S == "g")
return 1;

DefaultOpt = getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
}

unsigned MaxOptLevel = 3;
if (DefaultOpt > MaxOptLevel) {
// If the optimization level is not supported, fall back on the default
// optimization
Diags.Report(diag::warn_drv_optimization_value)
<< Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
DefaultOpt = MaxOptLevel;
}

return DefaultOpt;
}

unsigned clang::getOptimizationLevelSize(ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
if (A->getOption().matches(options::OPT_O)) {
switch (A->getValue()[0]) {
default:
return 0;
case 's':
return 1;
case 'z':
return 2;
}
}
}
return 0;
}

/// Parse the argument to the -ftest-module-file-extension
/// command-line argument.
///
Expand Down