Added LLVM optimisation passes for libobjc2.

This commit is contained in:
theraven 2010-03-13 18:43:56 +00:00
parent fb26e9a9ef
commit 93251416eb
8 changed files with 650 additions and 0 deletions

20
opts/COPYING Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2009 David Chisnall
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

1
opts/Debug/.dir Normal file
View File

@ -0,0 +1 @@
Sun 13 Sep 2009 13:29:32 UTC

192
opts/Debug/IvarPass.d Normal file
View File

@ -0,0 +1,192 @@
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.o \
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.d \
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.o: \
IvarPass.cpp /usr/home/theraven/llvm/include/llvm/Pass.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/PassSupport.h \
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h \
/usr/home/theraven/llvm/include/llvm/Function.h \
/usr/home/theraven/llvm/include/llvm/GlobalValue.h \
/usr/home/theraven/llvm/include/llvm/Constant.h \
/usr/home/theraven/llvm/include/llvm/User.h \
/usr/home/theraven/llvm/include/llvm/Value.h \
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h \
/usr/home/theraven/llvm/include/llvm/Use.h \
/usr/home/theraven/llvm/include/llvm/Support/Casting.h \
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h \
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/CallingConv.h \
/usr/home/theraven/llvm/include/llvm/BasicBlock.h \
/usr/home/theraven/llvm/include/llvm/Instruction.h \
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h \
/usr/home/theraven/llvm/include/llvm/Instruction.def \
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h \
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h \
/usr/home/theraven/llvm/include/llvm/Argument.h \
/usr/home/theraven/llvm/include/llvm/Attributes.h \
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
/usr/home/theraven/llvm/include/llvm/Module.h \
/usr/home/theraven/llvm/include/llvm/Function.h \
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
/usr/home/theraven/llvm/include/llvm/OperandTraits.h \
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
/usr/home/theraven/llvm/include/llvm/Metadata.h \
/usr/home/theraven/llvm/include/llvm/Type.h \
/usr/home/theraven/llvm/include/llvm/LLVMContext.h \
/usr/home/theraven/llvm/include/llvm/System/Atomic.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h \
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h \
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h \
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h \
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h \
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h \
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
/usr/home/theraven/llvm/include/llvm/Value.h \
/usr/home/theraven/llvm/include/llvm/Instructions.h \
/usr/home/theraven/llvm/include/llvm/InstrTypes.h \
/usr/home/theraven/llvm/include/llvm/Operator.h \
/usr/home/theraven/llvm/include/llvm/Constants.h \
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h \
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h \
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
/usr/home/theraven/llvm/include/llvm/Constants.h
/usr/home/theraven/llvm/include/llvm/Pass.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/PassSupport.h:
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h:
/usr/home/theraven/llvm/include/llvm/Function.h:
/usr/home/theraven/llvm/include/llvm/GlobalValue.h:
/usr/home/theraven/llvm/include/llvm/Constant.h:
/usr/home/theraven/llvm/include/llvm/User.h:
/usr/home/theraven/llvm/include/llvm/Value.h:
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h:
/usr/home/theraven/llvm/include/llvm/Use.h:
/usr/home/theraven/llvm/include/llvm/Support/Casting.h:
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h:
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/CallingConv.h:
/usr/home/theraven/llvm/include/llvm/BasicBlock.h:
/usr/home/theraven/llvm/include/llvm/Instruction.h:
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h:
/usr/home/theraven/llvm/include/llvm/Instruction.def:
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h:
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h:
/usr/home/theraven/llvm/include/llvm/Argument.h:
/usr/home/theraven/llvm/include/llvm/Attributes.h:
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
/usr/home/theraven/llvm/include/llvm/Module.h:
/usr/home/theraven/llvm/include/llvm/Function.h:
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
/usr/home/theraven/llvm/include/llvm/OperandTraits.h:
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
/usr/home/theraven/llvm/include/llvm/Metadata.h:
/usr/home/theraven/llvm/include/llvm/Type.h:
/usr/home/theraven/llvm/include/llvm/LLVMContext.h:
/usr/home/theraven/llvm/include/llvm/System/Atomic.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h:
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h:
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h:
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h:
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h:
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h:
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
/usr/home/theraven/llvm/include/llvm/Value.h:
/usr/home/theraven/llvm/include/llvm/Instructions.h:
/usr/home/theraven/llvm/include/llvm/InstrTypes.h:
/usr/home/theraven/llvm/include/llvm/Operator.h:
/usr/home/theraven/llvm/include/llvm/Constants.h:
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h:
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h:
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
/usr/home/theraven/llvm/include/llvm/Constants.h:

