Skip to content

Commit 3cf3f42

Browse files
committed
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
1 parent 960a6f2 commit 3cf3f42

File tree

7 files changed

+92
-19
lines changed

7 files changed

+92
-19
lines changed

include/swift/AST/DiagnosticsDriver.def

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ ERROR(error_unable_to_make_temporary_file,driver,none,
6969
ERROR(error_no_input_files,driver,none,
7070
"no input files", ())
7171

72+
ERROR(error_invalid_arch,driver,none,
73+
"invalid target architecture '%0'", (StringRef))
74+
7275
#ifndef DIAG_NO_UNDEF
7376
# if defined(DIAG)
7477
# undef DIAG

include/swift/AST/IRGenOptions.h

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "swift/AST/LinkLibrary.h"
2222
#include <string>
23+
#include <vector>
2324

2425
namespace swift {
2526

@@ -50,6 +51,9 @@ class IRGenOptions {
5051
std::string Triple;
5152
// The command line string that is to be stored in the DWARF debug info.
5253
std::string DWARFDebugFlags;
54+
// The CPU and features.
55+
std::string TargetCPU;
56+
std::vector<std::string> TargetFeatures;
5357

5458
/// The libraries and frameworks specified on the command line.
5559
SmallVector<LinkLibrary, 4> LinkLibraries;

include/swift/Driver/Options.td

+8
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ def target : Joined<["--"], "target=">, Flags<[DriverOption, FrontendOption]>,
273273
def target_legacy_spelling : Separate<["-"], "target">,
274274
Flags<[DriverOption, FrontendOption]>, Alias<target>;
275275

276+
def target_cpu : Separate<["-"], "target-cpu">,
277+
Flags<[DriverOption, FrontendOption]>,
278+
HelpText<"Generate code for a particular CPU variant">;
279+
def target_feature : Separate<["-"], "target-feature">,
280+
Flags<[DriverOption, FrontendOption]>,
281+
HelpText<"Generate code with a particular CPU feature enabled or disabled">,
282+
MetaVarName<"[+-]<feature-name>">;
283+
276284
def working_directory : Separate<["-"], "working-directory">,
277285
Flags<[FrontendOption]>,
278286
HelpText<"Resolve file paths relative to the specified directory">;

lib/Driver/Driver.cpp

+20-14
Original file line numberDiff line numberDiff line change
@@ -1095,39 +1095,45 @@ std::string Driver::getProgramPath(StringRef Name, const ToolChain &TC) const {
10951095
return Name;
10961096
}
10971097

1098-
static llvm::Triple computeTargetTriple(StringRef DefaultTargetTriple,
1098+
static void setTargetFromArch(DiagnosticEngine &diags, llvm::Triple &target,
1099+
StringRef archName) {
1100+
llvm::Triple::ArchType archValue
1101+
= tools::darwin::getArchTypeForDarwinArchName(archName);
1102+
if (archValue != llvm::Triple::UnknownArch) {
1103+
target.setArch(archValue);
1104+
} else {
1105+
diags.diagnose(SourceLoc(), diag::error_invalid_arch, archName);
1106+
}
1107+
}
1108+
1109+
static llvm::Triple computeTargetTriple(DiagnosticEngine &diags,
1110+
StringRef DefaultTargetTriple,
10991111
const ArgList &Args,
11001112
StringRef DarwinArchName) {
11011113
// FIXME: need to check -target for overrides
11021114

1103-
llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple));
1115+
llvm::Triple target(llvm::Triple::normalize(DefaultTargetTriple));
11041116

11051117
// Handle Darwin-specific options available here.
1106-
if (Target.isOSDarwin()) {
1118+
if (target.isOSDarwin()) {
11071119
// If an explict Darwin arch name is given, that trumps all.
11081120
if (!DarwinArchName.empty()) {
1109-
Target.setArch(
1110-
tools::darwin::getArchTypeForDarwinArchName(DarwinArchName));
1111-
return Target;
1112-
}
1121+
setTargetFromArch(diags, target, DarwinArchName);
11131122

11141123
// Handle the Darwin '-arch' flag.
1115-
if (Arg *A = Args.getLastArg(options::OPT_arch)) {
1116-
llvm::Triple::ArchType DarwinArch
1117-
= tools::darwin::getArchTypeForDarwinArchName(A->getValue());
1118-
if (DarwinArch != llvm::Triple::UnknownArch)
1119-
Target.setArch(DarwinArch);
1124+
} else if (Arg *A = Args.getLastArg(options::OPT_arch)) {
1125+
setTargetFromArch(diags, target, A->getValue());
11201126
}
11211127
}
11221128

11231129
// TODO: handle other target/pseudo-target flags as necessary.
11241130

1125-
return Target;
1131+
return target;
11261132
}
11271133

11281134
const ToolChain &Driver::getToolChain(const ArgList &Args,
11291135
StringRef DarwinArchName) const {
1130-
llvm::Triple Target = computeTargetTriple(DefaultTargetTriple, Args,
1136+
llvm::Triple Target = computeTargetTriple(Diags, DefaultTargetTriple, Args,
11311137
DarwinArchName);
11321138

11331139
ToolChain *&TC = ToolChains[Target.str()];

lib/Driver/Tools.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,17 @@ static void addCommonFrontendArgs(const ToolChain &TC,
132132
}
133133
}
134134

135+
// Should this be done by the tool chain?
136+
static void configureDefaultCPU(const llvm::Triple &triple,
137+
ArgStringList &args) {
138+
if (triple.isOSDarwin() && triple.getArch() == llvm::Triple::arm64) {
139+
args.push_back("-target-cpu");
140+
args.push_back("cyclone");
141+
args.push_back("-target-feature");
142+
args.push_back("+neon");
143+
}
144+
}
145+
135146
Job *Swift::constructJob(const JobAction &JA, std::unique_ptr<JobList> Inputs,
136147
std::unique_ptr<CommandOutput> Output,
137148
const ActionList &InputActions, const ArgList &Args,
@@ -264,6 +275,14 @@ Job *Swift::constructJob(const JobAction &JA, std::unique_ptr<JobList> Inputs,
264275
// Pass the optimization level down to the frontend.
265276
Args.AddLastArg(Arguments, options::OPT_O_Group);
266277

278+
// Handle the CPU and its preferences.
279+
if (auto arg = Args.getLastArg(options::OPT_target_cpu)) {
280+
arg->render(Args, Arguments);
281+
} else {
282+
configureDefaultCPU(getToolChain().getTriple(), Arguments);
283+
}
284+
Args.AddAllArgs(Arguments, options::OPT_target_feature);
285+
267286
if (Args.hasArg(options::OPT_parse_as_library) ||
268287
Args.hasArg(options::OPT_emit_library))
269288
Arguments.push_back("-parse-as-library");
@@ -371,6 +390,8 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Arch) {
371390

372391
.Case("x86_64", llvm::Triple::x86_64)
373392

393+
.Case("arm64", llvm::Triple::arm64)
394+
374395
.Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
375396
.Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
376397
.Cases("armv7s", "xscale", llvm::Triple::arm)

lib/Frontend/CompilerInvocation.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,29 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
764764
Opts.OptLevel = 0;
765765
}
766766

767+
if (const Arg *A = Args.getLastArg(OPT_O_Group)) {
768+
if (A->getOption().matches(OPT_O0)) {
769+
Opts.OptLevel = 0;
770+
}
771+
else {
772+
unsigned OptLevel;
773+
if (StringRef(A->getValue()).getAsInteger(10, OptLevel) || OptLevel > 3) {
774+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
775+
A->getAsString(Args), A->getValue());
776+
return true;
777+
}
778+
779+
Opts.OptLevel = OptLevel;
780+
}
781+
} else {
782+
Opts.OptLevel = 0;
783+
}
784+
785+
if (const Arg *A = Args.getLastArg(OPT_target_cpu)) {
786+
Opts.TargetCPU = A->getValue();
787+
}
788+
Opts.TargetFeatures = Args.getAllArgValues(OPT_target_feature);
789+
767790
if (Args.hasArg(OPT_disable_all_runtime_checks)) {
768791
Opts.DisableAllRuntimeChecks = true;
769792
}

lib/IRGen/IRGen.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/IR/Module.h"
3030
#include "llvm/IR/Verifier.h"
3131
#include "llvm/Linker/Linker.h"
32+
#include "llvm/MC/SubtargetFeature.h"
3233
#include "llvm/PassManager.h"
3334
#include "llvm/Support/Debug.h"
3435
#include "llvm/Support/ErrorHandling.h"
@@ -90,17 +91,24 @@ static std::unique_ptr<llvm::Module> performIRGeneration(IRGenOptions &Opts,
9091

9192
// Set up TargetOptions.
9293
// Things that maybe we should collect from the command line:
93-
// - CPU
94-
// - features
9594
// - relocation model
9695
// - code model
9796
TargetOptions TargetOpts;
9897
TargetOpts.NoFramePointerElim = Opts.DisableFPElim;
99-
98+
99+
// Create the target features string.
100+
std::string targetFeatures;
101+
if (!Opts.TargetFeatures.empty()) {
102+
llvm::SubtargetFeatures features;
103+
for (std::string &feature : Opts.TargetFeatures)
104+
features.AddFeature(feature);
105+
targetFeatures = features.getString();
106+
}
107+
100108
// Create a target machine.
101109
llvm::TargetMachine *TargetMachine
102-
= Target->createTargetMachine(Opts.Triple, /*cpu*/ "generic",
103-
/*features*/ "",
110+
= Target->createTargetMachine(Opts.Triple, Opts.TargetCPU,
111+
std::move(targetFeatures),
104112
TargetOpts, Reloc::PIC_,
105113
CodeModel::Default, OptLevel);
106114
if (!TargetMachine) {

0 commit comments

Comments
 (0)