Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2011-307
$eventId
ID of event: wwdc2011
$eventContentId
ID of session without event part: 307
$eventShortId
Shortened ID of event: wwdc11
$year
Year of session: 2011
$extension
Extension of original filename: m4v
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2011] [Session 307] Moving to A...

WWDC11 • Session 307

Moving to Apple LLVM compiler

Developer Tools • iOS, OS X • 58:40

Apple LLVM is the modern compiler for Mac OS X and iOS development. Discover the latest features in the Apple LLVM compiler, and see how to take advantage of them in your application. Learn from Apple's compiler team as they walk you through the steps to migrate your project from GCC to LLVM.

Speakers: Doug Gregor, Bob Wilson

Unlisted on Apple Developer site

Downloads from Apple

HD Video (208.9 MB)

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning, I'm Bob Wilson, I'm the manager of the LLVM core team. Thank you for coming today to find out about moving to the LLVM compiler. So let's get started. One of the big announcements we made on Monday is that Apple has moved to the LLVM compiler. We're building both Mac OS X Lion and iOS 5 with LLVM-based compilers. And we're here today to ask you to do the same thing.

So if you're new here, or even if you're not, you may be wondering, what is LLVM? Or what other compiler would I use? So before we go into LLVM, I want to give you a little history lesson on compilers at Apple. So for quite a long time now, Apple has been using the GNU GCC compiler.

A lot of you are familiar with that. And that's one of its advantages. It's portable, it's familiar, people have been using it. It has pretty good performance. We've built a lot of great software products. You have built a lot of great apps using the GCC compiler. And it works, so that's great. But it's had some downsides too.

One of those is that the error messages that you get from GCC are not always as helpful as they could be. Sometimes they're downright confusing. One of the big problems for us is that we would really like to integrate the compiler into other tools. Now, GCC has a 25-year-old monolithic architecture. It is a compiler, and that's all that it is. You take in source code, and it puts out object code.

So we'd like to do better than that. It's also been hard to improve GCC. I said the performance has been pretty good, and it has, but we really want to take performance up to the next level. And GCC has been stifling innovation for us in the compiler. So we need a better compiler. And that is LLVM.

That's our LLVM dragon logo up there. So the architecture of LLVM is really one of the key things that makes it work for us. LLVM is architected as a set of reusable compiler components. We can hook them up in different ways, we can integrate them in different tools. Some examples of components: The Clang front end, which is a unified C, C++, and Objective-C parser. It's designed to be really fast. It's designed to give good error messages.

Optimizations. We have a great set of sophisticated transformations that we can apply to make your apps run faster. We have machine code generators for a variety of targets, including the Intel and ARM processors that we use in Apple products. and we have a set of various low-level tools such as assemblers and disassemblers.

So just as an example, consider the LLDB debugger you may have heard about this week. We want to use the Clang front end in the debugger when you say print the value of this expression. We want to allow you to have any arbitrary expression from the language, and so we need to have a parser that can understand that language. So it makes a lot of sense to take that front end, put it in the debugger. We also want to be able to set breakpoints, step through code, disassemble. So we can take those components from the LLVM components, put them into LLDB, and really integrate everything together.

LLVM is an open source project. We invite you to visit us online at LLVM.org. You can learn more about the project. You can even get involved and help out in the development if you want to. So this is just some background on LLVM and where we're coming from. Let's get into the compilers in Xcode.

If you've been using Xcode for a while, you may have seen we have two different compilers with LLVM. The first one is LLVM-GCC, which takes this high-tech LLVM backend, symbolized by this race car, combines that with the same old GCC front end. We basically just bolt them together. It's a little bit awkward, but it has one big advantage, and this is why we call this our legacy compiler. The GCC front end will accept all the same code as the GCC compiler did, because it's the same compiler.

So this has played a useful role for us and continues to do that, but it still has the same problems. You still get the same confusing error messages from GCC. You still have the same monolithic architecture that keeps us from integrating it. So it's time to retire that GNU. We're going to send it out to Pasteur.

and replace that with the Clang front end, symbolized by this racehorse. Now we have all new LLVM based technology. They work together really well. And this is where we're putting all of our focus for new features in the compiler. So in this next part of the talk, we're going to talk a bit about some of those features.

One of those that we think is really helpful that you will enjoy is diagnostics. We spend a lot of time trying to give you error messages that make it as clear as possible what the problem in your code is. We're going to talk about how LLVM is integrated in Xcode, so you get the great benefits of the LLVM compiler without having to leave the great Xcode IDE environment. We have a static analyzer. It deeply analyzes your program to help find problems before you even realize they're there. We've got some new C++ language features to talk about.

and we've got great performance. So I want to clarify that some of these features here have been in LLVM for a while. Some of them are brand new in version 3 of the LLVM compiler. So we're going to go through some of these today, and I'd like to introduce Doug Gregor, who is our Clang technical lead, who's going to start us off.

