-
-
Save MasterDuke17/1c45e013eac54ac54e6578d49eabd36c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dan@hermes:~/p6/rakudo$ ./perl6-gdb-m t/spec/integration/advent2012-day14.t | |
================================================================================================ | |
This is Rakudo Perl 6 running in the GNU debugger, which often allows the user to generate useful back- | |
traces to debug or report issues in Rakudo, the MoarVM backend or the currently running code. | |
This Rakudo version is 2018.08.109.g.0.a.45.ffbc.6 built on MoarVM version 2018.08.88.gad.12.d.8.e.4.d, | |
running on ubuntu (18.04.1.LTS.Bionic.Beaver) / linux (4.15.0.34.generic) | |
Type `bt full` to generate a backtrace if applicable, type `q` to quit or `help` for help. | |
------------------------------------------------------------------------------------------------ | |
Reading symbols from /home/dan/Source/perl6/install/bin/moar...done. | |
Starting program: /home/dan/Source/perl6/install/bin/moar --execname=./perl6-gdb-m --libpath=. --libpath=blib --libpath=/home/dan/Source/perl6/install/share/nqp/lib --libpath=/home/dan/Source/perl6/install/share/nqp/lib --libpath=/home/dan/Source/perl6/install/share/nqp/lib /home/dan/Source/perl6/rakudo/perl6.moarvm --nqp-lib=blib t/spec/integration/advent2012-day14.t | |
[Thread debugging using libthread_db enabled] | |
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". | |
[New Thread 0x7ffff6136700 (LWP 12802)] | |
1..6 | |
ok 1 - prime (alpha) | |
ok 2 - prime (beta) | |
P6opaque: get_boxed_ref could not unbox for the representation 'P6bigint' of type Scalar | |
in sub is-prime-rm at t/spec/integration/advent2012-day14.t line 40 | |
in block <unit> at t/spec/integration/advent2012-day14.t line 57 | |
# Looks like you planned 6 tests, but ran 2 | |
[Thread 0x7ffff7fd06c0 (LWP 12798) exited] | |
[Inferior 1 (process 12798) exited with code 0377] | |
(gdb) b MVM_exception_throw_adhoc | |
Breakpoint 1 at 0x7ffff74c66d9: file src/core/exceptions.c, line 855. | |
(gdb) r | |
Starting program: /home/dan/Source/perl6/install/bin/moar --execname=./perl6-gdb-m --libpath=. --libpath=blib --libpath=/home/dan/Source/perl6/install/share/nqp/lib --libpath=/home/dan/Source/perl6/install/share/nqp/lib --libpath=/home/dan/Source/perl6/install/share/nqp/lib /home/dan/Source/perl6/rakudo/perl6.moarvm --nqp-lib=blib t/spec/integration/advent2012-day14.t | |
[Thread debugging using libthread_db enabled] | |
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". | |
[New Thread 0x7ffff6136700 (LWP 12804)] | |
Thread 1 "moar" hit Breakpoint 1, MVM_exception_throw_adhoc (tc=0x555555758cc0, messageFormat=0x7ffff76966a0 "%s positionals passed; expected %d argument%s but got %d") at src/core/exceptions.c:855 | |
855 MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) { | |
(gdb) c | |
Continuing. | |
Thread 1 "moar" hit Breakpoint 1, MVM_exception_throw_adhoc (tc=0x555555758cc0, messageFormat=0x7ffff76966a0 "%s positionals passed; expected %d argument%s but got %d") at src/core/exceptions.c:855 | |
855 MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) { | |
(gdb) c | |
Continuing. | |
1..6 | |
ok 1 - prime (alpha) | |
ok 2 - prime (beta) | |
Thread 1 "moar" hit Breakpoint 1, MVM_exception_throw_adhoc (tc=0x555555758cc0, messageFormat=0x7ffff76ab800 "P6opaque: get_boxed_ref could not unbox for the representation '%s' of type %s") at src/core/exceptions.c:855 | |
855 MVM_NO_RETURN void MVM_exception_throw_adhoc(MVMThreadContext *tc, const char *messageFormat, ...) { | |
(gdb) call MVM_dump_backtrace(tc) | |
at t/spec/integration/advent2012-day14.t:40 (<ephemeral file>:) | |
from t/spec/integration/advent2012-day14.t:35 (<ephemeral file>:is-prime-rm) | |
from t/spec/integration/advent2012-day14.t:24 (<ephemeral file>:is-prime-rm) | |
from t/spec/integration/advent2012-day14.t:57 (<ephemeral file>:) | |
from SETTING::src/core/Any-iterable-methods.pm6:942 (./CORE.setting.moarvm:) | |
from SETTING::src/core/Any-iterable-methods.pm6:423 (./CORE.setting.moarvm:push-all) | |
from SETTING::src/core/Iterator.pm6:69 (./CORE.setting.moarvm:push-until-lazy) | |
from SETTING::src/core/Array.pm6:197 (./CORE.setting.moarvm:from-iterator) | |
from SETTING::src/core/array_operators.pm6:36 (./CORE.setting.moarvm:circumfix:<[ ]>) | |
from t/spec/integration/advent2012-day14.t:57 (<ephemeral file>:<unit>) | |
from t/spec/integration/advent2012-day14.t:1 (<ephemeral file>:<unit-outer>) | |
from gen/moar/stage2/NQPHLL.nqp:1675 (/home/dan/Source/perl6/install/share/nqp/lib/NQPHLL.moarvm:eval) | |
from gen/moar/stage2/NQPHLL.nqp:1914 (/home/dan/Source/perl6/install/share/nqp/lib/NQPHLL.moarvm:evalfiles) | |
from gen/moar/stage2/NQPHLL.nqp:1804 (/home/dan/Source/perl6/install/share/nqp/lib/NQPHLL.moarvm:command_eval) | |
from src/Perl6/Compiler.nqp:42 (blib/Perl6/Compiler.moarvm:command_eval) | |
from gen/moar/stage2/NQPHLL.nqp:1763 (/home/dan/Source/perl6/install/share/nqp/lib/NQPHLL.moarvm:command_line) | |
from gen/moar/main.nqp:47 (/home/dan/Source/perl6/rakudo/perl6.moarvm:MAIN) | |
from gen/moar/main.nqp:38 (/home/dan/Source/perl6/rakudo/perl6.moarvm:<mainline>) | |
from <unknown>:1 (/home/dan/Source/perl6/rakudo/perl6.moarvm:<main>) | |
from <unknown>:1 (/home/dan/Source/perl6/rakudo/perl6.moarvm:<entry>) | |
(gdb) bt | |
#0 MVM_exception_throw_adhoc (tc=0x555555758cc0, messageFormat=0x7ffff76ab800 "P6opaque: get_boxed_ref could not unbox for the representation '%s' of type %s") at src/core/exceptions.c:855 | |
#1 0x00007ffff7564300 in get_boxed_ref (tc=0x555555758cc0, st=0x555555e05ac0, root=0x7ffff27edaf8, data=0x7ffff27edb10, repr_id=20) at src/6model/reprs/P6opaque.c:597 | |
#2 0x00007ffff762e86d in get_bigint_body (tc=0x555555758cc0, obj=0x7ffff27edaf8) at src/math/bigintops.c:148 | |
#3 0x00007ffff762f147 in MVM_bigint_add (tc=0x555555758cc0, result_type=0x555555e07368, a=0x7ffff27edaf8, b=0x555556d87cf8) at src/math/bigintops.c:455 | |
#4 0x00007ffff74dfb36 in MVM_interp_run (tc=0x555555758cc0, initial_invoke=0x7ffff764040c <toplevel_initial_invoke>, invoke_data=0x5555557e5270) at src/core/interp.c:3273 | |
#5 0x00007ffff7640571 in MVM_vm_run_file (instance=0x555555758260, filename=0x7fffffffe1fa "/home/dan/Source/perl6/rakudo/perl6.moarvm") at src/moar.c:420 | |
#6 0x0000555555555b4e in main (argc=10, argv=0x7fffffffdd58) at src/main.c:300 | |
(gdb) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/Perl6/Optimizer.nqp b/src/Perl6/Optimizer.nqp | |
index 728834369..7ca8dedc0 100644 | |
--- a/src/Perl6/Optimizer.nqp | |
+++ b/src/Perl6/Optimizer.nqp | |
@@ -892,6 +892,8 @@ class Perl6::Optimizer { | |
has $!debug; | |
+ has %!range_bounds; | |
+ | |
# Entry point for the optimization process. | |
method optimize($past, *%adverbs) { | |
# Initialize. | |
@@ -916,6 +918,33 @@ class Perl6::Optimizer { | |
$!eliminated_block_contents := QAST::Op.new( :op('die_s'), | |
QAST::SVal.new( :value('INTERNAL ERROR: Execution of block eliminated by optimizer') ) ); | |
+ %!range_bounds := nqp::hash( | |
+ '&infix:<..>', -> $op { | |
+ my @lb := get_bound($op[0], 0, $!symbols); | |
+ my @ub := get_bound($op[1], 0, $!symbols); | |
+ @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
+ }, | |
+ '&infix:<..^>', -> $op { | |
+ my @lb := get_bound($op[0], 0, $!symbols); | |
+ my @ub := get_bound($op[1],-1, $!symbols); | |
+ @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
+ }, | |
+ '&infix:<^..>', -> $op { | |
+ my @lb := get_bound($op[0], 1, $!symbols); | |
+ my @ub := get_bound($op[1], 0, $!symbols); | |
+ @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
+ }, | |
+ '&infix:<^..^>', -> $op { | |
+ my @lb := get_bound($op[0], 1, $!symbols); | |
+ my @ub := get_bound($op[1],-1, $!symbols); | |
+ @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
+ }, | |
+ '&prefix:<^>', -> $op { | |
+ my @ub := get_bound($op[0],-1, $!symbols); | |
+ @ub ?? [QAST::IVal.new( :value(0) ), @ub[0]] !! [] | |
+ }, | |
+ ); | |
+ | |
# Walk and optimize the program. | |
self.visit_block($!symbols.UNIT); | |
@@ -1024,7 +1053,7 @@ class Perl6::Optimizer { | |
} | |
# Range operators we can optimize into loops, and how to do it. | |
- sub get_bound($node,$extra) { | |
+ sub get_bound($node,$extra,$symbols) { | |
# 0 | |
if nqp::istype($node, QAST::Want) && $node[1] eq 'Ii' { | |
@@ -1044,47 +1073,41 @@ class Perl6::Optimizer { | |
} | |
} | |
+ elsif nqp::istype($node, QAST::Var) { | |
# my int $foo | |
- elsif nqp::istype($node, QAST::Var) | |
- && nqp::objprimspec($node.returns) == 1 { | |
- return [$extra | |
- ?? QAST::Op.new( :op<add_i>, :returns($node.returns), | |
- $node, | |
- QAST::IVal.new( :value($extra) ) | |
- ) | |
- !! $node | |
- ] | |
+ if nqp::objprimspec($node.returns) == 1 { | |
+ return [$extra | |
+ ?? QAST::Op.new( :op<add_i>, :returns($node.returns), | |
+ $node, | |
+ QAST::IVal.new( :value($extra) ) | |
+ ) | |
+ !! $node | |
+ ] | |
+ } | |
+ # my Int $foo | |
+ elsif nqp::objprimspec($node.returns) == 0 { | |
+ my int $found := 0; | |
+ my $vname; | |
+ try { | |
+ $vname := $symbols.find_lexical_symbol($node.name); | |
+ $found := 1; | |
+ } | |
+ if $found && $vname<type> =:= $symbols.find_in_setting("Int") { | |
+ return [$extra | |
+ ?? QAST::Op.new( :op<add_I>, :returns($node.returns), | |
+ $node, | |
+ QAST::IVal.new( :value($extra) ), | |
+ QAST::WVal.new( :value($symbols.find_in_setting("Int")) ) | |
+ ) | |
+ !! $node | |
+ ] | |
+ } | |
+ } | |
} | |
# No way we can make this faster | |
[] | |
} | |
- my %range_bounds := nqp::hash( | |
- '&infix:<..>', -> $op { | |
- my @lb := get_bound($op[0], 0); | |
- my @ub := get_bound($op[1], 0); | |
- @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
- }, | |
- '&infix:<..^>', -> $op { | |
- my @lb := get_bound($op[0], 0); | |
- my @ub := get_bound($op[1],-1); | |
- @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
- }, | |
- '&infix:<^..>', -> $op { | |
- my @lb := get_bound($op[0], 1); | |
- my @ub := get_bound($op[1], 0); | |
- @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
- }, | |
- '&infix:<^..^>', -> $op { | |
- my @lb := get_bound($op[0], 1); | |
- my @ub := get_bound($op[1],-1); | |
- @lb && @ub ?? [@lb[0], @ub[0]] !! [] | |
- }, | |
- '&prefix:<^>', -> $op { | |
- my @ub := get_bound($op[0],-1); | |
- @ub ?? [QAST::IVal.new( :value(0) ), @ub[0]] !! [] | |
- }, | |
- ); | |
# Poisonous calls. | |
my %poison_calls := nqp::hash( | |
@@ -1112,11 +1135,12 @@ class Perl6::Optimizer { | |
# If it's a for 1..1000000 { } we can simplify it to a while loop. We | |
# check this here, before the tree is transformed by call inline opts. | |
if ($optype eq 'p6for' || $optype eq 'p6forstmt') && $op.sunk && @($op) == 2 { | |
+# note("about to optimize a ^ for"); | |
my $theop := $op[0]; | |
if nqp::istype($theop, QAST::Stmts) { $theop := $theop[0] } | |
if nqp::istype($theop, QAST::Op) | |
- && nqp::existskey(%range_bounds, $theop.name) | |
+ && nqp::existskey(%!range_bounds, $theop.name) | |
&& $!symbols.is_from_core($theop.name) | |
&& $op[1].has_ann('code_object') { | |
self.optimize_for_range($op, $op[1], $theop); | |
@@ -1133,10 +1157,10 @@ class Perl6::Optimizer { | |
&& $op[0][1].has_ann('code_object') | |
&& ( | |
nqp::istype((my $c1 := $op[0][0]), QAST::Op) | |
- && nqp::existskey(%range_bounds, $c1.name) | |
+ && nqp::existskey(%!range_bounds, $c1.name) | |
|| nqp::istype($op[0][0], QAST::Stmts) | |
&& nqp::istype(($c1 := $op[0][0][0]), QAST::Op) | |
- && nqp::existskey(%range_bounds, $c1.name) | |
+ && nqp::existskey(%!range_bounds, $c1.name) | |
) && $!symbols.is_from_core($c1.name) | |
{ | |
self.optimize_for_range($op, $op[0][1], $c1); | |
@@ -2245,12 +2269,13 @@ class Perl6::Optimizer { | |
my $phasers := nqp::istype($code, $block) | |
?? nqp::getattr($code, $block, '$!phasers') | |
!! nqp::null(); | |
- if $count == 1 && nqp::isnull($phasers) && %range_bounds{$c2.name}($c2) -> @bounds { | |
+ if $count == 1 && nqp::isnull($phasers) && %!range_bounds{$c2.name}($c2) -> @bounds { | |
my $it_var := QAST::Node.unique('range_it_'); | |
my $max_var := QAST::Node.unique('range_max_'); | |
my $callee_var := QAST::Node.unique('range_callee_'); | |
$op.shift while $op.list; | |
$op.op('stmts'); | |
+ if nqp::objprimspec(@bounds[0]) == 1 && nqp::objprimspec(@bounds[1]) == 1 { | |
$op.push(QAST::Stmts.new( | |
# my int $it := @bounds[0] - 1 | |
@@ -2305,6 +2330,65 @@ class Perl6::Optimizer { | |
# return Nil | |
QAST::WVal.new( :value($!symbols.Nil) ) | |
)); | |
+ } | |
+ else { | |
+ $op.push(QAST::Stmts.new( | |
+ | |
+# my Int $it := @bounds[0] - 1 | |
+ QAST::Op.new( :op<bind>, | |
+ QAST::Var.new( | |
+ :name($it_var), :scope<local>, :decl<var>, :returns($!symbols.find_in_setting("Int")) | |
+ ), | |
+ QAST::Op.new( :op<sub_I>, | |
+ QAST::Op.new( :op<decont>, @bounds[0]), | |
+ QAST::IVal.new( :value(1)), | |
+ QAST::WVal.new( :value($!symbols.find_in_setting("Int")) ) | |
+ ) | |
+ ), | |
+ | |
+# my Int $max := @bounds[1] | |
+ QAST::Op.new( :op<bind>, | |
+ QAST::Var.new( | |
+ :name($max_var), :scope<local>, :decl<var>, :returns($!symbols.find_in_setting("Int")) | |
+ ), | |
+ @bounds[1] | |
+ ), | |
+ | |
+# my $callee := { }; | |
+ QAST::Op.new( :op<bind>, | |
+ QAST::Var.new(:name($callee_var), :scope<local>, :decl<var>), | |
+ $callee | |
+ ), | |
+ | |
+# nqp::while( | |
+# nqp::isle_I( | |
+# nqp::bind($it,nqp::add_I($it,1,Int)), | |
+# $max | |
+# ) | |
+ QAST::Op.new( :op<while>, | |
+ QAST::Op.new( :op<isle_I>, | |
+ QAST::Op.new( :op<bind>, | |
+ QAST::Var.new(:name($it_var), :scope<local>, :returns($!symbols.find_in_setting("Int"))), | |
+ QAST::Op.new( :op<add_I>, | |
+ QAST::Op.new( :op<decont>, QAST::Var.new(:name($it_var),:scope<local>,:returns($!symbols.find_in_setting("Int")))), | |
+ QAST::IVal.new( :value(1) ), | |
+ QAST::WVal.new( :value($!symbols.find_in_setting("Int")) ) | |
+ ) | |
+ ), | |
+ QAST::Op.new( :op<decont>, QAST::Var.new(:name($max_var), :scope<local>, :returns($!symbols.find_in_setting("Int")))) | |
+ ), | |
+ | |
+# nqp::call($callee, $it) | |
+ QAST::Op.new( :op<call>, | |
+ QAST::Var.new(:name($callee_var), :scope<local> ), | |
+ QAST::Var.new(:name($it_var), :scope<local>, :returns($!symbols.find_in_setting("Int"))) | |
+ ) | |
+ ), | |
+ | |
+# return Nil | |
+ QAST::WVal.new( :value($!symbols.Nil) ) | |
+ )); | |
+ } | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment