return false;
}
- /// HandleTargetOptions - Perform initialization based on the user
- /// configured set of features.
- virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features) {
+ /// HandleTargetOptions - Perform initialization based on the user configured
+ /// set of features (e.g., +sse4). The list is guaranteed to have at most one
+ /// entry per feature.
+ virtual void HandleTargetFeatures(const std::vector<std::string> &Features) {
}
// getRegParmMax - Returns maximal number of args passed in registers.
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCSectionMachO.h"
using namespace clang;
bool Enabled) const;
virtual void getDefaultFeatures(const std::string &CPU,
llvm::StringMap<bool> &Features) const;
- virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
+ virtual void HandleTargetFeatures(const std::vector<std::string> &Features);
};
void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
/// HandleTargetOptions - Perform initialization based on the user
/// configured set of features.
-void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
- if (Features.lookup("sse42"))
- SSELevel = SSE42;
- else if (Features.lookup("sse41"))
- SSELevel = SSE41;
- else if (Features.lookup("ssse3"))
- SSELevel = SSSE3;
- else if (Features.lookup("sse3"))
- SSELevel = SSE3;
- else if (Features.lookup("sse2"))
- SSELevel = SSE2;
- else if (Features.lookup("sse"))
- SSELevel = SSE1;
- else if (Features.lookup("mmx"))
- SSELevel = MMX;
+void
+X86TargetInfo::HandleTargetFeatures(const std::vector<std::string> &Features) {
+ // Remember the maximum enabled sselevel.
+ for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
+ // Ignore disabled features.
+ if (Features[i][0] == '-')
+ continue;
+
+ assert(Features[i][0] == '+' && "Invalid target feature!");
+ X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Features[i].substr(1))
+ .Case("sse42", SSE42)
+ .Case("sse41", SSE41)
+ .Case("ssse3", SSSE3)
+ .Case("sse2", SSE2)
+ .Case("sse", SSE1)
+ .Case("mmx", MMX)
+ .Default(NoMMXSSE);
+ SSELevel = std::max(SSELevel, Level);
+ }
}
/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
// 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<bool> &Features) {
+void clang::InitializeCompileOptions(CompileOptions &Opts,
+ const TargetInfo &Target) {
using namespace codegenoptions;
- assert(Features.empty() && "invalid map");
- // Initialize the feature map based on the target.
+ // Compute the target features, we need the target to handle this because
+ // features may have dependencies on one another.
+ llvm::StringMap<bool> Features;
Target.getDefaultFeatures(TargetCPU, Features);
// Apply the user specified deltas.
Name);
exit(1);
}
+
+ // Apply the feature via the target.
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<bool> &Features) {
- using namespace codegenoptions;
- Opts.OptimizeSize = OptSize;
- Opts.DebugInfo = GenerateDebugInfo;
- Opts.DisableLLVMOpts = DisableLLVMOptimizations;
+ // Add the features to the compile options.
+ //
+ // FIXME: If we are completely confident that we have the right set, we only
+ // need to pass the minuses.
+ for (llvm::StringMap<bool>::const_iterator it = Features.begin(),
+ ie = Features.end(); it != ie; ++it)
+ Opts.Features.push_back(std::string(it->second ? "+" : "-") + it->first());
// -Os implies -O2
Opts.OptimizationLevel = OptSize ? 2 : OptLevel;
Opts.Inlining = (Opts.OptimizationLevel > 1) ? CompileOptions::NormalInlining
: CompileOptions::OnlyAlwaysInlining;
- Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize);
+ Opts.CPU = TargetCPU;
+ Opts.DebugInfo = GenerateDebugInfo;
+ Opts.DisableLLVMOpts = DisableLLVMOptimizations;
+ Opts.DisableRedZone = DisableRedZone;
+ Opts.MergeAllConstants = !NoMergeConstants;
+ Opts.NoCommon = NoCommon;
+ Opts.NoImplicitFloat = NoImplicitFloat;
+ Opts.OptimizeSize = OptSize;
Opts.SimplifyLibCalls = 1;
+ Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize);
#ifdef NDEBUG
Opts.VerifyModule = 0;
#endif
-
- Opts.CPU = TargetCPU;
- Opts.Features.clear();
- for (llvm::StringMap<bool>::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;
}
void clang::InitializeDiagnosticOptions(DiagnosticOptions &Opts) {
void clang::InitializeLangOptions(LangOptions &Options, LangKind LK,
TargetInfo &Target,
- const CompileOptions &CompileOpts,
- const llvm::StringMap<bool> &Features) {
+ const CompileOptions &CompileOpts) {
using namespace langoptions;
bool NoPreprocess = false;
// Pass the map of target features to the target for validation and
// processing.
- Target.HandleTargetFeatures(Features);
+ Target.HandleTargetFeatures(CompileOpts.Features);
if (LangStd == lang_unspecified) {
// Based on the base language, pick one.
#ifndef LLVM_CLANGCC_OPTIONS_H
#define LLVM_CLANGCC_OPTIONS_H
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
void InitializeAnalyzerOptions(AnalyzerOptions &Opts);
-// FIXME: This can be sunk into InitializeCompileOptions now that that happens
-// before language initialization?
-void ComputeFeatureMap(TargetInfo &Target, llvm::StringMap<bool> &Features);
-
void InitializeDiagnosticOptions(DiagnosticOptions &Opts);
void InitializeCompileOptions(CompileOptions &Opts,
- const llvm::StringMap<bool> &Features);
+ const TargetInfo &Target);
void InitializeHeaderSearchOptions(HeaderSearchOptions &Opts,
llvm::StringRef BuiltinIncludePath,
void InitializeLangOptions(LangOptions &Options, LangKind LK,
TargetInfo &Target,
- const CompileOptions &CompileOpts,
- const llvm::StringMap<bool> &Features);
+ const CompileOptions &CompileOpts);
void InitializePreprocessorOptions(PreprocessorOptions &Opts);
Opts.getOutputFile() = OutputFile;
- // Compute the feature set, which may effect the language.
- ComputeFeatureMap(Target, Opts.getTargetFeatures());
-
// Initialize backend options, which may also be used to key some language
// options.
- InitializeCompileOptions(Opts.getCompileOpts(), Opts.getTargetFeatures());
+ InitializeCompileOptions(Opts.getCompileOpts(), Target);
// Initialize language options.
LangOptions LangInfo;
// code path to make this obvious.
if (LK != langkind_ast)
InitializeLangOptions(Opts.getLangOpts(), LK, Target,
- Opts.getCompileOpts(), Opts.getTargetFeatures());
+ Opts.getCompileOpts());
// Initialize the header search options.
InitializeHeaderSearchOptions(Opts.getHeaderSearchOpts(),