From 2aebd102c5cd0d18858495da77d5287666995f36 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 15:24:29 +0200 Subject: MLKLLVMCompiler: Directly build argument lists without first constructing an array. --- MLKLLVMCompiler.h | 8 +++++ MLKLLVMCompiler.mm | 88 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 72 insertions(+), 24 deletions(-) diff --git a/MLKLLVMCompiler.h b/MLKLLVMCompiler.h index 0fbf51e..379d791 100644 --- a/MLKLLVMCompiler.h +++ b/MLKLLVMCompiler.h @@ -53,6 +53,14 @@ using namespace llvm; onObject:(Value *)object withArgumentVector:(std::vector *)argv name:(NSString *)name; ++(Value *) insertMethodCall:(NSString *)messageName + onObject:(Value *)object + withArgumentVector:(std::vector *)argv + name:(NSString *)name + returnType:(const Type *)returnType; ++(Value *) insertVoidMethodCall:(NSString *)messageName + onObject:(Value *)object + withArgumentVector:(std::vector *)argv; +(Value *) insertMethodCall:(NSString *)messageName onObject:(Value *)object; diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 93c0640..0a55972 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -187,28 +187,50 @@ static Constant name:@""]; } ++(Value *) insertVoidMethodCall:(NSString *)messageName + onObject:(Value *)object + withArgumentVector:(std::vector *)argv +{ + return [self insertMethodCall:messageName + onObject:object + withArgumentVector:argv + name:@"" + returnType:(Type::VoidTy)]; +} + ++(Value *) insertMethodCall:(NSString *)messageName + onObject:(Value *)object + withArgumentVector:(std::vector *)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 *)argv - name:(NSString *)name; + name:(NSString *)name + returnType:(const Type *)returnType { std::vector argtypes (2, PointerTy); - FunctionType *ftype = FunctionType::get (PointerTy, argtypes, true); + FunctionType *ftype = FunctionType::get (returnType, argtypes, true); Value *sel = [self insertSelectorLookup:messageName]; #ifdef __NEXT_RUNTIME__ Constant *function = - module->getOrInsertFunction ("objc_msgSend", - ftype); + module->getOrInsertFunction ("objc_msgSend", ftype); #else std::vector 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); + module->getOrInsertFunction ("objc_msg_lookup", lookup_ftype); Value *function = builder.CreateCall2 (lookup_function, object, sel, "method_impl"); #endif @@ -420,6 +442,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); [_compiler insertTrace:@"In function."]; @@ -438,15 +462,14 @@ static Constant ap); [_compiler insertTrace:@"After va_start."]; - 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); @@ -460,13 +483,35 @@ static Constant function->getBasicBlockList().push_back (loopBlock); [_compiler insertTrace:@"Adding argument."]; + builder.CreateCondBr (builder.CreateICmpEQ (builder.CreateLoad (lambdaList), + ConstantPointerNull::get (PointerTy)), + lambdaListNewBlock, + lambdaListUpdateBlock); + + builder.SetInsertPoint (lambdaListNewBlock); + function->getBasicBlockList().push_back (lambdaListNewBlock); std::vector 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 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); @@ -477,12 +522,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; @@ -508,10 +547,11 @@ static Constant verifyFunction (*function); NSLog (@"Optimise..."); fpm->run (*function); - //NSLog (@"Assemble..."); - //id (*function_code)(...) = (id (*)(...)) execution_engine->getPointerToFunction (function); + NSLog (@"Assemble..."); + // Assembling explicitly is needed in order to allow libffi to call + // the function. + execution_engine->getPointerToFunction (function); NSLog (@"Done."); - //function_code (0, MLKEndOfArgumentsMarker); function->dump(); NSLog (@"Function built."); @@ -520,7 +560,7 @@ static Constant 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), -- cgit v1.2.3