From 0fe5cb29e43a0c7eee94910c56fdfe68cc02c1fc Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Mon, 26 Jul 2010 23:37:28 -0700 Subject: [PATCH] New pass-aware compiler driver --- CompilerDriver.pm | 82 +++++++++++++++++++++++++++++------------------ Makefile | 21 ++++-------- niecza_eval | 22 +++++++------ 3 files changed, 68 insertions(+), 57 deletions(-) diff --git a/CompilerDriver.pm b/CompilerDriver.pm index 3eadc143..c6ca9e36 100644 --- a/CompilerDriver.pm +++ b/CompilerDriver.pm @@ -7,6 +7,8 @@ use Sub::Exporter -setup => { exports => [ qw(compile) ] }; +use Time::HiRes 'time'; + use autodie ':all'; open ::NIECZA_OUT, ">&", \*STDOUT; @@ -43,44 +45,60 @@ sub compile { my ($m, $a) = $args{file} ? ('parsefile', $args{file}) : ('parse', $args{code}); - my $ast = Niecza::Grammar->$m($a, setting => $args{lang}, - actions => 'Niecza::Actions')->{_ast}; - - if ($args{ast}) { - delete $ast->mainline->{outer}; - delete $ast->{setting}; - print STDOUT YAML::XS::Dump($ast); - return; - } - - $::SETTING_RESUME = undef; - - $ast->lift_decls; - $ast->extract_scopes; - $ast->to_cgop; - $ast->to_anf; - my $basename = $::UNITNAME; - $basename =~ s/::/\//g; - $basename ||= 'MAIN'; - - open ::NIECZA_OUT, ">", $basename . ".cs"; - print ::NIECZA_OUT <$m($a, setting => $args{lang}, + actions => 'Niecza::Actions')->{_ast}; } ], + [ 'lift_decls', sub { + $::SETTING_RESUME = undef; + $ast->lift_decls; } ], + [ 'extract_scopes', sub { $ast->extract_scopes } ], + [ 'to_cgop', sub { $ast->to_cgop } ], + [ 'to_anf', sub { $ast->to_anf } ], + [ 'writecs', sub { + $basename = $::UNITNAME; + $basename =~ s/::/\//g; + $basename ||= 'MAIN'; + + open ::NIECZA_OUT, ">", $basename . ".cs"; + print ::NIECZA_OUT <write; - close ::NIECZA_OUT; - store $::SETTING_RESUME, ($basename . '_ast.store') - if $::SETTING_RESUME; - - return if $args{csonly}; - - system "gmcs", ($args{main} ? () : ("/target:library")), "/r:Kernel.dll", - (map { "/r:$_.dll" } @::UNITDEPS), - "/out:${basename}." . ($args{main} ? 'exe' : 'dll'), "${basename}.cs"; + $ast->write; + close ::NIECZA_OUT; + store $::SETTING_RESUME, ($basename . '_ast.store') + if $::SETTING_RESUME; + $ast = undef; } ], + [ 'gmcs', sub { + system "gmcs", ($args{main} ? () : ("/target:library")), + "/r:Kernel.dll", (map { "/r:$_.dll" } @::UNITDEPS), + "/out:${basename}." . ($args{main} ? 'exe' : 'dll'), + "${basename}.cs"; } ], + [ 'aot', sub { + system "mono", "--aot", "${basename}." . + ($args{main} ? 'exe' : 'dll'); } ]); + + for my $p (@phases) { + next if $p->[1] eq 'aot' && !$args{aot}; + my $t1 = time if $args{stagetime}; + $p->[1]->(); + my $t2 = time if $args{stagetime}; + printf "%-20s: %gs\n", (($::UNITNAME || 'MAIN') . " " . $p->[0]), + $t2 - $t1 if $args{stagetime}; + if ($args{stopafter} && $args{stopafter} eq $p->[0]) { + if ($ast) { + print STDERR YAML::XS::Dump($ast); + } + return; + } + } } 1; diff --git a/Makefile b/Makefile index 684a23d7..9d9b76ad 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,8 @@ all: CORE.dll git rev-parse HEAD | cut -c1-7 > VERSION test: $(COMPILER) test.pl CORE.dll Test.dll - perl niecza_eval --cs-only test.pl - gmcs /r:Kernel.dll /r:CORE.dll /r:Test.dll MAIN.cs - prove -e 'mono --debug=casts' MAIN.exe + perl niecza_eval -v --stop-after=gmcs test.pl + prove -e mono MAIN.exe .DELETE_ON_ERROR: @@ -18,19 +17,11 @@ Kernel.dll: Kernel.cs gmcs /target:library /out:Kernel.dll Kernel.cs mono --aot Kernel.dll -CORE.cs: $(COMPILER) CORE.setting - perl niecza_eval --language=NULL --cs-only -c CORE.setting +CORE.dll: $(COMPILER) Kernel.dll CORE.setting + perl niecza_eval --aot -L NULL -v -c CORE.setting -CORE.dll: Kernel.dll CORE.cs - gmcs /target:library /out:CORE.dll /r:Kernel.dll CORE.cs - mono --aot CORE.dll - -Test.cs: $(COMPILER) CORE.dll Test.pm6 - perl niecza_eval --cs-only -c Test.pm6 - -Test.dll: Kernel.dll CORE.dll Test.cs - gmcs /target:library /out:Test.dll /r:Kernel.dll /r:CORE.dll Test.cs - mono --aot Test.dll +Test.dll: $(COMPILER) Kernel.dll CORE.dll Test.pm6 + perl niecza_eval --aot -v -c Test.pm6 Niecza/Grammar.pmc: Niecza/Grammar.pm6 .STD_build_stamp STD5PREFIX=$(STDBASE)/ $(STDENV) $(STDBASE)/viv -5 -o Niecza/Grammar.pmc Niecza/Grammar.pm6 diff --git a/niecza_eval b/niecza_eval index f89266f4..e9817e37 100755 --- a/niecza_eval +++ b/niecza_eval @@ -8,9 +8,10 @@ use Getopt::Long; use autodie ':all'; my @evaluate; -my $ast; my $module; -my $csonly; +my $stagestats; +my $stopafter; +my $aot; my $lang = 'CORE'; sub usage { @@ -24,16 +25,17 @@ usage: niecza -e 'code' # run a one-liner OR: niecza # interactive shell general options: - --cs-only # stop after .cs generation - --ast # stop after AST generation --language=NAME # select your setting + --stage-stats # detailed timing info + --stop-after=STAGE # stop after STAGE and dump AST + --aot # run ahead-of-time compiler EOM exit $ex; } -GetOptions('ast' => \$ast, 'evaluate|e=s' => \@evaluate, - 'compile|c' => \$module, 'cs-only' => \$csonly, - 'language|L=s' => \$lang) +GetOptions('evaluate|e=s' => \@evaluate, 'aot' => \$aot, + 'compile|c' => \$module, 'language|L=s' => \$lang, + 'stage-stats|v' => \$stagestats, 'stop-after=s' => \$stopafter) or usage(\*STDERR, 1); my $excl = 0; @@ -44,9 +46,9 @@ if ($excl > 1 || $module && !@ARGV) { } sub run { - compile(main => !$module, csonly => $csonly, ast => $ast, - lang => $lang, @_); - system 'mono --debug=casts MAIN.exe' if !$module && !$csonly && !$ast; + compile(main => !$module, stopafter => $stopafter, aot => $aot, + stagetime => $stagestats, lang => $lang, @_); + system 'mono --debug=casts MAIN.exe' if !$module && !$stopafter; } if (@ARGV) {