Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Check proto as well as candidates in optimizer.
This fixes issues where we could end up inlining calls to candidates
that would never be reachable due to restrictions in the proto. Also,
we catch some such issues at compile time now.
  • Loading branch information
jnthn committed Jan 2, 2013
1 parent 0f0bb50 commit f63c42d
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions src/Perl6/Optimizer.pm
Expand Up @@ -163,34 +163,36 @@ class Perl6::Optimizer {
# the proto.
my $dispatcher;
try { if $obj.is_dispatcher { $dispatcher := 1 } }
if $dispatcher {
# Try to do compile-time multi-dispatch.
if $dispatcher && $obj.onlystar {
# Try to do compile-time multi-dispatch. Need to consider
# both the proto and the multi candidates.
my @ct_arg_info := self.analyze_args_for_ct_call($op);
if +@ct_arg_info {
my @types := @ct_arg_info[0];
my @flags := @ct_arg_info[1];
my @ct_result := pir::perl6_multi_dispatch_ct__PPPP($obj, @types, @flags);
if @ct_result[0] == 1 {
my $chosen := @ct_result[1];
my $ct_result_proto := pir::perl6_trial_bind_ct__IPPP($obj.signature, @types, @flags);
my @ct_result_multi := pir::perl6_multi_dispatch_ct__PPPP($obj, @types, @flags);
if $ct_result_proto == 1 && @ct_result_multi[0] == 1 {
my $chosen := @ct_result_multi[1];
if $op.op eq 'chain' { $!chain_depth := $!chain_depth - 1 }
if $*LEVEL >= 2 && $obj.onlystar {
if $*LEVEL >= 2 {
return nqp::can($chosen, 'inline_info') && nqp::istype($chosen.inline_info, QAST::Node)
?? self.inline_call($op, $chosen)
!! self.call_ct_chosen_multi($op, $obj, $chosen);
}
}
elsif @ct_result[0] == -1 {
elsif $ct_result_proto == -1 || @ct_result_multi[0] == -1 {
self.report_innevitable_dispatch_failure($op, @types, @flags, $obj);
}
}

# Otherwise, inline the proto.
if $op.op eq 'chain' { $!chain_depth := $!chain_depth - 1 }
if $*LEVEL >= 2 && $obj.onlystar {
if $*LEVEL >= 2 {
return self.inline_proto($op, $obj);
}
}
elsif nqp::can($obj, 'signature') {
elsif !$dispatcher && nqp::can($obj, 'signature') {
# If we know enough about the arguments, do a "trial bind".
my @ct_arg_info := self.analyze_args_for_ct_call($op);
if +@ct_arg_info {
Expand Down

0 comments on commit f63c42d

Please sign in to comment.