Started 1.6.1 release announcement, updated LLVM optimisations to work with LLVM 3.1.

main
theraven 14 years ago
parent 6f1589a841
commit abff244ef9

@ -1,50 +1,27 @@
GNUstep Objective-C Runtime 1.6 GNUstep Objective-C Runtime 1.6.1
=============================== ===============================
This is the seventh official release of the GNUstep Objective-C runtime (a.k.a. This is a point release to the seventh official release of the GNUstep
libobjc2). This runtime was designed to support the features of Objective-C 2 Objective-C runtime (a.k.a. libobjc2). This runtime was designed to support
for use with GNUstep and other Objective-C programs. Highlights of this the features of Objective-C 2 for use with GNUstep and other Objective-C
release include: programs. Highlights of this release include:
- Compatibility with the new runtime APIs introduced with Mac OS X 10.7 / iOS 5. - Improved support for ARC autorelease pools.
- Support for small objects (ones hidden inside a pointer). On 32-bit systems, - Some small bug fixes in blocks support.
the runtime permits one small object class, on 64-bit systems it permits 4.
This is used by GNUstep for small NSNumber and NSString instances, and these
are used by LanguageKit for message sending to small integers.
- Support for prototype-style object orientation. You can now add methods, as - Improvements to the Objective-C++ unified exception model support.
well as associated references, to individual objects, and clone them. The
runtime now supports everything required for the JavaScript object model,
including the ability to use blocks as methods on x86, x86-64 and ARM.
- Support for Apple-compatible objc_msgSend() functions for x86, x86-64, and - Updated optimisation passes to work with LLVM 3.1
ARM. Using these approximately halves the cost of message sending operations
and results in a 10% smaller total binary size.
- A fully maintained POSIX Makefile to make bootstrapping builds and packaging
easier. This will be used automatically if GNUstep Make is not installed.
- Improvements to the included LLVM optimisation passes. Testing on a 2.8GHz
Xeon, a loop of 200,000,000 class messages took 0.8 seconds with all
optimisations enabled (including speculative inlining). With -Os, the test
took 2 seconds. With explicit IMP caching in the source code, the test took
1.2 seconds. For reference, the same test using the GCC Objective-C runtime
took 11 seconds (when compiled with either Clang/LLVM or GCC).
Various features of this release required some per-platform assembly code. For
the 1.6.0 release, ARM, x86 and x86-64 (with the SysV ABI, not with the Win64
ABI) are supported. Future releases in the 1.6.x series will extend this to
other architectures.
You may obtain the code for this release from subversion at the following You may obtain the code for this release from subversion at the following
subversion branch: subversion branch:
svn://svn.gna.org/svn/gnustep/libs/libobjc2/1.6 svn://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1
Alternatively, a tarball is available from: Alternatively, a tarball is available from:
http://download.gna.org/gnustep/libobjc2-1.6.tar.bz2 http://download.gna.org/gnustep/libobjc2-1.6.1.tar.bz2
The runtime library is responsible for implementing the core features of the The runtime library is responsible for implementing the core features of the
object model, as well as exposing introspection features to the user. The object model, as well as exposing introspection features to the user. The

@ -56,8 +56,13 @@ namespace
GlobalVariable *classNameVar = dyn_cast<GlobalVariable>( GlobalVariable *classNameVar = dyn_cast<GlobalVariable>(
call->getOperand(0)->stripPointerCasts()); call->getOperand(0)->stripPointerCasts());
if (0 == classNameVar) { continue; } if (0 == classNameVar) { continue; }
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
ConstantDataArray *init = dyn_cast<ConstantDataArray>(
classNameVar->getInitializer());
#else
ConstantArray *init = dyn_cast<ConstantArray>( ConstantArray *init = dyn_cast<ConstantArray>(
classNameVar->getInitializer()); classNameVar->getInitializer());
#endif
if (0 == init || !init->isCString()) { continue; } if (0 == init || !init->isCString()) { continue; }
lookup.first = call; lookup.first = call;
lookup.second = init->getAsString(); lookup.second = init->getAsString();

