[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