Thank you, Bob. So we're going to take a look at some of the features of the Apple LLVM compiler powered by the Clang front end. And first we're going to look at the user interface of the compiler, since at Apple we're all about user interfaces. And so here's our great 1970s command line technology for using compiler. Wow.

Run the compiler, you give it a C source file, it builds an executable. This is really boring and uninteresting. The only important part about this side of the user interface is that we accept the same command line options as GCC. So we're backward compatible with GCC, and this means if you have a make file project, if you have scripts that build code just by calling the compiler directly, just replace GCC and G++ with Clang and Clang++. Command line options are the same, we support GNU extensions, so it's drop-in compatibility. It's very easy to move from one compiler to the other.

A lot of you probably don't even use this because you use Xcode, and that's fine. The other side of the user interface are the compiler's diagnostics. So these you probably see every day, right? These are the warnings and the errors that the compiler generates when it finds some kind of problem in your source code.

Right? Maybe you're not conformant with the standard, or maybe it just found something fishy in your source code it wants to tell you about. When it finds the problem, it's going to try to diagnose the problem internally and explain the problem to you in simple terms so you can understand how to fix the problem quickly and move on.

Most important thing of compiler diagnostics is clarity. Here's an example where GCC utterly and completely fails the clarity test. It's a great error message. It tells you the parser state at the point where something went wrong. Does that help you? I hope not. It doesn't help me either.

There's only one important information, there's only one bit of useful information here. And that is the file and the line where the error happened. And you can go look at the source code and figure out what the actual problem is. With the Apple LLVM compiler, we want to do a lot better.

So here we give a clear diagnostic. It says what the problem is. This webframe view type you thought existed, it doesn't exist. There's no type by that name, maybe because you forgot to include a header. We also show the line of source code where the problem happens, and the little green caret points exactly to the line and column where this problem occurred. So you look at the right part of your source code to fix the problem.

The last thing we do, if you're actually using the terminal, you will see this coloration here, just to try to bring your eye to the part that matters of the source code. So you can find the errors quickly, sort through the diagnostic that you get, and fix the problem.

There are a number of innovations in the way the Apple LLVM compiler presents diagnostics to really help you understand the problem and fix it fast. One of those is diagnostic ranges. So here we have an example where we have some problem with the binary expression. So the subtraction operation doesn't work because the types are wrong.

So we have a text description that shows what the problem, describes what the problem is, but we also show you with the caret exactly which operation failed. Right, where's the problem? And it's going to highlight with the little underlines the left and right hand sides of that operation, so that on busy lines where you have a lot of operators, you have a lot of operands going on, you can see exactly what the compiler is talking about.

With some diagnostics, this is absolutely critical, because here we have a whole ton of equal signs on the line. We don't think there's assignment. There wasn't meant to be assignment. Here it is. The compiler is going to point out, this is the place where you made a mistake. In this case, you used assignment instead of equality. And with that diagnostic range information with the caret, you can find that problem very quickly.

Something we introduced last year was spell checking. So a lot of the mistakes we make as programmers are we just mistype something, we miscapitalize it. So here I have this little mistake where I was a little bit lazy on the shift key when I was typing, and I capitalized the U in NSMutableArray. The compiler could say, "I don't know what the NSMutableArray identifier means," and leave you at that, and you'll stare at it for a while before you realize the height of the bars and the U is a little bit too high.

Instead what it does is it realizes you tried to name something that doesn't exist, so it's going to look at all the names that would have made sense at that particular point in your program. And if it finds something close, it will suggest that something close with a spell checking diagnostic.

So this year, we've taken this a little bit further and tried to make it better. So it recognizes more names in more places, it provides better corrections, recovers from those corrections better, and it actually can get to the point now where we can correct for mistyped keywords to really deal with any of the problems that you show up in your source code that are simple typing mistakes.

Now spell checking is an interesting, different kind of diagnostic from the others. So with the previous diagnostics we saw, the compiler told you there was a problem, but it didn't necessarily know what kind of fix to apply here. With spell checking it says, this is the problem and here is the solution. Fix it to take that one step further and actually show you how the solution would look in your source code. So what we're doing here is the same NSMutableArray example we saw earlier, where we suggest a correction.

Now here in the output, we've underlined the mistyped NSMutable array with the wrong capital U to tell you this is the part of the code you need to change to fix the problem. And underneath in green, we're saying this is the fix to apply. Here's the text you put up there in replacing the underlying text to solve the problem.

So fixits are really, really great, because they find the little syntactic annoyances like dropped open square brackets on message sends for nested message sends, or missing semicolons at the end of an expression that you actually wanted to turn into a statement. And fixits can really, really help solve these little problems quickly that add up to wasting your developer time, just to get you to the point where you can actually build your app and test it, do the interesting part of development.

So let's talk about something new. We've introduced a bunch of new warnings into the Apple LLVM compiler, and one of the big new classes of warnings are warnings on uninitialized variables. So here in this example, we have some variable delta, and we have a call to transform that uses a block that happens to refer to delta.

