updates from David.

llvm-svn: 49217
This commit is contained in:
Chris Lattner 2008-04-04 15:59:59 +00:00
parent 15c6b7c948
commit 019193acea
1 changed files with 46 additions and 23 deletions

View File

@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
#include <stdarg.h>
#include "CGObjCRuntime.h"
#include "llvm/Module.h"
#include "llvm/Support/Compiler.h"
@ -74,15 +73,21 @@ CGObjCEtoile::CGObjCEtoile(llvm::Module &M,
PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
// Object type
llvm::OpaqueType *OpaqueObjTy = llvm::OpaqueType::get();
llvm::PATypeHolder OpaqueObjTy = llvm::OpaqueType::get();
llvm::Type *OpaqueIdTy = llvm::PointerType::getUnqual(OpaqueObjTy);
IdTy = llvm::PointerType::getUnqual(llvm::StructType::get(OpaqueIdTy, NULL));
OpaqueObjTy->refineAbstractTypeTo(IdTy);
IdTy = llvm::StructType::get(OpaqueIdTy, NULL);
llvm::cast<llvm::OpaqueType>(OpaqueObjTy.get())->refineAbstractTypeTo(IdTy);
IdTy = llvm::cast<llvm::StructType>(OpaqueObjTy.get());
IdTy = llvm::PointerType::getUnqual(IdTy);
// Call structure type.
llvm::OpaqueType *OpaqueSlotTy = llvm::OpaqueType::get();
CallTy = llvm::StructType::get(llvm::PointerType::getUnqual(OpaqueSlotTy),
SelectorTy, IdTy, NULL);
llvm::PATypeHolder OpaqueSlotTy = llvm::OpaqueType::get();
CallTy = llvm::StructType::get(
llvm::PointerType::getUnqual(OpaqueSlotTy),
SelectorTy,
IdTy,
NULL);
//CallTy = llvm::PointerType::getUnqual(CallTy);
// IMP type
std::vector<const llvm::Type*> IMPArgs;
@ -91,10 +96,16 @@ CGObjCEtoile::CGObjCEtoile(llvm::Module &M,
IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
// Slot type
SlotTy = llvm::StructType::get(IntTy, IMPTy, PtrToInt8Ty, PtrToInt8Ty,
llvm::Type::Int32Ty, NULL);
OpaqueSlotTy->refineAbstractTypeTo(SlotTy);
SlotTy = llvm::PointerType::getUnqual(SlotTy);
SlotTy = llvm::StructType::get(IntTy,
IMPTy,
PtrToInt8Ty,
PtrToInt8Ty,
llvm::Type::Int32Ty,
NULL);
llvm::cast<llvm::OpaqueType>(
OpaqueSlotTy.get())->refineAbstractTypeTo(SlotTy);
SlotTy = llvm::PointerType::getUnqual(
llvm::cast<llvm::StructType>(OpaqueSlotTy.get()));
// Lookup function type
std::vector<const llvm::Type*> LookupFunctionArgs;
@ -102,12 +113,13 @@ CGObjCEtoile::CGObjCEtoile(llvm::Module &M,
LookupFunctionArgs.push_back(IdTy);
LookupFunctionArgs.push_back(SelectorTy);
LookupFunctionArgs.push_back(IdTy);
LookupFunctionTy = llvm::FunctionType::get(SlotTy, LookupFunctionArgs, false);
LookupFunctionTy =
llvm::FunctionType::get(SlotTy, LookupFunctionArgs, false);
LookupFunctionTy = llvm::PointerType::getUnqual(LookupFunctionTy);
}
// Looks up the selector for the specified name / type pair.
/// Looks up the selector for the specified name / type pair.
llvm::Value *CGObjCEtoile::getSelector(llvm::LLVMFoldingBuilder &Builder,
llvm::Value *SelName,
llvm::Value *SelTypes)
@ -117,20 +129,28 @@ llvm::Value *CGObjCEtoile::getSelector(llvm::LLVMFoldingBuilder &Builder,
SelTypes = llvm::ConstantPointerNull::get(PtrToInt8Ty);
}
llvm::Constant *SelFunction =
TheModule.getOrInsertFunction("lookup_typed_selector", SelectorTy,
PtrToInt8Ty, PtrToInt8Ty, NULL);
TheModule.getOrInsertFunction("lookup_typed_selector",
SelectorTy,
PtrToInt8Ty,
PtrToInt8Ty,
NULL);
llvm::SmallVector<llvm::Value*, 2> Args;
Args.push_back(SelName);
Args.push_back(SelTypes);
return Builder.CreateCall(SelFunction, Args.begin(), Args.end());
}
#define SET(structure, index, value) do {\
llvm::Value *element_ptr = Builder.CreateStructGEP(structure, index);\
Builder.CreateStore(value, element_ptr);} while(0)
static void SetField(llvm::LLVMFoldingBuilder &Builder,
llvm::Value *Structure,
unsigned Index,
llvm::Value *Value) {
llvm::Value *element_ptr = Builder.CreateStructGEP(Structure, Index);
Builder.CreateStore(Value, element_ptr);
}
// Generate code for a message send expression on the Etoile runtime.
// BIG FAT WARNING: Much of this code will need factoring out later.
llvm::Value *CGObjCEtoile::generateMessageSend(llvm::LLVMFoldingBuilder &Builder,
llvm::Value *CGObjCEtoile::generateMessageSend(
llvm::LLVMFoldingBuilder &Builder,
const llvm::Type *ReturnTy,
llvm::Value *Sender,
llvm::Value *Receiver,
@ -172,9 +192,9 @@ llvm::Value *CGObjCEtoile::generateMessageSend(llvm::LLVMFoldingBuilder &Builder
// Create the call structure
llvm::Value *Call = Builder.CreateAlloca(CallTy);
SET(Call, 0, Slot);
SET(Call, 1, cmd);
SET(Call, 2, Sender);
SetField(Builder, Call, 0, Slot);
SetField(Builder, Call, 1, cmd);
SetField(Builder, Call, 2, Sender);
// Get the IMP from the slot and call it
// TODO: Property load / store optimisations
@ -194,6 +214,8 @@ llvm::Value *CGObjCEtoile::generateMessageSend(llvm::LLVMFoldingBuilder &Builder
return Builder.CreateCall(IMP, Args.begin(), Args.end());
}
/// Generates an LLVM Function object corresponding to the Objective-C method,
/// including the implicit arguments.
llvm::Function *CGObjCEtoile::MethodPreamble(
const llvm::Type *ReturnTy,
const llvm::Type *SelfTy,
@ -207,7 +229,8 @@ llvm::Function *CGObjCEtoile::MethodPreamble(
for (unsigned i=0; i<ArgC ; i++) {
Args.push_back(ArgTy[i]);
}
llvm::FunctionType *MethodTy = llvm::FunctionType::get(ReturnTy, Args, isVarArg);
llvm::FunctionType *MethodTy =
llvm::FunctionType::get(ReturnTy, Args, isVarArg);
llvm::Function *Method = new llvm::Function(MethodTy,
llvm::GlobalValue::InternalLinkage,
".objc.method",