WWDC2013 Session 402

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
[Applause]
>> Thank you.
[applause] Good afternoon!
Welcome to "What's New
in the LLVM Compiler?"
My name is Evan.
Let's-- shall we start?
What's our mission?
We want to provide the
Best-in-Class tools for you,
for the developers, the
lifelines of our platforms.
We want to make sure
you have the best tools
to build your awesome apps.
We want to support the best--
the latest hardware,
be Macs, iOS devices.
We want to make sure we can
build your codes so they run
as fast as they can
on the unit--
latest iPhone, the
iPads and the Macs.
I want to make sure the
performance is great.
We're not satisfied if we
cannot squeeze every ounce
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of performance in
audio applications.
And we want to make sure you
have the great productivity.
We want our tools to run fast
and we want to provide you
with the best diagnoses.
We want to give you as
much information we can
to make your job easy.
So let's take a look at what
have we done in different areas.
First, let's talk
about the support
for the latest hardware,
armv7s architecture.
This is something
you may have seen.
This is not new in Xcode 5
but there's something new
happened during the last year.
The iPhone 5-- for the iPhone
5, we have the Apple A6 chip,
that's something Apple
built and very proud of it.
We worked very closely
with our team
to make sure the compiler
generate the best code words.
If you care about performance
on your app on the latest iPhone
and the latest iPads, you
want to build your application
for this architecture.
This is simple because
this is already a part
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the standard architecture for
iOS apps so we encourage you,
just go with it,
don't pick and choose,
just use the standard
architecture
and you'd get the best
performance for your apps.
Next, let's talk
about Intel AVX.
AVX stands for Advanced
Vector Extension.
Anything with the word
"Advanced" sounds great there.
It must be good,
you should use it.
So Intel AVX is not new.
It's been around for a couple of
years, but this year you have--
you have heard, we have just
announced Haswell-Based Macs,
they have Intel AVX2,
so AVX was all
about getting the best
performance with your loop
with a lot of parallels in,
a lot of floating
point computation code.
AVX2 takes a little step further
and bring the same kind of power
to the-- your integer code.
It had a few more other kind
of instructions to make it easy
to vectorize your code
so you definitely want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to take advantage of AVX2.
So using AVX2 is easy but it's
not quite, kind of, work-free.
You do want to make sure
your app does runtime checks
to make the hardware you're
running the code support AVX2.
So you may want to
partition your code
to have a special version that
only run on AVX2 and compile
with the -mavx2 instruction,
I mean, -2avx2, -mavx2 option.
If you have any questions
about this,
feel free to come
by to our labs.
We'll be happy to
talk to you about it
and also we'll be talking
a lot more about AVX2
and many other things
we talked about today
in tomorrow's session, that's--
we're we going to focus
on how you can using
the LLVM technology
to fully optimize your code.
So if you use AVX2 in Xcode
5, it's pretty simple,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
go to the Build Configuration
and just enable Additional
Vector Extension, choose AVX2.
This is going to be important to
get your code to performance--
to the best you can on
the Haswell-Based Macs.
Next, let's focus
on performance.
We've done a lot of
work in this area.
We have many new features,
a lot of work we're
very, very proud of.
We're so proud of, in
fact, we've made a video,
I'd like to show you today.
I'm just kidding.
[Laughter]
[ Laughter & Applause ]
They will be editing the video
for a long time before
I can show you anything.
But let's take a quick look
what we have done for you.
So the compiler has
definitely improved a lot.
The performance has
gotten better every year.
This past year as you've
seen, just a quick chart--
a few examples, we're
getting quite a bit
of performance of your code.
So if you're just
building your application
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with the new LLVM compiler
in Xcode 5, you're going
to get some significant
improvement for your code.
So it ranges differently
depends on what kind
of code you're writing.
If your iOS app, you're
going to see the same kind
of performance but a bit more.
We've been really,
really focused on this
and we're working really
closely with our team
to bring you the best compiler
technology in this area.
So here you can see across
the board teams of 20,
30 percent performance
gains just by switching
to the latest Xcode
5 and using--
latest Apple LLVM compiler.
One other thing I want to talk
to you very briefly about,
Strict Aliasing, this is
technology we introduced
in Xcode and Apple LLVM
compiler about a year or so ago.
The only difference here is,
you know, during the past year,
we have enabled by
default in 4.-- Xcode 4.6.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I just want to bring
this to your attention,
in case you have some any kind
of legacy code that's
still building and shipping
with the older Xcode,
you might be--
want to be aware of this change.
So I'm not going to go
into a lot of details
but strict aliasing is basically
using the type of informations
to do more advanced
than pointer analysis.
The reason we turn on
strict aliasing is simple,
its performance.
It's a-- few percentage is here
and there, but in some cases,
we see significant wins such
as 20 percent improvement
for some simulation benchmarks.
So again, just want to remind
you, if you are legacy code,
they might be using some illegal
scenes such as typecasting
from one type to another
that's not compatible
from floating point to
integer or vice-versa.
If you want it, you have code
that does this, please switch
to a well understood [inaudible]
such as-- unions to do the cut--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
type conversion and
you'd be home free.
Chances are, since we've been--
you've been shipping your
application with Xcode 4.6,
this is working perfectly for
you, there's absolutely nothing
for you to worry about.
One other thing I
wanted to bring
to your attention is
Link-time Optimization.
Again, this is not
a new feature.
What's new is we've
put so much effort
into Link-time Optimization
during last year
and we feel so great about it.
We have enabled it using it
to build some key
Apple technologies
in the Mac and iOS release.
So some examples such as Apple
LLVM compiler itself is built
with LTO.
This can have the benefit
of compiling your code
up to 6-- 6 percent faster.
The iOS Kernel, that's
important application,
can do some of the-- IO--
performance can be up to 20--
20 percent faster and in
addition to performance,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
sometimes you have [inaudible]
benefit such as iOS iMovie app
that got 25 percent smaller
just by building with LTO.
So we think LTO is great.
You definitely want
to try it out.
But in case you have a
really massive application,
this could have impact on
the build time because LTO is
about bringing everything about
your application into last stage
and do the all the optimization,
compilation at that time.
So if you find you
were building with LTO
and that's taking too much time
and maybe and you're running
out of memory, you consider
dropping the debugging full
level to a Line table only,
that can have a significant
improvement to the real time.
Something new in Xcode 5,
here's the Auto Vectorizer.
We talked about this in
"What's New in Xcode?"
this morning.
This is something that
we built from the grown
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
up during the past year.
This is already showing
amazing results.
This is certainly some really
computation intensive code
and can have 2 to 5 to 8
times the benefit for you--
for your computation
intensive loop.
And this works great for both
iOS and OS X applications
so you can have portable code
that you write simple code
that works perfectly for all
the-- for both platforms.
So previously, if
you are familiar
with ARM NEON intrinsics,
you may be using--
intrinsics to kind of get the
best performance on your loop.
And now we're saying,
all you have
to do is you just write
simple scalar code
and let the compiler
do the rest for you.
It's that simple,
it's that powerful,
you definitely want to try it.
[applause] Thank you.
[Applause]
So the auto-vectorizer,
again, is new in Xcode 5,
go to the Build Setting
and choose vectorize loops,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and let us know, we're really
proud of this technology
and we think we-- you'll get
a lot of benefit from it.
Again, this is something
we're going to go
into a lot more details
in tomorrow's session.
What we're going to talk about,
how to optimize your
code using the LLVM.
The last thing, if you've been
playing with the new Xcode 5,
you may-- may have noticed a
new optimization level, -Ofast.
What is this?
Well, think about it as
if it's a turbo button
for your application.
You press it and you
go-- your code goes fast.
So through -Ofast, it turn
out all the -03 optimizations,
squeezing as much performance
out of your code as possible.
It turn on the vectorization,
it turn on the -ffast-math
optimization.
For floating point code,
that can have a significant
performance benefits.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So what do you want to do
is for your release build,
choose -Ofast, not with Debug
Build, only the Release Build.
So a quick disclaimer, there's
a few things you should be aware
about -Ofast, particularly,
because you used -ffast-math.
You can do aggressive
optimization
such as re-association of your
floating-point expressions
and many other things can
have subtle impact precisions
of your code.
So if your application has to be
incongruous precise as using--
floating point, test carefully.
We believe for the
majority of the code,
this will just work
fine but please test
and let us know how it works.
And one other thing is,
this doesn't turn on LTO
for you automatically.
We want to control
that separately becomes
the compile to impact.
So that's all I want to talk
about-- about performance.
Next up, I would like to
ask, Bob Wilson to come up,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about all the work we have done
to improve your productivities.
Thank you.
[ Applause ]
>> Thanks Evan.
So the Apple LLVM Compiler can
help your apps to run faster.
It can also improve
your productivity
and help you develop higher
quality apps with fewer bugs.
So in the rest of the
session, we're going to go
through a number
of different ways
that the compiler
can help with that.
By updating the compiler
and some of the other tools,
we give you a more
consistent experience
with an easier installation
and update process.
We've got some new C++
features that make it easier
to express the code
that you want
and we've improved the compiler
warnings and the static analyzer
to help you catch bugs before
you have to go and spend a lot
of time debugging your app.
And finally, we've got a great
new feature that makes it easier
to document your code
right in the comments.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's dive into
these starting
with the compiler
and tool updates.
So Apple has been using
the gnu gcc compiler
for quite a few years
but a few years back,
we decided we really
wanted a better compiler.
We wanted better performance,
we wanted tighter integration
in the Xcode, we wanted more
helpful diagnostic messages
that really explain to you when
there's a problem in your code
in a way that makes sense
and you could easily
see how to fix it.
So we began to invest in the
llvm compiler and for a number
of years now, we've shipped both
gcc and the llvm compiler side
by side, as well as the
hybrid llvm-gcc to ease
that transition away from
gcc to the llvm compiler.
And I'm really pleased
to say that this year,
in Xcode 5, the gnu is gone.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We only have the llvm compiler.
[ Applause ]
Yeah, as I said, that
makes me happy too.
The good news for you
is this gives you a
consistent experience.
And in the past, if you've
been building with gcc,
you'd see inconsistencies
between the diagnostics reported
to you in Xcode while you're
editing, which are coming
from LLVM and the messages,
the problems you'd see
at build time using gcc.
And all of that mess
has gone now.
There's just one compiler
and everything is consistent.
It's also really good news
because it means we
can focus our efforts
on adding new features in just
one compiler and move forward
at an even faster rate.
So I'm going to come
back and talk about some
of those advances in
LLVM in just a minute
but before I do that, I want
to go over a related topic
which is the command line tools.
If you're not already familiar
with the command line tools,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
this is a package that we
provide separately from Xcode
that is useful for
building open source
and other common Unix
software on the Mac.
And it consists of two basic
components, there's a set
of tools such as the
compiler that install
in the /usr/bin directory and
then there's the Mac OS X SDK,
with headers and /usr/include,
libraries and user lib,
and also in System
Library/Frameworks.
This is what the
command line tools look
like on Mountain Lion.
Now if you're an Xcode
developer, you've got Xcode
but you just want to go and
build some open source code,
you may find yourself
still needing
to install the command line
tools even though you already
got Xcode.
And the reason for that is that
the standard Unix convention is
that the compiler and the
other tools live in /usr/bin
and that's not where
Xcode puts them.
So new in Mavericks,
we have the inspiration
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that Xcode already has
all of those same tools,
it already has the OS X SDK so
there's no reason to make you go
and download this
separate package just
to get those same things.
And the way this works is
that the Mavericks OS comes
with a set of shims
installed in /usr/bin.
These shims are just
really small,
simple wrapper executables
that know where to find Xcode
and where to find the
corresponding tools inside
of Xcode.
So if you run the compiler from
/usr/bin via one of these shims,
it just reinvokes the
compiler from Xcode
for you automatically.
So the summary of this is
if you have Xcode and you're
on Mavericks, there's
no longer any need
to ever download the
command line tools.
[applause] So what if
you don't have Xcode?
What then?
Well, if you-- say you've got
a brand new Mac and you try
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to run the compiler
from /usr/bin,
you'll get this message telling
you, "Hey, you need some tools,"
and it's giving you choice.
You can click on that Get
Xcode button, it'll bring you
to the apps store and you
can install Xcode just
as in the normal way.
You can also choose Install
which will install a standalone
set of command line tools.
Let's take a closer look
at what that looks like.
This is about the Mavericks
version of command line tools.
We have the same
shims in /usr/bin
and the tools now install
into library developer command
line tools and the shims forward
to that location
automatically in the same way
that they would forward
to Xcode.
My favorite feature
about this is it's hooked
up to software update.
On Mountain Lion,
if you've got--
if a new version of command
line tools was released,
it's up to you to remember that
you need to go and install it.
With Mavericks, you'll get a
notification in the apps store
to tell you that an update is
available and you just go in it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and install it in the same way.
So that update process
is so much smoother now.
It's also easier to
remove the tools.
Say that you had installed the
command line tools separately.
Maybe, you were in a coffee
shop or something and you--
you needed to download
a compiler quickly,
with a low bandwidth connection,
the command line tools
are much smaller,
but then when you get home,
you got more bandwidth,
you probably want to install
Xcode, now you're left
with these tools, you
don't need them anymore.
On Mountain Lion,
it was really hard
to ever remove the
command line tools
because they were scattered
throughout your root
file system.
Now, they're all in one place,
Library/Developer/
CommandLineTools.
And if you've got Xcode, you
can just blow that folder away
and everything will
continue working.
So again, just to summarize,
the command line tools make
it really easy to install
and update and even
remove in a way
that Mountain Lion
didn't provide.
But before we get back to
the compiler, there's--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
there's one issue I want
to let you know about.
Notice that we've only
talked about one part
of the command line tools
which is the tools
themselves in /usr/bin.
Remember, there's
that SO 10 SDK?
And it's moved.
It's no longer installed
in the /directory.
This is the problem
for the compiler
because the compiler knows
where that SDK is installed.
But if you've got, make files
or scripts or anything else
that refers to files in
usr/include, usr/lib,
or System/Library/Frameworks
with hard coded paths
then you're going to need
to fix those things
up so that they know
where to find that Mac OS X SDK.
How do you know?
Where is it installed?
We do have something
to help with that.
xcrun is a tool you
may be familiar with.
It's been included with
Xcode for a long time.
Like those shims,
it's just a wrapper,
it knows where to
find tools in Xcode
and you can use it to run them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's now included with
a command line tools
and it has a new option.
If you run xcrun
-- show-sdk-path --
sdk and a short name like
macosx, it will print
out the full path to the
SDK and you can use this
to programmatically update
make files or scripts
with the full path to the SDK.
And related feature, since
xcrun knows where the SDK is,
you can also use this to tell
the compiler where the SDK is.
In the past, you'd have to
use the -isys root option
to the compiler and give it the
full paths to the SDK you want
to use and those full
paths are often quite long.
If you're on the command
line, it's a lot to type.
Well now, you can use
xcrun, give it a short name,
like iPhone OS or Mac OS X and
it will communicate that through
to the compiler so you don't
have to type the whole path.
You can also set the
SDKROOT environment variable
and xcrun will notice
and pick that up
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and use that to set the SDK.
So try out the new command line
tools, I hope you like them,
and now let's get back to the
compiler, starting with C++.
C++11 is a major update
to the C++ language.
This is something that we've
been working on rolling
out in Xcode for a while now.
This year, in Apple LLVM version
5.0, we have complete support
for everything in C++11
with the sole exception
of thread local storage.
Here's a list of some of the
major features we've added
in the last year and I don't
have time to go into all
of these in any detail.
So I just-- to give you a taste
if I wanted to single out one
of them to look at a
little more closely,
which is Inheriting
Constructors, and let's look
at this with an example.
I've got here a simple class.
It's got an integer A field
and a float B field and a set
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of constructors that let you
specify the initial values
for various combinations
of those fields using
default values
for the things you
didn't specify.
Now I want to make
a derive class Y
with those same constructors.
And I just want to pass
the same values along
to the base class constructors.
There's a lot of
boiler-plate code here
and it's also error
prone to maintain.
If you make a change in the
base class, you've got to go
and update all the drive
classes in ways that match.
And C++11 inheriting
constructors let you replace all
that boiler plate
which just using X::X.
And all this does is
tell the compiler if--
if I see a use of one
of these constructors
that matches the signature
from the base class,
just implicitly declare that,
and it will invoke
the constructor
from the base class
as you'd expect.
Notice though, I've added an
int c field in the derive class.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
How do we initialize that?
Well, there-- there's a lot of
different ways you could do it
and C++11 has a number of
features that help with this.
I want to-- since it fits
nicely in this example,
I wanted to talk about
one way to do that.
This is not a new
feature this year
but it's something that's
been around for a while
which is non-static data
member initializers.
You can now set the initial
value right in the class
and this tells the compiler if I
don't have some other values set
in the constructor to use
that as a default value.
Notice we can use the same
thing in the base class X
to set the values of fields A
and B, and then remove a lot
of the complexity from
the constructors there.
So together, inheriting
constructors,
a non-static data
member initializers,
take the simple example and
make it a lot more clear
and concise and easy
to maintain.
While we're on the topic of C++,
there's one other
important piece
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which is the Runtime Library.
We've been going
through a transition
from the older GNU lib
standard C++ library
to the new LLVM libc++.
And if you want to use a lot
of those features from C++11,
you really need libc++
to support them.
It supports the number
of the language features
and it also has a number
of new library components
that come with C++11.
One thing that is
new this year is
that we've made this
the compiler default
if you're deploying to
iOS 7 or OS X Mavericks.
If you want to deploy back
as far as iOS 5 or OS X Lion,
you can still choose
to use libc++ by going
to the Xcode build settings,
look for C++ standard
library and choose libc++.
So again, C++11 is a huge
change to the language.
If you're a C++ programmer,
I strongly encourage you
to check it out and there's a
lot of great new features there
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that can make you
more productive.
Our next topic is about
Compiler Warnings.
So as you're writing your code
and building, the compiler is--
is looking closely at that
code and in the process,
we can catch errors or--
and warn you about them so
that you can fix them quickly
without having to spend
a lot of time debugging.
So there's three different
categories of changes
that I want to talk about
related to compiler warnings.
First, we have some
new compiler warnings.
We have a number of warnings
that have been around for awhile
but we've identified them
as being really important
and we're going to now enable
them by default in new projects.
And finally, there's
a few warnings
that are really serious,
it cause serious problems
and we're now going to treat
them as errors by default.
So let's-- dive into
this starting
with the new compiler warnings.
The first one is
unsequenced modification.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is a warning about
non-portable code.
C-based languages don't define
the order of some operations
and I'll give you an
example in just a minute,
but if you have some
code working
with a different compiler
from a different platform or--
or wherever and you move
to using the LLVM compiler,
it may behave differently
in a way that causes a bug.
Let's look at an example.
This simple function is supposed
to just increment a value
and return it but
there's a problem.
There's actually two
assignments to the value X here,
the equal operator does an
assignment, the plus, plus,
post increment operator
does a separate assignment
and the order between those two
is not defined by the language.
Some compilers may
do them in one order,
some may do it in
the other order.
So the LLVM compiler now gives
you a warning about this.
It's an indication to you,
you need to look at your code
and figure out how
to rewrite that so
that the ordering
is well-defined.
Let's go on to the next
new warning which is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about integer overflow.
In some cases, the
compiler can determine
that an integer operation
is going to overflow.
This is almost certain
to cause a bug at runtime
so we now warn about that.
For example, if we're
multiplying two constants,
they're big numbers,
not that big,
but when you multiply them
the product is too big
to even fit in a 32-bit integer.
So the LLVM compiler
will now warn about this
and tell you, this doesn't fit.
The obvious solution in
a case like this would be
to use a larger size
integer such as long longs.
You can use long long constants
and a long long return value
and the warning goes away.
So those are two new warnings.
Let's talk about
some of the warnings
that we're now going
to enable by default.
Unused functions,
this is an easy one.
While you're editing your
project, it's not that uncommon
to leave behind some pieces of
code that are no longer used.
And if those are in static
functions either in declarations
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or actual definitions
with the function body
like I've shown here, the
compiler can detect this
and warn you, and this is just
an opportunity for you to clean
up your code, remove
some of that unused craft
and make it easier to maintain.
We're going to now enable this
by default in new projects.
Implicit Boolean
conversions is another warning
like that, enabled by default.
This is especially helpful in
C++, and let's see an example.
Here, I've got a helper function
that I've declared and I want
to check and see if the
helper is available,
I'm going to call it.
The compiler warns and says,
"If you take the address
of the function, it will
always evaluate to true."
So the conditional here
isn't doing what we expect.
In a case like this,
you probably meant
to make that a weak import.
And you just need to
add the weak attribute
on that function declaration
to tell the compiler
that this value, this
function pointer maybe zero
and without the warning
goes away.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So this again is a serious
problem enabled by default,
the warning is enabled
by default.
A similar issue is
with Enum conversions.
Here's an example of that.
I've got two Enums, a set of
shapes and a set of circles
and I want to-- I have a draw
function that can draw that
and I try to draw a blue circle
but I-- I got the order wrong.
It's supposed to be
Draw Circle Blue,
instead of Draw Blue Circle.
The implicit Enum conversion
warning detects that.
It would actually warn
twice here, ones for each
of the arguments, because
they're both in the wrong order.
Again, this is something
that's trivial to fix.
If you have a problem
like this, you really want
to fix it right away
and so we're now enabling
this warning by default.
Undeclared selectors,
let's look at an example.
I want to make a timer, an NS
timer to go off in 60 seconds
and when that timer goes off, I
want to send the close message
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the current object,
but I've got a typo.
Instead of close with an
"S" I wrote close with a "Z"
and the undeclared selector
warning will catch this.
The last category of
warnings that I want to talk
about are two issues
that are so serious,
we're going to treat them
as errors by default.
Mismatched Return Types, this is
where you're simply
missing a return value
and here's an example of that.
I had intended to make a safe
square root function based
on the realization you can't
compute the square root
of a negative value so I'm
checking if the input is less
than zero, I'll just return.
But I didn't think about the
fact that the function needs
to return something, is
declared to return a float.
The compiler catches
this of course says,
"You're missing a return value."
A problem like this is really
serious because it's going
to lead to undefined behavior
and your program is going
to crash or it's just going
to do something really wrong.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So this is now going to
be treated as an error
by default in new projects.
Another very serious problem
like that is Unintentional
Root Classes.
This is more of a
typo kind of problem.
I'm declaring a new interface,
my class, and I just forgot
to specify the base class.
The compiler again
catches this and suggest
that you declare an NS
object base class or--
or maybe some other base class
that would be more
appropriate in your code.
This, too, we are going to
treat as an error by default.
Now, if you really did intend
for that to be a root class,
you can add NS root class
before the add interface just
to tell the compiler, "Yeah,
this is really what I meant."
So to summarize all
these warning changes,
we have two new warnings:
unsequenced modifications
and integer overflow.
We have four warnings that
are now going to be enabled
by default in new
projects, unused functions,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
implicit Boolean
and Enum conversions
and undeclared selectors,
and finally, two warnings
that are really serious:
mismatch return types
and unintentional root classes
that we're going to treat
as errors by default
in new projects.
So just as the warnings
can help you catch bugs,
the LLVM compiler provides
a really powerful feature
to go deeper in analyzing
your code
and finding more subtle issues
and so to talk about that,
I'd like to invite
up Anna Zaks to talk
about the Static
Analyzer and finish
up the rest of the session.
[ Applause ]
>> Thank you, Bob.
First, I'm going to
talk about the new
and exciting features
we've added
to the static analyzer
over the past year.
And for those of you who had
never used the static analyzer,
you'll get to learn it-- learn
about what it is all about
and how it can help you
in your development cycle.
So everyone agrees
that bugs are bad
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and as Bob has just mentioned,
compiler warnings might pinpoint
some of those bugs to you.
So how the analyzer issues are
different from compiler warnings
and why should you use
the static analyzer?
Well, the static analyzer
performs much deeper analysis
of your program.
It systematically explores
every paths for your program
which allows it to
find those hard
to reproduce edge case bugs.
The static analyzer that ships
to this Xcode 5 finds
new kinds of bugs.
It performs deeper
record analysis especially
for objective-C and C++ and
it also exposes new workflows
that will allow you to
tailor analysis power
to your specific setting.
So let's first talk
about the new kinds
of bugs analyzer can find.
Most of you are familiar
with NSDictionary
and NSMutableDictionary APIs
that this code snippet is using.
However, let's bring here
the Apple documentation site
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that will tell us exactly
what this method does.
So the Apple documentation
tells us
that this method
creates a dictionary
with a given key and value pair.
However, look at the fine print.
Here in the parameter
section, it also tells us
that if the value is nil,
then an exception will
be thrown at runtime.
And the runtime exception is
not something any of us want
to happen on the user's iPad
or an iPhone while our
application is being run there.
So how can the static
analyzer help?
Well, let's go back to our
code snippet and suppose here
that the default object was set
to nil earlier along
the execution path.
So if the analyzer
knows this, it can--
it will warn you and
it will remind you
that this API should
not be used in this way.
And of course if you've switched
to the new literal syntax,
they're also going to warn
but with a slightly
different error message.
Well, mostly you will say,
"This code is too simple.
I don't try code like that.
I don't set an object to nil and
immediately create an array."
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Well, we've run the analyzer
with this warning turned on,
on several large Objective-C
code bases and it found issues
in every single one of them.
Here's an example from a
large Objective-C code base
where the analyzer warns.
Here it tells you that the
object inModifiedKeys is--
could be nil and it is
used to create a dictionary
so when the analyzer
reports an issue to you,
not only does it point
to the line number
where the issue occurred
but it also explains
to you why this problem
has happened.
And the analyzer explains
issues by showing you a path
through your program on which
the-- the problem occurs.
So in just-- in order to
see the path, you just click
on the issue and the
path gets displayed.
And notice at the top
of the editor window,
you'll also see analyzer
issue navigation bar
that will allow you to
step through this task
and examine each
step along the way.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So let's see what
actually happens here.
Why the analyzer thinks
there is a problem?
Well, first, we call
postNotificationName method.
And here we-- in-- the
creator's third argument
for this method call,
the special case,
the case when inModifiedKeys
object is nil.
So we say, "If inModifiedKeys
object is not nil,
create a dictionary, otherwise,
just pass a nil and use
that as a third argument."
This program keeps running
along the same paths and later
on the same API is gone
and called again and here,
the programmer just
forgot to check for--
they don't check if
inModifiedKeys is nil.
They just-- just called it--
they just create a dictionary
and use it at the
third argument.
So clearly there is
an inconsistency here
and this is what
the analyzer notices
and this is why it
reports the issue.
So we've-- we've also
stand a lot of time
and we've greatly
improved our C++ support.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So here's another
example of a new--
of warning that we've
added to C++.
Here, we-- we allocate an
object and later on be freed.
So, of course, the
problem here is
that object allocators was
new, should be the allocated
with delete, because calling a
free function will not call the
distractor of the object so
this might result in memory
or resource leaks which are
hard to find at runtime.
So we've added several new
warnings over the past year.
We are going to warn if you're
trying to add a nil element
to NSMutableArray or nil key or
value to NSMutableDictionary.
We also warn on use-after-free
in C++, mismatched deallocators
and creation references
to null in C++.
And of course these new
warnings just add on top
of the growing body
of the analyzer issues
that we've added over the years.
And know that both old and
new issues greatly benefit
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from the power of the
analysis because again a factor
to finding bugs in your programs
is actually understanding what
your program does.
For example, when you call
a method, what happens?
Some of you might
remember that last year,
we've added cross function
reasoning for C functions.
Well, this year, we've extended
it to objective-C and C++.
And we found that this greatly
benefit the power of analysis
because it's so natural for
people to split their cord
into subfunctions or submethods.
I'm going to explain
to you how this works
and why this important
by showing you how the analyzer
operates behind the scenes,
on this code snippet.
So as I mentioned earlier, the
analyzer analyzes your program
by systemically exploring every
paths through your program.
And it has to be statically
without running your program.
And in order to do that,
it extracts away the values
of your variables and
constructs a draft
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from extract system states--
of extract system states
and transitions between them.
So let's construct such a
draft for this code snippet.
The analyzer starts with
the initial state and then
as it evaluates the
statement in your program,
it construct a second
state, so here we create,
allocate an object,
localized its name.
Notice here how the
analyzer splits the path
to capture the fact that L could
be nil and from now on is going
to explore both of these paths.
So now let's go back and see
what happened when the analyzed
or when the simulated
this last method call.
So previously the analyzer had
to use the most pessimistic
assumptions
about what a method
call could do.
However, it's silly.
If the method implementation
is available
to us, we should use that.
So let's go back and replay
how this will work now.
So in this case, the
analyzer knows that the type
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of object A is asset and
given the object type
and the method name, we can
just very high assurance detect
which method will be
called at runtime.
And this-- if this
method's implementation is
in the same source file or
one of the included headers,
then we can bring the
method implementation
and use it while we
simulate this method call.
So here what will happen,
the analyzer will simulate a
method call, add localized name
to the properties
map, add regular name
through the properties
map and return.
Now, let's see what happens on--
along the path on
which L is nil.
Again, we simulate a method call
and next we add nil
to the dictionary.
And here the analyzer notice
that this is a problem,
adding a nil to
NSMutableDictionary is
against the rules so
it's going to warn you.
So if you were going to run this
code through Xcode right now,
this is what you would see, you
would see a path through both--
both of the methods that shows
you how the problem could
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
have occurred.
As I mentioned previously,
we've also extended this
cross method reasoning to C++
so here's another
example, C++ example.
Here, we allocate a buffer and
we use autopointer to yield
with memory management for us.
So if you were to run this
code through the analyzer,
the analyzer is actually
going to report a bug.
It's going to tell us that
here the memory is allocated
with operator array new
or news square bracket
and it should be deallocator
as operator array delete,
however it tells us
that deallocators
was operator delete.
Notice here that
we don't see the--
the allocation side so what
happens actually if we click
on this warning to extend it,
we'll see that the analyzer sees
the distractor of autopointer
and it sees which the
allocation method it uses there
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and this is what's required
to report this problem.
So this just highlights how
important the cross method
reasoning is for C++ since so
much implementation detail is
hidden in the headers.
OK, so to summarize,
what made this possible?
If you do path specific
tracking of object types,
we reason about constructors
and destructors in C++.
Also, if your method
implementation is either
in the given source file or in
one of the included headers,
the analyzer will be able
to use it while it's
simulating a method call.
However, like the compiler,
the analyzer only reasons
about one source file at a time.
So if your method implementation
is in another source file,
it will not be able to see the
[inaudible] during the analysis.
So now, I'm sure you're all
excited about going to have
and running the analyzer
on your code
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and the only question you
have is how do I do that?
How do I trigger
analysis of my project?
Well, there are several
ways of doing that.
So first, we can go to Xcode
and choose product analyze
and that is going to trigger
analysis of your whole project
that minute or that
second from within Xcode.
However, often what
you've done--
do is you've analyzed
the project before
and you've changed one or
two files and you just want
to reanalyze those files.
So we've added a new
feature in Xcode 5,
you can go to product
perform action and choose
to analyze a single
file, that's much faster.
Well, some of you might want
to have continuous feedback
from the analyzer as part
of your active development.
You can go to build settings
for Xcode and you can choose
to analyze during build.
What that will do is it will
trigger analysis every time you
build your project.
If you have a project that
analyzer warning is free,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
then we highly recommend that
you use aesthetic analysis
as part of your continuous
integration.
You can do that by just
adding Xcode build analyze
to your integration-- continuous
integration script of choice
or you can set up a bot
through Xcode by going
to product create bot.
And for more information
about creating a bot
that rruns the aesthetic
analyzer and other stuff,
please attend the session
that will happen right
after this session in Presidio,
"Continuous Integration
with Xcode 5."
Now, I've told you how to choose
which code to analyze and when
to trigger the analysis.
However, what you also can
control is the analysis power.
There are two analysis
mode, there is Shallow,
shallow for quick
analysis, and there is Deep
for more thorough analysis
that might find more issues
but might take significantly
longer.
And here are the defaults
that you can change by going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the Xcode build settings.
So the default for--
mode for analysis with--
during analyze action is deep
and the analyze action is
what's gets used when you go
to product-- product menu
choose analyze or what gets used
when you use analyzer as part
of your continuous integration.
The default mode of analysis
during build is shallow
because this is when you
want a very fast turnaround.
Now, if there is one
thing to remember,
that is we suggest you
always analyze your project
in deep mode as part
of your qualifications.
Now, last but not least, let's
talk about your comments.
So most of you had heard
this question before,
where is the documentation,
or maybe some
of you always write the
documentation then you've
probably asked this
question before.
And a very handy way of
writing the documentation is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to use structured
comments such as Doxygen.
This is very useful because
the documentation stays--
has more chance of
staying up-to-date,
it's easier to write, it
stays with your code, however,
up to now, the compiler
and Xcode only pays special
attention to your code
but skips your comments.
Well, in Xcode 5, the
Xcode 5 pays attention
to everything you wrote
including your comments
and this allows us to provide
a great user experience
and developer experience.
Let's see what that means.
So previously, if you went
to Xcode and option clicked
on a method to see what it does,
if the method was not declared
in the system header,
this is all you would see,
it will just tell
you, the header--
which just tell you the header
where this method was declared
which is useful but
not so useful.
Well, now, what will happen is
we will generate and display
to you the documentation that
is based on your comment.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Another way of viewing
quick help is
through quick help inspector.
You can configure
Xcode to display it
on the right-hand side
of the Xcode window.
And then whenever you
hover your cursor over--
over a given method name,
that documentation will
be displayed there.
No-- no need to option click.
Now, another way of using your
comments is code completion
so whenever a user-- someone
who's using your API types the
name of the method,
not only will--
will it display its
full signature
but will also display the
comment that is based on your--
the connotation that's
based on your comment
or the brief section
of your comment.
Now, let's talk about
how this feature works.
This feature is powered
by the compiler.
The compiler parses your
comments along with your code
and attaches comments to the
declarations and this allows us
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to create a very
precise representation
of your whole program that
includes your comments
and this precise representation,
not only allows us
to show you your comments back
but also give you active
feedback about them.
So we've also added a
new warning that's called
Wdocumentation and you can turn
it on by going to build settings
and choosing-- turning
documentation comments to--
from no to yes.
What this warning does
is it tries to make sure
that your comments
stay up-to-date
and don't have some
simple errors
that the analyzer can find--
that the compiler can find.
I'll give you some examples.
So here is the first example,
here we have a method
whose signature changed.
This method used to return
an error code, however,
now it returns a void.
Notice here that
the comment is stale
and the compiler notices
this and it tells you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you should probably
change the stale comment,
this method does not
return anything anymore.
Here is yet another example.
Here we have-- started
writing this documentation
and probably we got
distracted because we forgot
to fill in the brief section.
Again the compiler is going
to warn us-- warn and tell us,
"Hey, you definitely
meant to fill this
in but you just forgot."
Here is yet another example.
Here, we have a method
that takes two arguments:
name and bundle.
However, we've mistyped
bundle and instead
of writing bundle,
we wrote bungle.
Not-- not only the
compiler notices this
but it's also a little
bit psychic.
It's going to issue a
Fix-it and it will tell you,
"didn't you mean
bungle-- bundle?"
And the only action necessary
for you to fix this problem is
to just click enter and your
code will be-- all header.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So we've added support
to structured comments
such as Doxygen and HeaderDoc
and HeaderDoc is
Apple-structured comment format.
For more information
about this structured--
comment format, please visit
the website that I've listed
at the bottom of the slide.
We highly encourage you to
write your documentation
and using structured comments
and instantly see them appear
in quick help and
code completion.
If you'd like to hear
feedback about your comments
from the compiler,
don't forget to turn
on the connotation comments
warning, it's all wired up,
ready for your comments.
So to summarize, we've
covered a lot of topics today.
Now, the LLVM compiler
is stronger than ever.
It produces faster apps
by providing support
for latest hardware and having--
enabling new, aggressive
optimizations, it also--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we also want to make
sure that you can focus
on writing your features
so we streamlined the
development process
by making the tools
installation easier,
providing almost
complete C++11 support,
providing stricter
warnings, deeper analyzing--
analysis and taking full use
of your comments in the ID
to make it easier for
you to concentrate
and focus on the code.
For more information,
please contact our
Developers Tools Evangelist
and visit these websites.
If you want to learn more
about the new optimizations
that Evan talked about,
please visit Optimize Your Code
Using LLVM Session tomorrow.
There will be also two
related sessions today:
Advances in Objective-C at
4:30 and Continuous Integration
with Xcode 5 right after this
session at 3:15 in Presidio.
Thank you all for coming and
enjoy the rest of your day.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]