The Apple LLVM compiler wouldn't give any warnings on this previously. Now we can produce a warning that describes exactly what's going wrong here. So here we have not initialized delta, and yet we've captured in a block. So the Apple LLVM compiler will tell you this through a warning that says delta is uninitialized at the point of capture, and refer back to the variable delta through this extra note. We'll see these a little bit more later. Through this extra note that points out what variable of delta is actually being referred to, because what may have happened here is you're referring to the wrong variable, not that it's actually an uninitialized variable.

Now, with uninitialized warnings, these were available in GCC and LLVM GCC, and have been for a long time. There's one really annoying aspect of them, which is that they depended on how the optimizer ran. So this means that as the optimizer found different ways to optimize your code, you would get different warnings out of this, which is infuriating.

And more importantly, when you did this with GCC, you wouldn't get warnings if the optimizer wasn't turned on. So your debug builds, the most important place to see these warnings, you would never actually get any benefits of this warning. In the Apple LLVM compiler, we wanted to do better, and the way we did this is to implement these warnings in the front end, so that you get the exact same behavior in debug mode, in release mode, it doesn't depend on any of the back end optimization stuff.

So we realize, so with uninitialized warnings, we also realized that the optimizer in GCC didn't always produce useful warnings. And so with the Apple LLVM compiler, we decided to be a bit more conservative with the introduction of this. We want everyone to be able to use it. However, we didn't turn it on by default. If you want these warnings, and we suggest that you really do want these warnings, you can use "-w uninitialized", or "-w all", to bring in these uninitialized variable warnings.

We've also been conservative in that we only want to diagnose warnings, diagnose unused variables, initialized variables, in cases where the compiler is certain there's a problem. And so, you've probably been looking at this example for a couple seconds, is this an uninitialized variable use, or is it not? Well, we've initialized under this if statement.

So if we should transform, then we set delta. And then later on in the code we check, well, should we transform and then use delta? So clearly from the programmer's standpoint, this code is good. Should transform is going to return the same thing twice in a row, of course.

Right, so this is some kind of global program invariant that you are thinking of in your head, and the compiler has no idea whether this invariant holds or not. And so our way to deal with this at this point is to say, we're not going to diagnose this as a warning, because it's probably going to lead to what you would consider as false positives, something that clearly the compiler is wrong. The way we tackle this is we added another flag called -w conditional uninitialized.

And this is for people that really want to make sure that they don't have uninitialized variables. And they want to have warnings about this sort of case, where the compiler can't reason about program invariants or large-scale invariants, and they want to see that, and they're willing to rewrite their code.

So this is the more aggressive version for people that want to deal with all of these problems. -w uninitialized should be good for anyone at all, and we highly recommend that you turn it on. Let's look at something specifically for Objective-C called the InferredResultType. Take a look at this little bit of code.

There's a bug here. I'm sure you've all found it by now. Yes, I hope. No compiler that we've ever shipped has been able to diagnose this, because it doesn't understand how these functions actually work. What we've done with the Apple LLVM compiler version 3 is we've added some type inferencing that allows us to detect this problem.

Now this is great. You allocate an NSArray on the right hand side. You initialize that array. Compiler now knows that that returns an NSArray and can warn you that you just assigned it over to a variable that thinks it's an NS set, which is a completely different class. This is a ticking time bomb in your source code if you're allowed. Now we can actually diagnose this.

The way we do it is through inference. We actually understand Cocoa conventions, Cocoa naming conventions, within the compiler to understand that when you send a message to alloc and init, you get back an instance of that type. We think this will be really great. It detects a huge number of subtle bugs that have been around for a very long time in code. We think you're going to like it.

Now this is just one advancement to Objective-C. Of course, you've also heard of Arc. And we have another session later on this week called Objective-C Advancements in Depth, where you can go to learn about other advances to the Objective-C language. With that, let's move on to Xcode integration.

So one of the great things about building your compiler as a modular system is you can take some of the components in that modular system and put them into new places. Like here we take the Clang parser and front end and move it into Xcode to give a better user experience. First place you'll tend to see this is in the live warnings and errors.

Essentially what's happening here is as you're typing in your editor, you're introducing new code, and of course you're introducing new bugs. So what the compiler is going to do is it's going to run behind the scenes to check your source code to see if you've introduced a problem.

If you have introduced a problem, you'll get a little pop-up here. So you get the underlying under the issue in this particular code, underlying the string literal, and you get a little badge in the left-hand side that indicates that the compiler has found a problem here. If you want to go solve it, you can go click on the badge to get some information about what the problem is, fix the problem. As soon as you fix that problem, the warning goes away from your editor.

This is actually somewhat of a change in the workflow. We tend to write a bunch of code and then build and see what the compiler does, and then build and see what the compiler does again. Instead, you can interact with the compiler here. And once you've dealt with all of the issues that it's diagnosed, well at that point, the file's going to compile cleanly. And you can just build and start testing your app.

So when you get one of these live warnings or errors, you can go click on the badge on the left hand side, and it's going to pop up to something like this. So it'll show you what the problem is. The problem in this case is that we have incompatible pointer types. We tried to pass a character array, this is string literal, to something that expected an NSString.

