forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial set of changes to add a new 'swift_driver' executable.
- Added a couple of new targets: - libswiftDriver, which contains most of the driver implementation - swift_driver, which produces the actual executable - Added centralized version information into libswiftBasic. - Added a new "Driver Design & Internals" document, which currently describes the high-level design of the Swift driver. - Implemented an early version of the functionality of the driver, including versions of the Parse, Pipeline, Bind, Translate, and Execute driver stages. Parse, Pipeline, and Bind are largely implemented; Translate and Execute are early placeholders. (Translate produces "swift_driver --version" and "ld -v" commands, while Execute performs all subtasks sequentially, rather than in parallel.) This is just the starting point for the Swift driver. Tests for the existing behavior are forthcoming. Swift SVN r10933
- Loading branch information
Showing
46 changed files
with
2,789 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
========================= | ||
Driver Design & Internals | ||
========================= | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Introduction | ||
============ | ||
|
||
This document serves to describe the high-level design of the Swift 1.0 compiler | ||
driver (which includes what the driver is intended to do, and the approach it | ||
takes to do that), as well as the internals of the driver (which is meant to | ||
provide a brief overview of and rationale for how the high-level design is | ||
implemented). | ||
|
||
The Swift 1.0 driver is not intended to be GCC/Clang compatible, as it does not | ||
need to serve as a drop-in replacement for either driver. However, the design | ||
of the driver is inspired by Clang's design (though it is "smarter" than Clang, | ||
since it performs some limited dependency analysis), and will only diverge if it | ||
produces a better design, or if it needs to implement something which Clang | ||
does not. | ||
|
||
High-Level Driver Design | ||
======================== | ||
|
||
The compiler driver for Swift will roughly follow the same design as Clang's | ||
compiler driver: it will parse command-line arguments into Arg objects; use | ||
those to generate a pipeline of Actions; bind Tools to each Action, which will | ||
then translate an Action into a Job; execute Jobs; and return a result code. | ||
However, since Swift source files must be compiled on a per-module basis, | ||
external build systems cannot easily detect while files in a module must be | ||
recompiled to accurately produce an executable. As a result, the Swift compiler | ||
driver must perform dependency tracking on its own, which means that all Jobs | ||
will not be executed. Instead, Jobs will be logically grouped, and each | ||
Job will have the opportunity to influence whether other Jobs in the same | ||
logical group will be executed. | ||
|
||
.. contents:: | ||
:local: | ||
|
||
Overview | ||
-------- | ||
|
||
The diagram below, taken from Clang's "Driver Design & Internals" document, | ||
shows the high-level design of the Swift compiler driver. | ||
|
||
.. admonition:: TODO | ||
|
||
Update diagram to show conditional Job execution | ||
|
||
.. image:: DriverDesign.png | ||
:align: center | ||
:alt: Driver Design Diagram | ||
|
||
1. Parse input strings into an ArgList of Args. | ||
|
||
2. Establish a pipeline of Action groups, such as the following: | ||
|
||
- A0: Input, "a.swift" | ||
|
||
- A1: Input, "b.swift" | ||
|
||
- B0: Compile, {A0}, "a.o" | ||
|
||
- B1: Compile, {A1}, "b.o" | ||
|
||
- C0: Link, {B0, B1}, "a.out" | ||
|
||
4. Bind the appropriate Tool to each Action. | ||
|
||
5. Using the bound Tools, translate each Action into a Job, creating a graph. | ||
|
||
6. Execute each top-level Job by performing the following: | ||
|
||
1. Ask each Job which is an input to the current Job if it needs to | ||
execute. This will have the side-effect of loading dependency | ||
information from the last build (if present). If a Job already | ||
knows that it needs to execute, schedule it for execution. | ||
|
||
2. Execute each Job which is scheduled for execution. This will have the | ||
side-effect of creating new dependency information for that Job. | ||
|
||
3. After each Job finishes execution, load the new dependency information | ||
and reevaluate every Job which is a peer to that Job. | ||
|
||
7. After all top-level Jobs been processed, the build artifacts should be | ||
present on disk, either from a new execution or from a previous execution. | ||
Return a result code. | ||
|
||
Driver Stages | ||
------------- | ||
|
||
The Swift compiler driver is conceptually broken into five stages: Parse | ||
(transforming input strings to ArgList/Args), Pipeline (transforming Args into | ||
groups of Actions), Bind (assigning Tools and other build information to | ||
Actions), Translate (using Tools to translate Actions into Jobs), and Execute. | ||
From a high level, these look like Clang's driver stages, and functionally | ||
they're similar. However, unlike Clang, Translate and Execute will, optimally, | ||
only be performed on a subset of Actions, and the execution of one Action will | ||
influence whether or not another Action is executed. | ||
|
||
Parse: Option parsing | ||
^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
This is a fairly straightforward port of the Clang driver's Parse stage. The | ||
command line arguments are parsed as options and inputs into Arg instances. | ||
|
||
Pipeline: Converting Args into Actions | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
This is also a fairly straightforward port of the Clang driver's Pipeline stage. | ||
At this stage, the driver will take the input Args and input files and establish | ||
a graph of Actions. | ||
|
||
Bind: Tool and Filename Selection | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
This stage, like the Clang driver's Bind stage, selects an appropriate Tool to | ||
use for each Action in a pipeline. This is achieved by asking the Toolchain for | ||
the right Tool for a given Action. Once every Action in the pipeline has a Tool, | ||
this stage will determine how to pass output from one Action to the next. | ||
|
||
For Actions which do not already have output filenames but require one, this | ||
stage will also assign unique output filenames. | ||
|
||
Translate: Translating Actions into Jobs using Tools | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
This stage, like the Clang driver's Translate stage, uses the Tool bound to each | ||
Action to translate the Args in ArgList into tool-specific arguments. Unlike | ||
Clang's Translate stage, though, the Swift driver will translate the graph of | ||
Actions into a graph of Jobs, instead of putting it into a serial queue. | ||
|
||
This stage must result in a graph of Jobs instead of a queue of Jobs so that | ||
Jobs can remain logically grouped. All Jobs which are an input to a particular | ||
Job will be given the opportunity to impact whether other Jobs in that logical | ||
group need to be executed; this permits us to perform partial rebuilds when | ||
safe. | ||
|
||
Execute | ||
^^^^^^^ | ||
|
||
This stage, like the Clang driver's Execute stage, executes the Jobs which are | ||
created by Translate. Unlike Clang's Execute stage, Swift's will support | ||
concurrency: at the most basic level, this will be something like ``make -jn``, | ||
where the compiler executes up to n Jobs concurrently. This could be enhanced to | ||
include things like intelligently scaling back the number of Jobs if the system | ||
is under pressure, but that may not be necessary for Swift 1.0. (Another | ||
possible enhancement would be to let an external build system update the value | ||
of n as the build continues, but that will definitely not be necessary for 1.0.) | ||
|
||
Jobs will be scheduled onto a single work queue. Multiple Jobs may execute | ||
simultaneously, but Job termination will be handled on a single thread. When a | ||
Job terminates, the driver will evaluate the other Jobs in that Job's group | ||
to determine if any additional Jobs need to be scheduled. Once all outstanding | ||
Jobs in the same group have terminated, any unprocessed Jobs will be evaluated | ||
before executing the downstream Job for which all of the Jobs in that group are | ||
an input. | ||
|
||
Driver Internals | ||
================ | ||
|
||
TBD |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ Contents | |
StoredAndComputedVariables | ||
SIL | ||
TypeChecker | ||
DriverInternals | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_subdirectory(swift) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
##===- include/Makefile ------------------------------------*- Makefile -*-===## | ||
# | ||
# This source file is part of the Swift.org open source project | ||
# | ||
# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors | ||
# Licensed under Apache License v2.0 with Runtime Library Exception | ||
# | ||
# See http://swift.org/LICENSE.txt for license information | ||
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
# | ||
##===----------------------------------------------------------------------===## | ||
|
||
SWIFT_LEVEL := .. | ||
DIRS := swift | ||
|
||
include $(SWIFT_LEVEL)/Makefile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//===- Version.h - Swift Version Number -------------------------*- C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// \file | ||
/// \brief Defines version macros and version-related utility functions | ||
/// for Swift. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_BASIC_VERSION_H | ||
#define SWIFT_BASIC_VERSION_H | ||
|
||
#include <string> | ||
|
||
namespace swift { | ||
namespace version { | ||
|
||
/// \brief Retrieves a string representing the complete Swift version, which | ||
/// includes the Swift version number, the repository version, and the vendor | ||
/// tag. | ||
std::string getSwiftFullVersion(); | ||
|
||
} // end namespace version | ||
} // end namespace swift | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
add_subdirectory(Driver) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef SWIFT_DRIVER_ACTION_H | ||
#define SWIFT_DRIVER_ACTION_H | ||
|
||
#include "swift/Basic/LLVM.h" | ||
#include "swift/Driver/Types.h" | ||
#include "swift/Driver/Util.h" | ||
#include "llvm/ADT/ArrayRef.h" | ||
|
||
namespace llvm { | ||
namespace opt { | ||
class Arg; | ||
} | ||
} | ||
|
||
namespace swift { | ||
namespace driver { | ||
class Action; | ||
|
||
class Action { | ||
public: | ||
typedef ActionList::size_type size_type; | ||
typedef ActionList::iterator iterator; | ||
typedef ActionList::const_iterator const_iterator; | ||
|
||
enum ActionClass { | ||
Input = 0, | ||
CompileJob, | ||
LinkJob, | ||
|
||
JobFirst=CompileJob, | ||
JobLast=LinkJob | ||
}; | ||
|
||
static const char *getClassName(ActionClass AC); | ||
|
||
private: | ||
ActionClass Kind; | ||
types::ID Type; | ||
|
||
ActionList Inputs; | ||
|
||
unsigned OwnsInputs : 1; | ||
|
||
protected: | ||
Action(ActionClass Kind, types::ID Type) | ||
: Kind(Kind), Type(Type), OwnsInputs(true) {} | ||
Action(ActionClass Kind, ArrayRef<Action *> Inputs, types::ID Type) | ||
: Kind(Kind), Type(Type), Inputs(Inputs.begin(), Inputs.end()), | ||
OwnsInputs(true) {} | ||
|
||
public: | ||
virtual ~Action(); | ||
|
||
const char *getClassName() const { return Action::getClassName(getKind()); } | ||
|
||
bool getOwnsInputs() const { return OwnsInputs; } | ||
void setOwnsInputs(bool Value) { OwnsInputs = Value; } | ||
|
||
ActionClass getKind() const { return Kind; } | ||
types::ID getType() const { return Type; } | ||
|
||
ArrayRef<Action *> getInputs() const { return Inputs; } | ||
|
||
size_type size() const { return Inputs.size(); } | ||
|
||
iterator begin() { return Inputs.begin(); } | ||
iterator end() { return Inputs.end(); } | ||
const_iterator begin() const { return Inputs.begin(); } | ||
const_iterator end() const { return Inputs.end(); } | ||
}; | ||
|
||
class InputAction : public Action { | ||
virtual void anchor(); | ||
const llvm::opt::Arg &Input; | ||
|
||
public: | ||
InputAction(const llvm::opt::Arg &Input, types::ID Type) | ||
: Action(Action::Input, Type), Input(Input) {} | ||
const llvm::opt::Arg &getInputArg() const { return Input; } | ||
|
||
static bool classof(const Action *A) { | ||
return A->getKind() == Action::Input; | ||
} | ||
}; | ||
|
||
class JobAction : public Action { | ||
virtual void anchor(); | ||
protected: | ||
JobAction(ActionClass Kind, ArrayRef<Action *> Inputs, types::ID Type) | ||
: Action(Kind, Inputs, Type) {} | ||
|
||
public: | ||
static bool classof(const Action *A) { | ||
return (A->getKind() >= ActionClass::JobFirst && | ||
A->getKind() <= ActionClass::JobLast); | ||
} | ||
}; | ||
|
||
class CompileJobAction : public JobAction { | ||
virtual void anchor(); | ||
public: | ||
CompileJobAction(Action *Input, types::ID OutputType) | ||
: JobAction(Action::CompileJob, Input, OutputType) {} | ||
|
||
static bool classof(const Action *A) { | ||
return A->getKind() == Action::CompileJob; | ||
} | ||
}; | ||
|
||
class LinkJobAction : public JobAction { | ||
virtual void anchor(); | ||
public: | ||
LinkJobAction(ArrayRef<Action *> Inputs) | ||
: JobAction(Action::LinkJob, Inputs, types::TY_Image) {} | ||
|
||
static bool classof(const Action *A) { | ||
return A->getKind() == Action::LinkJob; | ||
} | ||
}; | ||
|
||
} // end namespace driver | ||
} // end namespace swift | ||
|
||
#endif |
Oops, something went wrong.