From: Daniel Dunbar Date: Tue, 10 Nov 2009 19:51:53 +0000 (+0000) Subject: clang-cc: Start moving "pure" option handling to Options.cpp, to separate it X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0498cfc445b21bc2946591825b207e8ef548d10d;p=clang clang-cc: Start moving "pure" option handling to Options.cpp, to separate it from the logic part of clang-cc, and to enforce limited scoping. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86711 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/clang-cc/Options.cpp b/tools/clang-cc/Options.cpp new file mode 100644 index 0000000000..582bddb488 --- /dev/null +++ b/tools/clang-cc/Options.cpp @@ -0,0 +1,156 @@ +//===--- Options.cpp - clang-cc Option Handling ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This file contains "pure" option handling, it is only responsible for turning +// the options into internal *Option classes, but shouldn't have any other +// logic. + +#include "Options.h" +#include "clang/Frontend/CompileOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/CommandLine.h" + +using namespace clang; + +//===----------------------------------------------------------------------===// +// Code Generation Options +//===----------------------------------------------------------------------===// + +namespace codegenoptions { + +static llvm::cl::opt +DisableLLVMOptimizations("disable-llvm-optzns", + llvm::cl::desc("Don't run LLVM optimization passes")); + +static llvm::cl::opt +DisableRedZone("disable-red-zone", + llvm::cl::desc("Do not emit code that uses the red zone."), + llvm::cl::init(false)); + +static llvm::cl::opt +GenerateDebugInfo("g", + llvm::cl::desc("Generate source level debug information")); + +static llvm::cl::opt +NoCommon("fno-common", + llvm::cl::desc("Compile common globals like normal definitions"), + llvm::cl::ValueDisallowed); + +static llvm::cl::opt +NoImplicitFloat("no-implicit-float", + llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)"), + llvm::cl::init(false)); + +static llvm::cl::opt +NoMergeConstants("fno-merge-all-constants", + llvm::cl::desc("Disallow merging of constants.")); + +// It might be nice to add bounds to the CommandLine library directly. +struct OptLevelParser : public llvm::cl::parser { + bool parse(llvm::cl::Option &O, llvm::StringRef ArgName, + llvm::StringRef Arg, unsigned &Val) { + if (llvm::cl::parser::parse(O, ArgName, Arg, Val)) + return true; + if (Val > 3) + return O.error("'" + Arg + "' invalid optimization level!"); + return false; + } +}; +static llvm::cl::opt +OptLevel("O", llvm::cl::Prefix, + llvm::cl::desc("Optimization level"), + llvm::cl::init(0)); + +static llvm::cl::opt +OptSize("Os", llvm::cl::desc("Optimize for size")); + +static llvm::cl::opt +TargetCPU("mcpu", + llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)")); + +static llvm::cl::list +TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); + +} + +//===----------------------------------------------------------------------===// +// Option Object Construction +//===----------------------------------------------------------------------===// + +/// ComputeTargetFeatures - Recompute the target feature list to only +/// be the list of things that are enabled, based on the target cpu +/// and feature list. +void clang::ComputeFeatureMap(TargetInfo &Target, + llvm::StringMap &Features) { + using namespace codegenoptions; + assert(Features.empty() && "invalid map"); + + // Initialize the feature map based on the target. + Target.getDefaultFeatures(TargetCPU, Features); + + // Apply the user specified deltas. + for (llvm::cl::list::iterator it = TargetFeatures.begin(), + ie = TargetFeatures.end(); it != ie; ++it) { + const char *Name = it->c_str(); + + // FIXME: Don't handle errors like this. + if (Name[0] != '-' && Name[0] != '+') { + fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n", + Name); + exit(1); + } + if (!Target.setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) { + fprintf(stderr, "error: clang-cc: invalid target feature name: %s\n", + Name + 1); + exit(1); + } + } +} + +void clang::InitializeCompileOptions(CompileOptions &Opts, + const llvm::StringMap &Features) { + using namespace codegenoptions; + Opts.OptimizeSize = OptSize; + Opts.DebugInfo = GenerateDebugInfo; + Opts.DisableLLVMOpts = DisableLLVMOptimizations; + + // -Os implies -O2 + Opts.OptimizationLevel = OptSize ? 2 : OptLevel; + + // We must always run at least the always inlining pass. + Opts.Inlining = (Opts.OptimizationLevel > 1) ? CompileOptions::NormalInlining + : CompileOptions::OnlyAlwaysInlining; + + Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize); + Opts.SimplifyLibCalls = 1; + +#ifdef NDEBUG + Opts.VerifyModule = 0; +#endif + + Opts.CPU = TargetCPU; + Opts.Features.clear(); + for (llvm::StringMap::const_iterator it = Features.begin(), + ie = Features.end(); it != ie; ++it) { + // FIXME: If we are completely confident that we have the right set, we only + // need to pass the minuses. + std::string Name(it->second ? "+" : "-"); + Name += it->first(); + Opts.Features.push_back(Name); + } + + Opts.NoCommon = NoCommon; + + Opts.DisableRedZone = DisableRedZone; + Opts.NoImplicitFloat = NoImplicitFloat; + + Opts.MergeAllConstants = !NoMergeConstants; +} diff --git a/tools/clang-cc/Options.h b/tools/clang-cc/Options.h new file mode 100644 index 0000000000..088029f4ad --- /dev/null +++ b/tools/clang-cc/Options.h @@ -0,0 +1,28 @@ +//===-- Options.h - clang-cc Option Handling --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANGCC_OPTIONS_H +#define LLVM_CLANGCC_OPTIONS_H + +#include "llvm/ADT/StringMap.h" + +namespace clang { + +class CompileOptions; +class LangOptions; +class TargetInfo; + +void ComputeFeatureMap(TargetInfo &Target, llvm::StringMap &Features); + +void InitializeCompileOptions(CompileOptions &Opts, + const llvm::StringMap &Features); + +} // end namespace clang + +#endif diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index f8ad8bac39..f08c768be3 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -15,11 +15,11 @@ // //===----------------------------------------------------------------------===// +#include "Options.h" #include "clang/Frontend/AnalysisConsumer.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/CompileOptions.h" #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Frontend/FixItRewriter.h" #include "clang/Frontend/FrontendDiagnostic.h" @@ -616,10 +616,6 @@ static llvm::cl::opt DollarsInIdents("fdollars-in-identifiers", llvm::cl::desc("Allow '$' in identifiers")); -static llvm::cl::opt -DisableLLVMOptimizations("disable-llvm-optzns", - llvm::cl::desc("Don't run LLVM optimization passes")); - static llvm::cl::opt MainFileName("main-file-name", llvm::cl::desc("Main file name to use for debug info")); @@ -815,8 +811,7 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, if (EmitAllDecls) Options.EmitAllDecls = 1; - // The __OPTIMIZE_SIZE__ define is tied to -Oz, which we don't - // support. + // The __OPTIMIZE_SIZE__ define is tied to -Oz, which we don't support. Options.OptimizeSize = 0; Options.Optimize = !!CompileOpts.OptimizationLevel; @@ -1211,145 +1206,6 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA) { delete PA; } -//===----------------------------------------------------------------------===// -// Code generation options -//===----------------------------------------------------------------------===// - -namespace codegenoptions { - - -static llvm::cl::opt -DisableRedZone("disable-red-zone", - llvm::cl::desc("Do not emit code that uses the red zone."), - llvm::cl::init(false)); - -static llvm::cl::opt -GenerateDebugInfo("g", - llvm::cl::desc("Generate source level debug information")); - -static llvm::cl::opt -NoCommon("fno-common", - llvm::cl::desc("Compile common globals like normal definitions"), - llvm::cl::ValueDisallowed); - -static llvm::cl::opt -NoImplicitFloat("no-implicit-float", - llvm::cl::desc("Don't generate implicit floating point instructions (x86-only)"), - llvm::cl::init(false)); - -static llvm::cl::opt -NoMergeConstants("fno-merge-all-constants", - llvm::cl::desc("Disallow merging of constants.")); - -// It might be nice to add bounds to the CommandLine library directly. -struct OptLevelParser : public llvm::cl::parser { - bool parse(llvm::cl::Option &O, llvm::StringRef ArgName, - llvm::StringRef Arg, unsigned &Val) { - if (llvm::cl::parser::parse(O, ArgName, Arg, Val)) - return true; - if (Val > 3) - return O.error("'" + Arg + "' invalid optimization level!"); - return false; - } -}; -static llvm::cl::opt -OptLevel("O", llvm::cl::Prefix, - llvm::cl::desc("Optimization level"), - llvm::cl::init(0)); - -static llvm::cl::opt -OptSize("Os", llvm::cl::desc("Optimize for size")); - -static llvm::cl::opt -TargetCPU("mcpu", - llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)")); - -static llvm::cl::list -TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); - -} - -/// ComputeTargetFeatures - Recompute the target feature list to only -/// be the list of things that are enabled, based on the target cpu -/// and feature list. -static void ComputeFeatureMap(TargetInfo &Target, - llvm::StringMap &Features) { - using namespace codegenoptions; - assert(Features.empty() && "invalid map"); - - // Initialize the feature map based on the target. - Target.getDefaultFeatures(TargetCPU, Features); - - // Apply the user specified deltas. - for (llvm::cl::list::iterator it = TargetFeatures.begin(), - ie = TargetFeatures.end(); it != ie; ++it) { - const char *Name = it->c_str(); - - // FIXME: Don't handle errors like this. - if (Name[0] != '-' && Name[0] != '+') { - fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n", - Name); - exit(1); - } - if (!Target.setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) { - fprintf(stderr, "error: clang-cc: invalid target feature name: %s\n", - Name + 1); - exit(1); - } - } -} - -static void InitializeCompileOptions(CompileOptions &Opts, - const llvm::StringMap &Features) { - using namespace codegenoptions; - Opts.OptimizeSize = OptSize; - Opts.DebugInfo = GenerateDebugInfo; - Opts.DisableLLVMOpts = DisableLLVMOptimizations; - - // -Os implies -O2 - Opts.OptimizationLevel = OptSize ? 2 : OptLevel; - - // We must always run at least the always inlining pass. - Opts.Inlining = (Opts.OptimizationLevel > 1) ? CompileOptions::NormalInlining - : CompileOptions::OnlyAlwaysInlining; - - Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize); - Opts.SimplifyLibCalls = 1; - -#ifdef NDEBUG - Opts.VerifyModule = 0; -#endif - - Opts.CPU = TargetCPU; - Opts.Features.clear(); - for (llvm::StringMap::const_iterator it = Features.begin(), - ie = Features.end(); it != ie; ++it) { - // FIXME: If we are completely confident that we have the right set, we only - // need to pass the minuses. - std::string Name(it->second ? "+" : "-"); - Name += it->first(); - Opts.Features.push_back(Name); - } - - Opts.NoCommon = NoCommon; - - // Handle -ftime-report. - Opts.TimePasses = TimeReport; - - Opts.DisableRedZone = DisableRedZone; - Opts.NoImplicitFloat = NoImplicitFloat; - - Opts.MergeAllConstants = !NoMergeConstants; -} - -static void FinalizeCompileOptions(CompileOptions &Opts, - const LangOptions &Lang) { - if (Lang.NoBuiltin) - Opts.SimplifyLibCalls = 0; - if (Lang.CPlusPlus) - Opts.NoCommon = 1; -} - //===----------------------------------------------------------------------===// // Fix-It Options //===----------------------------------------------------------------------===// @@ -2153,6 +2009,17 @@ static void ConstructDiagnosticOptions(DiagnosticOptions &Opts) { Opts.MessageLength = MessageLength; } +static void FinalizeCompileOptions(CompileOptions &Opts, + const LangOptions &Lang) { + if (Lang.NoBuiltin) + Opts.SimplifyLibCalls = 0; + if (Lang.CPlusPlus) + Opts.NoCommon = 1; + + // Handle -ftime-report. + Opts.TimePasses = TimeReport; +} + static void ConstructCompilerInvocation(CompilerInvocation &Opts, const char *Argv0, const DiagnosticOptions &DiagOpts, @@ -2186,7 +2053,7 @@ static void ConstructCompilerInvocation(CompilerInvocation &Opts, // Initialize the other preprocessor options. InitializePreprocessorOptions(Opts.getPreprocessorOpts()); - // Finalize, some code generation options. + // Finalize some code generation options. FinalizeCompileOptions(Opts.getCompileOpts(), Opts.getLangOpts()); }