Compiler Benchmarks GCC vs. LLVM
phoronix.comFollow this link in order to read a very in depth analysis and comparison of the GCC-Compilers and the new LLVM/Clang Compiler Suite.
Playing with Clang and Xcode
The Getting Started page of the Clang project’s web site does a fine job of explaining how to use make (on suitable platforms) or CMake on Windows. They even state that CMake can generate project files for several IDEs, but neglect to mention Xcode, my editor of choice on OS X.
In any case, the process is painfully simple. I’ll repeat some of the instructions on Clang’s own website for completeness here:
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
$ cd llvm/tools
$ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
$ cd ../..
$ mkdir llvm-xcode
$ cd llvm-xcode
$ cmake -G Xcode ../llvm
$ open LLVM.xcodeproj
This will create an LLVM.xcodeproj file, among many others. Opening this file reveals 200-odd (at time of writing) targets. Note that this xcodeproj file will reference all files with absolute paths, so sharing it is probably out of the question.
I initially had trouble building certain targets (e.g. LLVMX86Info) as the backing CMakeLists.txt files referenced old dependencies that had since been renamed. This issue was fixed at the start of August.
Working with LLVM/Clang has one tangible benefit: autocompletion and being able to look up symbols using Ctrl+Cmd+J.
Xcode Build Settings Part 1: Preprocessing
That screen. You know the one. The table of text. The one with scary sounding terms such as Mach-O Type and Rez Search Paths. The one you’re probably avoiding right now, for fear that changing one of the magic incantations will leave you with an empty husk of an app powered only by sadness and regret. There’s actually a whole ton of useful stuff which you probably didn’t know about. In this multi-part article, we’ll go over some of the fun possibilities once you understand the available settings.
I know I said this wasn’t that scary. And I stick by that. But there’s one thing to be aware of. You can’t actually undo any changes you make (and might later regret). So please please please make sure you are working in a clean repo before playing around with settings you aren’t familiar with so that you can easily reset in case something blows up on you.
With that out of the way, let’s go poke it with a stick, shall we?

