[macruby-changes] [1859] MacRuby/branches/fp-optimized-experimental
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jun 15 14:14:44 PDT 2009
Revision: 1859
http://trac.macosforge.org/projects/ruby/changeset/1859
Author: pthomson at apple.com
Date: 2009-06-15 14:14:43 -0700 (Mon, 15 Jun 2009)
Log Message:
-----------
Got the complex case of floating-point operations working.
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-15 04:43:56 UTC (rev 1858)
+++ MacRuby/branches/fp-optimized-experimental/compiler.cpp 2009-06-15 21:14:43 UTC (rev 1859)
@@ -1856,7 +1856,6 @@
bb = elseBB;
Value *elseVal = compile_dispatch_call(params);
- elseBB = bb;
BranchInst::Create(mergeBB, elseBB);
bb = mergeBB;
@@ -1872,6 +1871,158 @@
}
PHINode *
+RoxorCompiler::compile_variable_arith_node(SEL sel, Value *leftVal, Value *rightVal, int argc, std::vector<Value *>params)
+{
+ GlobalVariable *is_redefined = GET_VM()->redefined_op_gvar(sel, true);
+ // 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, is_redefined_val, ConstantInt::getFalse(), "", bb);
+
+ Function *f = bb->getParent();
+
+ BasicBlock *redefBB = BasicBlock::Create("op_not_redefined", f);
+ BasicBlock *toDblBB = BasicBlock::Create("op_floating_cast", f);
+ BasicBlock *toIntBB = BasicBlock::Create("op_integral_cast", f);
+ BasicBlock *elseBB = BasicBlock::Create("op_dispatch", f);
+ BasicBlock *mergeBB = BasicBlock::Create("op_merge", f);
+
+ BranchInst::Create(redefBB, elseBB, isOpRedefined, bb);
+ bb = redefBB;
+
+ Value *leftAndOp = BinaryOperator::CreateAnd(leftVal, threeVal, "", bb);
+ Value *rightAndOp = BinaryOperator::CreateAnd(rightVal, threeVal, "", bb);
+ Value *andSum = BinaryOperator::CreateAdd(leftAndOp, rightAndOp, "", bb);
+
+ Value *leftAsInt = NULL;
+ Value *rightAsInt = NULL;
+ Value *leftAsDouble = NULL;
+ Value *rightAsDouble = NULL;
+ Value *opVal = NULL;
+
+ SwitchInst *switcher = SwitchInst::Create(andSum, elseBB, 2, bb);
+ switcher->addCase(ConstantInt::get(IntTy, 6), toDblBB);
+ switcher->addCase(ConstantInt::get(IntTy, 2), toIntBB);
+
+ bb = toDblBB;
+ Value *unmaskedLeft = BinaryOperator::CreateXor(leftVal, threeVal, "", bb);
+ Value *unmaskedRight = BinaryOperator::CreateXor(rightVal, threeVal, "", bb);
+ leftAsDouble = new BitCastInst(unmaskedLeft, Type::DoubleTy, "", bb);
+ rightAsDouble = new BitCastInst(unmaskedRight, Type::DoubleTy, "", bb);
+
+ bool result_is_bool = false;
+ if (sel == selPLUS) {
+ opVal = BinaryOperator::CreateAdd(leftAsDouble, rightAsDouble, "", bb);
+ }
+ else if (sel == selMINUS) {
+ opVal = BinaryOperator::CreateSub(leftAsDouble, rightAsDouble, "", bb);
+ }
+ else if (sel == selDIV) {
+ opVal = BinaryOperator::CreateSDiv(leftAsDouble, rightAsDouble, "", bb);
+ }
+ else if (sel == selMULT) {
+ opVal = BinaryOperator::CreateMul(leftAsDouble, rightAsDouble, "", bb);
+ }
+ else {
+ result_is_bool = true;
+
+ CmpInst::Predicate predicate;
+
+ if (sel == selLT) {
+ predicate = FCmpInst::FCMP_OLT;
+ }
+ else if (sel == selLE) {
+ predicate = FCmpInst::FCMP_OLE;
+ }
+ else if (sel == selGT) {
+ predicate = FCmpInst::FCMP_OGT;
+ }
+ else if (sel == selGE) {
+ predicate = FCmpInst::FCMP_OGE;
+ }
+ else if ((sel == selEq) || (sel == selEqq)) {
+ predicate = FCmpInst::FCMP_OEQ;
+ }
+ else if (sel == selNeq) {
+ predicate = FCmpInst::FCMP_ONE;
+ }
+ else {
+ abort();
+ }
+
+ opVal = new FCmpInst(predicate, leftAsDouble, rightAsDouble, "", bb);
+ opVal = SelectInst::Create(opVal, trueVal, falseVal, "", bb);
+ }
+
+ Value *castedResult = new BitCastInst(opVal, IntTy, "", bb);
+ Value *dblReturnResult = BinaryOperator::CreateOr(castedResult, threeVal, "", bb);
+ BranchInst::Create(mergeBB, toDblBB);
+
+ bb = toIntBB;
+ leftAsInt = BinaryOperator::CreateAShr(leftVal, twoVal, "", bb);
+ rightAsInt = BinaryOperator::CreateAShr(rightVal, twoVal, "", bb);
+
+ if (sel == selPLUS) {
+ opVal = BinaryOperator::CreateAdd(leftAsInt, rightAsInt, "", bb);
+ }
+ else if (sel == selMINUS) {
+ opVal = BinaryOperator::CreateSub(leftAsInt, rightAsInt, "", bb);
+ }
+ else if (sel == selDIV) {
+ opVal = BinaryOperator::CreateSDiv(leftAsInt, rightAsInt, "", bb);
+ }
+ else if (sel == selMULT) {
+ opVal = BinaryOperator::CreateMul(leftAsInt, rightAsInt, "", bb);
+ }
+ else {
+ result_is_bool = true;
+
+ CmpInst::Predicate predicate;
+
+ if (sel == selLT) {
+ predicate = ICmpInst::ICMP_SLT;
+ }
+ else if (sel == selLE) {
+ predicate = ICmpInst::ICMP_SLE;
+ }
+ else if (sel == selGT) {
+ predicate = ICmpInst::ICMP_SGT;
+ }
+ else if (sel == selGE) {
+ predicate = ICmpInst::ICMP_SGE;
+ }
+ else if ((sel == selEq) || (sel == selEqq)) {
+ predicate = ICmpInst::ICMP_EQ;
+ }
+ else if (sel == selNeq) {
+ predicate = ICmpInst::ICMP_NE;
+ }
+ else {
+ abort();
+ }
+
+ opVal = new ICmpInst(predicate, leftAsInt, rightAsInt, "", bb);
+ opVal = SelectInst::Create(opVal, trueVal, falseVal, "", bb);
+ }
+
+ Value *shiftedResult = BinaryOperator::CreateShl(opVal, twoVal, "", bb);
+ Value *intReturnResult = BinaryOperator::CreateOr(shiftedResult, oneVal, "", bb);
+ BranchInst::Create(mergeBB, toIntBB);
+
+ bb = elseBB;
+ Value *elseVal = compile_dispatch_call(params);
+ elseBB = bb;
+ BranchInst::Create(mergeBB, elseBB);
+
+ bb = mergeBB;
+ PHINode *pn = PHINode::Create(RubyObjTy, "op_tmp", mergeBB);
+ pn->addIncoming(dblReturnResult, toDblBB);
+ pn->addIncoming(intReturnResult, toIntBB);
+ pn->addIncoming(elseVal, elseBB);
+
+ return pn;
+}
+
+PHINode *
RoxorCompiler::compile_variable_and_floating_node(SEL sel, double fixedDouble, Value *targetVal, Value *otherVal,
int argc, std::vector<Value *> ¶ms)
{
@@ -2069,8 +2220,7 @@
return compile_variable_and_floating_node(sel, rightDouble, leftVal, rightVal, argc, params);
}
} else {
- printf("Both are variables, dying\n");
- return NULL;
+ return compile_variable_arith_node(sel, leftVal, rightVal, argc, params);
}
}
// Other operators (#<< or #[] or #[]=)
Modified: MacRuby/branches/fp-optimized-experimental/compiler.h
===================================================================
--- MacRuby/branches/fp-optimized-experimental/compiler.h 2009-06-15 04:43:56 UTC (rev 1858)
+++ MacRuby/branches/fp-optimized-experimental/compiler.h 2009-06-15 21:14:43 UTC (rev 1859)
@@ -189,6 +189,8 @@
PHINode *
compile_variable_and_floating_node(SEL sel, double fixedDouble, Value *val, Value *other,
int argc, std::vector<Value *> ¶ms);
+ PHINode *
+ compile_variable_arith_node(SEL sel, Value *leftVal, Value *rightVal, int argc, std::vector<Value *>params);
Value *compile_protected_call(Function *func,
std::vector<Value *> ¶ms);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090615/a7fe4ccb/attachment.html>
More information about the macruby-changes
mailing list