Permalink
Browse files

Implement :combine.

  • Loading branch information...
1 parent 51655ac commit caae63522095991b3778d1de9705abc1102fdb1c tcurtis committed Aug 3, 2010
Showing with 74 additions and 8 deletions.
  1. +3 −0 setup.nqp
  2. +24 −4 src/Tree/Optimizer.nqp
  3. +17 −0 src/Tree/Optimizer/CombinedPass.nqp
  4. +6 −4 src/Tree/Optimizer/Pass.nqp
  5. +24 −0 src/Tree/Optimizer/Transformers.nqp
View
@@ -31,6 +31,7 @@ sub MAIN() {
'build/PCT/Pattern.pir', 'src/PCT/Pattern.nqp',
'build/POST/Pattern.pir', 'src/POST/Pattern.nqp',
'build/Tree/Optimizer.pir', 'src/Tree/Optimizer.nqp',
+ 'build/Tree/Optimizer/CombinedPass.pir', 'src/Tree/Optimizer/CombinedPass.nqp',
'build/Tree/Optimizer/Pass.pir', 'src/Tree/Optimizer/Pass.nqp',
'build/Tree/Optimizer/Transformers.pir', 'src/Tree/Optimizer/Transformers.nqp',
'build/Tree/Pattern.pir', 'src/Tree/Pattern.nqp',
@@ -52,6 +53,7 @@ sub MAIN() {
'build/PCT/Pattern.pbc', 'build/PCT/Pattern.pir',
'build/POST/Pattern.pbc', 'build/POST/Pattern.pir',
'build/Tree/Optimizer.pbc', 'build/Tree/Optimizer.pir',
+ 'build/Tree/Optimizer/CombinedPass.pbc', 'build/Tree/Optimizer/CombinedPass.pir',
'build/Tree/Optimizer/Pass.pbc', 'build/Tree/Optimizer/Pass.pir',
'build/Tree/Optimizer/Transformers.pbc', 'build/Tree/Optimizer/Transformers.pir',
'build/Tree/Pattern.pbc', 'build/Tree/Pattern.pir',
@@ -80,6 +82,7 @@ sub MAIN() {
build/PCT/Pattern.pbc
build/POST/Pattern.pbc
build/Tree/Optimizer.pbc
+ build/Tree/Optimizer/CombinedPass.pbc
build/Tree/Optimizer/Pass.pbc
build/Tree/Optimizer/Transformers.pbc
build/Tree/Pattern.pbc
View
@@ -1,6 +1,8 @@
class Tree::Optimizer;
INIT {
+ pir::load_bytecode('Tree/Optimizer/Transformers.pbc');
+ pir::load_bytecode('Tree/Optimizer/CombinedPass.pbc');
pir::load_bytecode('Tree/Optimizer/Pass.pbc');
pir::load_bytecode('nqp-setting.pbc');
}
@@ -92,9 +94,9 @@ method remove-dependency ($dependent, $dependency) {
}
}
-method run ($tree) {
+method run ($tree, :$combine) {
my $result := $tree;
- for self.pass-order -> $pass {
+ for self.pass-order(:combine($combine)) -> $pass {
$result := self.run-pass($pass, $result);
}
$result;
@@ -104,9 +106,14 @@ method run-pass ($pass, $tree) {
$pass.run($tree);
}
-method pass-order () {
+method combine-passes (*@passes) {
+ Tree::Optimizer::CombinedPass.new(@passes);
+}
+
+method pass-order (:$combine) {
my @result;
my @no-preds;
+ my @combine-buffer;
for %!passes {
@no-preds.push($_.key) unless
pir::exists__IQs(%!predecessors, $_.key);
@@ -115,7 +122,18 @@ method pass-order () {
my %old-succs := pir::clone__PP(%!successors);
while +@no-preds != 0 {
my $name := @no-preds.pop;
- @result.push(self.find-pass($name));
+ my $pass := self.find-pass($name);
+ if $combine {
+ if pir::defined__IP($pass.when) && $pass.recursive {
+ @combine-buffer.push($pass);
+ } else {
+ @result.push(self.combine-passes(|@combine-buffer));
+ @combine-buffer := [];
+ @result.push($pass);
+ }
+ } else {
+ @result.push($pass);
+ }
for %!successors{$name} -> $dependent {
self.remove-dependency($dependent, $name);
unless %!predecessors{$dependent} &&
@@ -131,5 +149,7 @@ method pass-order () {
}
%!predecessors := %old-preds;
%!successors := %old-succs;
+ @result.push(self.combine-passes(|@combine-buffer))
+ if $combine && @combine-buffer;
@result;
}
@@ -0,0 +1,17 @@
+class Tree::Optimizer::CombinedPass;
+
+has $!transformer;
+
+method new (@passes) {
+ my $self := pir::new__PP(self.HOW.get_parrotclass(self));
+ $self.BUILD(:passes(@passes));
+ $self;
+}
+
+method BUILD (:@passes) {
+ $!transformer := Tree::Optimizer::Transformer::Combined.new(@passes)
+}
+
+method run ($tree) {
+ $!transformer.walk($tree);
+}
@@ -1,9 +1,5 @@
class Tree::Optimizer::Pass;
-INIT {
- pir::load_bytecode('Tree/Optimizer/Transformers.pbc');
-}
-
has $!name;
has $!recursive;
has $!transformation;
@@ -12,9 +8,15 @@ has $!when;
our multi method name () { $!name; }
our multi method name ($name) { $!name := $name; }
+our multi method recursive () { $!recursive; }
+our multi method recursive ($recursive) { $!recursive := $recursive; }
+
our multi method transformation () { $!transformation; }
our multi method transformation ($tran) { $!transformation := $tran; }
+our multi method when () { $!when; }
+our multi method when ($when) { $!when := $when; }
+
method new ($trans, *%adverbs) {
pir::die(" A pass' transformation must not be undefined.")
unless pir::defined__IP($trans);
@@ -16,10 +16,34 @@ class Tree::Optimizer::Transformer::Single is Tree::Transformer {
method transform () { $!transform; }
}
+class Tree::Optimizer::Transformer::Combined is Tree::Transformer {
+ has @!passes;
+
+ method new (@passes) {
+ my $self := pir::new__PP(self.HOW.get_parrotclass(self));
+ $self.BUILD(@passes);
+ $self;
+ }
+
+ method BUILD (@passes) { @!passes := @passes; }
+
+ method passes () { @!passes; }
+}
+
module Tree::Walker {
our multi walk (Tree::Optimizer::Transformer::Single $walker, $node) {
my $result := $walker.transform()($node);
replaceChildren($result, walkChildren($walker, $result));
$result;
}
+
+ our multi walk (Tree::Optimizer::Transformer::Combined $walker, $node) {
+ my $result := $node;
+ for $walker.passes -> $pass {
+ my $/ := $pass.when.ACCEPTS($node, :exact(1));
+ $result := $pass.transformation()($/) if $/;
+ }
+ replaceChildren($result, walkChildren($walker, $result));
+ $result;
+ }
}

0 comments on commit caae635

Please sign in to comment.