The first thing we’re going to play around with is one of the least likely to blow up in your face. Compiler flags are used to define constants at build time, that can then be used in your code to do some tricky things to customize your code for specific build configurations.
There are 3 possible places to set these up:
OTHER_CFLAGS(Other C Flags)GCC_PREPROCESSOR_DEFINITIONS(Preprocessor Macros)INFOPLIST_PREPROCESSOR_DEFINITIONS(Info.plist Preprocessor Definitions)
The difference between the Other C Flags setting and the two Preprocessor settings is that anything you pass into Other C Flags is passed directly to the compiler as is. This means that if you want to set up a constant named FOO, you would have to format the C Flag as -DFOO. This gets passed as is to the compiler, and defines the FOO constant. However, this also means that a malformed C Flag could potentially blow up your build.
Conversely, anything passed in through one of the Preprocessor settings is passed to the compiler with -D automatically. So that same constant from before can simply be set up as FOO. This means that even if you write a malformed flag, you will only get a malformed definition in return. Because of this, I recommend sticking to the Preprocessor macros settings for defining compiler flags, leaving the Other C Flags setting for times when you actually want to pass flags directly to the compiler.
Compiler flags can be set either as a value definition (FOO=1), or a constant definition (FOO). Constant definitions are essentially boolean. They are either set, or not set. Value definitions can have value, but you really don’t want the compiler going through complex conditionals to generate your code. If you want to use a value definition, stick to setting the flag to 1 and simply checking for its existence.
So how do you use this? The most common use is dynamically swapping out sections of code based on the build configurations. Once you have your flags set up, you can do some slick dynamic compiling in your code. As an example, you could swap out an API endpoint based on the build configuration like so:
#if RELEASE
static NSString *const MY_API_URI = @"https://api.example.com/";
#else
static NSString *const MY_API_URI = @"https://api.staging-example.com/";
#endif
Remember Info.plist Preprocessor Definitions? These can be used in conjunction with the INFOPLIST_PREPROCESS (Preprocess Info.plist File) flag to do the same kind of dynamic compilation for your Info.plist file. The simplest use of this technique is to swap out your bundle identifiers and modify your product names so that you can distinguish beta builds from release builds, and be able to keep both installed at the same time. Right click on your Info.plist file, and choose Open As -> Source Code. You should now see the plist file in its raw XML. Now look for the sections you want to modify, and use the same kind of compiler conditionals used earlier.
<key>CFBundleDisplayName</key>
#if RELEASE
<string>${PRODUCT_NAME}</string>
#else
<string>${PRODUCT_NAME} Beta</string>
#endif
<key>CFBundleIdentifier</key>
#if RELEASE
<string>com.yourcompany.myapp-appstore</string>
#else
<string>com.yourcompany.myapp-beta</string>
#endif
Once you start adding compiler conditionals into your Info.plist, Xcode will start to tell you that the file has been corrupted, and is unreadable. Don’t worry, it isn’t. You can always do the same right click -> Open As -> Source Code tango you used to add the compiler conditionals in the first place. The one issue this may cause is that the “Summary” screen in newer versions of Xcode will become unable to read your Info.plist file. This means that if you want to change any of the settings contained within the file, you will have to edit the XML directly, which isn’t always the most pleasant of experiences.
Bonus roundThere are actually some built in flags you can use to help compile your source code dynamically. The most interesting ones for our purposes are TARGET_IPHONE_SIMULATOR and TARGET_OS_IPHONE. These are set as value definitions, so you should be using #if to check the conditional, not #ifdef. This can be used in all sorts of interesting ways. My favorite use-case is an extension of the dynamic API constant from earlier. When developing against an API for a rails app for which I have access to the source code I prefer to run the app locally, instead of dealing with calls to a staging server. So I take the example above, and modify it like so:
#if TARGET_IPHONE_SIMULATOR
static NSString *const MY_API_URI = @"http://localhost:3000/";
#elif RELEASE
static NSString *const MY_API_URI = @"https://api.example.com/";
#else
static NSString *const MY_API_URI = @"https://api.staging-example.com/";
#endif
Now, when building for the simulator, I’m pointing the app at my local Rails server. But the app is still pointing at the real API for release builds, and the staging API for everything else. Huge time saver.
In addition, there are a number of variables you can use inside your compiler flags to create the flags dynamically. Notably, the CONFIGURATION variable corresponds to the build configuration name. That means that setting up a preprocessor macro with CONFIGURATION_$(CONFIGURATION) for all build settings will resolve to CONFIGURATION_Debug for builds under the ‘Debug’ build setting, but will resolve to CONFIGURATION_Release for builds under the ‘Release’ setting. [HockeyApp][http://www.hockeyapp.net] recommends using this same technique to keep their Beta Testing code out of your release builds for the app store.
I’d be remiss if I didn’t state that this technique should be used extremely sparingly. The use cases presented here are examples of how you may want to use source code preprocessing, but you can quickly go too far. Used correctly and sensibly however, Preprocessors can be a powerful addition to your workflow. You just have to know where to find them.
Problem solved: compiling python 3.3 on osx
It is a follow-up on this post.
Turns out this problem has been reported to python bug database: http://bugs.python.org/issue13241.
The llvm gcc compiler that comes with XCode 4.x is causing the problem.
Do
CC=gcc-4.2; ./configurewill fix the issue.
OS X GCC Installer
github.comDownloading and installing the massive Xcode installer is a huge hassle if you just want GCC and related tools.
The osx-gcc-installer allows you to install the essential compilers from either pre-built binary packages or helps you create your own installer.
Compiling Ruby with RVM on Mac OS X 10.7 Lion under XCode 4.2.1
rocksolidwebdesign.comAlgunas opciones dado que GCC 4.2 (no LLVM) no es instalado por Xcode 4.2.1.
Por ahora no he instalado osx-gcc-installer tal y como se indica aquí, pero probablemente me toque. Mientras, logré compilar ruby-1.9.3 con RVM mediante:
rvm install 1.9.3 -C —with-gcc=clang
iOS app crashing with destroyed stack in .protobuf
SymptomiOS app crashing with destroyed stack of only two frames containing illegal pointers in .protobuf 1 returned by PLCrashReporter, but only on 4.2.1 and a certain revision of a certain device.
What happenedLLVM 1.7 optimizations were enabled. Turned it off, sent new build to Testflight, tester happy.
What I didAs follows:
- “restored” iPhone from 4.3 to 4.2.1 using Xcode Organizer’s “Restore” command
- greeted in the face with message that the baseband can’t be rolled back
- bricked device
- actually ran TinyUmbrella and fetched some SHSH for 4.2.1
- pinpointed
gs.apple.comto Saurik’s (“community”) auth server - spent a few hours checking out iRecovery and iBoot syntax
- ran random stuff, finally downgraded iPhone successfully to 4.2.1. Then, not being able to reproduce the bug at all.
- out of frustration, searched something like “iOS 4.2.1 random crash”, and was reminded of @zonble talking about LLVM optimizations doing tomfoolery when once we had food together…
Get dedicated testing devices, you dummie. And stop mucking around with IPSWs. Get a matrix of them (on the X axis devices by generation, e.g. iPhone 1G/3G/3GS/4, iPod touch 1G/2G/3G/4G; on the Y axis devices by iOS version, e.g. 4.0/4.1/4.2.1/4.3.2) and get one of these crazy hubs which has 100 USB ports on them. 2
p.s. Although NSOperationQueue is thread safe, -[CMMotionManager privateDealloc] puts some work on the thread CLMotionCore::runMotionThread runs, and it calls -cancelAllOperations on its queue there, which actually leaked on 4.2. Not sure if there’s a deeper bug, I subclassed NSOperationQueue and gave it a pool; the message went away.
-
PLSymbolicateby Jonas Witt helps a lot. Works under Ruby 1.8.7, and RVM helped a lot too. ↩ -
I can bet my knickers that the Japanese makes such stuff. You can even run iconclock on all of them at the same time. ↩
Numba: a Python-to-LLVM compiler
github.comFrom the home page:
Numba is an Open Source NumPy-aware optimizing compiler for Python […]. It uses the remarkable LLVM compiler infrastructure to compile Python byte-code to machine code especially for use in the NumPy run-time and SciPy modules.
I’ve found this article where they compare Numba with Cython, and it seems it gives really good performance by just adding some annotations. This is the code they use:
import numpy as np
from numba import double
from numba.decorators import jit
@jit(arg_types=[double[:,:], double[:,:]])
def pairwise_numba(X, D):
M = X.shape[0]
N = X.shape[1]
for i in range(M):
for j in range(M):
d = 0.0
for k in range(N):
tmp = X[i, k] - X[j, k]
d += tmp * tmp
D[i, j] = np.sqrt(d)
LLVM 2.0... amazing feature!
I guess you know this website http://llvm.org/ and I guess you know what I am talking about. OK.
There is a new feature I love about LLVM and this is the private instance variables. Now, you can do the following
#import <Cocoa/Cocoa.h>
@interface MyClass : NSObject {
NSString *myString;
}
- (void)doSomething;
@end
@implementation {
NSString *newString;
} - (void) doSomething {
...
}
@end
So you can now declare instance variable in the implementation. This works with Mac and iOS. To make this works you need to switch to the LLVM compiler in the Build Settings.
The Design of LLVM
drdobbs.comAn article on the design of LLVM and the special characteristics that makes it somehow better than GCC…
![]()
ARC, or why you will love LLVM
Don’t take me wrong, I strongly believe that anyone writing a compiler deserves my respect. Is not a task for the feeblest. Yet, my relationship with GCC was not always a good one. How not to hate the cryptic messages spilled by the parser from time to time? Well, let’s praise Stallman irreducibility, Apple condemn GCC and replace it with LLVM1. Regardless of the actual reasons, the change brings a better compiler to the table. One that can parse and understand code even better than my cocker spaniel, which is much more of what GCC gives us. And because the compiler is able to understand the code, well, to understand it a little better than GCC, then Apple decided that LLVM can take care of the memory-management tasks. In Apple own words:
“The compiler has a complete understanding of your objects, and releases each object the instant it is no longer used, so apps run as fast as ever, with predictable, smooth performance.”
And yes, the best part is that this is not GC. It is just let the compiler insert the release when needed. ARC works on top of the familiar reference counting.
Basically, ARC requires Apple LLVM compiler 3.0 (or later, as the time of writing, the default compiler is Apple LLVM 3.1), and the compiler flag -fobjc-arc set. Both of these requirements are set by default by Xcode 4.2 and later.
As you must remember, the only secret of reference counting is to keep an eye on ownership.
- You are owner of every object you create (using
+alloc,+allocWithZone:or+new. - You can share ownership of an object (messaging it with
-copy,-mutableCopyor-retain) - When no longer needed, ownership is relinquished with
-release. - Only relinquish objects that you own.
To ease the task, ARC introduced a few qualifiers to instruct the compiler how the objects ownership would be handle.
__strong
Default qualifier.
Semantically,
NSString __strong * someString = [[NSString alloc] initWithString:@"some string"];
Is the same of
NSString * someString = [[NSString alloc] initWithString:@"some string"];
The ownership is relinquish at the end of the present scope. This means that the release message is send automatically when the control flow leaves the scope where the strong variable was obtained.
By the way, any variable qualified with __strong, __weak and __autoreleasing are initialized to nil.
id __strong someStringVar;
id __weak someWeakVar;
id __autoreleasing someAutoreleasingVar;
Is semantically the same of
id __strong someStringVar = nil;
id __weak someWeakVar = nil;
id __autoreleasing someAutoreleasingVar = nil;
This seems small, but add o the security of the code (we are no longer dealing with undefined states).
The strong reference will generate ownership even for objects that are not created.
NSSet __strong *set = [NSSet set];
Here set is owned for the whole life of the scope.
Members variables can be qualified as __strong as well. In fact, because the compiler can insert automatically the members variable, all we need to do is to define the property.
@property (strong) CLLocation *latestKnownLocation;
And obviously, synthesize it.
@synthesize latestKnownLocation;
As long as the class instance is alive, there is going to be a strong reference to latestKnownLocation.
__weak
So, by default (we don’t even have to type __strong), the compiler will take care of the memory management most of the time. But, what happens, for instance, when two objects refer each other. That’s exactly the kind of relationship that exists between an object and its delegate. We have a tableViewDelegate which is going to serve as a delegate for a UITableView. If the table view delegate property is qualified as strong, and the same happens with the tableView property of the delegate, then, when the delegate reference counter is never going to be zero, because there is always a reference from the table view, and the table view reference counter is also impossible to reduce to zero, because it is referenced from the delegate. This is circular reference.
To avoid these kind of situations, the rule of thumb is not to claim ownership of delegates and other objects that refers to each other (like IBOutlets for instance). Let’s revisit our previous example, because the table view does not claim ownership of the delegate, the delegate can be deallocated with no problem, and because there is no delegate referencing the table view, the the table view can also be deallocated. Even better, when the object that a variable qualified as __weak is discarded, the variable value is set to nil.
The __weak qualifier is only available for iOS 5 (or later) and OSX Lion (or later). For older OSs, __unsafe_unretained qualifier must be used instead.
__unsafe_unretained
This qualifier exclude the variable from ARC mechanisms. Because no check is perform, and references are not niled, if you set a variable as __unsafe_unretained you hold the responsibility of checking if the object is still there when needed.
__autoreleasing
Because ARC handles the little nuances of memory management, it is very rare to use auto release mechanism explicitly, thou the environment provides the needed tools.
The thing is that when an object is referenced but not created, i.e., none of the methods in the family +alloc, or -copy is called, the object is automatically registered to the auto release pool. When an object is returned from a method, the compiler checks the name of the method. Naming convention is important here because the compiler used the method name to know how to handle the returned object ownership.
Most programmers are going to use __autoreleasing mainly to handle errors via indirect pointers. In ARC indirect pointers are by default qualified as __autoreleasing. The method that handle the error will take an __autoreleasing parameter:
- (BOOL)performWithError:(__autoreleasing NSError **)error {
// try something prone to failure
if ( failure ) {
*error = [[NSError alloc] initWithDomain:@"Some Error Domain"
code:101
userInfo:nil];
return NO;
}
return YES
}
And the caller portion would be something like
NSError __autoreleasing *error = nil;
if ( ![self performWithError:&error] ) {
// Deal with the error
NSLog(@"error: %@", error);
}
Legacy Code
There are plenty of code that is not ARC ready (yet). That’s not a big deal. Once again, ARC is not GC, and it works on a a copyable unit basis. To add non-ARC units to your app, Select the Target you are working with, then the Build Phases tab, and look for legacy units in Compiled Sources. Add -fno-objc-arc to each one. Recompile. You are done.
-
You would like to think that they choose compiler over the other because one is better, but that’s not the whole history. The tipping point was the more forgiven nature of LLVM License ↩
筆記
- zonble: 分享一下
- zonble: LLVM 現在在 compile 的時候,會同時檢查一下 coding convention
- zonble: 所有用 new 開頭的 method,都期待 retain count 是 1
- zonble: 例如 [ZBDocument newDocument] 這類的
- zonble: 但是這個檢查不分 class 或 instance method
- zonble: 所以如果有個 property 叫做 new... 什麼的,就噴出一堆警告
- zonble: 例如 document.newVersion 就認為不好
- zonble: 而除了 new 開頭或 init 開頭的 method,檢查的時候就都要求是 autorelease 物件
- zonble: 所以像 [ZBDocument createDocument]
- zonble: 最好就改成 [ZBDocument newDocument];
BlockRuntime project allows to use blocks on iOS < 4
BlockRuntime project on github