moving Scala ASTs one step closer to C

39 views
Skip to first unread message

Miguel Garcia

unread,
Jun 29, 2011, 9:14:22 AM6/29/11
to jvm-la...@googlegroups.com

Hi, 

In case you've been looking for a low-level IR for Scala ASTs, now you can inspect and transform a three-address-like IR (which are also valid Scala ASTs) emitted by a compiler plugin to that effect. 

Sample input: 

    object Test {
      def main(args: Array[String]) {
        val res = 
          if(b(1) + b(2) * b(3) > 0) { throw new Exception; "thenBranch" } 
          else { "elseBranch" } 
      }
      def b(n: Int) = { scala.Console.println(n); n }
    }



Sample output (excerpt): 

    def main(args: Array[java.lang.String]): Unit = {
      var tmp10: java.lang.String = _;
      val tmp1: Int = Test.this.b(1);
      val tmp2: Int = tmp1;
      val tmp3: Int = Test.this.b(2);
      val tmp4: Int = tmp3;
      val tmp5: Int = Test.this.b(3);
      val tmp6: Int = tmp4.*(tmp5);
      val tmp7: Int = tmp2.+(tmp6);
      val tmp8: Int = tmp7;
      val tmp9: Boolean = tmp8.>(0);
      if (tmp9)
        {
          val tmp11: java.lang.Exception = new java.lang.Exception();
          throw tmp11;
          tmp10 = "thenBranch"
        }
      else
        tmp10 = "elseBranch";
      val res: java.lang.String = tmp10;
      ()
    }


The PDF at
is the technical documentation for the sources at 



If you want to use this plugin *today*, please notice [1] (that came to light during the development of this plugin). Alternatively, the plugin sources show how to workaround that. 


Comments and suggestions are welcome (at http://groups.google.com/forum/#!forum/scala-internals). 


Miguel 



Rémi Forax

unread,
Jun 29, 2011, 10:10:59 AM6/29/11
to jvm-la...@googlegroups.com
Hi Miguel,
given that we (mostly :) use the JVM, what is the point of such transformation.
I understand why you can need this for a C or a LLVM backend but
for the JVM a transformation like this will hurt the perf,
the interpreter perf (too much bytecode)
and the JIT inlining heuristic (too much bytecode => no inlining).

other comments inlined:
I'm curious why tmp10 = "thenBranch" appears.
You do your transformation after the typechecking pass but before the dead
instruction detection (why the code compile BTW).

Is it because there is no such pass in the scala compiler ?

Another question, can you compare the interest of this transformation with
a SSA to AST ?




The PDF at
is the technical documentation for the sources at 



If you want to use this plugin *today*, please notice [1] (that came to light during the development of this plugin). Alternatively, the plugin sources show how to workaround that. 


Comments and suggestions are welcome (at http://groups.google.com/forum/#!forum/scala-internals). 


Miguel 



Rémi

Miguel Garcia

unread,
Jun 29, 2011, 11:33:00 AM6/29/11
to jvm-la...@googlegroups.com

Rémi,


> given that we (mostly :) use the JVM, what is the point of such transformation.

Program verification, jumpstarting support for new backends, case study for those wanting to learn compiler internals. 


> I understand why you can need this for a C or a LLVM backend 

Or Objective-C, C# 3.0, OpenCL. I guess the list goes on, that's for potential users to determine. 


> but for the JVM a transformation like this will hurt the perf,
> the interpreter perf (too much bytecode)
> and the JIT inlining heuristic (too much bytecode => no inlining).

Yes, that's why compiler plugin in question is not part of the standard compilation pipeline. 


> I'm curious why tmp10 = "thenBranch" appears.

The transformation focuses in doing just one thing: making eval order explicit by storing intermediate results in temp vars. 

To obtain different output, other compiler plugins can be brought into play, depending on specific goals. 


> You do your transformation after the typechecking pass but before the dead
> instruction detection (why the code compile BTW).

The (standard) phases of the Scala compiler are: 

prompt>scalac -Xshow-phases

    phase name  id  description
    ----------  --  -----------
        parser   1  parse source into ASTs, perform simple desugaring
         namer   2  resolve names, attach symbols to named trees
packageobjects   3  load package objects
         typer   4  the meat and potatoes: type the trees
superaccessors   5  add super accessors in traits and nested classes
       pickler   6  serialize symbol tables
     refchecks   7  reference/override checking, translate nested objects
      liftcode   8  reify trees
       uncurry   9  uncurry, translate function values to anonymous classes
     tailcalls  10  replace tail calls by jumps
    specialize  11  @specialized-driven class and method specialization
 explicitouter  12  this refs to outer pointers, translate patterns
       erasure  13  erase types, add interfaces for traits
      lazyvals  14  allocate bitmaps, translate lazy vals into lazified defs
    lambdalift  15  move nested functions to top level
  constructors  16  move field definitions into constructors
       flatten  17  eliminate inner classes
         mixin  18  mixin composition
       cleanup  19  platform-specific cleanups, generate reflective calls
         icode  20  generate portable intermediate code
       inliner  21  optimization: do inlining
      closelim  22  optimization: eliminate uncalled closures
           dce  23  optimization: eliminate dead code
           jvm  24  generate JVM bytecode
      terminal  25  The last phase in the compiler chain

I'm running the "three-address" transformation right after phase (19). 

The output code compiles because it's well typed, http://www.scala-lang.org/docu/files/ScalaReference.pdf 


> Is it because there is no such pass in the scala compiler ?

That's
           dce  23  optimization: eliminate dead code


> Another question, can you compare the interest of this transformation 
> with a SSA to AST ?

In the spirit of flexible, well-focused transformations, I guess it's possible to obtain an SSA form from the "three-address" IR, but that's for others to take upon. 


Miguel 


Reply all
Reply to author
Forward
0 new messages