Clearly that's not going to work. Of course, this is one of those cases that Objective-C programmers tend to make this mistake. And so the compiler actually recognizes that this is the problem and suggests to fix it. So now you see how we've taken the fix it feature from the compiler and surfaced it in Xcode via this little pop-up. What the pop-up suggests is the simple correct fix to this problem, which is introduce the @ sign to turn this C string literal into an Objective-C string literal. You just accept the fix it by clicking on that. Your source code is updated and the warning goes away.

Fixits can solve a number of problems. So in this case, we fixed that problem, but it turns out I introduced a bunch of bugs in my one simple logging statement. And here, I used the wrong conversion specifier. I used %d, that's for integers, not %f for doubles, but I had given a double. Compiler, of course, can detect this, reports it, but it goes one step further and actually suggests the replacement that fixes your string literal in place so you have the right conversion specifier for using NSLog.

This is way better than going and hunting through the NSLog documentation to figure out what is the conversion specifier I need in this particular case. Compiler knows what it is, it can check it, it can tell you exactly how to fix your code without doing anything else. The fixits we've seen so far, however, have been fairly simple.

When there's been a fixit to suggest, it's been obvious what the answer was. Introduce the @ sign, introduce a missing semicolon, whatever. Sometimes fixits aren't that simple. So here we have a case where we're doing a test with bitwise and, and then we're doing an equality comparison against zero.

This is suspicious, because the precedence rules for these operators in C are actually a little bit weird and not usually up with programmers' expectations. And so in this case, the compiler is going to warn about it and suggest two different options. Now the first option in this case is "silence the compiler". This is the "I know what I'm doing", this is what I meant to write, and what it's going to do is it's going to introduce parentheses around the equality expression, because that's what's evaluated first in this case, I'm sure you all knew that.

It's going to introduce those parentheses to tell the compiler "this is what I meant", which silences the warning. Of course, it also tells future programmers that look at this, "yes, this is actually what I meant, there's no bug here". Of course, in this case, we're trying to do a bitwise test here, and we look at the second option.

The second option is going to insert the parentheses in the other place around the first expression, the bitwise "and", to evaluate that first and test the result against zero. This option changes the semantics of the source code, but in this case, it actually fixes the bug in the source code that was found by the compiler.

So when you see these fix it pop up, look through the options, decide what is the best option for you. Either way, we will silence the compiler and move along so you can get back to a clean editor with no issues, and your file will compile then with no errors.

So another place where we've surfaced more information from the compiler in Xcode is the notes feature. So in previous examples, there are a couple examples where we had some sort of warning or error that came out of the compiler, and then there was a note that provided additional information to tell you that that warning or that error is actually related to something else in this other part of your source code.

[Transcript missing]

If you look in the issue navigator, there's going to be this little disclosure triangle next to the incomplete implementation issue.

Select that triangle, and now you get all the extra information the compiler is giving you. So in this case it's telling you these three methods need to be defined somewhere. and David It's essentially a little to-do list of what you actually need to do to fix the problem.

Now if you were to go in and click on one of those method definitions, it's going to jump to the declaration of that method, which shows you the method that hasn't been implemented yet, and you get the choice of either jumping back to the implementation to go implement that method, or realizing, hey, I don't need this method anymore, delete it at this point.

Either way, the note's going to go away, and once you've resolved all the problems in the note, the warning is going to go away. The last feature I want to talk about in Xcode is code completion. So the idea here is that Xcode has always had a code completion engine, but the compiler is really the tool that understands your code better than any other tool on the system ever can.

The compiler has to know everything about the language that it has to compile. And so it can actually give you more accurate completions based on its deep semantic knowledge of how the program works and what's available at that point. So in this case, we're doing a simple completion in a C++ or Objective C++ program that asks for all of the entities that start with M in the standard namespace.

Something we unfortunately couldn't do with the previous code completion engine, we can do now that we use the compiler, because the compiler understands everything. It understands class templates, and so it can give you the map class template with placeholders for all the template arguments. It understands function templates like max and make tuple and so on, along with typedefs and everything else.

And so you can get more completions out of this using all of the features of the language. Now, it can even reason about complicated things. So, this particular code looks really, really simple. All we have is some variable i, we apply the arrow operator, and ask for everything starting with f there.

Behind the scenes, this is not so simple. So I is actually an iterator into one of the data structures that comes out of the standard library. What's an iterator? Well, it's a custom class. In this case, it's actually a class template of some sort. So behind the scenes, what the code completion engine is doing is it's understanding all of C++ templates, understanding all of template instantiation, how that happens.

Then it gets back to a class. However, then it has to look at the arrow operator, and it introduces the notions of operator overloading. It understands operator overloading, so it can see exactly through that arrow operator, it's overloaded, and down to what the compiler would actually see to give you the same results the compiler would see.

This gives us more accurate completions, and we can adjust the priority of completions based on information such as, well, what's the type that you actually want to use at this particular point? With that, we're going to look at something that's also based on the Clang front end and integrated in Xcode. It's called the Xcode Static Analyzer.

