From f632ef49a7d5465943ac7ac7c666c0490887caad Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 13 Aug 2008 00:43:48 +0200 Subject: Revert "MLKCompiledClosure: Always indirect through a function pointer before doing a call." This reverts commit dfe50b2e72ddbd0148870748975f00e7fc662314. --- MLKCompiledClosure.h | 3 +-- MLKCompiledClosure.m | 14 +++----------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/MLKCompiledClosure.h b/MLKCompiledClosure.h index 589c0de..7df6c68 100644 --- a/MLKCompiledClosure.h +++ b/MLKCompiledClosure.h @@ -27,9 +27,8 @@ @interface MLKCompiledClosure : NSObject { int _dataLength; - id (**_code)(); + id (*_code)(); id *_data; - BOOL _ownPointer; // do we own the _code pointer cell? } // Why intptr_t? Because it makes it easier to call this method from diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index 5dbf6dd..c2ab290 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -38,10 +38,7 @@ _data = data; _dataLength = dataLength; - _ownPointer = YES; - - _code = malloc (sizeof (id (*)())); - *_code = code; + _code = code; for (i = 0; i < _dataLength; i++) { @@ -89,7 +86,7 @@ format:@"FFI type is invalid (this is probably a bug)."]; } - ffi_call (&cif, FFI_FN (*_code), &return_value, (void**)argv); + ffi_call (&cif, FFI_FN (_code), &return_value, (void**)argv); // FIXME return [NSArray arrayWithObject:nullify(return_value)]; @@ -111,16 +108,11 @@ [super dealloc]; - // FIXME: Decrease refcount of *_code. Note: When releasing *_code, - // also release _code regardless of whether we own it. - + // FIXME: Decrease refcount of _code. for (i = 0; i < _dataLength; i++) { LRELEASE (_data[i]); } free (_data); - - if (_ownPointer) - free (_code); } @end -- cgit v1.2.3 From 1d741f977203814b9c5b0b5d524af25eff27a3c1 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 13 Aug 2008 01:00:09 +0200 Subject: LLVM compiler: Bind the lambda list. --- MLKLLVMCompiler.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 3ad0c10..72571a7 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -108,7 +108,6 @@ static Constant forCompiler:self]]; builder.CreateRet (v); - function->dump(); verifyFunction (*function); fpm->run (*function); @@ -400,6 +399,8 @@ static Constant Value *nsmutablearray = [_compiler insertClassLookup:@"NSMutableArray"]; Value *mlkcons = [_compiler insertClassLookup:@"MLKCons"]; + + // FIXME: Heap-allocate if appropriate. Value *lambdaList = builder.CreateAlloca (PointerTy, NULL, "lambda_list"); builder.CreateStore ([_compiler insertMethodCall:@"array" @@ -451,6 +452,7 @@ static Constant while ((form = [e nextObject])) { //NSLog (@"%LAMBDA: Processing subform."); + [form->_context setValue:lambdaList forSymbol:_lambdaListName]; value = [form processForLLVM]; } -- cgit v1.2.3 From a8a3de11ce7219d9567fb5d341276325f8df04be Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 13 Aug 2008 11:04:55 +0200 Subject: Add COMPILE. --- MLKPackage.m | 1 + MLKRoot.m | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/MLKPackage.m b/MLKPackage.m index a05f822..acaf6db 100644 --- a/MLKPackage.m +++ b/MLKPackage.m @@ -154,6 +154,7 @@ static NSMutableDictionary *packages = nil; [sys export:[sys intern:@"FIXNUM-EQ"]]; [sys export:[sys intern:@"DECLARATIONS-AND-DOC-AND-FORMS"]]; [sys export:[sys intern:@"DECLARATIONS-AND-FORMS"]]; + [sys export:[sys intern:@"COMPILE"]]; [sys export:[sys intern:@"OBJC-CLASS-OF"]]; [sys export:[sys intern:@"OBJC-SUBCLASSP"]]; diff --git a/MLKRoot.m b/MLKRoot.m index 940181c..a003912 100644 --- a/MLKRoot.m +++ b/MLKRoot.m @@ -22,6 +22,7 @@ #import "MLKDynamicContext.h" #import "MLKInterpretedClosure.h" #import "MLKInterpreter.h" +#import "MLKLLVMCompiler.h" #import "MLKNumber.h" #import "MLKPackage.h" #import "MLKRoot.h" @@ -702,4 +703,15 @@ as provided by method %@ of object %@", cons:forms with:nil]]); } + + ++(NSArray *) compile:(NSArray *)args +{ + NSLog (@"Compiling lambda form."); + id thing = [MLKLLVMCompiler compile:denullify([args objectAtIndex:0]) + inContext:[MLKLexicalContext globalContext]]; + NSLog (@"Compilation done."); + NSLog (@"Compiled: %@", thing); + RETURN_VALUE (thing); +} @end -- cgit v1.2.3 From 207427cfa0c42a511ef677cf456430855c86c319 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:16:55 +0200 Subject: LLVM compiler: Implement Objective-C message sending for the GNU runtime. --- MLKLLVMCompiler.mm | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 72571a7..b902bbe 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -175,16 +175,24 @@ static Constant { std::vector argtypes (2, PointerTy); FunctionType *ftype = FunctionType::get (PointerTy, argtypes, true); - Constant *function = - module->getOrInsertFunction ( + + Value *sel = [self insertSelectorLookup:messageName]; + #ifdef __NEXT_RUNTIME__ - "objc_msgSend", + Constant *function = + module->getOrInsertFunction ("objc_msgSend", + ftype); #else - "objc_msg_send", + 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); + 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 argd (*argv); -- cgit v1.2.3 From ae6e74608bfb068a431ba397f4b69cabc31d06e2 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:21:41 +0200 Subject: LLVM compiler: Add trace messages to compiled code. --- MLKLLVMCompiler.h | 2 ++ MLKLLVMCompiler.mm | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/MLKLLVMCompiler.h b/MLKLLVMCompiler.h index 7a38679..0fbf51e 100644 --- a/MLKLLVMCompiler.h +++ b/MLKLLVMCompiler.h @@ -61,6 +61,8 @@ using namespace llvm; withName:(NSString *)name; +(Value *) insertClassLookup:(NSString *)className; + ++(void) insertTrace:(NSString *)message; #endif @end diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index b902bbe..8c837ef 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -81,7 +83,17 @@ static Constant fpm->add (createInstructionCombiningPass()); fpm->add (createReassociatePass()); fpm->add (createGVNPass()); - fpm->add (createCFGSimplificationPass()); + // 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 @@ -107,16 +119,22 @@ static Constant inContext:context forCompiler:self]]; + [self insertTrace:@"Bla.\n"]; + builder.CreateRet (v); 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; } @@ -247,6 +265,23 @@ 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])); + + Constant *function2 = + module->getOrInsertFunction ("fflush", + Type::Int32Ty, + PointerTy, + NULL); +} @end @@ -341,13 +376,14 @@ static Constant Value *functionCell = builder.CreateLoad ([_context functionCellForSymbol:_head]); Value *functionPtr = builder.CreateLoad (functionCell); - Value *closureDataPointer = builder.CreateLoad ([_context closureDataPointerForSymbol:_head]); + Value *closureDataCell = builder.CreateLoad ([_context closureDataPointerForSymbol:_head]); + Value *closureDataPtr = builder.CreateLoad (closureDataCell); NSEnumerator *e = [_argumentForms objectEnumerator]; MLKForm *form; std::vector args; - args.push_back (closureDataPointer); + args.push_back (closureDataPtr); while ((form = [e nextObject])) { @@ -391,6 +427,7 @@ static Constant BasicBlock *joinBlock = BasicBlock::Create ("function_body"); builder.SetInsertPoint (initBlock); + [_compiler insertTrace:@"In function."]; Value *endmarker = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)MLKEndOfArgumentsMarker, @@ -404,6 +441,7 @@ static Constant PointerTy, NULL), ap); + [_compiler insertTrace:@"After va_start."]; Value *nsmutablearray = [_compiler insertClassLookup:@"NSMutableArray"]; Value *mlkcons = [_compiler insertClassLookup:@"MLKCons"]; @@ -419,12 +457,14 @@ static Constant builder.SetInsertPoint (loopInitBlock); function->getBasicBlockList().push_back (loopInitBlock); + [_compiler insertTrace:@"In loop."]; Value *arg = builder.CreateVAArg (ap, PointerTy, "arg"); Value *cond = builder.CreateICmpEQ (arg, endmarker); builder.CreateCondBr (cond, joinBlock, loopBlock); builder.SetInsertPoint (loopBlock); function->getBasicBlockList().push_back (loopBlock); + [_compiler insertTrace:@"Adding argument."]; std::vector argv (1, arg); builder.CreateStore ([_compiler insertMethodCall:@"addObject:" onObject:builder.CreateLoad(lambdaList) @@ -435,6 +475,7 @@ static Constant builder.SetInsertPoint (joinBlock); function->getBasicBlockList().push_back (joinBlock); + [_compiler insertTrace:@"After loop."]; builder.CreateCall (module->getOrInsertFunction ("llvm.va_end", Type::VoidTy, PointerTy, @@ -464,6 +505,7 @@ static Constant value = [form processForLLVM]; } + [_compiler insertTrace:@"Returning."]; builder.CreateRet (value); function->dump(); @@ -471,7 +513,10 @@ static Constant verifyFunction (*function); NSLog (@"Optimise..."); fpm->run (*function); + //NSLog (@"Assemble..."); + //id (*function_code)(...) = (id (*)(...)) execution_engine->getPointerToFunction (function); NSLog (@"Done."); + //function_code (0, MLKEndOfArgumentsMarker); function->dump(); NSLog (@"Function built."); @@ -480,6 +525,10 @@ static Constant Value *closure_data = ConstantPointerNull::get (PointerTy); argv[0] = function; + // argv[0] = (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, + // (uint64_t)function_code, + // false), + // PointerTy)); argv.push_back (closure_data); argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, 0, -- cgit v1.2.3 From 33d61cbd7c4017d4f7832b331721cf00000a8c0b Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:22:41 +0200 Subject: MLKCompiledClosure: Add debugging messages. --- MLKCompiledClosure.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index c2ab290..6737acc 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -86,9 +86,16 @@ format:@"FFI type is invalid (this is probably a bug)."]; } + NSLog (@"Calling %p (argc = %d)", _code, argc); + _code(0, MLKEndOfArgumentsMarker); + for (i = 0; i < argc; i++) + { + NSLog (@"Argument %d: %p", i, *((void**)argv[i])); + } + ffi_call (&cif, FFI_FN (_code), &return_value, (void**)argv); - // FIXME + // FIXME: multiple values return [NSArray arrayWithObject:nullify(return_value)]; } -- cgit v1.2.3 From 286720abbafdbb544748c58f12d78f1591d28326 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:23:17 +0200 Subject: LOAD: Cosmetic changes. --- MLKInterpreter.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MLKInterpreter.m b/MLKInterpreter.m index 42d22ed..693c742 100644 --- a/MLKInterpreter.m +++ b/MLKInterpreter.m @@ -1320,7 +1320,6 @@ NSString *formdesc; NSAutoreleasePool *pool; - //NSLog (@"%@", code); //NSLog (@"%@", MLKPrintToString(code)); //NSLog (@"%@", stream); //NSLog (@"..."); @@ -1328,9 +1327,9 @@ pool = [[NSAutoreleasePool alloc] init]; code = [MLKReader readFromStream:stream - eofError:NO - eofValue:eofValue - recursive:NO + eofError:NO + eofValue:eofValue + recursive:NO preserveWhitespace:NO]; if (code == eofValue) -- cgit v1.2.3 From df1bbb796753c98e68c858a45b83f3cc918ee68f Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:24:34 +0200 Subject: GNUmakefile: Link LLVM's ipo component in. --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index 9bd1c2f..ac6c368 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -76,7 +76,7 @@ ifeq ($(USE_LLVM),YES) ADDITIONAL_OBJCCFLAGS = $(ADDITIONAL_OBJCFLAGS) ToiletKit_OBJCC_FILES = MLKLLVMCompiler.mm ToiletKit_OBJCCFLAGS = `llvm-config --cxxflags` $(ToiletKit_OBJCFLAGS) -ToiletKit_LDFLAGS += `llvm-config --ldflags` `llvm-config --libs backend engine linker codegen transformutils scalaropts analysis` +ToiletKit_LDFLAGS += `llvm-config --ldflags` `llvm-config --libs backend engine linker codegen transformutils scalaropts analysis ipo` endif #TOOL_NAME = etoilet -- cgit v1.2.3 From 291c50e6fc89dea5d2e0ba731a2188a4ccacbd06 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 13:43:42 +0200 Subject: MLKCompiledClosure: Fix an off-by-one error in argument handling. --- MLKCompiledClosure.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index 6737acc..85b1bf5 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -72,7 +72,7 @@ for (i = 1; i < argc - 1; i++) { arg_types[i] = &ffi_type_pointer; - argpointers[i-1] = denullify([arguments objectAtIndex:i]); + argpointers[i-1] = denullify([arguments objectAtIndex:(i-1)]); argv[i] = &argpointers[i-1]; } -- cgit v1.2.3 From 95c1ccd0b1d863e8a7f3643b025dc80000af5aa8 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 13:44:57 +0200 Subject: MLKLLVMCompiler: Make compilable with the latest unstable version of LLVM. --- MLKLLVMCompiler.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 8c837ef..72b1c3d 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -47,7 +47,7 @@ using namespace llvm; static ExecutionEngine *execution_engine; static llvm::Module *module; -static IRBuilder builder; +static IRBuilder builder; static FunctionPassManager *fpm; static PointerType *PointerTy; static ModuleProvider *module_provider; -- cgit v1.2.3 From 9464d1a63f4d2d30b1db08ffbcc4a4994ca16f22 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 13:46:35 +0200 Subject: MLKLLVMCompiler: Cleanups. --- MLKLLVMCompiler.mm | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 72b1c3d..93c0640 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -80,6 +80,7 @@ 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()); @@ -119,7 +120,7 @@ static Constant inContext:context forCompiler:self]]; - [self insertTrace:@"Bla.\n"]; + [self insertTrace:@"Bla."]; builder.CreateRet (v); verifyFunction (*function); @@ -275,12 +276,6 @@ static Constant NULL); builder.CreateCall (function, createGlobalStringPtr ([message UTF8String])); - - Constant *function2 = - module->getOrInsertFunction ("fflush", - Type::Int32Ty, - PointerTy, - NULL); } @end @@ -525,10 +520,6 @@ static Constant Value *closure_data = ConstantPointerNull::get (PointerTy); argv[0] = function; - // argv[0] = (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, - // (uint64_t)function_code, - // false), - // PointerTy)); argv.push_back (closure_data); argv.push_back (builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, 0, @@ -541,6 +532,8 @@ static Constant onObject:mlkcompiledclosure withArgumentVector:&argv]; + //function->viewCFG(); + return closure; } @end -- cgit v1.2.3 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 From 6f05d2a89573bd0cb6bb93d8c5a900254e711339 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 15:25:26 +0200 Subject: MLKCompiledClosure: Remove debugging call to _code. --- MLKCompiledClosure.m | 1 - 1 file changed, 1 deletion(-) diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index 85b1bf5..6eb9154 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -87,7 +87,6 @@ } NSLog (@"Calling %p (argc = %d)", _code, argc); - _code(0, MLKEndOfArgumentsMarker); for (i = 0; i < argc; i++) { NSLog (@"Argument %d: %p", i, *((void**)argv[i])); -- cgit v1.2.3 From be719f278f6b7c58cb2f0dfbd6edce19a3df85cc Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 15:28:10 +0200 Subject: LLVM compiler: Remove various debugging messages. --- MLKCompiledClosure.m | 10 +++++----- MLKLLVMCompiler.mm | 20 ++++++-------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index 6eb9154..c9f1e97 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -86,11 +86,11 @@ format:@"FFI type is invalid (this is probably a bug)."]; } - NSLog (@"Calling %p (argc = %d)", _code, argc); - for (i = 0; i < argc; i++) - { - NSLog (@"Argument %d: %p", i, *((void**)argv[i])); - } +// NSLog (@"Calling %p (argc = %d)", _code, argc); +// for (i = 0; i < argc; i++) +// { +// NSLog (@"Argument %d: %p", i, *((void**)argv[i])); +// } ffi_call (&cif, FFI_FN (_code), &return_value, (void**)argv); diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 0a55972..11001dc 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -120,8 +120,6 @@ static Constant inContext:context forCompiler:self]]; - [self insertTrace:@"Bla."]; - builder.CreateRet (v); verifyFunction (*function); fpm->run (*function); @@ -446,7 +444,6 @@ static Constant BasicBlock *lambdaListUpdateBlock = BasicBlock::Create ("lambda_list_update"); builder.SetInsertPoint (initBlock); - [_compiler insertTrace:@"In function."]; Value *endmarker = builder.CreateIntToPtr (ConstantInt::get(Type::Int64Ty, (uint64_t)MLKEndOfArgumentsMarker, @@ -460,7 +457,6 @@ static Constant PointerTy, NULL), ap); - [_compiler insertTrace:@"After va_start."]; Value *mlkcons = [_compiler insertClassLookup:@"MLKCons"]; @@ -475,14 +471,12 @@ static Constant builder.SetInsertPoint (loopInitBlock); function->getBasicBlockList().push_back (loopInitBlock); - [_compiler insertTrace:@"In loop."]; Value *arg = builder.CreateVAArg (ap, PointerTy, "arg"); Value *cond = builder.CreateICmpEQ (arg, endmarker); builder.CreateCondBr (cond, joinBlock, loopBlock); builder.SetInsertPoint (loopBlock); function->getBasicBlockList().push_back (loopBlock); - [_compiler insertTrace:@"Adding argument."]; builder.CreateCondBr (builder.CreateICmpEQ (builder.CreateLoad (lambdaList), ConstantPointerNull::get (PointerTy)), lambdaListNewBlock, @@ -515,7 +509,6 @@ static Constant builder.SetInsertPoint (joinBlock); function->getBasicBlockList().push_back (joinBlock); - [_compiler insertTrace:@"After loop."]; builder.CreateCall (module->getOrInsertFunction ("llvm.va_end", Type::VoidTy, PointerTy, @@ -539,21 +532,20 @@ static Constant value = [form processForLLVM]; } - [_compiler insertTrace:@"Returning."]; builder.CreateRet (value); function->dump(); - NSLog (@"Verify..."); + //NSLog (@"Verify..."); verifyFunction (*function); - NSLog (@"Optimise..."); + //NSLog (@"Optimise..."); fpm->run (*function); - NSLog (@"Assemble..."); - // Assembling explicitly is needed in order to allow libffi to call + //NSLog (@"Assemble..."); + // Explicit assembly is needed in order to allow libffi to call // the function. execution_engine->getPointerToFunction (function); - NSLog (@"Done."); + //NSLog (@"Done."); function->dump(); - NSLog (@"Function built."); + //NSLog (@"Function built."); builder.SetInsertPoint (outerBlock); -- cgit v1.2.3 From efafbf36521acb710e92258af13191893e1d75c8 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 15:28:44 +0200 Subject: MLKArray: Add method +array. --- MLKArray.h | 1 + MLKArray.m | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/MLKArray.h b/MLKArray.h index 5fedf1c..1205b69 100644 --- a/MLKArray.h +++ b/MLKArray.h @@ -31,6 +31,7 @@ NSArray *_displacement; } ++(id) array; -(id) initWithDimensions:(NSArray *)dimensions; -(NSArray *) dimensions; diff --git a/MLKArray.m b/MLKArray.m index 5890953..11c7889 100644 --- a/MLKArray.m +++ b/MLKArray.m @@ -30,6 +30,14 @@ @implementation MLKArray ++(id) array +{ + return LAUTORELEASE ([[self alloc] + initWithDimensions: + [NSArray arrayWithObject: + [MLKInteger integerWithInt:0]]]); +} + -(id) initWithDimensions:(NSArray *)dimensions { NSEnumerator *e; -- cgit v1.2.3 From e4718a30d1b9253035555392753185855692bdca Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 16:57:16 +0200 Subject: MLKLLVMCompiler: Enable more optimisation passes. --- MLKLLVMCompiler.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 11001dc..969d12c 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -85,13 +85,13 @@ static Constant 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()); + //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()); -- cgit v1.2.3 From 69d20805fb9c361f2011f24e4c47288d678a995a Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Fri, 15 Aug 2008 23:25:45 +0200 Subject: =?UTF-8?q?GNUmakefile:=20Explicitly=20link=20some=20LLVM=20librar?= =?UTF-8?q?ies=20into=20the=20=E2=80=98toilet=E2=80=99=20executable.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GNUmakefile b/GNUmakefile index ac6c368..e2ea521 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -93,7 +93,7 @@ etshell_OBJCFLAGS = -w toilet_OBJC_FILES = MLKReadEvalPrintLoop.m toilet_OBJC_LIBS += -ledit -lncurses -lToiletKit -LToiletKit.framework \ - -LToiletKit.framework/Versions/Current + -LToiletKit.framework/Versions/Current `llvm-config --ldflags` `llvm-config --libs scalaropts analysis ipo` toilet_OBJCFLAGS = -Wall Test_OBJC_FILES = MLKLowLevelTests.m -- cgit v1.2.3 From 79abb06fbce7ee8f72556ededeee3eb88baf2fc8 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 18:42:30 +0200 Subject: MLKCompiledClosure: Add accessors. --- MLKCompiledClosure.h | 3 +++ MLKCompiledClosure.m | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/MLKCompiledClosure.h b/MLKCompiledClosure.h index 7df6c68..772f29c 100644 --- a/MLKCompiledClosure.h +++ b/MLKCompiledClosure.h @@ -46,5 +46,8 @@ -(NSString *) description; -(NSString *) descriptionForLisp; +-(id (*)()) code; +-(void *) closureData; + -(void) dealloc; @end diff --git a/MLKCompiledClosure.m b/MLKCompiledClosure.m index c9f1e97..73f308b 100644 --- a/MLKCompiledClosure.m +++ b/MLKCompiledClosure.m @@ -108,6 +108,16 @@ return [NSString stringWithFormat:@"", self]; } +-(id (*)()) code +{ + return _code; +} + +-(void *) closureData +{ + return _data; +} + -(void) dealloc { int i; -- cgit v1.2.3 From 82d94f911150e1c9df1d5a44aa52d85637227afa Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 18:44:46 +0200 Subject: %FSET, %FSETQ: Set global function bindings in a way that compiled code can understand. --- MLKLLVMCompiler.mm | 10 ++--- MLKLexicalContext-MLKLLVMCompilation.h | 16 ++++---- MLKLexicalContext-MLKLLVMCompilation.mm | 72 ++++++++++++++++++--------------- MLKLexicalContext.h | 4 ++ MLKLexicalContext.m | 57 ++++++++++++++++++++++++++ MLKLexicalEnvironment.m | 52 ++++++++++++++++++++++++ 6 files changed, 165 insertions(+), 46 deletions(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index 969d12c..e9507a9 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -366,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]); } @@ -389,9 +389,9 @@ static Constant // XXX Issue a style warning. } - Value *functionCell = builder.CreateLoad ([_context functionCellForSymbol:_head]); + Value *functionCell = builder.CreateLoad ([_context functionCellValueForSymbol:_head]); Value *functionPtr = builder.CreateLoad (functionCell); - Value *closureDataCell = builder.CreateLoad ([_context closureDataPointerForSymbol:_head]); + Value *closureDataCell = builder.CreateLoad ([_context closureDataPointerValueForSymbol:_head]); Value *closureDataPtr = builder.CreateLoad (closureDataCell); NSEnumerator *e = [_argumentForms objectEnumerator]; @@ -528,7 +528,7 @@ static Constant while ((form = [e nextObject])) { //NSLog (@"%LAMBDA: Processing subform."); - [form->_context setValue:lambdaList forSymbol:_lambdaListName]; + [form->_context setValueValue:lambdaList forSymbol:_lambdaListName]; value = [form processForLLVM]; } diff --git a/MLKLexicalContext-MLKLLVMCompilation.h b/MLKLexicalContext-MLKLLVMCompilation.h index 0e9056b..eaae1f3 100644 --- a/MLKLexicalContext-MLKLLVMCompilation.h +++ b/MLKLexicalContext-MLKLLVMCompilation.h @@ -34,13 +34,13 @@ using namespace llvm; #ifdef __cplusplus -(void) setVariableHeapAllocation:(BOOL)heapp forSymbol:(id)name; -(BOOL) variableHeapAllocationForSymbol:(id)name; --(Value *) functionCellForSymbol:(id)name; --(Value *) closureDataPointerForSymbol:(id)name; --(Value *) bindingForSymbol:(id)name; --(Value *) valueForSymbol:(id)name; --(void) setFunctionCell:(Value *)cellPtr forSymbol:(id)name; --(void) setClosureDataPointer:(Value *)pointer forSymbol:(id)name; --(void) setBinding:(Value *)binding forSymbol:(id)name; --(void) setValue:(Value *)value forSymbol:(id)name; +-(Value *) functionCellValueForSymbol:(id)name; +-(Value *) closureDataPointerValueForSymbol:(id)name; +-(Value *) bindingValueForSymbol:(id)name; +-(Value *) valueValueForSymbol:(id)name; +//-(void) setFunctionCellValue:(Value *)cellPtr forSymbol:(id)name; +//-(void) setClosureDataPointerValue:(Value *)pointer forSymbol:(id)name; +//-(void) setBindingValue:(Value *)binding forSymbol:(id)name; +-(void) setValueValue:(Value *)value forSymbol:(id)name; #endif @end diff --git a/MLKLexicalContext-MLKLLVMCompilation.mm b/MLKLexicalContext-MLKLLVMCompilation.mm index 8be1f24..2ff7ec0 100644 --- a/MLKLexicalContext-MLKLLVMCompilation.mm +++ b/MLKLexicalContext-MLKLLVMCompilation.mm @@ -22,8 +22,11 @@ #import #include -#include #include +#include +#include +#include +#include using namespace llvm; using namespace std; @@ -45,56 +48,59 @@ using namespace std; return (flag && [flag boolValue]); } --(Value *) functionCellForSymbol:(id)name +-(Value *) functionCellValueForSymbol:(id)name { - return (Value *) [[self deepPropertyForFunction:name - key:@"LLVM.function-cell"] - pointerValue]; + return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, + (uint64_t)[self functionCellForSymbol:name], + false), + PointerType::get(Type::Int8Ty, 0))); } --(Value *) closureDataPointerForSymbol:(id)name +-(Value *) closureDataPointerValueForSymbol:(id)name { - return (Value *) [[self deepPropertyForFunction:name - key:@"LLVM.closure-data-pointer"] - pointerValue]; + return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, + (uint64_t)[self closureDataPointerForSymbol:name], + false), + PointerType::get(Type::Int8Ty, 0))); } --(Value *) bindingForSymbol:(id)name +-(Value *) bindingValueForSymbol:(id)name { - return (Value *) [[self deepPropertyForVariable:name - key:@"LLVM.variable-binding"] - pointerValue]; + return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, + (uint64_t)[self bindingForSymbol:name], + false), + PointerType::get(Type::Int8Ty, 0))); } --(Value *) valueForSymbol:(id)name +-(Value *) valueValueForSymbol:(id)name { return (Value *) [[self deepPropertyForVariable:name key:@"LLVM.variable-value"] pointerValue]; } --(void) setFunctionCell:(Value *)cellPtr forSymbol:(id)name -{ - [self setDeepProperty:[NSValue valueWithPointer:cellPtr] - forFunction:name - key:@"LLVM.function-cell"]; -} +// -(void) setFunctionCellValue:(Value *)cellPtr forSymbol:(id)name +// { +// [self setDeepProperty:[NSValue valueWithPointer:cellPtr] +// forFunction:name +// key:@"LLVM.function-cell"]; +// } --(void) setClosureDataPointer:(Value *)pointer forSymbol:(id)name -{ - [self setDeepProperty:[NSValue valueWithPointer:pointer] - forFunction:name - key:@"LLVM.closure-data"]; -} +// -(void) setClosureDataPointerValue:(Value *)pointer forSymbol:(id)name +// { +// [self setDeepProperty:[NSValue valueWithPointer:pointer] +// forFunction:name +// key:@"LLVM.closure-data"]; +// } --(void) setBinding:(Value *)binding forSymbol:(id)name -{ - [self setDeepProperty:[NSValue valueWithPointer:binding] - forVariable:name - key:@"LLVM.variable-binding"]; -} +// -(void) setBindingValue:(Value *)binding forSymbol:(id)name +// { +// [self setDeepProperty:[NSValue valueWithPointer:binding] +// forVariable:name +// key:@"LLVM.variable-binding"]; +// } --(void) setValue:(Value *)value forSymbol:(id)name +-(void) setValueValue:(Value *)value forSymbol:(id)name { [self setDeepProperty:[NSValue valueWithPointer:value] forVariable:name diff --git a/MLKLexicalContext.h b/MLKLexicalContext.h index de6bfd7..fc2abc3 100644 --- a/MLKLexicalContext.h +++ b/MLKLexicalContext.h @@ -105,5 +105,9 @@ forFunction:(id)name key:(id)key; +-(void *) functionCellForSymbol:(id)name; +-(void *) closureDataPointerForSymbol:(id)name; +-(id) bindingForSymbol:(id)name; + -(void) dealloc; @end diff --git a/MLKLexicalContext.m b/MLKLexicalContext.m index d051b2a..1eaa51c 100644 --- a/MLKLexicalContext.m +++ b/MLKLexicalContext.m @@ -22,6 +22,7 @@ #import #import #import +#import #import "MLKCons.h" #import "MLKDynamicContext.h" @@ -358,6 +359,62 @@ static MLKSymbol *LEXICAL; } } +-(void *) functionCellForSymbol:(id)name +{ + id prop = [self deepPropertyForFunction:name + key:@"LEXCTX.function-cell"]; + + if (!prop) + { + void *cell = malloc (sizeof(id (*)())); + prop = [NSValue valueWithPointer:cell]; + [self setDeepProperty:prop + forFunction:name + key:@"LEXCTX.function-cell"]; + return cell; + } + else + { + return [prop pointerValue]; + } +} + +-(void *) closureDataPointerForSymbol:(id)name +{ + id prop = [self deepPropertyForFunction:name + key:@"LEXCTX.closure-data"]; + + if (!prop) + { + void *cell = malloc (sizeof(id (*)())); + prop = [NSValue valueWithPointer:cell]; + [self setDeepProperty:prop + forFunction:name + key:@"LEXCTX.closure-data"]; + return cell; + } + else + { + return [prop pointerValue]; + } +} + +-(id) bindingForSymbol:(id)name +{ + id prop = [self deepPropertyForVariable:name + key:@"LEXCTX.variable-binding"]; + + if (!prop) + { + prop = [MLKBinding binding]; + [self setDeepProperty:prop + forVariable:name + key:@"LEXCTX.variable-binding"]; + } + + return prop; +} + -(void) dealloc { LRELEASE (_macros); diff --git a/MLKLexicalEnvironment.m b/MLKLexicalEnvironment.m index fbeb9aa..ca6b4a9 100644 --- a/MLKLexicalEnvironment.m +++ b/MLKLexicalEnvironment.m @@ -24,8 +24,10 @@ #import #import +#import "MLKCompiledClosure.h" #import "MLKCons.h" #import "MLKEnvironment.h" +#import "MLKLexicalContext.h" #import "MLKLexicalEnvironment.h" #import "MLKPackage.h" #import "MLKParenReader.h" @@ -141,11 +143,61 @@ static MLKLexicalEnvironment *global_environment; -(void) setFunction:(id)value forSymbol:(MLKSymbol *)symbol { [_functions setValue:value forSymbol:symbol]; + + if ([_functions environmentForSymbol:symbol] == global_environment->_functions) + { + // If we're changing the global environment, we need to + // interoperate with compiled code. In this case, be sure to set + // the global function cell. + // + // Note that this reserves memory for the function cell that is + // never freed, which is why we do it for global function bindings + // only! + id (**cell)(void *, ...) = [[MLKLexicalContext globalContext] + functionCellForSymbol:symbol]; + void **closure_data_cell = [[MLKLexicalContext globalContext] + closureDataPointerForSymbol:symbol]; + if ([value isKindOfClass:[MLKCompiledClosure class]]) + { + *cell = (id (*)(void *, ...))[value code]; + *closure_data_cell = [value closureData]; + } + else + { + *cell = MLKInterpretedFunctionTrampoline; + *closure_data_cell = value; + } + } } -(void) addFunction:(id)value forSymbol:(MLKSymbol *)symbol { [_functions addValue:value forSymbol:symbol]; + + if (self == global_environment) + { + // If we're changing the global environment, we need to + // interoperate with compiled code. In this case, be sure to set + // the global function cell. + // + // Note that this reserves memory for the function cell that is + // never freed, which is why we do it for global function bindings + // only! + id (**cell)(void *, ...) = [[MLKLexicalContext globalContext] + functionCellForSymbol:symbol]; + void **closure_data_cell = [[MLKLexicalContext globalContext] + closureDataPointerForSymbol:symbol]; + if ([value isKindOfClass:[MLKCompiledClosure class]]) + { + *cell = (id (*)(void *, ...))[value code]; + *closure_data_cell = [value closureData]; + } + else + { + *cell = MLKInterpretedFunctionTrampoline; + *closure_data_cell = value; + } + } } -(BOOL) fboundp:(MLKSymbol *)symbol -- cgit v1.2.3 From 66168b73736dff38b6db98d08d8a1fbe255012a8 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 18:54:51 +0200 Subject: MLKLexicalContext(MLKLLVMCompilation): Fix value types. --- MLKLexicalContext-MLKLLVMCompilation.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MLKLexicalContext-MLKLLVMCompilation.mm b/MLKLexicalContext-MLKLLVMCompilation.mm index 2ff7ec0..9ca18e4 100644 --- a/MLKLexicalContext-MLKLLVMCompilation.mm +++ b/MLKLexicalContext-MLKLLVMCompilation.mm @@ -50,10 +50,14 @@ using namespace std; -(Value *) functionCellValueForSymbol:(id)name { + std::vector types (1, PointerType::get(Type::Int8Ty, 0)); return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, (uint64_t)[self functionCellForSymbol:name], false), - PointerType::get(Type::Int8Ty, 0))); + PointerType::get(FunctionType::get(PointerType::get(Type::Int8Ty, 0), + types, + true), + 0))); } -(Value *) closureDataPointerValueForSymbol:(id)name @@ -61,7 +65,7 @@ using namespace std; return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, (uint64_t)[self closureDataPointerForSymbol:name], false), - PointerType::get(Type::Int8Ty, 0))); + PointerType::get(PointerType::get(Type::Int8Ty, 0), 0))); } -(Value *) bindingValueForSymbol:(id)name -- cgit v1.2.3 From a3ce495d346709238b24a381ef2ab80a8cf03c95 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 21:55:13 +0200 Subject: MLKFunctionCallForm: Process arguments as forms. --- MLKForm.m | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/MLKForm.m b/MLKForm.m index e78a790..a5bebe5 100644 --- a/MLKForm.m +++ b/MLKForm.m @@ -292,7 +292,20 @@ -(id) complete { self = [super complete]; - LASSIGN (_argumentForms, [_tail array]); + + id rest; + NSMutableArray *argumentForms = [NSMutableArray array]; + + rest = [_form cdr]; + while (rest) + { + [argumentForms addObject:[MLKForm formWithObject:[rest car] + inContext:_context + forCompiler:_compiler]]; + rest = [rest cdr]; + } + + LASSIGN (_argumentForms, argumentForms); return self; } -- cgit v1.2.3 From a78119062f100f3da6e1243ce464c2819da64a2b Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 21:56:34 +0200 Subject: MLKLexicalContext(MLKLLVMCompilation): Further fix value types. --- MLKLexicalContext-MLKLLVMCompilation.h | 5 +++-- MLKLexicalContext-MLKLLVMCompilation.mm | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/MLKLexicalContext-MLKLLVMCompilation.h b/MLKLexicalContext-MLKLLVMCompilation.h index eaae1f3..d42140e 100644 --- a/MLKLexicalContext-MLKLLVMCompilation.h +++ b/MLKLexicalContext-MLKLLVMCompilation.h @@ -26,6 +26,7 @@ #include #include #include +#include using namespace llvm; #endif @@ -34,8 +35,8 @@ using namespace llvm; #ifdef __cplusplus -(void) setVariableHeapAllocation:(BOOL)heapp forSymbol:(id)name; -(BOOL) variableHeapAllocationForSymbol:(id)name; --(Value *) functionCellValueForSymbol:(id)name; --(Value *) closureDataPointerValueForSymbol:(id)name; +-(Instruction *) functionCellValueForSymbol:(id)name; +-(Instruction *) closureDataPointerValueForSymbol:(id)name; -(Value *) bindingValueForSymbol:(id)name; -(Value *) valueValueForSymbol:(id)name; //-(void) setFunctionCellValue:(Value *)cellPtr forSymbol:(id)name; diff --git a/MLKLexicalContext-MLKLLVMCompilation.mm b/MLKLexicalContext-MLKLLVMCompilation.mm index 9ca18e4..744351a 100644 --- a/MLKLexicalContext-MLKLLVMCompilation.mm +++ b/MLKLexicalContext-MLKLLVMCompilation.mm @@ -48,19 +48,21 @@ using namespace std; return (flag && [flag boolValue]); } --(Value *) functionCellValueForSymbol:(id)name +-(Instruction *) functionCellValueForSymbol:(id)name { std::vector types (1, PointerType::get(Type::Int8Ty, 0)); return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, (uint64_t)[self functionCellForSymbol:name], false), - PointerType::get(FunctionType::get(PointerType::get(Type::Int8Ty, 0), - types, - true), + PointerType::get(PointerType::get(FunctionType::get(PointerType::get(Type::Int8Ty, + 0), + types, + true), + 0), 0))); } --(Value *) closureDataPointerValueForSymbol:(id)name +-(Instruction *) closureDataPointerValueForSymbol:(id)name { return (new IntToPtrInst (ConstantInt::get(Type::Int64Ty, (uint64_t)[self closureDataPointerForSymbol:name], -- cgit v1.2.3 From 40ee78a3229146beecdc16ce64e8270b7fdc7513 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 21:58:26 +0200 Subject: MLKFunctionCallForm(MLKLLVMCompilation): Remove spurious load instructions. Simple function calls work now. --- MLKLLVMCompiler.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MLKLLVMCompiler.mm b/MLKLLVMCompiler.mm index e9507a9..4313ac9 100644 --- a/MLKLLVMCompiler.mm +++ b/MLKLLVMCompiler.mm @@ -389,9 +389,9 @@ static Constant // XXX Issue a style warning. } - Value *functionCell = builder.CreateLoad ([_context functionCellValueForSymbol:_head]); + Value *functionCell = builder.Insert ([_context functionCellValueForSymbol:_head]); Value *functionPtr = builder.CreateLoad (functionCell); - Value *closureDataCell = builder.CreateLoad ([_context closureDataPointerValueForSymbol:_head]); + Value *closureDataCell = builder.Insert ([_context closureDataPointerValueForSymbol:_head]); Value *closureDataPtr = builder.CreateLoad (closureDataCell); NSEnumerator *e = [_argumentForms objectEnumerator]; -- cgit v1.2.3 From 3f11cb6b3ddd03d3211dd355cbac23884fa5a6e3 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2008 22:10:01 +0200 Subject: Restore possibility of building without LLVM. --- GNUmakefile | 5 +++-- MLKRoot.m | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index e2ea521..7fb8754 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -56,7 +56,6 @@ ToiletKit_OBJC_FILES = functions.m globals.m MLKArray.m \ MLKForeignProcedure.m MLKForm.m MLKInteger.m \ MLKInterpretedClosure.m MLKInterpreter.m \ MLKLexicalContext.m \ - MLKLexicalContext-MLKLLVMCompilation.m \ MLKLexicalEnvironment.m MLKNumber.m MLKPackage.m \ MLKParenReader.m MLKQuoteReader.m MLKRatio.m \ MLKReader.m MLKReadtable.m MLKReaderError.m \ @@ -74,8 +73,10 @@ ToiletKit_LDFLAGS = -lgmp -lffi -ldl USE_LLVM := YES ifeq ($(USE_LLVM),YES) ADDITIONAL_OBJCCFLAGS = $(ADDITIONAL_OBJCFLAGS) +ToiletKit_OBJC_FILES += MLKLexicalContext-MLKLLVMCompilation.m ToiletKit_OBJCC_FILES = MLKLLVMCompiler.mm -ToiletKit_OBJCCFLAGS = `llvm-config --cxxflags` $(ToiletKit_OBJCFLAGS) +ToiletKit_OBJCFLAGS = -DUSE_LLVM +ToiletKit_OBJCCFLAGS = -DUSE_LLVM `llvm-config --cxxflags` $(ToiletKit_OBJCFLAGS) ToiletKit_LDFLAGS += `llvm-config --ldflags` `llvm-config --libs backend engine linker codegen transformutils scalaropts analysis ipo` endif diff --git a/MLKRoot.m b/MLKRoot.m index a003912..b051dd3 100644 --- a/MLKRoot.m +++ b/MLKRoot.m @@ -704,7 +704,7 @@ as provided by method %@ of object %@", with:nil]]); } - +#ifdef USE_LLVM +(NSArray *) compile:(NSArray *)args { NSLog (@"Compiling lambda form."); @@ -714,4 +714,5 @@ as provided by method %@ of object %@", NSLog (@"Compiled: %@", thing); RETURN_VALUE (thing); } +#endif @end -- cgit v1.2.3