summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-06 03:16:41 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-06 03:16:41 +0000
commit4dbaaa6f43adb0b80c9818d0b5f75ff04793bde3 (patch)
treead0691312af54ca924a634338411c87f2b460350
parentb2d4a52e3f94c3b7d5d13e5e6087ae7807a4e79c (diff)
downloadbcm5719-llvm-4dbaaa6f43adb0b80c9818d0b5f75ff04793bde3.tar.gz
bcm5719-llvm-4dbaaa6f43adb0b80c9818d0b5f75ff04793bde3.zip
Improve handling of (X86) target features.
- This is a WIP... - This adds -march= handling to the driver, and fixes the defaulting of -mcpu on Darwin (which was using the wrong test). Instead of handling -m{sse, ...} in the driver, pass them to clang-cc as -target-feature [+-]name In clang-cc, communicate with the (clang) target to discover the legal features of a target, and the features which are enabled based on -mcpu. This is currently hardcoded just enough to not be a feature regression, we need to get this information from the backend's TableGen information somehow. This is used to construct the full list of features which are being used, which is in turn used to initialize the predefines. llvm-svn: 71061
-rw-r--r--clang/include/clang/Basic/TargetInfo.h28
-rw-r--r--clang/include/clang/Driver/Options.def42
-rw-r--r--clang/lib/Basic/Targets.cpp97
-rw-r--r--clang/lib/Driver/Tools.cpp98
-rw-r--r--clang/test/CodeGen/mmintrin-test.c4
-rw-r--r--clang/test/Driver/analyze.c2
-rw-r--r--clang/test/Driver/clang-translation.c4
-rw-r--r--clang/test/Sema/carbon-pth.c6
-rw-r--r--clang/test/Sema/carbon.c3
-rw-r--r--clang/test/SemaCXX/carbon.cpp2
-rw-r--r--clang/test/SemaObjC/cocoa-pth.m6
-rw-r--r--clang/test/SemaObjC/cocoa.m3
-rw-r--r--clang/test/SemaObjCXX/cocoa.mm2
-rw-r--r--clang/tools/clang-cc/clang-cc.cpp101
14 files changed, 217 insertions, 181 deletions
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 94fa0d4aea2..ce54db75813 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -14,6 +14,8 @@
#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
#define LLVM_CLANG_BASIC_TARGETINFO_H
+// FIXME: Daniel isn't smart enough to use a prototype for this.
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <vector>
@@ -334,22 +336,16 @@ public:
/// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {}
- /// HandleTargetFeatures - Handle target-specific options like -mattr=+sse2
- /// and friends. An array of arguments is passed in: if they are all valid,
- /// this should handle them and return -1. If there is an error, the index of
- /// the invalid argument should be returned along with an optional error
- /// string.
- ///
- /// Note that the driver should have already consolidated all the
- /// target-feature settings and passed them to us in the -mattr list. The
- /// -mattr list is treated by the code generator as a diff against the -mcpu
- /// setting, but the driver should pass all enabled options as "+" settings.
- /// This means that the target should only look at + settings.
- virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
- std::string &ErrorReason) {
- if (NumStrs == 0)
- return -1;
- return 0;
+ /// getDefaultFeatures - Get the default set of target features for
+ /// the \args CPU; this should include all legal feature strings on
+ /// the target.
+ virtual void getDefaultFeatures(const std::string &CPU,
+ llvm::StringMap<bool> &Features) {
+ }
+
+ /// HandleTargetOptions - Perform initialization based on the user
+ /// configured set of features.
+ virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features) {
}
// getRegParmMax - Returns maximal number of args passed in registers.
diff --git a/clang/include/clang/Driver/Options.def b/clang/include/clang/Driver/Options.def
index 5d35602e5b0..cf077be969d 100644
--- a/clang/include/clang/Driver/Options.def
+++ b/clang/include/clang/Driver/Options.def
@@ -108,6 +108,7 @@ OPTION("<g group>", g_Group, Group, INVALID, INVALID, "", 0, 0, 0)
OPTION("<i group>", i_Group, Group, INVALID, INVALID, "", 0, 0, 0)
OPTION("<clang i group>", clang_i_Group, Group, i_Group, INVALID, "", 0, 0, 0)
OPTION("<m group>", m_Group, Group, INVALID, INVALID, "", 0, 0, 0)
+OPTION("<m x86 features group>", m_x86_Features_Group, Group, INVALID, INVALID, "", 0, 0, 0)
OPTION("<u group>", u_Group, Group, INVALID, INVALID, "", 0, 0, 0)
OPTION("<pedantic group>", pedantic_Group, Group, INVALID, INVALID, "", 0, 0, 0)
@@ -477,41 +478,42 @@ OPTION("-i", i, Joined, i_Group, INVALID, "", 0, 0, 0)
OPTION("-keep_private_externs", keep__private__externs, Flag, INVALID, INVALID, "", 0, 0, 0)
OPTION("-l", l, JoinedOrSeparate, INVALID, INVALID, "l", 0, 0, 0)
OPTION("-m32", m32, Flag, m_Group, INVALID, "d", 0, 0, 0)
-OPTION("-m3dnowa", m3dnowa, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-m3dnow", m3dnow, Flag, m_Group, INVALID, "", 0, 0, 0)
+OPTION("-m3dnowa", m3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-m3dnow", m3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-m64", m64, Flag, m_Group, INVALID, "d", 0, 0, 0)
+OPTION("-march=", march_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
OPTION("-mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0, 0)
OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mmmx", mmmx, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-3dnow", mno_3dnow, Flag, m_Group, INVALID, "", 0, 0, 0)
+OPTION("-mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-3dnow", mno_3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-constant-cfstrings", mno_constant_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-mmx", mno_mmx, Flag, m_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-mmx", mno_mmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-pascal-strings", mno_pascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse2", mno_sse2, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse3", mno_sse3, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse41", mno_sse41, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse42", mno_sse42, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse4a", mno_sse4a, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse", mno_sse, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-ssse3", mno_ssse3, Flag, m_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse41", mno_sse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse42", mno_sse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mpascal-strings", mpascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mred-zone", mred_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-msoft-float", msoft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse2", msse2, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse3", msse3, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse41", msse41, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse42", msse42, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse4a", msse4a, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse", msse, Flag, m_Group, INVALID, "", 0, 0, 0)
-OPTION("-mssse3", mssse3, Flag, m_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse2", msse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse3", msse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse41", msse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse42", msse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse", msse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mtune=", mtune_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
OPTION("-multi_module", multi__module, Flag, INVALID, INVALID, "", 0, 0, 0)
OPTION("-multiply_defined_unused", multiply__defined__unused, Separate, INVALID, INVALID, "", 0, 0, 0)
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index e0db82d2a81..bb568b149b4 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -503,10 +503,7 @@ class X86TargetInfo : public TargetInfo {
} SSELevel;
public:
X86TargetInfo(const std::string& triple)
- : TargetInfo(triple),
- // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so
- // that the driver controls this.
- SSELevel(SSE2) {
+ : TargetInfo(triple), SSELevel(NoMMXSSE) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
@@ -536,49 +533,59 @@ public:
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const;
- virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
- std::string &ErrorReason);
+ virtual void getDefaultFeatures(const std::string &CPU,
+ llvm::StringMap<bool> &Features);
+ virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
};
-/// HandleTargetOptions - Handle target-specific options like -msse2 and
-/// friends. An array of arguments is passed in: if they are all valid, this
-/// should handle them and return -1. If there is an error, the index of the
-/// invalid argument should be returned along with an optional error string.
-int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs,
- std::string &ErrorReason) {
- for (unsigned i = 0; i != NumStrs; ++i) {
- const std::string &Feature = StrArray[i];
- if (Feature.size() < 2) return i;
- // Ignore explicitly disabled features.
- if (Feature[0] == '-') continue;
-
- // Feature strings are of the form "+feature".
- if (Feature[0] != '+') return i;
-
- // The set of supported subtarget features is defined in
- // lib/Target/X86/X86.td. Here we recognize and map onto our internal
- // state.
- if (Feature == "+mmx")
- SSELevel = std::max(SSELevel, MMX);
- else if (Feature == "+sse")
- SSELevel = std::max(SSELevel, SSE1);
- else if (Feature == "+sse2")
- SSELevel = std::max(SSELevel, SSE2);
- else if (Feature == "+sse3")
- SSELevel = std::max(SSELevel, SSE3);
- else if (Feature == "+ssse3")
- SSELevel = std::max(SSELevel, SSSE3);
- else if (Feature == "+sse41")
- SSELevel = std::max(SSELevel, SSE41);
- else if (Feature == "+sse42")
- SSELevel = std::max(SSELevel, SSE42);
- else if (Feature == "+64bit" || Feature == "+slow-bt-mem")
- // Ignore these features.
- continue;
- else
- return i;
- }
- return -1;
+void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
+ llvm::StringMap<bool> &Features) {
+ // FIXME: This should not be here.
+ Features["3dnow"] = false;
+ Features["3dnowa"] = false;
+ Features["mmx"] = false;
+ Features["sse"] = false;
+ Features["sse2"] = false;
+ Features["sse3"] = false;
+ Features["ssse3"] = false;
+ Features["sse41"] = false;
+ Features["sse42"] = false;
+
+ // LLVM does not currently recognize this.
+ // Features["sse4a"] = false;
+
+ // FIXME: This *really* should not be here.
+
+ // X86_64 always has SSE2.
+ if (PointerWidth == 64)
+ Features["sse2"] = Features["sse"] = Features["mmx"] = true;
+
+ // FIXME: LLVM says core2 has SSSE3, but gcc doesn't define
+ // __SSSE3__ with it? What else is going on here?
+ if (CPU == "core2")
+ Features["ssse3"] = Features["sse3"] = Features["sse2"] = Features["sse"] =
+ Features["mmx"] = true;
+ else if (CPU == "pentium4")
+ Features["sse2"] = Features["sse"] = Features["mmx"] = true;
+}
+
+/// 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;
}
/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 2a959b3c55a..a52498dc950 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -31,6 +31,13 @@
using namespace clang::driver;
using namespace clang::driver::tools;
+static const char *MakeFormattedString(const ArgList &Args,
+ const llvm::format_object_base &Fmt) {
+ std::string Str;
+ llvm::raw_string_ostream(Str) << Fmt;
+ return Args.MakeArgString(Str.c_str());
+}
+
void Clang::AddPreprocessingOptions(const Driver &D,
const ArgList &Args,
ArgStringList &CmdArgs,
@@ -318,52 +325,48 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
false))
CmdArgs.push_back("--soft-float");
- // FIXME: Need target hooks.
- if (memcmp(getToolChain().getPlatform().c_str(), "darwin", 6) == 0) {
- if (getToolChain().getArchName() == "x86_64")
- CmdArgs.push_back("--mcpu=core2");
- else if (getToolChain().getArchName() == "i386")
- CmdArgs.push_back("--mcpu=yonah");
- }
-
- // FIXME: Ignores ordering. Also, we need to find a realistic
- // solution for this.
- static const struct {
- options::ID Pos, Neg;
- const char *Name;
- } FeatureOptions[] = {
- { options::OPT_mmmx, options::OPT_mno_mmx, "mmx" },
- { options::OPT_msse, options::OPT_mno_sse, "sse" },
- { options::OPT_msse2, options::OPT_mno_sse2, "sse2" },
- { options::OPT_msse3, options::OPT_mno_sse3, "sse3" },
- { options::OPT_mssse3, options::OPT_mno_ssse3, "ssse3" },
- { options::OPT_msse41, options::OPT_mno_sse41, "sse41" },
- { options::OPT_msse42, options::OPT_mno_sse42, "sse42" },
- { options::OPT_msse4a, options::OPT_mno_sse4a, "sse4a" },
- { options::OPT_m3dnow, options::OPT_mno_3dnow, "3dnow" },
- { options::OPT_m3dnowa, options::OPT_mno_3dnowa, "3dnowa" }
- };
- const unsigned NumFeatureOptions =
- sizeof(FeatureOptions)/sizeof(FeatureOptions[0]);
-
- // FIXME: Avoid std::string
- std::string Attrs;
- for (unsigned i=0; i < NumFeatureOptions; ++i) {
- if (Args.hasArg(FeatureOptions[i].Pos)) {
- if (!Attrs.empty())
- Attrs += ',';
- Attrs += '+';
- Attrs += FeatureOptions[i].Name;
- } else if (Args.hasArg(FeatureOptions[i].Neg)) {
- if (!Attrs.empty())
- Attrs += ',';
- Attrs += '-';
- Attrs += FeatureOptions[i].Name;
+ // FIXME: Handle -mtune=.
+ (void) Args.hasArg(options::OPT_mtune_EQ);
+
+ if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+ // FIXME: We made need some translation here from the options gcc
+ // takes to names the LLVM backend understand?
+ CmdArgs.push_back("-mcpu");
+ CmdArgs.push_back(A->getValue(Args));
+ } else {
+ // Select default CPU.
+
+ // FIXME: Need target hooks.
+ if (memcmp(getToolChain().getOS().c_str(), "darwin", 6) == 0) {
+ if (getToolChain().getArchName() == "x86_64")
+ CmdArgs.push_back("--mcpu=core2");
+ else if (getToolChain().getArchName() == "i386")
+ CmdArgs.push_back("--mcpu=pentium4");
}
}
- if (!Attrs.empty()) {
- CmdArgs.push_back("--mattr");
- CmdArgs.push_back(Args.MakeArgString(Attrs.c_str()));
+
+ // FIXME: Use iterator.
+ for (ArgList::const_iterator
+ it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+ const Arg *A = *it;
+ if (A->getOption().matches(options::OPT_m_x86_Features_Group)) {
+ const char *Name = A->getOption().getName();
+
+ // Skip over "-m".
+ assert(Name[0] == '-' && Name[1] == 'm' && "Invalid feature name.");
+ Name += 2;
+
+ bool IsNegative = memcmp(Name, "no-", 3) == 0;
+ if (IsNegative)
+ Name += 3;
+
+ A->claim();
+ CmdArgs.push_back("-target-feature");
+ CmdArgs.push_back(MakeFormattedString(Args,
+ llvm::format("%c%s",
+ IsNegative ? '-' : '+',
+ Name)));
+ }
}
if (Args.hasFlag(options::OPT_fmath_errno,
@@ -1215,13 +1218,6 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Dest.addCommand(new Command(Exec, CmdArgs));
}
-static const char *MakeFormattedString(const ArgList &Args,
- const llvm::format_object_base &Fmt) {
- std::string Str;
- llvm::raw_string_ostream(Str) << Fmt;
- return Args.MakeArgString(Str.c_str());
-}
-
/// Helper routine for seeing if we should use dsymutil; this is a
/// gcc compatible hack, we should remove it and use the input
/// type information.
diff --git a/clang/test/CodeGen/mmintrin-test.c b/clang/test/CodeGen/mmintrin-test.c
index 97f3b3b67c6..2a9ab567233 100644
--- a/clang/test/CodeGen/mmintrin-test.c
+++ b/clang/test/CodeGen/mmintrin-test.c
@@ -1,6 +1,6 @@
-// RUN: clang-cc -triple i386-apple-darwin9 -emit-llvm -o %t %s &&
+// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -emit-llvm -o %t %s &&
// RUN: grep define %t | count 1 &&
-// RUN: clang-cc -triple i386-apple-darwin9 -g -emit-llvm -o %t %s &&
+// RUN: clang-cc -triple i386-apple-darwin9 -mcpu=pentium4 -g -emit-llvm -o %t %s &&
// RUN: grep define %t | count 1
#include <mmintrin.h>
diff --git a/clang/test/Driver/analyze.c b/clang/test/Driver/analyze.c
index f82199d356e..338c6148c1c 100644
--- a/clang/test/Driver/analyze.c
+++ b/clang/test/Driver/analyze.c
@@ -4,6 +4,6 @@
// RUN: clang -ccc-host-triple i386-apple-darwin9 -### --analyze -o /dev/null %s -msse 2> %t.log &&
// RUN: grep '"-analyze"' %t.log &&
// RUN: grep '"--fmath-errno=0"' %t.log &&
-// RUN: grep '"--mattr" "+sse"' %t.log &&
+// RUN: grep '"-target-feature" "+sse"' %t.log &&
// RUN: grep '"-mmacosx-version-min=10.5.0"' %t.log
diff --git a/clang/test/Driver/clang-translation.c b/clang/test/Driver/clang-translation.c
index 2421bd1f3ac..6d523954c7f 100644
--- a/clang/test/Driver/clang-translation.c
+++ b/clang/test/Driver/clang-translation.c
@@ -9,4 +9,8 @@
// RUN: grep '"-Os"' %t.log &&
// RUN: grep '"-o" .*clang-translation\.c\.out\.tmp\.s' %t.log &&
// RUN: grep '"--asm-verbose"' %t.log &&
+// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S %s -o %t.s 2> %t.log
+// RUN: grep '"--mcpu=pentium4"' %t.log &&
+// RUN: clang -ccc-host-triple x86_64-apple-darwin9 -### -S %s -o %t.s 2> %t.log
+// RUN: grep '"--mcpu=core2"' %t.log &&
// RUN: true
diff --git a/clang/test/Sema/carbon-pth.c b/clang/test/Sema/carbon-pth.c
index ebc88405457..c956d2a7a1c 100644
--- a/clang/test/Sema/carbon-pth.c
+++ b/clang/test/Sema/carbon-pth.c
@@ -1,6 +1,6 @@
-// RUN: clang-cc -emit-pth -o %t %s &&
-// RUN: clang-cc -token-cache %t %s &&
-// RUN: clang-cc -token-cache %t %s -E %s -o /dev/null
+// RUN: clang-cc -mcpu=pentium4 -emit-pth -o %t %s &&
+// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s &&
+// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s -E %s -o /dev/null
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
diff --git a/clang/test/Sema/carbon.c b/clang/test/Sema/carbon.c
index 8e6837f1256..5eda4385ac4 100644
--- a/clang/test/Sema/carbon.c
+++ b/clang/test/Sema/carbon.c
@@ -1,5 +1,4 @@
-// RUN: clang-cc %s -print-stats &&
-// RUN: clang-cc %s -disable-free
+// RUN: clang-cc -mcpu=pentium4 %s -print-stats
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
diff --git a/clang/test/SemaCXX/carbon.cpp b/clang/test/SemaCXX/carbon.cpp
index 983a000b2cf..0e7570f3352 100644
--- a/clang/test/SemaCXX/carbon.cpp
+++ b/clang/test/SemaCXX/carbon.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-cc %s -fsyntax-only -print-stats
+// RUN: clang-cc -mcpu=pentium4 %s -fsyntax-only -print-stats
#ifdef __APPLE__
#include <Carbon/Carbon.h>
#endif
diff --git a/clang/test/SemaObjC/cocoa-pth.m b/clang/test/SemaObjC/cocoa-pth.m
index 24b0579a249..dc806dfb7c0 100644
--- a/clang/test/SemaObjC/cocoa-pth.m
+++ b/clang/test/SemaObjC/cocoa-pth.m
@@ -1,6 +1,6 @@
-// RUN: clang-cc -emit-pth -o %t %s &&
-// RUN: clang-cc -token-cache %t %s &&
-// RUN: clang-cc -token-cache %t %s -E %s -o /dev/null
+// RUN: clang-cc -mcpu=pentium4 -emit-pth -o %t %s &&
+// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s &&
+// RUN: clang-cc -mcpu=pentium4 -token-cache %t %s -E %s -o /dev/null
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
diff --git a/clang/test/SemaObjC/cocoa.m b/clang/test/SemaObjC/cocoa.m
index 153c46e1034..b73b3c4ccd3 100644
--- a/clang/test/SemaObjC/cocoa.m
+++ b/clang/test/SemaObjC/cocoa.m
@@ -1,5 +1,4 @@
-// RUN: clang-cc %s -print-stats &&
-// RUN: clang-cc %s -disable-free
+// RUN: clang-cc -mcpu=pentium4 %s -print-stats
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
diff --git a/clang/test/SemaObjCXX/cocoa.mm b/clang/test/SemaObjCXX/cocoa.mm
index dd9684ce065..c061d4e0968 100644
--- a/clang/test/SemaObjCXX/cocoa.mm
+++ b/clang/test/SemaObjCXX/cocoa.mm
@@ -1,4 +1,4 @@
-// RUN: clang-cc %s -print-stats
+// RUN: clang-cc -mcpu=pentium4 %s -print-stats
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp
index 17eeac776c0..3726f1c738a 100644
--- a/clang/tools/clang-cc/clang-cc.cpp
+++ b/clang/tools/clang-cc/clang-cc.cpp
@@ -50,6 +50,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Support/CommandLine.h"
@@ -663,10 +664,6 @@ NeXTRuntime("fnext-runtime",
static llvm::cl::opt<bool>
Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences"));
-static llvm::cl::list<std::string>
-TargetFeatures("mattr", llvm::cl::CommaSeparated,
- llvm::cl::desc("Target specific attributes (-mattr=help for details)"));
-
static llvm::cl::opt<unsigned>
TemplateDepth("ftemplate-depth", llvm::cl::init(99),
llvm::cl::desc("Maximum depth of recursive template "
@@ -711,30 +708,14 @@ static llvm::cl::opt<bool>
StaticDefine("static-define", llvm::cl::desc("Should __STATIC__ be defined"));
static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
- TargetInfo *Target) {
+ TargetInfo *Target,
+ const llvm::StringMap<bool> &Features) {
// Allow the target to set the default the langauge options as it sees fit.
Target->getDefaultLangOptions(Options);
-
- // If there are any -mattr options, pass them to the target for validation and
- // processing. The driver should have already consolidated all the
- // target-feature settings and passed them to us in the -mattr list. The
- // -mattr list is treated by the code generator as a diff against the -mcpu
- // setting, but the driver should pass all enabled options as "+" settings.
- // This means that the target should only look at + settings.
- if (!TargetFeatures.empty()) {
- std::string ErrorStr;
- int Opt = Target->HandleTargetFeatures(&TargetFeatures[0],
- TargetFeatures.size(), ErrorStr);
- if (Opt != -1) {
- if (ErrorStr.empty())
- fprintf(stderr, "invalid feature '%s'\n",
- TargetFeatures[Opt].c_str());
- else
- fprintf(stderr, "feature '%s': %s\n",
- TargetFeatures[Opt].c_str(), ErrorStr.c_str());
- exit(1);
- }
- }
+
+ // Pass the map of target features to the target for validation and
+ // processing.
+ Target->HandleTargetFeatures(Features);
if (LangStd == lang_unspecified) {
// Based on the base language, pick one.
@@ -1429,8 +1410,47 @@ static llvm::cl::opt<std::string>
TargetCPU("mcpu",
llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)"));
+static llvm::cl::list<std::string>
+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<bool> &Features) {
+ 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<std::string>::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);
+ }
+
+ llvm::StringMap<bool>::iterator it = Features.find(Name + 1);
+ if (it == Features.end()) {
+ fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n",
+ Name);
+ exit(1);
+ }
+
+ // FIXME: Actually, we need to apply all the features implied by
+ // this feature.
+ it->second = (Name[0] == '+');
+ }
+}
+
static void InitializeCompileOptions(CompileOptions &Opts,
- const LangOptions &LangOpts) {
+ const LangOptions &LangOpts,
+ const llvm::StringMap<bool> &Features) {
Opts.OptimizeSize = OptSize;
Opts.DebugInfo = GenerateDebugInfo;
if (OptSize) {
@@ -1451,8 +1471,15 @@ static void InitializeCompileOptions(CompileOptions &Opts,
#endif
Opts.CPU = TargetCPU;
- Opts.Features.insert(Opts.Features.end(),
- TargetFeatures.begin(), TargetFeatures.end());
+ 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 | LangOpts.CPlusPlus;
@@ -1556,6 +1583,7 @@ static void SetUpBuildDumpLog(unsigned argc, char **argv,
static ASTConsumer *CreateASTConsumer(const std::string& InFile,
Diagnostic& Diag, FileManager& FileMgr,
const LangOptions& LangOpts,
+ const llvm::StringMap<bool>& Features,
Preprocessor *PP,
PreprocessorFactory *PPF) {
switch (ProgAction) {
@@ -1598,7 +1626,7 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile,
Act = Backend_EmitBC;
CompileOptions Opts;
- InitializeCompileOptions(Opts, LangOpts);
+ InitializeCompileOptions(Opts, LangOpts, Features);
return CreateBackendConsumer(Act, Diag, LangOpts, Opts,
InFile, OutputFile);
}
@@ -1620,7 +1648,8 @@ static ASTConsumer *CreateASTConsumer(const std::string& InFile,
/// ProcessInputFile - Process a single input file with the specified state.
///
static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
- const std::string &InFile, ProgActions PA) {
+ const std::string &InFile, ProgActions PA,
+ const llvm::StringMap<bool> &Features) {
llvm::OwningPtr<ASTConsumer> Consumer;
bool ClearSourceMgr = false;
FixItRewriter *FixItRewrite = 0;
@@ -1630,7 +1659,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
default:
Consumer.reset(CreateASTConsumer(InFile, PP.getDiagnostics(),
PP.getFileManager(), PP.getLangOptions(),
- &PP, &PPF));
+ Features, &PP, &PPF));
if (!Consumer) {
fprintf(stderr, "Unexpected program action!\n");
@@ -1999,6 +2028,10 @@ int main(int argc, char **argv) {
// Create a file manager object to provide access to and cache the filesystem.
FileManager FileMgr;
+ // Compute the feature set, unfortunately this effects the language!
+ llvm::StringMap<bool> Features;
+ ComputeFeatureMap(Target.get(), Features);
+
for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) {
const std::string &InFile = InputFilenames[i];
@@ -2016,7 +2049,7 @@ int main(int argc, char **argv) {
InitializeBaseLanguage();
LangKind LK = GetLanguage(InFile);
InitializeLangOptions(LangInfo, LK);
- InitializeLanguageStandard(LangInfo, LK, Target.get());
+ InitializeLanguageStandard(LangInfo, LK, Target.get(), Features);
// Process the -I options and set them in the HeaderInfo.
HeaderSearch HeaderInfo(FileMgr);
@@ -2041,7 +2074,7 @@ int main(int argc, char **argv) {
((PathDiagnosticClient*)DiagClient.get())->SetPreprocessor(PP.get());
// Process the source file.
- ProcessInputFile(*PP, PPFactory, InFile, ProgAction);
+ ProcessInputFile(*PP, PPFactory, InFile, ProgAction, Features);
HeaderInfo.ClearFileInfo();
DiagClient->setLangOptions(0);
OpenPOWER on IntegriCloud