@ -85,9 +85,14 @@ namespace
if (0 == method || method->isDeclaration()) { continue; } if (0 == method || method->isDeclaration()) { continue; }
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
InlineCost IC = CA.getInlineCost((*i), method, 200);
#else
InlineCost IC = CA.getInlineCost((*i), method, NeverInline); InlineCost IC = CA.getInlineCost((*i), method, NeverInline);
#define getCost getValue
#endif
// FIXME: 200 is a random number. Pick a better one! // FIXME: 200 is a random number. Pick a better one!
if (IC.isAlways() || (IC.isVariable() && IC.getValue() < 200)) { if (IC.isAlways() || (IC.isVariable() && IC.getCost() < 200)) {
cacher.SpeculativelyInline((*i).getInstruction(), method); cacher.SpeculativelyInline((*i).getInstruction(), method);
i->getInstruction()->setMetadata(MessageSendMDKind, 0); i->getInstruction()->setMetadata(MessageSendMDKind, 0);
modified = true; modified = true;

@ -47,7 +47,11 @@ namespace {
User *super = cast<User>(ClsStruct->getOperand(1)); User *super = cast<User>(ClsStruct->getOperand(1));
if (isa<ConstantPointerNull>(super)) return ""; if (isa<ConstantPointerNull>(super)) return "";
GlobalVariable *name = cast<GlobalVariable>(super->getOperand(0)); GlobalVariable *name = cast<GlobalVariable>(super->getOperand(0));
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
return cast<ConstantDataArray>(name->getInitializer())->getAsString();
#else
return cast<ConstantArray>(name->getInitializer())->getAsString(); return cast<ConstantArray>(name->getInitializer())->getAsString();
#endif
} }
size_t sizeOfClass(const std::string &className) { size_t sizeOfClass(const std::string &className) {
@ -88,7 +92,11 @@ namespace {
cast<GlobalVariable>( cast<GlobalVariable>(
cast<User>(ivar->getOperand(0))->getOperand(0)); cast<User>(ivar->getOperand(0))->getOperand(0));
std::string ivarNameStr = std::string ivarNameStr =
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
cast<ConstantDataArray>(name->getInitializer())->getAsString();
#else
cast<ConstantArray>(name->getInitializer())->getAsString(); cast<ConstantArray>(name->getInitializer())->getAsString();
#endif
// Remove the NULL terminator from the metadata string // Remove the NULL terminator from the metadata string
ivarNameStr.resize(ivarNameStr.size() - 1); ivarNameStr.resize(ivarNameStr.size() - 1);
if (ivarNameStr == ivarName.str()) if (ivarNameStr == ivarName.str())

@ -55,7 +55,11 @@ namespace {
Int32Ty = IntegerType::get(VMContext, 32); Int32Ty = IntegerType::get(VMContext, 32);
LLVMPointerType *PtrTy = Type::getInt8PtrTy(VMContext); LLVMPointerType *PtrTy = Type::getInt8PtrTy(VMContext);
Constant *moduleName = Constant *moduleName =
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
ConstantDataArray::getString(VMContext, M.getModuleIdentifier(), true);
#else
ConstantArray::get(VMContext, M.getModuleIdentifier(), true); ConstantArray::get(VMContext, M.getModuleIdentifier(), true);
#endif
moduleName = new GlobalVariable(M, moduleName->getType(), true, moduleName = new GlobalVariable(M, moduleName->getType(), true,
GlobalValue::InternalLinkage, moduleName, GlobalValue::InternalLinkage, moduleName,
".objc_profile_module_name"); ".objc_profile_module_name");
@ -75,7 +79,11 @@ namespace {
functions.push_back(ConstantExpr::getBitCast(F, PtrTy)); functions.push_back(ConstantExpr::getBitCast(F, PtrTy));
Constant * ConstStr = Constant * ConstStr =
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
llvm::ConstantDataArray::getString(VMContext, F->getName(), true);
#else
llvm::ConstantArray::get(VMContext, F->getName()); llvm::ConstantArray::get(VMContext, F->getName());
#endif
ConstStr = new GlobalVariable(M, ConstStr->getType(), true, ConstStr = new GlobalVariable(M, ConstStr->getType(), true,
GlobalValue::PrivateLinkage, ConstStr, "str"); GlobalValue::PrivateLinkage, ConstStr, "str");
functions.push_back( functions.push_back(

@ -68,9 +68,14 @@ namespace {
Function *method = M.getFunction(Entry->begin()->getKey()); Function *method = M.getFunction(Entry->begin()->getKey());
if (0 == method || method->isDeclaration()) { continue; } if (0 == method || method->isDeclaration()) { continue; }
#if (LLVM_MAJOR > 3) || ((LLVM_MAJOR == 3) && (LLVM_MINOR > 0))
InlineCost IC = CA.getInlineCost((*i), method, 200);
#else
InlineCost IC = CA.getInlineCost((*i), method, NeverInline); InlineCost IC = CA.getInlineCost((*i), method, NeverInline);
#define getCost getValue
#endif
// FIXME: 200 is a random number. Pick a better one! // FIXME: 200 is a random number. Pick a better one!
if (IC.isAlways() || (IC.isVariable() && IC.getValue() < 200)) { if (IC.isAlways() || (IC.isVariable() && IC.getCost() < 200)) {
cacher.SpeculativelyInline((*i).getInstruction(), method); cacher.SpeculativelyInline((*i).getInstruction(), method);
modified = true; modified = true;
} }

Loading…
Cancel
Save