mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
When targeting arm64-apple-ios, the target CPU is cyclone,
which provides the Neon feature. Do all the necessary plumbing to get this from the driver to the backend. Also, support -arch arm64, and diagnose bad -arch values instead of silently ignoring them. It's not clear to me that we really want to support -arch as an alternative to -target, but unless we rip it out or establish some sort of real policy about it, it really ought to do something approximating the right thing. It would be nice if we could abstract enough of clang's driver that we could re-use some of its basic logic about tool chains and targets instaed of iteratively rediscovering everything it does that's actually critically important. Swift SVN r16447
This commit is contained in:
@@ -69,6 +69,9 @@ ERROR(error_unable_to_make_temporary_file,driver,none,
|
||||
ERROR(error_no_input_files,driver,none,
|
||||
"no input files", ())
|
||||
|
||||
ERROR(error_invalid_arch,driver,none,
|
||||
"invalid target architecture '%0'", (StringRef))
|
||||
|
||||
#ifndef DIAG_NO_UNDEF
|
||||
# if defined(DIAG)
|
||||
# undef DIAG
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "swift/AST/LinkLibrary.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace swift {
|
||||
|
||||
@@ -50,6 +51,9 @@ public:
|
||||
std::string Triple;
|
||||
// The command line string that is to be stored in the DWARF debug info.
|
||||
std::string DWARFDebugFlags;
|
||||
// The CPU and features.
|
||||
std::string TargetCPU;
|
||||
std::vector<std::string> TargetFeatures;
|
||||
|
||||
/// The libraries and frameworks specified on the command line.
|
||||
SmallVector<LinkLibrary, 4> LinkLibraries;
|
||||
|
||||
@@ -273,6 +273,14 @@ def target : Joined<["--"], "target=">, Flags<[DriverOption, FrontendOption]>,
|
||||
def target_legacy_spelling : Separate<["-"], "target">,
|
||||
Flags<[DriverOption, FrontendOption]>, Alias<target>;
|
||||
|
||||
def target_cpu : Separate<["-"], "target-cpu">,
|
||||
Flags<[DriverOption, FrontendOption]>,
|
||||
HelpText<"Generate code for a particular CPU variant">;
|
||||
def target_feature : Separate<["-"], "target-feature">,
|
||||
Flags<[DriverOption, FrontendOption]>,
|
||||
HelpText<"Generate code with a particular CPU feature enabled or disabled">,
|
||||
MetaVarName<"[+-]<feature-name>">;
|
||||
|
||||
def working_directory : Separate<["-"], "working-directory">,
|
||||
Flags<[FrontendOption]>,
|
||||
HelpText<"Resolve file paths relative to the specified directory">;
|
||||
|
||||
@@ -1095,39 +1095,45 @@ std::string Driver::getProgramPath(StringRef Name, const ToolChain &TC) const {
|
||||
return Name;
|
||||
}
|
||||
|
||||
static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple,
|
||||
static void setTargetFromArch(DiagnosticEngine &diags, llvm::Triple &target,
|
||||
StringRef archName) {
|
||||
llvm::Triple::ArchType archValue
|
||||
= tools::darwin::getArchTypeForDarwinArchName(archName);
|
||||
if (archValue != llvm::Triple::UnknownArch) {
|
||||
target.setArch(archValue);
|
||||
} else {
|
||||
diags.diagnose(SourceLoc(), diag::error_invalid_arch, archName);
|
||||
}
|
||||
}
|
||||
|
||||
static llvm::Triple computeTargetTriple(DiagnosticEngine &diags,
|
||||
StringRef DefaultTargetTriple,
|
||||
const ArgList &Args,
|
||||
StringRef DarwinArchName) {
|
||||
// FIXME: need to check -target for overrides
|
||||
|
||||
llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple));
|
||||
llvm::Triple target(llvm::Triple::normalize(DefaultTargetTriple));
|
||||
|
||||
// Handle Darwin-specific options available here.
|
||||
if (Target.isOSDarwin()) {
|
||||
if (target.isOSDarwin()) {
|
||||
// If an explict Darwin arch name is given, that trumps all.
|
||||
if (!DarwinArchName.empty()) {
|
||||
Target.setArch(
|
||||
tools::darwin::getArchTypeForDarwinArchName(DarwinArchName));
|
||||
return Target;
|
||||
}
|
||||
setTargetFromArch(diags, target, DarwinArchName);
|
||||
|
||||
// Handle the Darwin '-arch' flag.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_arch)) {
|
||||
llvm::Triple::ArchType DarwinArch
|
||||
= tools::darwin::getArchTypeForDarwinArchName(A->getValue());
|
||||
if (DarwinArch != llvm::Triple::UnknownArch)
|
||||
Target.setArch(DarwinArch);
|
||||
} else if (Arg *A = Args.getLastArg(options::OPT_arch)) {
|
||||
setTargetFromArch(diags, target, A->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle other target/pseudo-target flags as necessary.
|
||||
|
||||
return Target;
|
||||
return target;
|
||||
}
|
||||
|
||||
const ToolChain &Driver::getToolChain(const ArgList &Args,
|
||||
StringRef DarwinArchName) const {
|
||||
llvm::Triple Target = computeTargetTriple(DefaultTargetTriple, Args,
|
||||
llvm::Triple Target = computeTargetTriple(Diags, DefaultTargetTriple, Args,
|
||||
DarwinArchName);
|
||||
|
||||
ToolChain *&TC = ToolChains[Target.str()];
|
||||
|
||||
@@ -132,6 +132,17 @@ static void addCommonFrontendArgs(const ToolChain &TC,
|
||||
}
|
||||
}
|
||||
|
||||
// Should this be done by the tool chain?
|
||||
static void configureDefaultCPU(const llvm::Triple &triple,
|
||||
ArgStringList &args) {
|
||||
if (triple.isOSDarwin() && triple.getArch() == llvm::Triple::arm64) {
|
||||
args.push_back("-target-cpu");
|
||||
args.push_back("cyclone");
|
||||
args.push_back("-target-feature");
|
||||
args.push_back("+neon");
|
||||
}
|
||||
}
|
||||
|
||||
Job *Swift::constructJob(const JobAction &JA, std::unique_ptr<JobList> Inputs,
|
||||
std::unique_ptr<CommandOutput> Output,
|
||||
const ActionList &InputActions, const ArgList &Args,
|
||||
@@ -264,6 +275,14 @@ Job *Swift::constructJob(const JobAction &JA, std::unique_ptr<JobList> Inputs,
|
||||
// Pass the optimization level down to the frontend.
|
||||
Args.AddLastArg(Arguments, options::OPT_O_Group);
|
||||
|
||||
// Handle the CPU and its preferences.
|
||||
if (auto arg = Args.getLastArg(options::OPT_target_cpu)) {
|
||||
arg->render(Args, Arguments);
|
||||
} else {
|
||||
configureDefaultCPU(getToolChain().getTriple(), Arguments);
|
||||
}
|
||||
Args.AddAllArgs(Arguments, options::OPT_target_feature);
|
||||
|
||||
if (Args.hasArg(options::OPT_parse_as_library) ||
|
||||
Args.hasArg(options::OPT_emit_library))
|
||||
Arguments.push_back("-parse-as-library");
|
||||
@@ -371,6 +390,8 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Arch) {
|
||||
|
||||
.Case("x86_64", llvm::Triple::x86_64)
|
||||
|
||||
.Case("arm64", llvm::Triple::arm64)
|
||||
|
||||
.Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
|
||||
.Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
|
||||
.Cases("armv7s", "xscale", llvm::Triple::arm)
|
||||
|
||||
@@ -764,6 +764,29 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
Opts.OptLevel = 0;
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_O_Group)) {
|
||||
if (A->getOption().matches(OPT_O0)) {
|
||||
Opts.OptLevel = 0;
|
||||
}
|
||||
else {
|
||||
unsigned OptLevel;
|
||||
if (StringRef(A->getValue()).getAsInteger(10, OptLevel) || OptLevel > 3) {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
A->getAsString(Args), A->getValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
Opts.OptLevel = OptLevel;
|
||||
}
|
||||
} else {
|
||||
Opts.OptLevel = 0;
|
||||
}
|
||||
|
||||
if (const Arg *A = Args.getLastArg(OPT_target_cpu)) {
|
||||
Opts.TargetCPU = A->getValue();
|
||||
}
|
||||
Opts.TargetFeatures = Args.getAllArgValues(OPT_target_feature);
|
||||
|
||||
if (Args.hasArg(OPT_disable_all_runtime_checks)) {
|
||||
Opts.DisableAllRuntimeChecks = true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@@ -90,17 +91,24 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
|
||||
|
||||
// Set up TargetOptions.
|
||||
// Things that maybe we should collect from the command line:
|
||||
// - CPU
|
||||
// - features
|
||||
// - relocation model
|
||||
// - code model
|
||||
TargetOptions TargetOpts;
|
||||
TargetOpts.NoFramePointerElim = Opts.DisableFPElim;
|
||||
|
||||
// Create the target features string.
|
||||
std::string targetFeatures;
|
||||
if (!Opts.TargetFeatures.empty()) {
|
||||
llvm::SubtargetFeatures features;
|
||||
for (std::string &feature : Opts.TargetFeatures)
|
||||
features.AddFeature(feature);
|
||||
targetFeatures = features.getString();
|
||||
}
|
||||
|
||||
// Create a target machine.
|
||||
llvm::TargetMachine *TargetMachine
|
||||
= Target->createTargetMachine(Opts.Triple, /*cpu*/ "generic",
|
||||
/*features*/ "",
|
||||
= Target->createTargetMachine(Opts.Triple, Opts.TargetCPU,
|
||||
std::move(targetFeatures),
|
||||
TargetOpts, Reloc::PIC_,
|
||||
CodeModel::Default, OptLevel);
|
||||
if (!TargetMachine) {
|
||||
|
||||
Reference in New Issue
Block a user