[macruby-changes] [1848] MacRuby/branches/fp-optimized-experimental

source_changes at macosforge.org source_changes at macosforge.org
Fri Jun 12 16:12:46 PDT 2009


Revision: 1848
          http://trac.macosforge.org/projects/ruby/changeset/1848
Author:   pthomson at apple.com
Date:     2009-06-12 16:12:46 -0700 (Fri, 12 Jun 2009)
Log Message:
-----------
More refactoring.

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

Modified: MacRuby/branches/fp-optimized-experimental/compiler.cpp
===================================================================
--- MacRuby/branches/fp-optimized-experimental/compiler.cpp	2009-06-12 22:06:44 UTC (rev 1847)
+++ MacRuby/branches/fp-optimized-experimental/compiler.cpp	2009-06-12 23:12:46 UTC (rev 1848)
@@ -1584,84 +1584,106 @@
 	return pn;
 }
 
-Value *
-RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc, std::vector<Value *> &params)
+PHINode *
+RoxorCompiler::precompile_floating_arith_node(SEL sel, double leftDouble, long rightDouble, int argc, std::vector<Value *> &params)
 {
-    // The not operator (!).
-    if (sel == selNot) {
-		return compile_negation_node(argc, params[1]);
+	GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
+	bool result_is_fixfloat = true;
+	double res;
+	// TODO: put checks in here for NaN, +/- infinity
+	if (sel == selPLUS) {
+		res = leftDouble + rightDouble;
 	}
-    // Pure arithmetic operations.
-    else if (sel == selPLUS || sel == selMINUS || sel == selDIV 
-	     || sel == selMULT || sel == selLT || sel == selLE 
-	     || sel == selGT || sel == selGE || sel == selEq
-	     || sel == selNeq || sel == selEqq) {
-
-	if (current_block_func != NULL || argc != 1) {
-	    return NULL;
+	else if (sel == selMINUS) {
+		res = leftDouble - rightDouble;
 	}
-
-	GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
-	
-	Value *leftVal = params[1]; // self
-	Value *rightVal = params.back();
-
-	VALUE leftRVal = 0, rightRVal = 0;
-	const bool leftIsConstant = unbox_ruby_constant(leftVal, &leftRVal);
-	const bool rightIsConst = unbox_ruby_constant(rightVal, &rightRVal);
-
-	if (leftIsConstant && rightIsConst && TYPE(leftRVal) == T_SYMBOL && TYPE(rightRVal) == T_SYMBOL) {
-	    // Both operands are symbol constants.
-	    if (sel == selEq || sel == selEqq || sel == selNeq) {
-			return compile_symbol_equality_node(sel, leftRVal, rightRVal, argc, params);
-	    }
-	    else {
+	else if (sel == selMULT) {
+		res = leftDouble * rightDouble;
+	}
+	else if (sel == selDIV) {
+		if (rightDouble == 0.0) {
 			return NULL;
-	    }
+		}
+		res = leftDouble / rightDouble;
+	} else {
+		result_is_fixfloat = false;
+		if (sel == selLT) {
+			res = leftDouble < rightDouble;
+		}
+		else if (sel == selLE) {
+			res = leftDouble <= rightDouble;
+		}
+		else if (sel == selGT) {
+			res = leftDouble > rightDouble;
+		}
+		else if (sel == selGE) {
+			res = leftDouble >= rightDouble;
+		}
+		else if ((sel == selEq) || (sel == selEqq)) {
+			res = leftDouble == rightDouble;
+		}
+		else if (sel == selNeq) {
+			res = leftDouble != rightDouble;
+		}
+		else {
+			abort();		
+		}
 	}
+	if (!result_is_fixfloat || FIXABLE_DBL(res)) {
+		Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
+		Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, 
+											is_redefined_val, ConstantInt::getFalse(), "", bb);
+		
+		Function *f = bb->getParent();
+		
+		BasicBlock *thenBB = BasicBlock::Create("op_not_redefined", f);
+		BasicBlock *elseBB  = BasicBlock::Create("op_dispatch", f);
+		BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
+		
+		BranchInst::Create(thenBB, elseBB, isOpRedefined, bb);
+		Value *thenVal = result_is_fixfloat
+		? ConstantInt::get(RubyObjTy, DBL2FIXFLOAT(res)) 
+		: (res == 1 ? trueVal : falseVal);
+		BranchInst::Create(mergeBB, thenBB);
+		
+		bb = elseBB;
+		Value *elseVal = compile_dispatch_call(params);
+		elseBB = bb;
+		BranchInst::Create(mergeBB, elseBB);
+		
+		PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", mergeBB);
+		pn->addIncoming(thenVal, thenBB);
+		pn->addIncoming(elseVal, elseBB);
+		bb = mergeBB;
+		
+		return pn;
+	}
+	return NULL; // loss of precision, call the dispatcher.
+}
 
-	const bool leftIsFixnumConstant = FIXNUM_P(leftRVal);
-	const bool rightIsFixnumConstant = FIXNUM_P(rightRVal);
-
-	long leftLong = leftIsFixnumConstant ? FIX2LONG(leftRVal) : 0;
-	long rightLong = rightIsFixnumConstant ? FIX2LONG(rightRVal) : 0;
+PHINode *
+RoxorCompiler::precompile_integral_arith_node(SEL sel, long leftLong, long rightLong, int argc, std::vector<Value *> &params)
+{
+	GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
+	bool result_is_fixnum = true;
+	long res;
 	
-	bool leftIsFixFloatConstant = FIXFLOAT_P(leftRVal);
-	bool rightIsFixFloatConstant = FIXFLOAT_P(rightRVal);
-	
-	double leftDouble = leftIsFixFloatConstant ? FIXFLOAT2DBL(leftRVal) : 0;
-	double rightDouble = rightIsFixFloatConstant ? FIXFLOAT2DBL(rightRVal) : 0;
-	
-	if (leftIsFixFloatConstant && rightIsFixnumConstant) {
-		rightIsFixFloatConstant = true;
-		rightDouble = (double)rightLong;
+	if (sel == selPLUS) {
+		res = leftLong + rightLong;
 	}
-	else if (leftIsFixnumConstant && rightIsFixFloatConstant) {
-		leftIsFixFloatConstant = true;
-		leftDouble = (double)leftLong;
+	else if (sel == selMINUS) {
+		res = leftLong - rightLong;
 	}
-
-	if (leftIsFixnumConstant && rightIsFixnumConstant) {
-	    // Both operands are fixnum constants.
-	    bool result_is_fixnum = true;
-	    long res;
-
-	    if (sel == selPLUS) {
-		res = leftLong + rightLong;
-	    }
-	    else if (sel == selMINUS) {
-		res = leftLong - rightLong;
-	    }
-	    else if (sel == selDIV) {
+	else if (sel == selDIV) {
 		if (rightLong == 0) {
 		    return NULL;
 		}
 		res = leftLong / rightLong;
-	    }
-	    else if (sel == selMULT) {
+	}
+	else if (sel == selMULT) {
 		res = leftLong * rightLong;
-	    }
-	    else {
+	}
+	else {
 		result_is_fixnum = false;
 		if (sel == selLT) {
 		    res = leftLong < rightLong;
@@ -1684,112 +1706,103 @@
 		else {
 		    abort();		
 		}
-	    }
-	    if (!result_is_fixnum || FIXABLE(res)) {
+	}
+	if (!result_is_fixnum || FIXABLE(res)) {
 		Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
 		Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, 
-			is_redefined_val, ConstantInt::getFalse(), "", bb);
-
+											is_redefined_val, ConstantInt::getFalse(), "", bb);
+		
 		Function *f = bb->getParent();
-
+		
 		BasicBlock *thenBB = BasicBlock::Create("op_not_redefined", f);
 		BasicBlock *elseBB  = BasicBlock::Create("op_dispatch", f);
 		BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
-
+		
 		BranchInst::Create(thenBB, elseBB, isOpRedefined, bb);
 		Value *thenVal = result_is_fixnum
-		    ? ConstantInt::get(RubyObjTy, LONG2FIX(res)) 
-		    : (res == 1 ? trueVal : falseVal);
+		? ConstantInt::get(RubyObjTy, LONG2FIX(res)) 
+		: (res == 1 ? trueVal : falseVal);
 		BranchInst::Create(mergeBB, thenBB);
-
+		
 		bb = elseBB;
 		Value *elseVal = compile_dispatch_call(params);
 		elseBB = bb;
 		BranchInst::Create(mergeBB, elseBB);
-
+		
 		PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", mergeBB);
 		pn->addIncoming(thenVal, thenBB);
 		pn->addIncoming(elseVal, elseBB);
 		bb = mergeBB;
+		
+		return pn;
+	}
+	// Non fixable (bignum), call the dispatcher.
+	return NULL;
+}
 
-		return pn;
-	    }
-	    // Non fixable (bignum), call the dispatcher.
+Value *
+RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc, std::vector<Value *> &params)
+{
+    // The not operator (!).
+    if (sel == selNot) {
+		return compile_negation_node(argc, params[1]);
+	}
+    // Pure arithmetic operations.
+    else if (sel == selPLUS || sel == selMINUS || sel == selDIV 
+	     || sel == selMULT || sel == selLT || sel == selLE 
+	     || sel == selGT || sel == selGE || sel == selEq
+	     || sel == selNeq || sel == selEqq) {
+
+	if (current_block_func != NULL || argc != 1) {
 	    return NULL;
 	}
-	else if (leftIsFixFloatConstant && rightIsFixFloatConstant) {
-		bool result_is_fixfloat = true;
-		double res;
-		// TODO: put checks in here for NaN, +/- infinity
-		if (sel == selPLUS) {
-			res = leftDouble + rightDouble;
-		}
-		else if (sel == selMINUS) {
-			res = leftDouble - rightDouble;
-		}
-		else if (sel == selMULT) {
-			res = leftDouble * rightDouble;
-		}
-		else if (sel == selDIV) {
-			if (rightDouble == 0.0) {
-				return NULL;
-			}
-			res = leftDouble / rightDouble;
-		} else {
-			result_is_fixfloat = false;
-			if (sel == selLT) {
-			    res = leftDouble < rightDouble;
-			}
-			else if (sel == selLE) {
-			    res = leftDouble <= rightDouble;
-			}
-			else if (sel == selGT) {
-			    res = leftDouble > rightDouble;
-			}
-			else if (sel == selGE) {
-			    res = leftDouble >= rightDouble;
-			}
-			else if ((sel == selEq) || (sel == selEqq)) {
-			    res = leftDouble == rightDouble;
-			}
-			else if (sel == selNeq) {
-			    res = leftDouble != rightDouble;
-			}
-			else {
-			    abort();		
-			}
-		    }
-		if (!result_is_fixfloat || FIXABLE_DBL(res)) {
-			Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
-			Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, 
-				is_redefined_val, ConstantInt::getFalse(), "", bb);
 
-			Function *f = bb->getParent();
+	GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
+	
+	Value *leftVal = params[1]; // self
+	Value *rightVal = params.back();
 
-			BasicBlock *thenBB = BasicBlock::Create("op_not_redefined", f);
-			BasicBlock *elseBB  = BasicBlock::Create("op_dispatch", f);
-			BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
+	VALUE leftRVal = 0, rightRVal = 0;
+	const bool leftIsConstant = unbox_ruby_constant(leftVal, &leftRVal);
+	const bool rightIsConst = unbox_ruby_constant(rightVal, &rightRVal);
 
-			BranchInst::Create(thenBB, elseBB, isOpRedefined, bb);
-			Value *thenVal = result_is_fixfloat
-			    ? ConstantInt::get(RubyObjTy, DBL2FIXFLOAT(res)) 
-			    : (res == 1 ? trueVal : falseVal);
-			BranchInst::Create(mergeBB, thenBB);
+	if (leftIsConstant && rightIsConst && TYPE(leftRVal) == T_SYMBOL && TYPE(rightRVal) == T_SYMBOL) {
+	    // Both operands are symbol constants.
+	    if (sel == selEq || sel == selEqq || sel == selNeq) {
+			return compile_symbol_equality_node(sel, leftRVal, rightRVal, argc, params);
+	    }
+	    else {
+			return NULL;
+	    }
+	}
 
-			bb = elseBB;
-			Value *elseVal = compile_dispatch_call(params);
-			elseBB = bb;
-			BranchInst::Create(mergeBB, elseBB);
+	const bool leftIsFixnumConstant = FIXNUM_P(leftRVal);
+	const bool rightIsFixnumConstant = FIXNUM_P(rightRVal);
 
-			PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", mergeBB);
-			pn->addIncoming(thenVal, thenBB);
-			pn->addIncoming(elseVal, elseBB);
-			bb = mergeBB;
+	long leftLong = leftIsFixnumConstant ? FIX2LONG(leftRVal) : 0;
+	long rightLong = rightIsFixnumConstant ? FIX2LONG(rightRVal) : 0;
+	
+	bool leftIsFixFloatConstant = FIXFLOAT_P(leftRVal);
+	bool rightIsFixFloatConstant = FIXFLOAT_P(rightRVal);
+	
+	double leftDouble = leftIsFixFloatConstant ? FIXFLOAT2DBL(leftRVal) : 0;
+	double rightDouble = rightIsFixFloatConstant ? FIXFLOAT2DBL(rightRVal) : 0;
+	
 
-			return pn;
-		}
+
+	if (leftIsFixnumConstant && rightIsFixnumConstant) {
+		return precompile_integral_arith_node(sel, leftLong, rightLong, argc, params);
 	}
-	else if (!(leftIsFixFloatConstant || rightIsFixFloatConstant)){
+	else if (leftIsFixFloatConstant && rightIsFixnumConstant) {
+		return precompile_floating_arith_node(sel, leftDouble, (double)rightLong, argc, params);
+	}
+	else if (leftIsFixnumConstant && rightIsFixFloatConstant) {
+		return precompile_floating_arith_node(sel, (double)leftLong, rightDouble, argc, params);
+	}
+	else if (leftIsFixFloatConstant && rightIsFixFloatConstant) {
+		return precompile_floating_arith_node(sel, leftDouble, rightDouble, argc, params);
+	}
+	else if (!(leftIsFixFloatConstant || rightIsFixFloatConstant)) {
 		// Either one or both of the operands was not a fixable constant.
 	    Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
 	    Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, 

Modified: MacRuby/branches/fp-optimized-experimental/compiler.h
===================================================================
--- MacRuby/branches/fp-optimized-experimental/compiler.h	2009-06-12 22:06:44 UTC (rev 1847)
+++ MacRuby/branches/fp-optimized-experimental/compiler.h	2009-06-12 23:12:46 UTC (rev 1848)
@@ -179,8 +179,13 @@
 	
 	PHINode *compile_negation_node(int argc, Value *val);
 	PHINode *compile_symbol_equality_node(SEL sel, VALUE leftRVal, VALUE rightRVal, int argc, std::vector<Value *> &params);
+	PHINode *
+	precompile_integral_arith_node(SEL sel, long leftLong, long rightLong, int argc, std::vector<Value *> &params);
+	PHINode *
+	precompile_floating_arith_node(SEL sel, double leftDouble, long rightDouble, int argc, std::vector<Value *> &params);
 
 
+
 	Value *compile_protected_call(Function *func,
 		std::vector<Value *> &params);
 	void compile_dispatch_arguments(NODE *args,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090612/09a08c8b/attachment-0001.html>


More information about the macruby-changes mailing list