186
opts/Debug/TypeFeedback.d Normal file
View File

@ -0,0 +1,186 @@
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.o \
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.d \
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.o: \
TypeFeedback.cpp /usr/home/theraven/llvm/include/llvm/Constants.h \
/usr/home/theraven/llvm/include/llvm/Constant.h \
/usr/home/theraven/llvm/include/llvm/User.h \
/usr/home/theraven/llvm/include/llvm/Value.h \
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h \
/usr/home/theraven/llvm/include/llvm/Use.h \
/usr/home/theraven/llvm/include/llvm/Support/Casting.h \
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h \
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/Type.h \
/usr/home/theraven/llvm/include/llvm/LLVMContext.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/System/Atomic.h \
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h \
/usr/home/theraven/llvm/include/llvm/OperandTraits.h \
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h \
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h \
/usr/home/theraven/llvm/include/llvm/Pass.h \
/usr/home/theraven/llvm/include/llvm/PassSupport.h \
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h \
/usr/home/theraven/llvm/include/llvm/Module.h \
/usr/home/theraven/llvm/include/llvm/Function.h \
/usr/home/theraven/llvm/include/llvm/GlobalValue.h \
/usr/home/theraven/llvm/include/llvm/CallingConv.h \
/usr/home/theraven/llvm/include/llvm/BasicBlock.h \
/usr/home/theraven/llvm/include/llvm/Instruction.h \
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h \
/usr/home/theraven/llvm/include/llvm/Instruction.def \
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h \
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h \
/usr/home/theraven/llvm/include/llvm/Argument.h \
/usr/home/theraven/llvm/include/llvm/Attributes.h \
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
/usr/home/theraven/llvm/include/llvm/Metadata.h \
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h \
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h \
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h \
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h \
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h \
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
/usr/home/theraven/llvm/include/llvm/Value.h \
/usr/home/theraven/llvm/include/llvm/Function.h \
/usr/home/theraven/llvm/include/llvm/Instructions.h \
/usr/home/theraven/llvm/include/llvm/InstrTypes.h \
/usr/home/theraven/llvm/include/llvm/Operator.h \
/usr/home/theraven/llvm/include/llvm/Constants.h \
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h
/usr/home/theraven/llvm/include/llvm/Constants.h:
/usr/home/theraven/llvm/include/llvm/Constant.h:
/usr/home/theraven/llvm/include/llvm/User.h:
/usr/home/theraven/llvm/include/llvm/Value.h:
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h:
/usr/home/theraven/llvm/include/llvm/Use.h:
/usr/home/theraven/llvm/include/llvm/Support/Casting.h:
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h:
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/Type.h:
/usr/home/theraven/llvm/include/llvm/LLVMContext.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/System/Atomic.h:
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h:
/usr/home/theraven/llvm/include/llvm/OperandTraits.h:
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h:
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h:
/usr/home/theraven/llvm/include/llvm/Pass.h:
/usr/home/theraven/llvm/include/llvm/PassSupport.h:
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h:
/usr/home/theraven/llvm/include/llvm/Module.h:
/usr/home/theraven/llvm/include/llvm/Function.h:
/usr/home/theraven/llvm/include/llvm/GlobalValue.h:
/usr/home/theraven/llvm/include/llvm/CallingConv.h:
/usr/home/theraven/llvm/include/llvm/BasicBlock.h:
/usr/home/theraven/llvm/include/llvm/Instruction.h:
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h:
/usr/home/theraven/llvm/include/llvm/Instruction.def:
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h:
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h:
/usr/home/theraven/llvm/include/llvm/Argument.h:
/usr/home/theraven/llvm/include/llvm/Attributes.h:
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
/usr/home/theraven/llvm/include/llvm/Metadata.h:
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h:
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h:
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h:
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h:
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h:
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
/usr/home/theraven/llvm/include/llvm/Value.h:
/usr/home/theraven/llvm/include/llvm/Function.h:
/usr/home/theraven/llvm/include/llvm/Instructions.h:
/usr/home/theraven/llvm/include/llvm/InstrTypes.h:
/usr/home/theraven/llvm/include/llvm/Operator.h:
/usr/home/theraven/llvm/include/llvm/Constants.h:
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h:

