A Brief Overview of Swift Compiler

Apple open-sourced Swift programming language and whole source code is now available on Github. There are thousands of programming languages available in the world and hundreds of on the way but underlying basics of programming languages remains the same. It’s very important to understand the roots so that you can learn programming languages easily. The languages are either compiled or interpreted. You can read the difference between them here. An interpreted languages take input and produce output directly however compiled languages first prepares executables and then with according to the data, they produce output.

Swift is a compiled language means before producing the actual output Swift perform various activities. These activities are generally performed by the Swift compiler. In this post, we will see the brief overview of the Swift compiler.

Phases Of Compiler

In the computer science, you might have learned the theory of compilers. The compiler has following five basic phases. Before diving into the Swift compiler, we will see those phases in brief.

  • Lexical Analysis

The job of lexical analyser is to take the programme text and convert it into the words and tokens. So what the heck are tokens? they are literally everything apart from the words. It might be white spaces, semicolon, braces etc. The lexical analyser takes everything literally everything and passes to Parser which is next phase.

  • Parsing

The main job of parsers is to take everything from lexical analyser, identify the roles, group them together so that programmers code make sense. The parser might know about the white spaces, braces and some branching logics etc. The parser then passes this code to Semantic Analyser.

  • Semantic Analyser

The process of semantic analysis can be important in language as it might identify types, logics of the programmes. It can also do some programme bindings. Once all these activities have done then it passes to optimisation phase

  • Optimisation

This compiler phases tried to clean your mess that you added to the code. This phase will decide whether to perform optimisation for certain code or not. At the end of this phase, your crappy code will be optimised for performance, memory related issues.

  • Code Generation

This is the final phase of the compiler where all your programme code turns into one giant binary file also known as executable. We can then execute this file different set of data.

In a summary, at the end compiler convert all your code into the giant file that nobody understands.

Swift Compiler

The swift compiler is very interesting, it not only does all the things that mentioned above but adds some salt and peppers that makes Swift different programming language than others. We will now understand the bigger picture of Swift Compiler. Obviously, we won’t go deep inside unless you want your hair turn grey or completely lose them. However, the main role of the compiler is to turn Swift into executable machine code.

The swift compiler has two dimensions like web or mobile applications i.e Frontend and Backend. Now we will see what happens at these two level

Swift Compiler- Frontend

The swift compiler does lexical analysis, parsing and semantic analysis from frontend and passes rest of the phases to the backend. Let’s consider following Swift code

This is the declaration of the Struct, it doesn’t have anything inside it. The lexical analyser takes this code as text with everything and produces something like this. Note that below is pseudo code.

As you can see that lexical analyser take everything and then passes it to the parser. The parser is smart enough to understand that it’s a structure and accept all the words and tokens from lexical analyser. The parser then converts lexical data into the structured representation of the programme. This representation is then passed to semantic analysis and then to the backend.

The frontend is also responsible for the features like Xcode integration, code completion and syntax highlighting.

Swift Compiler – Backend

The real power of Swift comes when the programmes come at the backend at compile time. Swift does some very smart things at the backend to deal with optimisation and code generation phase. The Swift compiler uses LLVM for optimization and binary generation. When Swift code parsed it’s in the form of  AST  stands for (Abstract Syntax Tree) which is then goes through semantic analysis and converted into Swift Intermediate Language (SIL). This is the place where additional Swift optimisation takes place which other programming languages didn’t have this kind of optimisationThis code goes through analysis and optimiser along with LLVM IR (Intermediate Representation).  The LLVM perform some magic and convert our original Swift code into assembly code and finally ends up in an executable file.

This is the basic flow of the Swift compilation process. I would love draw diagram but you won’t read this if there is the diagram.

Where is Swift Compiler Code

The process mentioned above is technically documented in the Swift compiler architecture here. There is no point to duplicate that information here but I would strongly recommend reading that page if you want to understand where is the code for each compiler phase in the Apple Swift GitHub repository. However here are quick links

Conclusion

The Swift compiler seems smarter than any other language’s compiler in term of optimisation and analysis. Those who are experienced Swift developers wanting to optimize their programs on Apple platforms must know that how the Swift Compiler works. I will cover practical example with various compiler tools in the next post. Please comment if I am missing or misrepresenting something.