The Xcode Static Analyzer is a really great tool that uses deep compiler analysis techniques to find bugs in your source code. Now the Static Analyzer is interesting. So the way it works is to actually look at all of the various paths through your program to find what conditions would trigger a bug.

So you can imagine that in the normal path of your code, you have no problems. However, it could be the case that if you take the if branch up here in your program, and then a couple lines down in the function, well, you take this else branch down here for some unrelated condition, along just that one path, you have some sort of bug. You have a null pointer to reference. Some kind of problem.

This is the kind of thing that's hard to find in testing, because you have to have those conditions exactly right to follow that path to hit the issue. The Static Analyzer is going to reason about all of the problems that you have to solve. All of your paths at the same time to see if there are problems along any of those paths, and report those as issues.

The kinds of problems it can find? Well, it can find these logic errors, right? Null dereference problems, where you forgot to check whether something was null before you actually went and accessed it. It'll produce an issue for that. The static analyzer understands the APIs. It understands how core foundation works, and the underlining Unix APIs, so it can tell you when you're misusing those APIs. It also knows Cocoa memory conventions. It understands when things are returned retained, when things are released. So it can detect memory leaks in your program in a path sensitive manner.

and it's better just to see how this works. So here's an example of finding leaks in a program using core foundation. The example here, we're creating a CFDate with CFDate create. We do that in the first case. And then when X is not zero, we release that date. The very end of the function, we return this CFDate, we return something.

So at this point, if you were testing it, perhaps in all of your testing, X is non-zero. Maybe it varies widely, but X never gets to be the value zero. You'll never see a leak in your testing. With the static analyzer, it checks all of your paths. It realizes, well, when X is zero, We're not going to call this release, and therefore this object is going to be leaked.

And it actually shows you this within the Xcode editor. You can see the arrows flowing from one point of your program to another. That's describing the path that it's taken through your program to find this bug. So it went to the CFD create. It skipped over the if statement and went directly to the return. And this is exactly the case under which this code leaks. The Xcode static analyzer can also reason about loops. So in this case, we have two loops. One that initializes an array, and another one that both reads and writes back to the array.

The static analyzer here is complaining that you're reading a garbage value when you read from the array. Well these loops, they look the same. It looks like there's no bug here. But the static analyzer has actually realized that because you're looping over different constraints here, In the first case, we only initialize the first three elements. In the second case, we're reading all four of the elements. So there's a bug here. The static analyzer will describe it to you by showing you the paths it took through the program under which you'll actually find this bug manifesting.

Static Analyzer is really a great tool. And you can use this directly from Xcode by going to the product menu and selecting Analyze. Analyze is essentially a special kind of build of your program. So it's essentially going to run your entire program through the compiler again, but this time it's going to do some detailed analysis of how your program works and its use of the Cocoa APIs, looking for leaks, looking for API abuses, looking for null dereferences. Now this takes more time than just a simple build does. So there's a trade-off here. On the other hand, it does find real bugs in your software that you want to fix before they get into testing.

When it finds those problems, it's going to report them the same way that a compiler would. So we have warnings and errors reported from the compiler. We also have static analyzer issues, and these are reported both in your editor and in the issue navigator. So you can explore them, find out what problems it found in your source code.

Now if you love the static analyzer, and I hope you all do, you can actually turn it on every time you do a build. So you find the problems as you introduce them before it crashes your app in testing. And here you can go into the build settings for your project. Under the build option setting there's run static analyzer. Just turn that on to yes, and every time you hit build you will also get static analysis results along with the normal warnings.

Now, Static Analyzer has one new feature this year inside Xcode for controlling specifically what checks to do. So we realized that Static Analyzer has a bunch of different checks. Not all checks are interesting to all people. So here you can again go into your build settings and decide what checks are important to you, what checks find real problems in your code, turn just those on, and you don't have to use other checkers that you don't like. We've done a lot of work on the Xcode Static Analyzer this year, and one big new feature is we have full support for analyzing C++ and Objective C++ programs.

Now C++ programmers can get all the same benefits as Objective-C programmers, and it's a good thing. So you can see here the static analyzer running on a very large C++ application, which happens to be the Apple LLVM compiler itself, and finding a real bug. So what's happening here is a little bit interesting. This is the dead stores checker. And the error that the static analyzer is giving here is that the value that you stored to S is never read.

Now this is actually a symptom of the real problem. The real problem is that we forgot to put break in here. And that's allowed by the language. Sometimes you do want to fall through. So what the static analyzer is doing is it's reasoning about the paths in your program. And what it realizes is that when we jump into this case statement, we allocate a new object and assign it over to S.

That's fine. We then fall through to the next case, which seems to be fine from the C language perspective. We allocate a new object and assign it to S, which completely clobbers the previous value of S. And that object that was previously assigned to S goes away. This is almost always an indication of something weird going on in your program. And in this case, we found the problem introduced the additional break. So we fixed the bug.

