[macruby-changes] [1399] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Tue Apr 7 20:31:43 PDT 2009
Revision: 1399
http://trac.macosforge.org/projects/ruby/changeset/1399
Author: lsansonetti at apple.com
Date: 2009-04-07 20:31:43 -0700 (Tue, 07 Apr 2009)
Log Message:
-----------
inline Symbols
Modified Paths:
--------------
MacRuby/branches/experimental/TODO
MacRuby/branches/experimental/roxor.cpp
MacRuby/branches/experimental/test_vm/literal.rb
Modified: MacRuby/branches/experimental/TODO
===================================================================
--- MacRuby/branches/experimental/TODO 2009-04-08 01:54:42 UTC (rev 1398)
+++ MacRuby/branches/experimental/TODO 2009-04-08 03:31:43 UTC (rev 1399)
@@ -16,6 +16,7 @@
[X] fast #send
[ ] fast regexp =~
[X] fast break
+[X] optimized Symbol's #== #=== #!= when both operands are constants
[ ] write a pass manager to eliminate unnecessary arrays generated by massigns
[ ] Array and Hash subclasses to hold immediate Ruby objects without boxing
[/] implement backtracing/symbolication
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-04-08 01:54:42 UTC (rev 1398)
+++ MacRuby/branches/experimental/roxor.cpp 2009-04-08 03:31:43 UTC (rev 1399)
@@ -326,7 +326,7 @@
ICmpInst *is_value_a_fixnum(Value *val);
void compile_ivar_slots(Value *klass, BasicBlock::InstListType &list,
BasicBlock::InstListType::iterator iter);
- bool unbox_fixnum_constant(Value *val, long *lval);
+ bool unbox_ruby_constant(Value *val, VALUE *rval);
SEL mid_to_sel(ID mid, int arity);
};
@@ -644,14 +644,12 @@
}
inline bool
-RoxorCompiler::unbox_fixnum_constant(Value *val, long *lval)
+RoxorCompiler::unbox_ruby_constant(Value *val, VALUE *rval)
{
if (ConstantInt::classof(val)) {
long tmp = cast<ConstantInt>(val)->getZExtValue();
- if (FIXNUM_P(tmp)) {
- *lval = FIX2LONG(tmp);
- return true;
- }
+ *rval = tmp;
+ return true;
}
return false;
}
@@ -1640,11 +1638,61 @@
Value *leftVal = params[1]; // self
Value *rightVal = params.back();
- long leftLong = 0, rightLong = 0;
- const bool leftIsConst = unbox_fixnum_constant(leftVal, &leftLong);
- const bool rightIsConst = unbox_fixnum_constant(rightVal, &rightLong);
+ VALUE leftRVal = 0, rightRVal = 0;
+ const bool leftIsConstant = unbox_ruby_constant(leftVal, &leftRVal);
+ const bool rightIsConst = unbox_ruby_constant(rightVal, &rightRVal);
- if (leftIsConst && rightIsConst) {
+ if (leftIsConstant && rightIsConst
+ && TYPE(leftRVal) == T_SYMBOL && TYPE(rightRVal) == T_SYMBOL) {
+ // Both operands are symbol constants.
+ if (sel == selEq || sel == selEqq || sel == selNeq) {
+ 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 = NULL;
+ if (sel == selEq || sel == selEqq) {
+ thenVal = leftRVal == rightRVal ? trueVal : falseVal;
+ }
+ else if (sel == selNeq) {
+ thenVal = leftRVal != rightRVal ? trueVal : falseVal;
+ }
+ else {
+ abort();
+ }
+ 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 {
+ return NULL;
+ }
+ }
+
+ const bool leftIsFixnumConstant = FIXNUM_P(leftRVal);
+ const bool rightIsFixnumConstant = FIXNUM_P(rightRVal);
+
+ long leftLong = leftIsFixnumConstant ? FIX2LONG(leftRVal) : 0;
+ long rightLong = rightIsFixnumConstant ? FIX2LONG(rightRVal) : 0;
+
+ if (leftIsFixnumConstant && rightIsFixnumConstant) {
// Both operands are fixnum constants.
bool result_is_fixnum = true;
long res;
@@ -1738,13 +1786,13 @@
bb = then1BB;
Value *leftAndOp = NULL;
- if (!leftIsConst) {
+ if (!leftIsFixnumConstant) {
leftAndOp = BinaryOperator::CreateAnd(leftVal, oneVal, "",
bb);
}
Value *rightAndOp = NULL;
- if (!rightIsConst) {
+ if (!rightIsFixnumConstant) {
rightAndOp = BinaryOperator::CreateAnd(rightVal, oneVal, "",
bb);
}
@@ -1780,7 +1828,7 @@
bb = then2BB;
Value *unboxedLeft;
- if (leftIsConst) {
+ if (leftIsFixnumConstant) {
unboxedLeft = ConstantInt::get(RubyObjTy, leftLong);
}
else {
@@ -1788,7 +1836,7 @@
}
Value *unboxedRight;
- if (rightIsConst) {
+ if (rightIsFixnumConstant) {
unboxedRight = ConstantInt::get(RubyObjTy, rightLong);
}
else {
@@ -2324,10 +2372,13 @@
inline bool
RoxorVM::should_invalidate_inline_op(SEL sel, Class klass)
{
+ if (sel == selEq || sel == selEqq || sel == selNeq) {
+ return klass == (Class)rb_cFixnum
+ || klass == (Class)rb_cSymbol;
+ }
if (sel == selPLUS || sel == selMINUS || sel == selDIV
|| sel == selMULT || sel == selLT || sel == selLE
- || sel == selGT || sel == selGE || sel == selEq
- || sel == selNeq || sel == selEqq) {
+ || sel == selGT || sel == selGE) {
return klass == (Class)rb_cFixnum;
}
Modified: MacRuby/branches/experimental/test_vm/literal.rb
===================================================================
--- MacRuby/branches/experimental/test_vm/literal.rb 2009-04-08 01:54:42 UTC (rev 1398)
+++ MacRuby/branches/experimental/test_vm/literal.rb 2009-04-08 03:31:43 UTC (rev 1399)
@@ -16,4 +16,15 @@
assert ":\"42\"", 'p :"#{40+2}"'
assert ":foo42", 'p :"foo#{40+2}"'
-assert "false", "p ['foo'] == [:foo]"
\ No newline at end of file
+assert 'true', "p :foo == :foo"
+assert 'true', "p :foo === :foo"
+assert 'true', "p :foo != :bar"
+assert 'false', "p :foo == :bar"
+assert 'false', "p :foo === :bar"
+assert 'false', "p :foo != :foo"
+
+assert '42', "class Symbol; def ==(o); p 42; end; end; :foo == :foo"
+assert '42', "class Symbol; def ===(o); p 42; end; end; :foo === :foo"
+assert '42', "class Symbol; def !=(o); p 42; end; end; :foo != :foo"
+
+assert "false", "p ['foo'] == [:foo]"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090407/eb9151da/attachment.html>
More information about the macruby-changes
mailing list