[macruby-changes] [1970] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Wed Jul 1 22:14:36 PDT 2009


Revision: 1970
          http://trac.macosforge.org/projects/ruby/changeset/1970
Author:   lsansonetti at apple.com
Date:     2009-07-01 22:14:36 -0700 (Wed, 01 Jul 2009)
Log Message:
-----------
AOT compiler: ivar slots support

Modified Paths:
--------------
    MacRuby/branches/experimental/compiler.cpp
    MacRuby/branches/experimental/compiler.h

Modified: MacRuby/branches/experimental/compiler.cpp
===================================================================
--- MacRuby/branches/experimental/compiler.cpp	2009-07-02 01:31:22 UTC (rev 1969)
+++ MacRuby/branches/experimental/compiler.cpp	2009-07-02 05:14:36 UTC (rev 1970)
@@ -136,6 +136,7 @@
     cObject = ConstantInt::get(RubyObjTy, (long)rb_cObject);
     PtrTy = PointerType::getUnqual(Type::Int8Ty);
     PtrPtrTy = PointerType::getUnqual(PtrTy);
+    Int32PtrTy = PointerType::getUnqual(Type::Int32Ty);
 
 #if ROXOR_COMPILER_DEBUG
     level = 0;
@@ -933,23 +934,72 @@
 	    "", bb);
 }
 
+Instruction *
+RoxorCompiler::gen_slot_cache(ID id)
+{
+    int *slot = (int *)malloc(sizeof(int));
+    *slot = -1;
+    return compile_const_pointer(slot, Int32PtrTy, false);
+}
+
+Instruction *
+RoxorAOTCompiler::gen_slot_cache(ID id)
+{
+    GlobalVariable *gvar = new GlobalVariable(
+	    Int32PtrTy,
+	    false,
+	    GlobalValue::InternalLinkage,
+	    Constant::getNullValue(Int32PtrTy),
+	    rb_id2name(id),
+	    RoxorCompiler::module);
+
+    ivar_slots.push_back(gvar);
+
+    return new LoadInst(gvar, "");
+}
+
+Instruction *
+RoxorCompiler::compile_slot_cache(ID id)
+{
+    if (inside_eval || current_block || !current_instance_method
+	|| current_module) {
+	return compile_const_pointer(NULL, Int32PtrTy);
+    }
+
+    std::map<ID, Instruction *>::iterator iter = ivar_slots_cache.find(id);
+    Instruction *slot;
+    if (iter == ivar_slots_cache.end()) {
+#if ROXOR_COMPILER_DEBUG
+	printf("allocating a new slot for ivar %s\n", rb_id2name(id));
+#endif
+	slot = gen_slot_cache(id);
+	ivar_slots_cache[id] = slot;
+    }
+    else {
+	slot = iter->second;
+    }
+
+    Instruction *insn = slot->clone();
+    BasicBlock::InstListType &list = bb->getInstList();
+    list.insert(list.end(), insn);
+    return insn;
+}
+
 Value *
 RoxorCompiler::compile_ivar_read(ID vid)
 {
     if (getIvarFunc == NULL) {
-	// VALUE rb_vm_ivar_get(VALUE obj, ID name, void *slot_cache);
+	// VALUE rb_vm_ivar_get(VALUE obj, ID name, int *slot_cache);
 	getIvarFunc = cast<Function>(module->getOrInsertFunction("rb_vm_ivar_get",
-		    RubyObjTy, RubyObjTy, IntTy, PtrTy, NULL)); 
+		    RubyObjTy, RubyObjTy, IntTy, Int32PtrTy, NULL)); 
     }
 
     std::vector<Value *> params;
 
     params.push_back(current_self);
     params.push_back(compile_id(vid));
+    params.push_back(compile_slot_cache(vid));
 
-    int *slot_cache = get_slot_cache(vid);
-    params.push_back(compile_const_pointer(slot_cache));
-
     return CallInst::Create(getIvarFunc, params.begin(), params.end(), "", bb);
 }
 