Since we're on the subject of C++, well, let's talk about C++ a little bit more. There's a whole lot of buzz in the C++ community about this thing we call C++ OX. So C++ OX is an upcoming revision to the C++ standard. It's been in the C++ community for about eight years. They've been working on it, and they've introduced major changes to both the language side of C++ and the standard libraries that come with it.

There's a whole pile of new language features that are great to use, and the C++ standard library has been improved to pick up and use those language features to give you a better library experience, and expanded with new great functionality. Now all of this is designed to provide great backward compatibility with your existing C++ applications.

So I'm thrilled to tell you here today that we are providing C++ OX support in the Apple LLVM compiler version 3. Yay! To get this support, again, just go into your build settings, and we have the C++ language dialect option. You can now pick C++ OX to get these great new C++ OX features. If you also want to rely on GNU extensions, there's GNU++ OX, which is all the C++ OX features, plus the GNU extensions you're probably accustomed to using within C++.

So nobody has managed to implement all of the C++ OX language. It's actually a huge set of new features. We've done pretty well, so we've tackled all of these features in the last year or so, but we're not going to go into any detail in this talk about those features. If you're interested in seeing how some of these features work, how they can be used to improve your app, I recommend you come to the LLVM technologies in-depth session tomorrow afternoon, where we'll tell you a bit more about how these features actually work.

Now I said that C++/OX was both a language thing, which is covered by the Apple LLVM compiler. It's also enhancements to the C++ standard library. For this, we introduce completely new LLVM C++ standard library, which we call libc++. Now this is a great new implementation of the C++ standard library. It's been re-engineered from the ground up with the idea of building the best library we can for C++/OX.

So we use these new C++/OX features throughout to give a better performing, easier to use standard library that supports the entire C++/OX standard. Now since we had this opportunity to re-engineer our C++ standard library, we could actually put to use all of the things that we've learned from maintaining the old C++ standard library.

So this new standard library has better data structures that take less memory and are faster. It has better algorithms that produce faster code. So that your uses of the C++ standard library will just go faster. It also introduces new functionalities such as regular expressions, smart pointers, hash tables, threading.

All of these new libraries that came into the C++/OX standard as part of the standard library, these are provided as part of libc++. libc++ is part of the LLVM project and as such it's fully open source. You can go learn more information about it at libcxx.llvm.org. And if you happen to love working on C++, you can go to libcxx.llvm.org.

And if you happen to love working on C++, you can go learn more information about it at libcxx.llvm.org. And if you happen to love working on C++, you can go learn more information about it at libcxx.llvm.org. And if you happen to love working on C++ template libraries, you can even come join us. No takers? Okay.

So we have better data structures and algorithms. I want to show you one of the coolest algorithms in libc++. And this is the sort algorithm. So here we have the sort algorithm, and we're comparing our existing C++ standard library, which is lib_standard_c++. You've been using it from GNU. And lib_c++. And so this performance chart is based on time, so smaller is better. And we're showing the variation in performance of the lib_standard_c++ sorting algorithm, depending on how the input looks.

and of course the algorithm is going to vary because different algorithms are better for different distributions of data. Now the libc++ approach to solving this problem is it actually recognizes these different kinds of patterns. When the whole sequence or when some sub-sequence of the sorted sequence fits into one of these cases, it can use a specialized algorithm that does a better job at sorting faster.

And doing so we get huge wins in many of the common cases, many times faster than the previous sorting algorithm. Now you notice there's one case where we weren't faster, and that's in the random case. If there's truly random data, there is some cost to this pattern recognition, and we end up being a little bit slower.

This is a perfectly acceptable engineering trade-off since data that you actually get to be sorted, it's never random. It has these substructures. We can zoom in on those, provide a better algorithm, and give you better overall sorting performance out of this library than we could in the previous library.

So libc++ is now available in Xcode 4.2, the same Xcode that has the new Apple LLVM compiler with C++ OX features. If you build your app against libc++, you can deploy it to both Lion and iOS 5. Selecting the C++ standard library is now available in the Xcode build settings.

Right next to the C++ language dialect, you can choose to use libc++. And together, C++ OX support in the compiler and C++ OX support in the new libc++ standard library gives an absolutely wonderful C++ OX experience for developing applications. We're going to talk a little bit more about libc++ in tomorrow's LLVM technologies in-depth session in Pacific Heights in the afternoon. With that, I'm going to turn it back over to Bob, who's going to talk about compiler performance. Thank you very much.

Thank you, Doug. So compilers are all about performance. We spend a lot of our time trying to make sure we get two different kinds of performance for you. One, build time. We want your apps to build really fast so you don't have to sit and wait. The second kind of performance is the code quality. We want to optimize your apps so that your users don't have to wait.

So let's start looking at build time. This is a graph showing the build speed in debug mode for a Mac OS app, particularly the Sketch example app. We're going to compare the build speed with GCC against the Apple LLVM compiler. So we've defined here the build speed of GCC is 1. Bigger bars are better.

The Apple LLVM compiler builds this app more than twice as fast. Sketch is a small example, so you may be wondering, does this same kind of win carry over to a really big application? I suspect most of you are familiar with the Preview app, so let's look at that.

