Skip to content

Commit ba977c2

Browse files
committed
working build, lots of debug output, more intelligence.
1 parent 459e172 commit ba977c2

File tree

1 file changed

+80
-38
lines changed

1 file changed

+80
-38
lines changed

src/NQP/Optimizer.nqp

Lines changed: 80 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ class NQP::Optimizer {
22
has @!block_stack;
33

44
method optimize($ast, *%adverbs) {
5-
#@!block_stack := [$ast[0]];
6-
#self.visit_children($ast);
5+
@!block_stack := [$ast[0]];
6+
self.visit_children($ast[0]);
77
$ast;
88
}
99

@@ -17,62 +17,104 @@ class NQP::Optimizer {
1717
$block;
1818
}
1919

20-
method find_sym(@name) {
21-
if +@name == 1 {
22-
my $final_name := @name[0];
23-
my $i := +@!block_stack;
24-
while $i > 0 {
25-
$i := $i - 1;
26-
my %sym := @!block_stack[$i].symbol($final_name);
27-
if +%sym {
28-
if nqp::existskey(%sym, 'value') {
29-
say("found your $final_name");
30-
return %sym<value>;
31-
}
32-
else {
33-
nqp::die("No compile-time value for $final_name");
34-
}
35-
}
20+
method find_lex($name) {
21+
my int $i := +@!block_stack;
22+
while $i > 0 {
23+
$i := $i - 1;
24+
my %sym := @!block_stack[$i].symbol($name);
25+
if +%sym {
26+
return %sym;
3627
}
3728
}
29+
NQPMu;
30+
}
31+
32+
method find_sym($name) {
33+
my %sym := self.find_lex($name);
34+
if !(%sym =:= NQPMu) && nqp::existskey(%sym, 'value') {
35+
return %sym<value>;
36+
}
37+
else {
38+
nqp::die("No compile-time value for $name");
39+
}
3840
}
3941

4042
method visit_op($op) {
4143
sub returns_int($node) {
4244
if nqp::objprimspec($node.returns) == 1 {
4345
return 1
4446
}
45-
if nqp::istype($node, QAST::Op) && $node.op ~~ /_i$/ {
46-
return 1
47+
if nqp::istype($node, QAST::Op) {
48+
my $typeinfo := nqp::substr($node.op, nqp::chars($node.op) - 2, 2);
49+
if $typeinfo eq "_i" {
50+
return 1
51+
} elsif $node.op eq 'chars' || $node.op eq 'ord' {
52+
return 1
53+
}
4754
} elsif nqp::istype($node, QAST::IVal) {
4855
return 1
56+
} elsif nqp::istype($node, QAST::Var) && $node.scope eq 'lexical' {
57+
my %sym;
58+
try {
59+
my %sym := self.find_lex($node.name);
60+
CATCH {
61+
say("could not find lexpad entry for " ~ $node.name);
62+
}
63+
}
64+
if nqp::existskey(%sym, 'type') && nqp::objprimspec(%sym<type>) == 1 {
65+
say("var " ~ $node.name ~ " is native int.");
66+
return 1
67+
}
4968
}
5069
return 0;
5170
}
5271
self.visit_children($op);
5372

54-
if $op.op ~~ /^$<opt>=(add|sub|mul)_n$/ {
55-
my $newopn := nqp::substr($op.op, 0, 3) ~ "_i";
56-
say($op.op ~ " " ~ $newopn ~ " " ~ $op.dump);
57-
say("returns int? " ~ returns_int($op[0]) ~ " \ " ~ returns_int($op[1]));
58-
if returns_int($op[0]) && returns_int($op[1]) {
59-
$op.name($newopn);
60-
$op.returns(self.find_sym(["int"]));
61-
say("transformed!");
62-
} else {
63-
$op.returns(self.find_sym(["num"]));
73+
my $typeinfo := nqp::substr($op.op, nqp::chars($op.op) - 2, 2);
74+
my $asm := nqp::substr($op.op, 0, 3);
75+
76+
try {
77+
if $typeinfo eq '_n' && ($asm eq 'add' || $asm eq 'sub' || $asm eq 'mul') {
78+
my $newopn := $asm ~ "_i";
79+
if returns_int($op[0]) && returns_int($op[1]) {
80+
my $newopn := nqp::substr($op.op, 0, 3) ~ "_i";
81+
$op.name($newopn);
82+
$op.returns(self.find_sym("int"));
83+
say($op.op ~ " " ~ $newopn ~ " " ~ $op.dump);
84+
say("transformed!");
85+
say("");
86+
} else {
87+
$op.returns(self.find_sym("num"));
88+
say(returns_int($op[0]) ~ " / " ~ returns_int($op[1]));
89+
say($op.op ~ " " ~ $newopn ~ " " ~ $op.dump);
90+
say("not transformed!");
91+
say("");
92+
}
93+
} elsif $typeinfo eq '_i' {
94+
$op.returns(self.find_sym("num"));
95+
} elsif $typeinfo eq '_s' {
96+
$op.returns(self.find_sym("str"));
97+
} elsif $op.op eq 'handle' {
98+
return self.visit_handle($op);
99+
} elsif $op.op eq 'numify' {
100+
# if we can establish that the argument is a list, we are good
101+
# to claim it returns an int.
102+
if nqp::istype($op[0], QAST::Var) {
103+
my $sigil := nqp::substr($op[0].name, 0, 1);
104+
if $sigil eq '@' || $sigil eq '%' {
105+
$op.returns(self.find_sym("int"))
106+
}
107+
}
108+
}
109+
CATCH {
110+
say("too bad, could not do the optimisation");
111+
say($op.dump);
64112
}
65-
} elsif $op.op ~~ /_i$/ {
66-
$op.returns(self.find_sym(["num"]));
67-
} elsif $op.op ~~ /_s$/ {
68-
$op.returns(self.find_sym(["str"]));
69-
} elsif $op.op eq 'handle' {
70-
return self.visit_handle($op);
71113
}
72-
114+
73115
$op;
74116
}
75-
117+
76118
method visit_handle($handle) {
77119
self.visit_children($handle, :skip_selectors);
78120
$handle;

0 commit comments

Comments
 (0)