[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 *> &params)
 {
@@ -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 *> &params);
+	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 *> &params);
-------------- 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