Skip to content

Commit

Permalink
Improve JIT type checks for casting and creating arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
dbussink committed Jun 25, 2013
1 parent 7ec4ae2 commit c3b6eaa
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
27 changes: 22 additions & 5 deletions vm/llvm/inline_primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,7 @@ namespace rubinius {
FunctionType* ft = FunctionType::get(st, types, false);
Function* func = cast<Function>(
ops.context()->module()->getOrInsertFunction(MUL_WITH_OVERFLOW, ft));
func->setDoesNotThrow();

Value* recv_int = ops.fixnum_strip(recv);
Value* arg_int = ops.fixnum_strip(arg);
Expand Down Expand Up @@ -1081,7 +1082,9 @@ namespace rubinius {
sig << "State";

Function* func = sig.function("rbx_float_allocate");
func->setDoesNotCapture(1);
func->setDoesNotAlias(0); // return value
func->setDoesNotThrow();

Value* call_args[] = { ops.state() };
CallInst* res = sig.call("rbx_float_allocate", call_args, 1, "result", ops.b());
Expand Down Expand Up @@ -1279,14 +1282,20 @@ namespace rubinius {

i.check_recv(klass, data);

Value* V = i.recv();
Value* cls = i.recv();

Signature sig(ops.context(), "Object");
sig << "State";
sig << "CallFrame";
sig << "Object";

Value* call_args[] = { ops.state(), ops.call_frame(), V };
Function* func = sig.function("rbx_create_instance");
func->setDoesNotCapture(1);
func->setDoesNotCapture(2);
func->setDoesNotCapture(3);
func->setDoesNotAlias(0);

Value* call_args[] = { ops.state(), ops.call_frame(), cls };

CallInst* out = sig.call("rbx_create_instance", call_args, 3,
"instance", ops.b());
Expand All @@ -1296,7 +1305,7 @@ namespace rubinius {
// allocation can be elided in that case.
out->setDoesNotThrow();

type::KnownType kt = type::KnownType::extract(ops.context(), V);
type::KnownType kt = type::KnownType::extract(ops.context(), cls);
if(kt.constant_cache_p()) {
ConstantCache* constant_cache = kt.constant_cache();
klass = try_as<Class>(constant_cache->value());
Expand Down Expand Up @@ -1438,7 +1447,8 @@ namespace rubinius {
call_frame
};

Value* res = sig.call("rbx_regexp_set_last_match", call_args, 3, "set_last_match", ops.b());
CallInst* res = sig.call("rbx_regexp_set_last_match", call_args, 3, "set_last_match", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.exception_safe();
Expand Down Expand Up @@ -1489,6 +1499,7 @@ namespace rubinius {
};

CallInst* res = sig.call("rbx_proc_call", call_args, 5, "result", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.context()->leave_inline();
Expand All @@ -1508,6 +1519,7 @@ namespace rubinius {
};

CallInst* res = sig.call("rbx_variable_scope_of_sender", call_args, 2, "result", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.exception_safe();
Expand All @@ -1528,6 +1540,7 @@ namespace rubinius {
};

CallInst* res = sig.call("rbx_compiledcode_of_sender", call_args, 2, "result", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.exception_safe();
Expand All @@ -1548,6 +1561,7 @@ namespace rubinius {
};

CallInst* res = sig.call("rbx_constant_scope_of_sender", call_args, 2, "result", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.exception_safe();
Expand All @@ -1568,6 +1582,7 @@ namespace rubinius {
};

CallInst* res = sig.call("rbx_location_of_closest_ruby_method", call_args, 2, "result", ops.b());
res->setDoesNotThrow();

i.set_result(res);
i.exception_safe();
Expand Down Expand Up @@ -1749,12 +1764,14 @@ namespace rubinius {

Function* func = sig.function(stub_res.name());
func->setDoesNotCapture(1);
func->setDoesNotThrow();

if(stub_res.pass_callframe()) {
func->setDoesNotCapture(2);
}

Value* res = sig.call(stub_res.name(), call_args, "prim_value", ops_.b());
CallInst* res = sig.call(stub_res.name(), call_args, "prim_value", ops_.b());
res->setDoesNotThrow();

// Only doing this when stub_res.can_fail() causes an exception
// to be thrown when running the ci specs, need to investigate.
Expand Down
10 changes: 9 additions & 1 deletion vm/llvm/jit_operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,15 @@ namespace rubinius {
uint32_t class_id = klass->class_id();
BasicBlock* use_cache = new_block("use_cache");

if(class_id == llvm_state()->fixnum_class_id()) {
type::KnownType recv_type = type::KnownType::extract(ctx_, obj);
uint32_t recv_class_id = recv_type.class_id();

if(recv_type.instance_p() && class_id == recv_class_id) {
if(llvm_state()->config().jit_inline_debug) {
ctx_->log() << "(eliding because of staticly known match)\n";
}
create_branch(positive);
} else if(class_id == llvm_state()->fixnum_class_id()) {
if(llvm_state()->config().jit_inline_debug) {
ctx_->log() << "(against Fixnum)\n";
}
Expand Down
7 changes: 7 additions & 0 deletions vm/llvm/jit_visit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,10 @@ namespace rubinius {
FunctionType* ft = FunctionType::get(ObjType, types, false);
Function* func = cast<Function>(
module_->getOrInsertFunction("rbx_string_dup", ft));
func->setDoesNotCapture(1);
func->setDoesNotCapture(2);
func->setDoesNotCapture(3);
func->setDoesNotAlias(0);

Value* call_args[] = {
state_,
Expand Down Expand Up @@ -3572,6 +3576,9 @@ namespace rubinius {
};

Value* val = sig.call("rbx_make_array", call_args, 3, "constant", b());
type::KnownType kt = type::KnownType::instance(llvm_state()->array_class_id());
kt.associate(ctx_, val);

stack_remove(count);
stack_push(val);
}
Expand Down
2 changes: 2 additions & 0 deletions vm/llvm/state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ namespace rubinius {
nil_class_id_ = G(nil_class)->class_id();
true_class_id_ = G(true_class)->class_id();
false_class_id_ = G(false_class)->class_id();
array_class_id_ = G(array)->class_id();
tuple_class_id_ = G(tuple)->class_id();

type_optz_ = state->shared().config.jit_type_optz;

Expand Down
10 changes: 10 additions & 0 deletions vm/llvm/state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ namespace rubinius {
uint32_t nil_class_id_;
uint32_t true_class_id_;
uint32_t false_class_id_;
uint32_t array_class_id_;
uint32_t tuple_class_id_;

bool type_optz_;

Expand Down Expand Up @@ -242,6 +244,14 @@ namespace rubinius {
return false_class_id_;
}

uint32_t array_class_id() {
return array_class_id_;
}

uint32_t tuple_class_id() {
return tuple_class_id_;
}

bool type_optz() {
return type_optz_;
}
Expand Down

0 comments on commit c3b6eaa

Please sign in to comment.