127
opts/IvarPass.cpp Normal file
View File

@ -0,0 +1,127 @@
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
#include "llvm/GlobalAlias.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Constants.h"
#include <string>
using namespace llvm;
using std::string;
namespace
{
class GNUNonfragileIvarPass : public FunctionPass
{
public:
static char ID;
GNUNonfragileIvarPass() : FunctionPass((intptr_t)&ID) {}
Module *M;
size_t PointerSize;
virtual bool doInitialization(Module &Mod) {
M = &Mod;
PointerSize = 8;
if (M->getPointerSize() == Module::Pointer32)
PointerSize = 4;
return false;
}
std::string getSuperName(Constant *ClsStruct) {
GlobalVariable *name =
cast<GlobalVariable>(ClsStruct->getOperand(1)->getOperand(0));
return cast<ConstantArray>(name->getInitializer())->getAsString();
}
size_t sizeOfClass(const std::string &className) {
if (className.compare(0, 8, "NSObject") == 0 ||
className.compare(0, 6, "Object") == 0) {
return PointerSize;
}
GlobalVariable *Cls = M->getGlobalVariable("_OBJC_CLASS_" + className);
if (!Cls) return 0;
Constant *ClsStruct = Cls->getInitializer();
// Size is initialized to be negative.
ConstantInt *Size = cast<ConstantInt>(ClsStruct->getOperand(5));
return sizeOfClass(getSuperName(ClsStruct)) - Size->getSExtValue();
}
size_t hardCodedOffset(const StringRef &className,
const StringRef &ivarName) {
GlobalVariable *Cls = M->getGlobalVariable(("_OBJC_CLASS_" + className).str(), true);
if (!Cls) return 0;
Constant *ClsStruct = Cls->getInitializer();
size_t superSize = sizeOfClass(getSuperName(ClsStruct));
if (!superSize) return 0;
ConstantStruct *IvarStruct = cast<ConstantStruct>(
cast<GlobalVariable>(ClsStruct->getOperand(6))->getInitializer());
int ivarCount = cast<ConstantInt>(IvarStruct->getOperand(0))->getSExtValue();
Constant *ivars = IvarStruct->getOperand(1);
for (int i=0 ; i<ivarCount ; i++) {
Constant *ivar = ivars->getOperand(i);
GlobalVariable *name =
cast<GlobalVariable>(ivar->getOperand(0)->getOperand(0));
std::string ivarNameStr =
cast<ConstantArray>(name->getInitializer())->getAsString();
if (ivarNameStr.compare(0, ivarName.size(), ivarName.str()) == 0)
return superSize +
cast<ConstantInt>(ivar->getOperand(2))->getSExtValue();
}
return 0;
}
virtual bool runOnFunction(Function &F) {
bool modified = false;
//llvm::cerr << "IvarPass: " << F.getName() << "\n";
for (Function::iterator i=F.begin(), end=F.end() ;
i != end ; ++i) {
for (BasicBlock::iterator b=i->begin(), last=i->end() ;
b != last ; ++b) {
if (LoadInst *indirectload = dyn_cast<LoadInst>(b)) {
if (LoadInst *load = dyn_cast<LoadInst>(indirectload->getOperand(0))) {
if (GlobalVariable *ivar =
dyn_cast<GlobalVariable>(load->getOperand(0))) {
StringRef variableName = ivar->getName();
if (!variableName.startswith("__objc_ivar_offset_"))
break;
size_t prefixLength = strlen("__objc_ivar_offset_");
StringRef suffix = variableName.substr(prefixLength,
variableName.size()-prefixLength);
std::pair<StringRef,StringRef> parts = suffix.split('.');
StringRef className = parts.first;
StringRef ivarName = parts.second;
// If the class, and all superclasses, are visible in this module
// then we can hard-code the ivar offset
if (size_t offset = hardCodedOffset(className, ivarName)) {
indirectload->replaceAllUsesWith(ConstantInt::get(indirectload->getType(), offset));
modified = true;
} else {
// If the class was compiled with the new
if (Value *offset =
M->getGlobalVariable(("__objc_ivar_offset_value_" + suffix).str())) {
load->replaceAllUsesWith(offset);
modified = true;
}
}
}
}
}
}
}
return modified;
}
};
char GNUNonfragileIvarPass::ID = 0;
RegisterPass<GNUNonfragileIvarPass> X("gnu-nonfragile-ivar", "Ivar fragility pass");
}
FunctionPass *createGNUNonfragileIvarPass(void)
{
return new GNUNonfragileIvarPass();
}

