[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 *> ¶ms)
+PHINode *
+RoxorCompiler::precompile_floating_arith_node(SEL sel, double leftDouble, long rightDouble, int argc, std::vector<Value *> ¶ms)
{
- // 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 *> ¶ms)
+{
+ 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 *> ¶ms)
+{
+ // 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 *> ¶ms);
+ PHINode *
+ precompile_integral_arith_node(SEL sel, long leftLong, long rightLong, int argc, std::vector<Value *> ¶ms);
+ PHINode *
+ precompile_floating_arith_node(SEL sel, double leftDouble, long rightDouble, int argc, std::vector<Value *> ¶ms);
+
Value *compile_protected_call(Function *func,
std::vector<Value *> ¶ms);
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