Simplifiy target feature handling by coalescing all the logic into
InitializeCompileOptions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86826 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 16d312a..f006ce9 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -384,9 +384,10 @@
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.
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index ad63555..4ee377e 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -17,9 +17,10 @@
#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;
@@ -655,7 +656,7 @@
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,
@@ -772,21 +773,25 @@
/// 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
diff --git a/tools/clang-cc/Options.cpp b/tools/clang-cc/Options.cpp
index 973b53a..7b22d28 100644
--- a/tools/clang-cc/Options.cpp
+++ b/tools/clang-cc/Options.cpp
@@ -530,15 +530,13 @@
// 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.
@@ -552,20 +550,22 @@
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;
@@ -574,30 +574,20 @@
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) {
@@ -769,8 +759,7 @@
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;
@@ -836,7 +825,7 @@
// 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.
diff --git a/tools/clang-cc/Options.h b/tools/clang-cc/Options.h
index aacf0a3..6d1447d 100644
--- a/tools/clang-cc/Options.h
+++ b/tools/clang-cc/Options.h
@@ -10,7 +10,7 @@
#ifndef LLVM_CLANGCC_OPTIONS_H
#define LLVM_CLANGCC_OPTIONS_H
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
namespace clang {
@@ -39,14 +39,10 @@
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,
@@ -55,8 +51,7 @@
void InitializeLangOptions(LangOptions &Options, LangKind LK,
TargetInfo &Target,
- const CompileOptions &CompileOpts,
- const llvm::StringMap<bool> &Features);
+ const CompileOptions &CompileOpts);
void InitializePreprocessorOptions(PreprocessorOptions &Opts);
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index 2a40656..fd1153c 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -1099,12 +1099,9 @@
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;
@@ -1113,7 +1110,7 @@
// 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(),