7
opts/Makefile Normal file
View File

@ -0,0 +1,7 @@
LEVEL = ../../../
LIBRARYNAME = GNUObjCRuntime
LOADABLE_MODULE = 1
USEDLIBS =
include $(LEVEL)/Makefile.common

30
opts/README Normal file
View File

@ -0,0 +1,30 @@
GNUstep Runtime Optimisations
=============================
This directory contains LLVM optimisations specific to libobjc2. To build
them, you must copy this directory to llvm/lib/Transforms/GNURuntime (where
llvm is the root of your llvm checkout).
Running GNU make will then create GNUObjCRuntime.so. This library can be
passed to opt to run optimisations on bitcode generated with clang or
LanguageKit.
Non-Fragile Ivar Pass
---------------------
Running `opt -gnu-nonfragile-ivar` will invoke the non-fragile instance
variable lowering pass. This will turn non-fragile instance variable accesses,
which go via one or two indirection layers, into more fragile ones. If a class
and all of its superclasses are present in the module then this pass will turn
indirect instance variable accesses into hard-coded ones.
For this pass to be most useful, it should be run as a link-time optimisation.
Type Feedback
-------------
Running `opt -gnu-objc-type-feedback` enables type feedback. Objective-C
message lookups will be replaced by calls to the profiling version in the
runtime library. The generated data can then be used for future optimisations
(speculative inlining, polymorphic inline caching, and so on), which have not
yet been written.

87
opts/TypeFeedback.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "llvm/Constants.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include <vector>
using namespace llvm;
namespace {
struct GNUObjCTypeFeedback : public ModulePass {
typedef std::pair<CallInst*,CallInst*> callPair;
typedef std::vector<callPair > replacementVector;
static char ID;
uint32_t callsiteCount;
const IntegerType *Int32Ty;
GNUObjCTypeFeedback() : ModulePass(&ID), callsiteCount(0) {}
void profileFunction(Function &F, Constant *ModuleID)
{
for (Function::iterator i=F.begin(), e=F.end() ;
i != e ; ++i)
{
replacementVector replacements;
for (BasicBlock::iterator b=i->begin(), last=i->end() ;
b != last ; ++b)
{
Module *M = F.getParent();
if (CallInst *call = dyn_cast<CallInst>(b))
{
if (Function *callee = call->getCalledFunction())
{
if (callee->getName() == "objc_msg_lookup_sender")
{
llvm::Value *args[] = { call->getOperand(1),
call->getOperand(2), call->getOperand(3),
ModuleID, ConstantInt::get(Int32Ty,
callsiteCount++) };
Function *profile = cast<Function>(
M->getOrInsertFunction("objc_msg_lookup_profile",
callee->getFunctionType()->getReturnType(),
args[0]->getType(), args[1]->getType(),
args[2]->getType(),
ModuleID->getType(), Int32Ty, NULL));
llvm::CallInst *profileCall =
CallInst::Create(profile, args, args+5, "", call);
replacements.push_back(callPair(call, profileCall));
}
}
}
}
for (replacementVector::iterator r=replacements.begin(),
e=replacements.end() ; e!=r ; r++)
{
r->first->replaceAllUsesWith(r->second);
r->second->getParent()->getInstList().erase(r->first);
}
}
}
public:
virtual bool runOnModule(Module &M)
{
LLVMContext &VMContext = M.getContext();
Int32Ty = IntegerType::get(VMContext, 32);
Constant *moduleName =
ConstantArray::get(VMContext, M.getModuleIdentifier(), true);
moduleName = new GlobalVariable(M, moduleName->getType(), true,
GlobalValue::InternalLinkage, moduleName,
".objc_profile_module_name");
for (Module::iterator F=M.begin(), e=M.end() ;
F != e ; ++F)
{
profileFunction(*F, moduleName);
}
return true;
}
};
char GNUObjCTypeFeedback::ID = 0;
RegisterPass<GNUObjCTypeFeedback> X("gnu-objc-type-feedback",
"Objective-C type feedback for the GNU runtime.", false, true);
}