And you see that the Apple LLVM compiler is about twice as fast building preview. And to put that into perspective, on my machine it takes about a minute to build preview in debug mode. So that twice as fast build time cuts that time that I have to wait down to about 30 seconds. Instead of waiting for a minute, I only have to wait for 30 seconds. That's a huge win and will save you a lot of time.

So that's for debug builds. What about release builds? If you're tuning performance, you may need to be building in release mode with full optimizations. So let's look at that. This graph is going to show build time in release mode, this time for iOS. We've taken five industry standard spec benchmarks, Again, we're comparing build speed against GCC. So GCC has a build speed of 1. Bigger bars are better, and the Apple LLVM compiler is faster across the board on these apps.

And in fact, it's typical to get build speeds two to three times faster with the Apple LLVM compiler. Again, saving you time while you're building your app. So the other kind of performance that I mentioned is not build time, but the quality of the code that we generate, so that your apps will run fast.

Looking at those same five standard benchmarks, again running on iOS, comparing against GCC, we're getting speed ups from 11% all the way up to 26% on these same five applications. This is huge. This is free performance for your apps, if they're anything like these benchmarks. And all you need to do to get this performance is to switch your compiler to the Apple LLVM compiler. So I want to zoom in for a minute on one area where performance really matters a lot, and that is media applications.

In most cases, if you have some sort of high performance media computation, it's best to use one of the standard frameworks. Sometimes you need more custom code. You need to do something that isn't supported directly. One option that's available to you now with the Apple LLVM compiler is to vectorize your code. I have an example up here to show how we can do this. This is just a toy example I made up where we're going to iterate through two arrays of vectors.

and multiply them and then accumulate the result. So the syntax that we're using here, if you're familiar with OpenCL, it should look familiar because this is the same syntax used for vector programming with OpenCL. There's a set of predefined types. Int32 by 4, for example, is a vector of four 32-bit integers. You can initialize those directly in your code. And you can apply standard C operators to those vector types.

So the neon vector unit in ARM processors has a very powerful set of instructions that can do much more than these standard C operators. What if you want to access some of those more esoteric functions? We have a solution for that as well. There's a standard set of intrinsics defined by ARM to be used for programming the neon vector unit.

This example here I've taken from an IDCT transform. This is real code. This is something that would be used when displaying a JPEG image. I'm not going to go into all of it, but that first function call there is doing a saturating, rounding, doubling, multiply, returning the high half of each vector element. You just can't write that in C very well. So you write it as a function call. The compiler is smart enough to recognize this is an intrinsic, and it's going to compile that down to a single instruction in your program. So you can get great performance.

Obviously, if you're going to go to the effort of rewriting your code like this, you want to make sure that it's worthwhile and that it really pays off. So let's look at what we get. This graph is again going to compare performance of GCC against the Apple LLVM compiler. I want to point out the scale here is not percentage. This is how many times faster.

The first benchmark, Galaxy, is simulating the gravitational fields within a galaxy of stars. GCC is defined by a rate of one. And the Apple LLVM compiler is about four times faster running this app. IDCT, this is the same transformation I mentioned in the example from the previous slide. Here we see the Apple LLVM compiler generates code that runs seven times faster. BigMult. This is doing multiplication of very, very large integers. This is typically used in public key cryptography. The LLVM compiler generates code that is about 21 times faster.

So we're pleased to announce we have all this great support for vector programming on iOS now. So I hope we've convinced you, looking at some of these features, that the LLVM compiler would be a great option for you to use. And if you're thinking about switching to use it, what do you have to do in your code to make use of it? The good news is, usually you don't have to do anything. It just works. But it is a different compiler. There's a few cases that you may run into occasionally. So we're going to take a little bit of time today to go through some of the more common cases.

Doug talked about the great warnings that we get in the LLVM compiler. Generally, that's a good thing, but if you're like me, you like to get your project to build with no warnings. And so you're getting new warnings you didn't get before. How do you turn them off? Here's an example. This is a simple function I made up. It's got an unused argument. Typically, this happens when you've got some conditional code that's turned off, and the compiler is warning about it.

So the programmer has gone in here and added a dummy use of the argument to tell the compiler, "I know it's unused. Don't warn me about it." And with GCC, that works. It will not warn because now it says, "Ah, this argument is used." The Apple LLVM compiler doesn't fall for that trick. It says, well, the argument is used, but that expression you put in, that's not used.

So the first solution in any kind of thing like this is to fix your code. And in this case, we can just insert a void cast to tell the compiler, yeah, I know, I really meant it, it's not used. Another option, if you notice at the end of that warning message, it's showing you the exact warning option that controls the message.

And so what you can do is to disable that warning, either in Xcode or on the command line. You can insert a no in there and make w no unused value and just turn that off. And we tell you exactly which option you need to turn off. What if you find this to be a useful warning, but there's some piece of code, maybe it's from a third party, or something you don't want to change, but you still want the warning? And we have a solution for that as well. You can put pragmas around this code. This is the same example. You see the warning from Xcode.