@@ -960,7 +1010,7 @@
 	// void rb_vm_ivar_set(VALUE obj, ID name, VALUE val, int *slot_cache);
 	setIvarFunc = 
 	    cast<Function>(module->getOrInsertFunction("rb_vm_ivar_set",
-			Type::VoidTy, RubyObjTy, IntTy, RubyObjTy, PtrTy,
+			Type::VoidTy, RubyObjTy, IntTy, RubyObjTy, Int32PtrTy,
 			NULL)); 
     }
 
@@ -969,10 +1019,8 @@
     params.push_back(current_self);
     params.push_back(compile_id(vid));
     params.push_back(val);
+    params.push_back(compile_slot_cache(vid));
 
-    int *slot_cache = get_slot_cache(vid);
-    params.push_back(compile_const_pointer(slot_cache));
-
     CallInst::Create(setIvarFunc, params.begin(), params.end(), "", bb);
 
     return val;
@@ -2347,27 +2395,41 @@
 
 void
 RoxorCompiler::compile_ivar_slots(Value *klass,
-				  BasicBlock::InstListType &list, 
-				  BasicBlock::InstListType::iterator list_iter)
+	BasicBlock::InstListType &list, 
+	BasicBlock::InstListType::iterator list_iter)
 {
     if (ivar_slots_cache.size() > 0) {
 	if (prepareIvarSlotFunc == NULL) {
-	    // void rb_vm_prepare_class_ivar_slot(VALUE klass, ID name, int *slot_cache);
+	    // void rb_vm_prepare_class_ivar_slot(VALUE klass, ID name,
+	    // 		int *slot_cache);
 	    prepareIvarSlotFunc = cast<Function>(
-		    module->getOrInsertFunction("rb_vm_prepare_class_ivar_slot", 
-			Type::VoidTy, RubyObjTy, IntTy, PtrTy, NULL));
+		    module->getOrInsertFunction(
+			"rb_vm_prepare_class_ivar_slot", 
+			Type::VoidTy, RubyObjTy, IntTy, Int32PtrTy, NULL));
 	}
-	for (std::map<ID, int *>::iterator iter = ivar_slots_cache.begin();
-		iter != ivar_slots_cache.end();
-		++iter) {
+	for (std::map<ID, Instruction *>::iterator iter
+		= ivar_slots_cache.begin();
+	     iter != ivar_slots_cache.end();
+	     ++iter) {
 
+	    ID ivar_name = iter->first;
+	    Instruction *ivar_slot = iter->second;
 	    std::vector<Value *> params;
+
 	    params.push_back(klass);
-	    params.push_back(compile_id(iter->first));
-	    Instruction *ptr = compile_const_pointer(iter->second, false);
-	    list.insert(list_iter, ptr);
-	    params.push_back(ptr);
 
+	    Value *id_val = compile_id(ivar_name);
+	    if (Instruction::classof(id_val)) {
+		Instruction *insn = cast<Instruction>(id_val);
+		insn->removeFromParent();
+		list.insert(list_iter, insn);
+	    }
+	    params.push_back(id_val);
+
+	    Instruction *insn = ivar_slot->clone();
+	    list.insert(list_iter, insn);
+	    params.push_back(insn);
+
 	    CallInst *call = CallInst::Create(prepareIvarSlotFunc, 
 		    params.begin(), params.end(), "");
 
@@ -2509,7 +2571,6 @@
 
 		    if (has_vars_to_save) {
 			current_var_uses = new AllocaInst(PtrTy, "", bb);
-			//current_var_uses = new MallocInst(PtrTy, "", bb);
 			new StoreInst(compile_const_pointer(NULL), current_var_uses, bb);
 		    }
 
@@ -2597,8 +2658,8 @@
 			     ++inst_it) {
 			    if (dyn_cast<ReturnInst>(inst_it)) {
 				if (params.empty()) {
-				    params.push_back(new LoadInst(current_var_uses, "", inst_it));
-				    params.push_back(NULL); // filled right after.
+				    params.push_back(NULL);
+				    params.push_back(NULL);
 				    int vars_count = 0;
 				    for (std::map<ID, Value *>::iterator iter = lvars.begin();
 					    iter != lvars.end(); ++iter) {
@@ -2617,6 +2678,8 @@
 				    params[1] = ConstantInt::get(Type::Int32Ty, vars_count);
 				}
 
+				params[0] = new LoadInst(current_var_uses, "", inst_it);
+
 				// TODO: only call the function if current_use is not NULL
 				CallInst::Create(keepVarsFunc, params.begin(), params.end(), "",
 					inst_it);
@@ -3206,7 +3269,8 @@
 
 			bool old_current_module = current_module;
 
-			std::map<ID, int *> old_ivar_slots_cache = ivar_slots_cache;
+			std::map<ID, Instruction *> old_ivar_slots_cache
+			    = ivar_slots_cache;
 			ivar_slots_cache.clear();
 
 			new StoreInst(classVal, current_opened_class, bb);
@@ -4337,10 +4401,15 @@
 Function *
 RoxorAOTCompiler::compile_main_function(NODE *node)
 {
-    Function *function = RoxorCompiler::compile_main_function(node);
+    current_instance_method = true;
 
+    Value *val = compile_node(node);
+    assert(Function::classof(val));
+    Function *function = cast<Function>(val);
+
     BasicBlock::InstListType &list = 
 	function->getEntryBlock().getInstList();
+    bb = &function->getEntryBlock();
 
     // Compile method caches.
 
@@ -4501,6 +4570,48 @@
 	list.insert(list.begin(), load);
     }
 
+    // Compile ivar slots.
+
+    if (!ivar_slots_cache.empty()) {
+	GlobalVariable *toplevel = compile_const_global_string("TopLevel");
+
+	std::vector<Value *> idxs;
+	idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+	idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+	Instruction *load = GetElementPtrInst::Create(toplevel,
+		idxs.begin(), idxs.end(), "");
+
+	std::vector<Value *> params;
+	params.push_back(load);
+
+	Instruction *call = CallInst::Create(objcGetClassFunc, params.begin(),
+		params.end(), "");
+
+	compile_ivar_slots(call, list, list.begin());
+	ivar_slots_cache.clear();
+
+	list.insert(list.begin(), call);
+	list.insert(list.begin(), load);
+    }
+
+    for (std::vector<GlobalVariable *>::iterator i = ivar_slots.begin();
+	 i != ivar_slots.end();
+	 ++i) {
+
+	GlobalVariable *gvar = *i;
+
+	Instruction *call = new MallocInst(Type::Int32Ty, "");
+	Instruction *assign1 =
+	    new StoreInst(ConstantInt::get(Type::Int32Ty, -1), call, "");
+	Instruction *assign2 = new StoreInst(call, gvar, "");
+
+	list.insert(list.begin(), assign2);
+	list.insert(list.begin(), assign1);
+	list.insert(list.begin(), call);
+    }
+
+    bb = NULL;
+
     return function;
 }
 

Modified: MacRuby/branches/experimental/compiler.h
===================================================================
--- MacRuby/branches/experimental/compiler.h	2009-07-02 01:31:22 UTC (rev 1969)
+++ MacRuby/branches/experimental/compiler.h	2009-07-02 05:14:36 UTC (rev 1970)
@@ -59,7 +59,7 @@
 
 	std::map<ID, Value *> lvars;
 	std::vector<ID> dvars;
-	std::map<ID, int *> ivar_slots_cache;
+	std::map<ID, Instruction *> ivar_slots_cache;
 	std::map<std::string, GlobalVariable *> static_strings;
 
 #if ROXOR_COMPILER_DEBUG
@@ -165,23 +165,25 @@
 	const Type *PtrTy;
 	const Type *PtrPtrTy;
 	const Type *IntTy;
+	const Type *Int32PtrTy;
 
 	void compile_node_error(const char *msg, NODE *node);
 
 	virtual Instruction *
-	compile_const_pointer(void *ptr, bool insert_to_bb=true) {
+	compile_const_pointer(void *ptr, const Type *type=NULL,
+		bool insert_to_bb=true) {
 	    Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
+	    if (type == NULL) {
+		type = PtrTy;
+	    }
 	    return insert_to_bb
-		? new IntToPtrInst(ptrint, PtrTy, "", bb)
-		: new IntToPtrInst(ptrint, PtrTy, "");
+		? new IntToPtrInst(ptrint, type, "", bb)
+		: new IntToPtrInst(ptrint, type, "");
 	}
 
 	Instruction *
         compile_const_pointer_to_pointer(void *ptr, bool insert_to_bb=true) {
-	    Value *ptrint = ConstantInt::get(IntTy, (long)ptr);
-	    return insert_to_bb
-		? new IntToPtrInst(ptrint, PtrPtrTy, "", bb)
-		: new IntToPtrInst(ptrint, PtrPtrTy, "");
+	    return compile_const_pointer(ptr, PtrPtrTy, insert_to_bb);
 	}
 
 	Value *compile_protected_call(Function *func,
@@ -227,7 +229,7 @@
 	virtual Value *compile_mcache(SEL sel, bool super);
 	virtual Value *compile_ccache(ID id);
 	virtual Instruction *compile_sel(SEL sel, bool add_to_bb=true) {
-	    return compile_const_pointer(sel, add_to_bb);
+	    return compile_const_pointer(sel, PtrTy, add_to_bb);
 	}
 	virtual Value *compile_id(ID id);
 	GlobalVariable *compile_const_global_string(const char *str);
@@ -255,24 +257,8 @@
 	Value *compile_conversion_to_ruby(const char *type,
 					  const Type *llvm_type, Value *val);
 
-	int *get_slot_cache(ID id) {
-	    if (inside_eval || current_block || !current_instance_method
-		|| current_module) {
-		return NULL;
-	    }
-	    std::map<ID, int *>::iterator iter = ivar_slots_cache.find(id);
-	    if (iter == ivar_slots_cache.end()) {
-#if ROXOR_COMPILER_DEBUG
-		printf("allocating a new slot for ivar %s\n", rb_id2name(id));
-#endif
-		int *slot = (int *)malloc(sizeof(int));
-		*slot = -1;
-		ivar_slots_cache[id] = slot;
-		return slot;
-	    }
-	    return iter->second;
-	}
-
+	Instruction *compile_slot_cache(ID id);
+	virtual Instruction *gen_slot_cache(ID id);
 	ICmpInst *is_value_a_fixnum(Value *val);
 	void compile_ivar_slots(Value *klass, BasicBlock::InstListType &list, 
 				BasicBlock::InstListType::iterator iter);
@@ -296,6 +282,7 @@
 	std::map<ID, GlobalVariable *> ccaches;
 	std::map<SEL, GlobalVariable *> sels;
 	std::map<ID, GlobalVariable *> ids;
+	std::vector<GlobalVariable *> ivar_slots;
 	GlobalVariable *cObject_gvar;
 
 	Value *compile_mcache(SEL sel, bool super);
@@ -307,10 +294,14 @@
 	Value *compile_nsobject(void);
 	Value *compile_id(ID id);
 
+	Instruction *gen_slot_cache(ID id);
+
 	Instruction *
-        compile_const_pointer(void *ptr, bool insert_to_bb=true) {
+        compile_const_pointer(void *ptr, const Type *type=NULL,
+		bool insert_to_bb=true) {
 	    if (ptr == NULL) {
-		return RoxorCompiler::compile_const_pointer(ptr, insert_to_bb);
+		return RoxorCompiler::compile_const_pointer(ptr, type,
+			insert_to_bb);
 	    }
 	    printf("compile_const_pointer() called with a non-NULL pointer " \
 		   "on the AOT compiler - leaving the ship!\n");
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090701/64639f76/attachment-0001.html>


More information about the macruby-changes mailing list