[macruby-changes] [1712] MacRuby/branches/fp-optimized-experimental/compiler.cpp

source_changes at macosforge.org source_changes at macosforge.org
Wed Jun 3 15:05:48 PDT 2009


Revision: 1712
          http://trac.macosforge.org/projects/ruby/changeset/1712
Author:   pthomson at apple.com
Date:     2009-06-03 15:05:48 -0700 (Wed, 03 Jun 2009)
Log Message:
-----------
Implemented preliminary compile-side optimization for floating-point numbers.

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

Modified: MacRuby/branches/fp-optimized-experimental/compiler.cpp
===================================================================
--- MacRuby/branches/fp-optimized-experimental/compiler.cpp	2009-06-03 20:41:10 UTC (rev 1711)
+++ MacRuby/branches/fp-optimized-experimental/compiler.cpp	2009-06-03 22:05:48 UTC (rev 1712)
@@ -162,6 +162,11 @@
 	*rval = tmp;
 	return true;
     }
+	else if (ConstantFP::classof(val)) {
+	double tmp = cast<ConstantFP>(val)->getValueAPF().convertToDouble();
+	*rval = tmp;
+	return true;
+	}
     return false;
 }
 
@@ -1611,6 +1616,12 @@
 
 	long leftLong = leftIsFixnumConstant ? FIX2LONG(leftRVal) : 0;
 	long rightLong = rightIsFixnumConstant ? FIX2LONG(rightRVal) : 0;
+	
+	const bool leftIsFixFloatConstant = FIXFLOAT_P(leftRVal);
+	const bool rightIsFixFloatConstant = FIXFLOAT_P(rightRVal);
+	
+	double leftDouble = leftIsFixFloatConstant ? FIXFLOAT2DBL(leftRVal) : 0;
+	double rightDouble = rightIsFixFloatConstant ? FIXFLOAT2DBL(rightRVal) : 0;
 
 	if (leftIsFixnumConstant && rightIsFixnumConstant) {
 	    // Both operands are fixnum constants.
@@ -1688,8 +1699,223 @@
 	    // Non fixable (bignum), call the dispatcher.
 	    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();
+
+			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;
+		}
+	}
+	else if (leftIsFixFloatConstant && rightIsFixnumConstant) {
+		bool result_is_fixfloat = true;
+		double res;
+		// TODO: put checks in here for NaN, +/- infinity
+		if (sel == selPLUS) {
+			res = leftDouble + rightLong;
+		}
+		else if (sel == selMINUS) {
+			res = leftDouble - rightLong;
+		}
+		else if (sel == selMULT) {
+			res = leftDouble * rightLong;
+		}
+		else if (sel == selDIV) {
+			if (rightLong == 0) {
+				return NULL;
+			}
+			res = leftDouble / rightDouble;
+		} else {
+			result_is_fixfloat = false;
+			if (sel == selLT) {
+			    res = leftDouble < rightLong;
+			}
+			else if (sel == selLE) {
+			    res = leftDouble <= rightLong;
+			}
+			else if (sel == selGT) {
+			    res = leftDouble > rightLong;
+			}
+			else if (sel == selGE) {
+			    res = leftDouble >= rightLong;
+			}
+			else if ((sel == selEq) || (sel == selEqq)) {
+			    res = leftDouble == rightLong;
+			}
+			else if (sel == selNeq) {
+			    res = leftDouble != rightLong;
+			}
+			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;
+		}
+	}
+	else if (leftIsFixnumConstant && rightIsFixFloatConstant) {
+		bool result_is_fixfloat = true;
+		double res;
+		// TODO: put checks in here for NaN, +/- infinity
+		if (sel == selPLUS) {
+			res = leftLong + rightDouble;
+		}
+		else if (sel == selMINUS) {
+			res = leftLong - rightDouble;
+		}
+		else if (sel == selMULT) {
+			res = leftLong * rightDouble;
+		}
+		else if (sel == selDIV) {
+			if (rightDouble == 0.0) {
+				return NULL;
+			}
+			res = leftLong / rightDouble;
+		} else {
+			result_is_fixfloat = false;
+			if (sel == selLT) {
+			    res = leftLong < rightDouble;
+			}
+			else if (sel == selLE) {
+			    res = leftLong <= rightDouble;
+			}
+			else if (sel == selGT) {
+			    res = leftLong > rightDouble;
+			}
+			else if (sel == selGE) {
+			    res = leftLong >= rightDouble;
+			}
+			else if ((sel == selEq) || (sel == selEqq)) {
+			    res = leftLong == rightDouble;
+			}
+			else if (sel == selNeq) {
+			    res = leftLong != 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;
+		}
+	}
 	else {
-	    // Either one or both is not a constant fixnum.
 	    Value *is_redefined_val = new LoadInst(is_redefined, "", bb);
 	    Value *isOpRedefined = new ICmpInst(ICmpInst::ICMP_EQ, 
 		    is_redefined_val, ConstantInt::getFalse(), "", bb);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090603/10dbd45f/attachment.html>


More information about the macruby-changes mailing list