If you put a diagnostic push pragma at the beginning of a region, and then a pop diagnostic at the end of the region, within that region you can change the settings for diagnostics. In particular here, we add this diagnostic ignored pragma to say ignore the unused value warning.

Another difference between the LLVM compiler and GCC is in terms of the default language. GCC defaults to the C89 language standard. The Apple LLVM compiler defaults to C99, so now we're only one decade behind. And in particular, this shows up often with inline function semantics. GCC, I'm sorry, C89 does not define a feature for inline functions. But there is an extension in GCC to do that. And unfortunately, that extension from GCC conflicts with the way C99 defines inline functions.

Here's an example. It's a simple minimum function where if you compile this with GCC, it may work fine. You switch to the LLVM compiler, and you get this scary-looking warning from the linker. And the issue here is that sometimes an inline function in C99 is not actually emitted out into the object file, so the linker can't find a definition. And the best solution for you in cases like this is to switch your code to use static inline functions. The good thing about static inline is that it behaves exactly the same between GCC and the LLVM compiler and C99, so you'll also get more portable code.

Here's another GCC extension that may cause problems for you. C, the language, has a feature of variable length arrays. C++ does not. But GCC lets you do it anyways. So what we do with the LLVM compiler is to allow you to use variable length arrays in C++ as long as those are arrays of plain old data types, pod types. If you're not familiar with those, a plain old data type is something like an integer. Anything with a complicated constructor or destructor would not be a pod type.

So if you see an error message like this from the LLVM compiler, the best thing to do is to change your code to use a standard C++ container, like a vector, instead of the variable length array. Another C++ issue relates to name lookup semantics. Here's an example. It's a template class for a stack. And then we then instantiate the stack with integer types using a standard vector to implement that. And with GCC, this would work fine.

With the LLVM compiler, you get an error. What's going on? The issue here is that GCC does not correctly implement the C++ language standard. And it's complaining because that pushback identifier is undeclared. The problem is that at the point where the template is defined, the language standard says you can't see that identifier. I'm not going to go into all the details on that, but the important point is that the LLVM compiler shows you exactly where the problem is, and it shows you how to fix it. If you insert that "this" reference, where it tells you, the error goes away.

If you run into that, just apply the fixits and you'll have more portable code. Besides moving to the LLVM compiler, you may also want to move to automatic reference counting. You've heard a lot about that at the conference. What we're going to recommend as a first step for that is that you switch to the LLVM compiler and clean up all your warnings.

And the reason for that is that warnings in non-ARC mode often become errors in ARC mode. In order to implement ARC, we formalized a lot of best practices in Objective-C code. If you'd like to learn more about that, I'll give another reference to the Objective-C Advancements in-depth talk on Friday morning.

So those are some tips for transitioning your code to the LLVM compiler. And hopefully you're all eager to go out and try it. And you're wondering, what do you need to do? You need to get Xcode 4.1 or 4.2. We recommend using those versions. And here in the build settings, you can select your compiler. If you go to the build settings, you can search for compiler. You'll find this compiler setting and switch to the Apple LLVM compiler. You'll see here, it's showing in the screenshot version 2.1.

What's up with that? We were talking about version 3. Xcode 4.1 is shipping with version 2.1 of the Apple LLVM compiler. This is basically a bug fix release of the compiler. We've added the W uninitialized option. There's better C++ standard conformance. But otherwise, this is not where we're putting the new features. To get all the new features, You'll want to move to Xcode 4.2, where we have version 3 of the LLVM compiler, with support for automatic reference counting. One feature we didn't mention here today is that this version of the compiler will support GCOV code coverage testing.

We've got all the new C++/OX features that Doug described, and also better code generation. If you'd like to learn more about the better code generation, come to the LLVM Technologies in-depth talk tomorrow afternoon. We'll have a lot of good information there. So to summarize, we've got two releases coming up. As shown by the highlights here, in Xcode 4.1, the default compiler is LLVM GCC. In Xcode 4.2, the default becomes the LLVM compiler. And there's one more change.

In 4.2, GCC is going away. So what this means for you is that if you're still using GCC, this is the time to try out one of the other compilers. Let us know if there's any problems. We'll be in the lab this afternoon. Come by, try it out. And if you find anything that you really can't get to work, please file bugs. Let us know about your issues.

So the Apple LLVM compiler is the future for Apple in compilers. We're putting all of our development work there. It helps you find bugs in your code with good diagnostics, the static analyzer. It gives you great performance. And we ask that you switch your apps today or as soon as you can.

If you'd like more information or pointers, I refer you to Michael Jurowicz, our developer tools evangelist. You can also visit the LLVM project online. And if you do find issues related to moving away from GCC, file bugs: developer.apple.com/bugreporter. And I suspect you'll find some good tips on transitioning in the Apple Developer Forums. There's two related sessions: LLVM Technologies in Depth, tomorrow afternoon at 2:00. Objective C Advancements in Depth, Friday morning.