summaryrefslogtreecommitdiff
path: root/MLKLLVMCompiler.mm
diff options
context:
space:
mode:
authorMatthias Benkard <mulk@minimulk.mst-plus>2008-08-16 22:51:22 +0200
committerMatthias Benkard <mulk@minimulk.mst-plus>2008-08-16 22:51:22 +0200
commit5cd4de577c08637cb5d78d1c3376b1ff80e74065 (patch)
treec9e0e279f0c95b5f7fc5c691821344cb2e5d3ce4 /MLKLLVMCompiler.mm
parentd858e84c0778dc1851b3a0e324caaf0bef05f274 (diff)
parent3f11cb6b3ddd03d3211dd355cbac23884fa5a6e3 (diff)
Merge branch 'master' of http://matthias.benkard.de/code/mulklisp
Diffstat (limited to 'MLKLLVMCompiler.mm')
-rw-r--r--MLKLLVMCompiler.mm154
1 files changed, 119 insertions, 35 deletions
diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm
index 3ad0c10..4313ac9 100644
--- a/MLKLLVMCompiler.mm
+++ b/MLKLLVMCompiler.mm
@@ -35,6 +35,8 @@
#include <llvm/Support/IRBuilder.h>
#include <llvm/Target/TargetData.h>
#include <llvm/Transforms/Scalar.h>
+#include <llvm/Transforms/IPO.h>
+#include <llvm/Transforms/Utils/UnifyFunctionExitNodes.h>
#include <llvm/Value.h>
#include <deque>
@@ -45,7 +47,7 @@ using namespace llvm;
static ExecutionEngine *execution_engine;
static llvm::Module *module;
-static IRBuilder builder;
+static IRBuilder<true, ConstantFolder> builder;
static FunctionPassManager *fpm;
static PointerType *PointerTy;
static ModuleProvider *module_provider;
@@ -78,10 +80,21 @@ static Constant
module_provider = new ExistingModuleProvider (module);
fpm = new FunctionPassManager (module_provider);
fpm->add (new TargetData (*execution_engine->getTargetData()));
+ //fpm->add (new TargetData (module));
fpm->add (createInstructionCombiningPass());
fpm->add (createReassociatePass());
fpm->add (createGVNPass());
+ // fpm->add (createVerifierPass());
+ //fpm->add (createLowerSetJmpPass());
+ //fpm->add (createRaiseAllocationsPass());
fpm->add (createCFGSimplificationPass());
+ fpm->add (createPromoteMemoryToRegisterPass());
+ //fpm->add (createGlobalOptimizerPass());
+ //fpm->add (createGlobalDCEPass());
+ //fpm->add (createFunctionInliningPass());
+
+ // Utilities.
+ // fpm->add (createUnifyFunctionExitNodesPass());
}
+(id) compile:(id)object
@@ -108,16 +121,19 @@ static Constant
forCompiler:self]];
builder.CreateRet (v);
- function->dump();
verifyFunction (*function);
fpm->run (*function);
// JIT-compile.
fn = (id (*)()) execution_engine->getPointerToFunction (function);
+ module->dump();
+ NSLog (@"%p", fn);
// Execute.
lambdaForm = fn();
+ NSLog (@"Closure built.");
+
return lambdaForm;
}
@@ -169,23 +185,53 @@ static Constant
name:@""];
}
++(Value *) insertVoidMethodCall:(NSString *)messageName
+ onObject:(Value *)object
+ withArgumentVector:(std::vector<Value*> *)argv
+{
+ return [self insertMethodCall:messageName
+ onObject:object
+ withArgumentVector:argv
+ name:@""
+ returnType:(Type::VoidTy)];
+}
+
++(Value *) insertMethodCall:(NSString *)messageName
+ onObject:(Value *)object
+ withArgumentVector:(std::vector<Value*> *)argv
+ name:(NSString *)name
+{
+ return [self insertMethodCall:messageName
+ onObject:object
+ withArgumentVector:argv
+ name:@""
+ returnType:PointerTy];
+}
+
+(Value *) insertMethodCall:(NSString *)messageName
onObject:(Value *)object
withArgumentVector:(std::vector<Value*> *)argv
- name:(NSString *)name;
+ name:(NSString *)name
+ returnType:(const Type *)returnType
{
std::vector <const Type *> argtypes (2, PointerTy);
- FunctionType *ftype = FunctionType::get (PointerTy, argtypes, true);
- Constant *function =
- module->getOrInsertFunction (
+ FunctionType *ftype = FunctionType::get (returnType, argtypes, true);
+
+ Value *sel = [self insertSelectorLookup:messageName];
+
#ifdef __NEXT_RUNTIME__
- "objc_msgSend",
+ Constant *function =
+ module->getOrInsertFunction ("objc_msgSend", ftype);
#else
- "objc_msg_send",
+ std::vector <const Type *> lookup_argtypes (2, PointerTy);
+ FunctionType *lookup_ftype = FunctionType::get (PointerType::get (ftype, 0),
+ lookup_argtypes,
+ false);
+ Constant *lookup_function =
+ module->getOrInsertFunction ("objc_msg_lookup", lookup_ftype);
+ Value *function =
+ builder.CreateCall2 (lookup_function, object, sel, "method_impl");
#endif
- ftype);
-
- Value *sel = [self insertSelectorLookup:messageName];
// XXX The following doesn't work. Why?
// std::deque <Value *> argd (*argv);
@@ -240,6 +286,17 @@ static Constant
Constant *nameptr = createGlobalStringPtr (cname);
return builder.CreateCall (function, nameptr, cname);
}
+
++(void) insertTrace:(NSString *)message
+{
+ Constant *function =
+ module->getOrInsertFunction ("puts",
+ Type::Int32Ty,
+ PointerTy,
+ NULL);
+
+ builder.CreateCall (function, createGlobalStringPtr ([message UTF8String]));
+}
@end
@@ -309,12 +366,12 @@ static Constant
if ([_context variableHeapAllocationForSymbol:_form])
{
- Value *binding = builder.CreateLoad ([_context bindingForSymbol:_form]);
+ Value *binding = builder.CreateLoad ([_context bindingValueForSymbol:_form]);
value = [_compiler insertMethodCall:@"value" onObject:binding];
}
else
{
- value = builder.CreateLoad ([_context valueForSymbol:_form],
+ value = builder.CreateLoad ([_context valueValueForSymbol:_form],
[MLKPrintToString(_form) UTF8String]);
}
@@ -332,15 +389,16 @@ static Constant
// XXX Issue a style warning.
}
- Value *functionCell = builder.CreateLoad ([_context functionCellForSymbol:_head]);
+ Value *functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]);
Value *functionPtr = builder.CreateLoad (functionCell);
- Value *closureDataPointer = builder.CreateLoad ([_context closureDataPointerForSymbol:_head]);
+ Value *closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]);
+ Value *closureDataPtr = builder.CreateLoad (closureDataCell);
NSEnumerator *e = [_argumentForms objectEnumerator];
MLKForm *form;
std::vector<Value *> args;
- args.push_back (closureDataPointer);
+ args.push_back (closureDataPtr);
while ((form = [e nextObject]))
{
@@ -382,6 +440,8 @@ static Constant
BasicBlock *loopBlock = BasicBlock::Create ("load_args");
BasicBlock *loopInitBlock = BasicBlock::Create ("load_args_prelude");
BasicBlock *joinBlock = BasicBlock::Create ("function_body");
+ BasicBlock *lambdaListNewBlock = BasicBlock::Create ("lambda_list_new");
+ BasicBlock *lambdaListUpdateBlock = BasicBlock::Create ("lambda_list_update");
builder.SetInsertPoint (initBlock);
@@ -398,13 +458,14 @@ static Constant
NULL),
ap);
- Value *nsmutablearray = [_compiler insertClassLookup:@"NSMutableArray"];
Value *mlkcons = [_compiler insertClassLookup:@"MLKCons"];
+
+ // FIXME: Heap-allocate if appropriate.
Value *lambdaList = builder.CreateAlloca (PointerTy, NULL, "lambda_list");
+ Value *lambdaListTail = builder.CreateAlloca (PointerTy, NULL, "lambda_list_tail");
- builder.CreateStore ([_compiler insertMethodCall:@"array"
- onObject:nsmutablearray],
- lambdaList);
+ builder.CreateStore (ConstantPointerNull::get (PointerTy), lambdaList);
+ builder.CreateStore (ConstantPointerNull::get (PointerTy), lambdaListTail);
builder.CreateBr (loopInitBlock);
builder.SetInsertPoint (loopInitBlock);
@@ -416,13 +477,35 @@ static Constant
builder.SetInsertPoint (loopBlock);
function->getBasicBlockList().push_back (loopBlock);
+ builder.CreateCondBr (builder.CreateICmpEQ (builder.CreateLoad (lambdaList),
+ ConstantPointerNull::get (PointerTy)),
+ lambdaListNewBlock,
+ lambdaListUpdateBlock);
+
+ builder.SetInsertPoint (lambdaListNewBlock);
+ function->getBasicBlockList().push_back (lambdaListNewBlock);
std::vector <Value *> argv (1, arg);
- builder.CreateStore ([_compiler insertMethodCall:@"addObject:"
- onObject:builder.CreateLoad(lambdaList)
- withArgumentVector:&argv],
- lambdaList);
+ argv.push_back (ConstantPointerNull::get (PointerTy));
+ Value *newLambdaList = [_compiler insertMethodCall:@"cons:with:"
+ onObject:mlkcons
+ withArgumentVector:&argv];
+ builder.CreateStore (newLambdaList, lambdaList);
+ builder.CreateStore (newLambdaList, lambdaListTail);
+ builder.CreateBr (loopInitBlock);
+ builder.SetInsertPoint (lambdaListUpdateBlock);
+ function->getBasicBlockList().push_back (lambdaListUpdateBlock);
+
+ Value *newCons = [_compiler insertMethodCall:@"cons:with:"
+ onObject:mlkcons
+ withArgumentVector:&argv];
+ std::vector <Value *> setcdr_argv (1, newCons);
+ [_compiler insertVoidMethodCall:@"setCdr:"
+ onObject:builder.CreateLoad(lambdaListTail)
+ withArgumentVector:&setcdr_argv];
+ builder.CreateStore (newCons, lambdaListTail);
builder.CreateBr (loopInitBlock);
+
builder.SetInsertPoint (joinBlock);
function->getBasicBlockList().push_back (joinBlock);
@@ -432,12 +515,6 @@ static Constant
NULL),
ap);
- argv[0] = builder.CreateLoad(lambdaList);
- builder.CreateStore ([_compiler insertMethodCall:@"listWithArray:"
- onObject:mlkcons
- withArgumentVector:&argv],
- lambdaList);
-
NSEnumerator *e = [_bodyForms objectEnumerator];
MLKForm *form;
Value *value = NULL;
@@ -451,26 +528,31 @@ static Constant
while ((form = [e nextObject]))
{
//NSLog (@"%LAMBDA: Processing subform.");
+ [form->_context setValueValue:lambdaList forSymbol:_lambdaListName];
value = [form processForLLVM];
}
builder.CreateRet (value);
function->dump();
- NSLog (@"Verify...");
+ //NSLog (@"Verify...");
verifyFunction (*function);
- NSLog (@"Optimise...");
+ //NSLog (@"Optimise...");
fpm->run (*function);
- NSLog (@"Done.");
+ //NSLog (@"Assemble...");
+ // Explicit assembly is needed in order to allow libffi to call
+ // the function.
+ execution_engine->getPointerToFunction (function);
+ //NSLog (@"Done.");
function->dump();
- NSLog (@"Function built.");
+ //NSLog (@"Function built.");
builder.SetInsertPoint (outerBlock);
Value *closure_data = ConstantPointerNull::get (PointerTy);
argv[0] = function;
- argv.push_back (closure_data);
+ argv[1] = closure_data;
argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty,
0,
false),
@@ -482,6 +564,8 @@ static Constant
onObject:mlkcompiledclosure
withArgumentVector:&argv];
+ //function->viewCFG();
+
return closure;
}
@end