Permalink
Browse files

added support for AOT compilation of literal ranges

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2409 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent 613ef0f commit 95f3b233195d68846bd08abd20b046f69e0122c4 @lrz lrz committed Aug 28, 2009
Showing with 67 additions and 23 deletions.
  1. +54 −22 compiler.cpp
  2. +3 −1 compiler.h
  3. +1 −0 include/ruby/intern.h
  4. +9 −0 range.c
View
@@ -197,16 +197,17 @@ RoxorCompiler::is_value_a_fixnum(Value *val)
return new ICmpInst(ICmpInst::ICMP_EQ, andOp, oneVal, "", bb);
}
-Value *
-RoxorCompiler::compile_protected_call(Function *func, std::vector<Value *> &params)
+Instruction *
+RoxorCompiler::compile_protected_call(Function *func,
+ std::vector<Value *> &params)
{
if (rescue_bb == NULL) {
CallInst *dispatch = CallInst::Create(func,
params.begin(),
params.end(),
"",
bb);
- return cast<Value>(dispatch);
+ return dispatch;
}
else {
BasicBlock *normal_bb = BasicBlock::Create("normal", bb->getParent());
@@ -221,7 +222,7 @@ RoxorCompiler::compile_protected_call(Function *func, std::vector<Value *> &para
bb = normal_bb;
- return cast<Value>(dispatch);
+ return dispatch;
}
}
@@ -2631,6 +2632,28 @@ RoxorCompiler::compile_optimized_dispatch_call(SEL sel, int argc,
return NULL;
}
+Instruction *
+RoxorCompiler::compile_range(Value *beg, Value *end, bool exclude_end,
+ bool add_to_bb)
+{
+ if (newRangeFunc == NULL) {
+ // VALUE rb_range_new(VALUE beg, VALUE end, int exclude_end);
+ newRangeFunc = cast<Function>(module->getOrInsertFunction(
+ "rb_range_new",
+ RubyObjTy, RubyObjTy, RubyObjTy, RubyObjTy, NULL));
+ }
+
+ std::vector<Value *> params;
+ params.push_back(beg);
+ params.push_back(end);
+ params.push_back(exclude_end ? trueVal : falseVal);
+
+ if (add_to_bb) {
+ return compile_protected_call(newRangeFunc, params);
+ }
+ return CallInst::Create(newRangeFunc, params.begin(), params.end(), "");
+}
+
Value *
RoxorCompiler::compile_literal(VALUE val)
{
@@ -4180,22 +4203,12 @@ RoxorCompiler::compile_node(NODE *node)
case NODE_DOT2:
case NODE_DOT3:
{
- if (newRangeFunc == NULL) {
- // VALUE rb_range_new(VALUE beg, VALUE end, int exclude_end);
- newRangeFunc = cast<Function>(module->getOrInsertFunction("rb_range_new",
- RubyObjTy, RubyObjTy, RubyObjTy, RubyObjTy, NULL));
- }
-
assert(node->nd_beg != NULL);
assert(node->nd_end != NULL);
- std::vector<Value *> params;
- params.push_back(compile_node(node->nd_beg));
- params.push_back(compile_node(node->nd_end));
- params.push_back(nd_type(node) == NODE_DOT2 ? falseVal : trueVal);
-
- return cast<Value>(CallInst::Create(newRangeFunc,
- params.begin(), params.end(), "", bb));
+ return compile_range(compile_node(node->nd_beg),
+ compile_node(node->nd_end),
+ nd_type(node) == NODE_DOT3);
}
break;
@@ -5181,11 +5194,30 @@ RoxorAOTCompiler::compile_main_function(NODE *node)
break;
default:
- printf("unrecognized literal `%s' (class `%s' type %d)\n",
- RSTRING_PTR(rb_inspect(val)),
- rb_obj_classname(val),
- TYPE(val));
- abort();
+ if (rb_obj_is_kind_of(val, rb_cRange)) {
+ VALUE beg = 0, end = 0;
+ bool exclude_end = false;
+ rb_range_extract(val, &beg, &end, &exclude_end);
+
+ Instruction *call = compile_range(
+ ConstantInt::get(RubyObjTy, beg),
+ ConstantInt::get(RubyObjTy, end),
+ exclude_end,
+ false);
+
+ Instruction *assign = new StoreInst(call, gvar, "");
+
+ list.insert(list.begin(), assign);
+ list.insert(list.begin(), call);
+ }
+ else {
+ printf("unrecognized literal `%s' (class `%s' type %d)\n",
+ RSTRING_PTR(rb_inspect(val)),
+ rb_obj_classname(val),
+ TYPE(val));
+ abort();
+ }
+ break;
}
}
View
@@ -219,7 +219,7 @@ class RoxorCompiler {
return compile_const_pointer(ptr, PtrPtrTy, insert_to_bb);
}
- Value *compile_protected_call(Function *func,
+ Instruction *compile_protected_call(Function *func,
std::vector<Value *> &params);
void compile_dispatch_arguments(NODE *args,
std::vector<Value *> &arguments, int *pargc);
@@ -279,6 +279,8 @@ class RoxorCompiler {
const size_t str_len, CFHashCode hash);
Value *compile_arity(rb_vm_arity_t &arity);
+ Instruction *compile_range(Value *beg, Value *end, bool exclude_end,
+ bool add_to_bb=true);
Value *compile_literal(VALUE val);
virtual Value *compile_immutable_literal(VALUE val);
virtual Value *compile_global_entry(NODE *node);
View
@@ -492,6 +492,7 @@ void rb_syswait(rb_pid_t pid);
rb_pid_t rb_spawn(int, VALUE*);
VALUE rb_detach_process(rb_pid_t pid);
/* range.c */
+void rb_range_extract(VALUE range, VALUE *begp, VALUE *endp, bool *exclude);
VALUE rb_range_new(VALUE, VALUE, int);
VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
/* random.c */
View
@@ -604,6 +604,15 @@ range_max(VALUE range, SEL sel)
}
}
+void
+rb_range_extract(VALUE range, VALUE *begp, VALUE *endp, bool *exclude)
+{
+ assert(begp != NULL && endp != NULL && exclude != NULL);
+ *begp = RANGE_BEG(range);
+ *endp = RANGE_END(range);
+ *exclude = EXCL(range);
+}
+
VALUE
rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err)
{

0 comments on commit 95f3b23

Please sign in to comment.