[macruby-changes] [4476] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Aug 27 18:08:35 PDT 2010


Revision: 4476
          http://trac.macosforge.org/projects/ruby/changeset/4476
Author:   lsansonetti at apple.com
Date:     2010-08-27 18:08:34 -0700 (Fri, 27 Aug 2010)
Log Message:
-----------
optimizing symetric masgns

Modified Paths:
--------------
    MacRuby/trunk/compiler.cpp
    MacRuby/trunk/compiler.h

Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp	2010-08-27 21:04:51 UTC (rev 4475)
+++ MacRuby/trunk/compiler.cpp	2010-08-28 01:08:34 UTC (rev 4476)
@@ -1050,6 +1050,61 @@
 }
 
 Value *
+RoxorCompiler::compile_multiple_assignment(NODE *node)
+{
+    assert(node->nd_value != NULL);
+
+    if (node->nd_next == NULL
+	    && node->nd_head != NULL
+	    && nd_type(node->nd_head) == NODE_ARRAY
+	    && nd_type(node->nd_value) == NODE_ARRAY
+	    && node->nd_head->nd_alen == node->nd_value->nd_alen) {
+
+	// Symetric multiple-assignment optimization.
+	// Grab all left operands in separate Allocas.
+	Instruction *first = bb->getParent()->getEntryBlock().getFirstNonPHI();
+	std::vector<Value *> tmp_rights;
+	NODE *right = node->nd_value;
+	for (int i = 0; i < node->nd_head->nd_alen; i++) {
+	    Value *slot = new AllocaInst(RubyObjTy, "", first);
+	    assert(right->nd_head != NULL);
+	    new StoreInst(compile_node(right->nd_head), slot, bb);
+	    tmp_rights.push_back(new LoadInst(slot, "", bb));
+	    right = right->nd_next;
+	}
+
+	// Compile assignments.
+	NODE *left = node->nd_head;
+	for (std::vector<Value *>::iterator i = tmp_rights.begin();
+		i != tmp_rights.end(); ++i) {
+	    assert(left->nd_head != NULL);
+	    compile_multiple_assignment_element(left->nd_head, *i);
+	    left = left->nd_next;
+	}
+
+	// Compile return value (a new Array) which is eliminated later if
+	// never used.
+	CallInst *ary = CallInst::Create(newArrayFunc,
+		ConstantInt::get(Int32Ty, tmp_rights.size()), "", bb);
+	RoxorCompiler::MAsgnValue val;
+	val.ary = ary;
+	for (unsigned int i = 0; i < tmp_rights.size(); i++) {
+	    Value *args[] = {
+		ary,
+		ConstantInt::get(Int32Ty, i),
+		tmp_rights[i]
+	    };
+	    CallInst *insn = CallInst::Create(asetArrayFunc, args, args + 3,
+		    "", bb);
+	    val.sets.push_back(insn);
+	}
+	masgn_values.push_back(val);
+	return ary;
+    }
+    return compile_multiple_assignment(node, compile_node(node->nd_value));
+}
+
+Value *
 RoxorCompiler::compile_prepare_block_args(Function *func, int *flags)
 {
     return compile_const_pointer(func);    
@@ -2610,6 +2665,9 @@
 
     std::map<ID, Value *> old_lvars = lvars;
     lvars.clear();
+    std::vector<MAsgnValue> old_masgn_values = masgn_values;
+    masgn_values.clear();
+
     Value *old_self = current_self;
 
     Function::arg_iterator arg;
@@ -2858,6 +2916,19 @@
 	}
     }
 
+    for (std::vector<MAsgnValue>::iterator i = masgn_values.begin();
+	    i != masgn_values.end(); ++i) {
+	MAsgnValue &v = *i;
+	if (v.ary->hasNUses(v.sets.size())) {
+	    for (std::vector<CallInst *>::iterator j = v.sets.begin();
+		    j != v.sets.end(); ++j) {
+		CallInst *insn = *j;
+		insn->eraseFromParent();
+	    }
+	    v.ary->eraseFromParent();
+	}
+    }
+
     rescue_rethrow_bb = old_rescue_rethrow_bb;
     rescue_invoke_bb = old_rescue_invoke_bb;
 
@@ -2865,6 +2936,7 @@
     bb = old_bb;
     entry_bb = old_entry_bb;
     lvars = old_lvars;
+    masgn_values = old_masgn_values;
     current_self = old_self;
     current_var_uses = old_current_var_uses;
     running_block = old_running_block;
@@ -3223,9 +3295,7 @@
 		    compile_node(node->nd_value));
 
 	case NODE_MASGN:
-	    assert(node->nd_value != NULL);
-	    return compile_multiple_assignment(node, 
-		    compile_node(node->nd_value));
+	    return compile_multiple_assignment(node);
 
 	case NODE_DASGN:
 	case NODE_DASGN_CURR:

Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h	2010-08-27 21:04:51 UTC (rev 4475)
+++ MacRuby/trunk/compiler.h	2010-08-28 01:08:34 UTC (rev 4476)
@@ -93,6 +93,13 @@
 	std::map<std::string, GlobalVariable *> static_strings;
 	std::map<CFHashCode, GlobalVariable *> static_ustrings;
 
+	class MAsgnValue {
+	    public:
+		CallInst *ary;
+		std::vector<CallInst *> sets;
+	};
+	std::vector<MAsgnValue> masgn_values;
+
 #if ROXOR_COMPILER_DEBUG
 	int level;
 # define DEBUG_LEVEL_INC() (level++)
@@ -355,6 +362,7 @@
 	Value *compile_gvar_assignment(NODE *node, Value *val);
 	Value *compile_gvar_get(NODE *node);
 	Value *compile_constant_declaration(NODE *node, Value *val);
+	Value *compile_multiple_assignment(NODE *node);
 	Value *compile_multiple_assignment(NODE *node, Value *val);
 	void compile_multiple_assignment_element(NODE *node, Value *val);
 	Value *compile_current_class(void);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100827/11c880be/attachment-0001.html>


More information about the macruby-changes mailing list