summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2004-07-05 16:40:36 +0000
committerIulian Dragos <jaguarul@gmail.com>2004-07-05 16:40:36 +0000
commitbd56492ebd57dc26170a8b825061281981516611 (patch)
treef745d2a6681c808a1734faab8735cd84dc66bec1
parent379107dc6e0d9cc64cbc4163745a542a15129d34 (diff)
downloadscala-bd56492ebd57dc26170a8b825061281981516611.tar.gz
scala-bd56492ebd57dc26170a8b825061281981516611.tar.bz2
scala-bd56492ebd57dc26170a8b825061281981516611.zip
Added wholeprog phase to compiler
-rw-r--r--config/list/compiler.lst1
-rw-r--r--config/list/scalac.lst5
-rw-r--r--sources/scala/tools/scalac/CompilerPhases.scala2
-rw-r--r--sources/scala/tools/scalac/Main.scala3
-rw-r--r--sources/scala/tools/scalac/wholeprog/Inline.scala49
-rw-r--r--sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala137
-rw-r--r--sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala54
-rw-r--r--sources/scalac/CompilerPhases.java7
-rw-r--r--sources/scalac/transformer/WholeProgPhase.java44
9 files changed, 196 insertions, 106 deletions
diff --git a/config/list/compiler.lst b/config/list/compiler.lst
index 5d2eaaac1c..2a9922180f 100644
--- a/config/list/compiler.lst
+++ b/config/list/compiler.lst
@@ -165,5 +165,6 @@ util/TypeNames.java
util/UniqueID.java
transformer/ICodePhase.java
+transformer/WholeProgPhase.java
##############################################################################
diff --git a/config/list/scalac.lst b/config/list/scalac.lst
index f40cbd0433..4a349ed07a 100644
--- a/config/list/scalac.lst
+++ b/config/list/scalac.lst
@@ -51,15 +51,12 @@ icode/ICTypeStack.scala
backend/GenJVMFromICode.scala
backend/GenJVMFromICodePhase.scala
-# Temporary hack - iuli
-MyCompilerPhases.scala
-
wholeprog/ApplicationBuilder.scala
wholeprog/PrintDotFile.scala
wholeprog/MonomorphicCS.scala
wholeprog/Inline.scala
+wholeprog/WholeProgPhase.scala
-# graph library - iuli
wholeprog/graph/Graph.scala
##############################################################################
diff --git a/sources/scala/tools/scalac/CompilerPhases.scala b/sources/scala/tools/scalac/CompilerPhases.scala
index 462b0d7327..97f81358bc 100644
--- a/sources/scala/tools/scalac/CompilerPhases.scala
+++ b/sources/scala/tools/scalac/CompilerPhases.scala
@@ -22,6 +22,8 @@ class CompilerPhases extends scalac_CompilerPhases {
Class.forName("scala.tools.scalac.typechecker.AnalyzerPhase$class");
protected override def TRANSMATCH_PHASE(): Class =
Class.forName("scala.tools.scalac.transformer.TransMatchPhase$class");
+ protected override def WHOLEPROG_PHASE(): Class =
+ Class.forName("scala.tools.scalac.wholeprog.WholeProgPhase$class");
protected override def ICODE_PHASE(): Class =
Class.forName("scala.tools.scalac.icode.ICodePhase$class");
protected override def GENJVMFROMICODE_PHASE(): Class =
diff --git a/sources/scala/tools/scalac/Main.scala b/sources/scala/tools/scalac/Main.scala
index 8b637c408e..6bec908796 100644
--- a/sources/scala/tools/scalac/Main.scala
+++ b/sources/scala/tools/scalac/Main.scala
@@ -9,6 +9,7 @@
import scalac.util.Reporter;
import scalac.{CompilerCommand, Global => scalac_Global};
import scalac.symtab.classfile.CLRPackageParser;
+//import scala.tools.scalac.MyCompilerPhases;
package scala.tools.scalac {
@@ -30,7 +31,7 @@ object Main {
def main1( exitOnError:boolean, args: Array[String] ):unit = {
val reporter = new Reporter();
val command = new CompilerCommand(
- PRODUCT, VERSION, reporter, new CompilerPhases());
+ PRODUCT, VERSION, reporter, new CompilerPhases()); // !! MyCompilerPhases
var ok = true;
if (command.parse(args) && command.files.list.size() > 0) {
if (command.target.value == scalac_Global.TARGET_MSIL) {
diff --git a/sources/scala/tools/scalac/wholeprog/Inline.scala b/sources/scala/tools/scalac/wholeprog/Inline.scala
index d5f0f0db46..ec5919309c 100644
--- a/sources/scala/tools/scalac/wholeprog/Inline.scala
+++ b/sources/scala/tools/scalac/wholeprog/Inline.scala
@@ -24,41 +24,23 @@ package scala.tools.scalac.wholeprog {
/** Perform inlining of the sites passed as parameter */
-class InlineMethods(sites: List[Tuple3[GNode[Symbol, MethodNode], GNode[Symbol, MethodNode], CallSite]],
+class InlineMethods(sites: MonomorphicCallSites#InlinableCollection,
global: scalac_Global)
extends Transformer(global) {
var inlines: int = 0;
var inlinedThis: Symbol = null;
- var inMain = false;
override def transform(tree: Tree): Tree = {
tree match {
case Tree$Apply(fun, args) => {
-// if (inMain)
-// Console.println("main " + fun);
- val s = sites.find( tuple => tree eq tuple._3.t);
- s match {
- case Some(Tuple3(cl, ce, s)) => expand(tree, cl, ce)
+
+ sites.get(tree) match {
+ case Some(Tuple3(cl, ce, s)) => expand(tree, cl, ce);
case _ => super.transform(tree);
}
}
- case Tree$ClassDef(_, name, _, _, _, _) => {
- //Console.println("Enter class " + name.toString());
- super.transform(tree);
- }
-
- case Tree$DefDef(_, name, _, _, _, _) => {
- //Console.println("Enter method " + name.toString());
- if (name.toString().equals("main"))
- inMain = true;
- else
- inMain = false;
- super.transform(tree);
- }
-
-
case _ => super.transform(tree);
}
}
@@ -76,7 +58,7 @@ class InlineMethods(sites: List[Tuple3[GNode[Symbol, MethodNode], GNode[Symbol,
assert(args.length == vparams(0).length,
"Call site has different nr. of arguments than def " + fun.symbol());
- res(0) = makeThisDef(fun); // was: makeThisDef(fun);
+ res(0) = makeThisDef(fun);
var i: int = 1;
while (i < res.length) {
// duplicate the formal parameter of the method and create a symbol for this def
@@ -96,8 +78,7 @@ class InlineMethods(sites: List[Tuple3[GNode[Symbol, MethodNode], GNode[Symbol,
subst += arg.symbol() -> sym;
// set the initial value to the actual parameter
-// arg.rhs = args(i - 1).duplicate();
- arg.rhs = (new InlineMethods(sites, global)).transform(args(i-1));
+ arg.rhs = args(i - 1).duplicate();
arg.setSymbol(sym);
arg.rhs.setType(sym.getType());
@@ -111,25 +92,22 @@ class InlineMethods(sites: List[Tuple3[GNode[Symbol, MethodNode], GNode[Symbol,
def makeThisDef(fun: Tree): Tree = {
val Tree$Select(qualifier, selector) = fun;
+// val tpe = make.TypeTerm(fun.pos);
val sym = caller.info.method.newVariable(fun.pos, 0, Name.fromString("inthis"));
-
+// sym.setType(qualifier.getType().singleDeref()); // it was .singleDeref() but unneded?
sym.setType(callee.info.classz.getType());
Logger.log("[inthis] Set type to " + sym.getType());
- val t = gen.ValDef(sym, (new InlineMethods(sites, global)).transform(qualifier)); // was: qualifier.duplicate());
+// val t = make.ValDef(fun.pos, 0, Name.fromString("inthis"), tpe, qualifier.duplicate());
+ val t = gen.ValDef(sym, qualifier.duplicate());
+// tpe.setType(qualifier.getType().deconst());
+// t.setSymbol(sym);
inlinedThis = sym;
t
}
- Logger.log("Trying to inline at " +
- caller.info.classz.name + "." +
- caller.info.method.name + " [" + Position.toString(tree.pos) + "] with " +
- callee.info.classz.name + "." +
- callee.info.method.name);
-
-
val locals = createLocals(tree, callee.info.code);
val updater = new UpdateAccesses(subst, caller.info.method);
val newRhs = updater.transform(rhs.duplicate());
@@ -213,7 +191,8 @@ class InlineMethods(sites: List[Tuple3[GNode[Symbol, MethodNode], GNode[Symbol,
}
override def getSymbolFor(tree: Tree): Symbol = {
- if (tree.symbol().isPrivate()) {
+ if (!tree.symbol().isPublic() ||
+ (tree.symbol().flags & Modifiers.PACKAGE) > 0 ) { // attention, was isPrivate()
touchedPrivate = true;
Logger.log("[inline] touched private symbol " +
SymbolPrinter.fullName(tree.symbol()));
diff --git a/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala b/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala
index 7605586cec..2302d09fb9 100644
--- a/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala
+++ b/sources/scala/tools/scalac/wholeprog/MonomorphicCS.scala
@@ -30,13 +30,15 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
type CallGraphNode = GNode[Symbol, MethodNode];
type CallGraphEdge = Edge[Symbol, CallEdge];
+ type InlinableCollection = HashMap[Tree, Tuple3[CallGraphNode, CallGraphNode, CallSite]];
+
private val global = globall;
val hierarchy = new Graph[Symbol, Symbol, String];
val callGraph = new CallGraph;
var instantiatedClasses = new HashSet[Symbol];
- var inlinable: List[Tuple3[CallGraphNode, CallGraphNode, CallSite]] = Nil;
+ var inlinable: InlinableCollection = new InlinableCollection;
/** create the class inheritance hierarchy */
@@ -88,8 +90,13 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
var closures: Int = 0;
def logStatistics(e: CallGraphEdge): Unit = {
- if (SymbolPrinter.fullName(cg.getNode(e.to).info.classz).startsWith("scala.Function"))
+ if (cg.getNode(e.to).info.method.name.toString().equals("apply")) {
closures = closures + 1;
+// Console.println("[closure] " + cg.getNode(e.from).info.classz.name + "." +
+// cg.getNode(e.from).info.method.name + " -> " +
+// cg.getNode(e.to).info.classz.name + "." +
+// cg.getNode(e.to).info.method.name);
+ }
if (cg.getNode(e.to).info.method.name.toString().equals("view"))
views = views + 1;
}
@@ -99,11 +106,7 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
val callee = cg.getNode(e.to);
if (canInline(caller, callee))
- inlinable = new Tuple3(caller, callee, e.info.site) :: inlinable;
- else
- Logger.log("[monomorphiccs] skipped monomorphic call site " +
- SymbolPrinter.fullName(caller.info.method) + " -> " +
- SymbolPrinter.fullName(callee.info.method));
+ inlinable += e.info.site.t -> new Tuple3(caller, callee, e.info.site);
}
def canInline(caller: CallGraphNode, callee: CallGraphNode): boolean =
@@ -116,53 +119,49 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
Logger.setFile("inlining.log");
- Console.println("[start build callgraph]");
+ Console.println("[start build callgraph]"); StopWatch.start;
buildCallGraph;
- Console.println("[end build callgraph]");
+ Console.println("[end build callgraph] " + StopWatch.stop + " ms");
if (global.args.Xrta.value) {
// perform additional pruning
Console.println("[start RTA]");
rapidTypeAnalysis(instantiatedClasses);
- Console.println("[end RTA]");
+ Console.println("[end RTA] " + StopWatch.stop + " ms");
}
if (!global.args.XdotFile.value.equals("$"))
dumpCallGraph;
- Console.println("[start Monomorphic call site identification]");
+ Console.println("[start Monomorphic call site identification]"); StopWatch.start;
cg.nodes.foreach( (id: Symbol, n: CallGraphNode) => {
- n.info.callSites.foreach( (site: CallSite) => {
- val mcs = cg.getOutEdges(id).filter( e: CallGraphEdge => e.info.site == site );
+ n.info.callSites.foreach( (site) => {
+ val mcs = cg.getOutEdges(id).filter( e => e.info.site == site );
if (mcs.length == 1) {
inlineCallSite(mcs.head);
-// Console.println("Monomorphic call-site: " +
-// SymbolPrinter.fullName(mcs.head.from) + " " +
-// SymbolPrinter.fullName(mcs.head.to));
+// Console.println("Monomorphic call-site: " + mcs.head.from + " " + mcs.head.to);
logStatistics(mcs.head);
nr = nr + 1;
}
});
});
-
- Console.println("[end Monomorphic call site identification]");
+ Console.println("[end Monomorphic call site identification] " + StopWatch.stop + " ms");
Console.println("We identified " + nr + " monomorphic call-sites. ("
- + inlinable.length + " inlinable).");
- Console.println("[closures = " + closures + ", views = " + views + "]");
+ + inlinable.size + " inlinable).");
+ Console.println("[closures = " + closures + " out of " + closuresTotal +
+ ", views = " + views + "out of " + viewsTotal + "]");
if (global.args.Xinline.value) {
- Console.println("[start inlining]");
-
-// inlinable.foreach( (t) => Console.println("inline callsite " + t._3.t));
+ Console.println("[start inlining]"); StopWatch.start;
doInline(inlinable);
- Console.println("[end inlining]");
+ Console.println("[end inlining] " + StopWatch.stop + " ms");
}
}
- /** Perform a (buggy) form of rapid type analysis, as described in Sundaresan 99
+ /** Perform a form of rapid type analysis, as described in Sundaresan 99
The idea is that the call graph can be signifficanly pruned if all edges that go
into a method of a class that was never instantiated in the program are removed.
@@ -183,35 +182,30 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
Logger.log("[RTA] Instantiated classes: ");
instantiatedClasses.foreach( s => Logger.log("[RTA] " + SymbolPrinter.fullName(s)));
-// callGraph.visitDFS( (n: CallGraphNode) => {
-// if (n.info.classz != null &&
-// !isInstatiated(n.info.classz)) {
-// callGraph.removeEdges(callGraph.getInEdges(n.id));
-// Logger.log("[RTA] Removed inedges for " + SymbolPrinter.fullName(n.id));
-// }
-// });
-
Console.println("[Visiting call graph]");
- callGraph.nodes.foreach( (id: Symbol, n: CallGraphNode) => {
- n.info.callSites.foreach( (site: CallSite) => {
- val targets = callGraph.getOutEdges(id).filter( e: CallGraphEdge => e.info.site == site );
+
+ val it = callGraph.nodeIterator;
+
+ while (it.hasNext) {
+ val n = it.next;
+
+ n.info.callSites.foreach( (site) => {
+ val targets = callGraph.getOutEdges(n.id).filter( e => e.info.site == site );
if (targets.length > 1) {
// test for instantiation
targets.foreach( (t: CallGraphEdge) => if ( !isInstatiated(callGraph.getNode(t.to).info.classz) ) {
callGraph.removeEdge(t);
- Logger.log("[RTA] Removed edge " +
- SymbolPrinter.fullName(t.from) + " -> " +
- SymbolPrinter.fullName(t.to));
-
+ Logger.log("[RTA] Removed edge to " + SymbolPrinter.fullName(t.to));
});
}
});
- });
+ }
+
}
/** perform inlines */
- def doInline(sites: List[Tuple3[CallGraphNode, CallGraphNode, CallSite]]): Unit = {
+ def doInline(sites: InlinableCollection): Unit = {
val transformer: Transformer = new InlineMethods(sites, global);
global.units.foreach( (u) => {
@@ -222,6 +216,11 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
Logger.flush;
}
+ var unknown = 0; // calls to "null" methods
+ var closuresTotal = 0; // calls to "apply" methods
+ var viewsTotal = 0; // calls to "view" methods
+
+
def buildCallGraph: Unit = {
createNodes(callGraph);
createEdges(callGraph);
@@ -239,7 +238,7 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
Console.println("Call graph: " + nodes + " nodes, " +
edges + " edges, [" /* + callGraph.edges.length */ + "]" +
- callsites + " callsites.");
+ callsites + " callsites." + "(unknown = " + unknown + ")");
}
def dumpCallGraph: Unit = {
@@ -270,7 +269,6 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
val methSym = tree.symbol();
cg.addNode(new CallGraphNode(methSym, new MethodNode(methSym, methSym.enclClass(), tree)));
- Logger.log("[callgraph] Created node " + SymbolPrinter.fullName(methSym));
}
case _ => ;
@@ -307,28 +305,20 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
case Tree$Apply(fun, args) => {
if (enclMethod != null) {
+ val targetMeth = fun.symbol();
+
+ if (targetMeth != null) {
+ if (targetMeth.name.toString().equals("apply"))
+ closuresTotal = closuresTotal + 1;
+ else if (targetMeth.name.toString().equals("view"))
+ viewsTotal = viewsTotal + 1;
+
+ createEdges(targetMeth, tree);
+ }
+ else
+ unknown = unknown + 1;
+
- var targetMeth = fun.symbol();
- var callsiteTree = tree;
-
- if (targetMeth == null)
- fun match {
- case Tree$TypeApply(innerFun, args) => {
- targetMeth = innerFun.symbol();
- callsiteTree = innerFun;
- //Console.println("Hopla, a type apply for " + innerFun);
- }
- case _ => ;
- }
-
- if (targetMeth == null)
- Console.println("Null symbol for method " + tree);
-
- //assert(targetMeth != null, "Null target method for " + tree);
- if (targetMeth != null)
- createEdges(targetMeth, callsiteTree);
-// else
-// Console.println("Null symbol: " + tree);
// fun match {
// case Tree$Select(qualifier, selector) => {
// val target = typeToSymbol(qualifier.getType());
@@ -399,7 +389,6 @@ class MonomorphicCallSites(globall: scalac_Global, application: Set[Symbol]) {
}
}
-// def makeNodeId(meth: Symbol): String = SymbolPrinter.fullName(meth);
}
/** Class that maintains information about nodes in the callgraph */
@@ -433,4 +422,20 @@ object SymbolPrinter {
}
+object StopWatch {
+ var startTimeMillis: Long = 0;
+
+ /** arm the stop watch */
+ def start: Unit = {
+ startTimeMillis = System.currentTimeMillis();
+ }
+
+ /** Retrieve the elapsed time and arm the stopwatch again */
+ def stop: Long = {
+ val time = System.currentTimeMillis() - startTimeMillis;
+ start;
+ time
+ }
+}
+
} // package wholeprog
diff --git a/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala b/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala
new file mode 100644
index 0000000000..aaf1942781
--- /dev/null
+++ b/sources/scala/tools/scalac/wholeprog/WholeProgPhase.scala
@@ -0,0 +1,54 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+/*
+** The Global analysis phase.
+**
+** We add a new phase in the compiler, WholeProgPhase.
+**
+** [iuli] 3.03.2004 */
+
+import scala.tools.scalac.{CompilerPhases => old_CompilerPhases}
+import scalac.{Global => scalac_Global}
+import scalac.transformer.{WholeProgPhase => scalac_WholeProgPhase}
+import scalac.PhaseDescriptor;
+import scalac.{CompilationUnit => scalac_Unit}
+import scalac.util.Name;
+
+package scala.tools.scalac.wholeprog {
+
+/**
+ * This phase analyzes the whole program and tries to derive some
+ * useful facts about it: which classes can be marked final, what
+ * methods, fields are never used, and monomorphic call-sites.
+ */
+class WholeProgPhase(global: scalac_Global, descriptor: PhaseDescriptor)
+ extends scalac_WholeProgPhase (global, descriptor) {
+
+
+ /* Apply the global analysis phase to the given units */
+ override def apply(units: Array[scalac_Unit]): unit = {
+
+ if (!global.args.XdotFile.value.equals("$")) {
+ val dotFilePrinter = new PrintDotFile(units);
+ dotFilePrinter.makeDotFile(global.args.XdotFile.value);
+ }
+
+ if (!global.args.XrootClass.value.equals("$")) {
+
+ var builder: ApplicationBuilder = new ApplicationBuilder(global);
+ builder.buildApplication(global.args.XrootClass.value, units);
+ }
+
+ if (!global.args.XdotFile.value.equals("$")) {
+ val dotFilePrinter = new PrintDotFile(units);
+ dotFilePrinter.makeDotFile(global.args.XdotFile.value + "2");
+ }
+ }
+
+}
+
+}
diff --git a/sources/scalac/CompilerPhases.java b/sources/scalac/CompilerPhases.java
index daaf55c34c..3dc4e9a24f 100644
--- a/sources/scalac/CompilerPhases.java
+++ b/sources/scalac/CompilerPhases.java
@@ -33,6 +33,7 @@ public abstract class CompilerPhases {
public final PhaseDescriptor EXPLICITOUTER;
public final PhaseDescriptor ADDCONSTRUCTORS;
public final PhaseDescriptor TAILCALL;
+ public final PhaseDescriptor WHOLEPROG;
public final PhaseDescriptor ADDINTERFACES;
public final PhaseDescriptor EXPANDMIXIN;
public final PhaseDescriptor MAKEBOXINGEXPLICIT;
@@ -61,6 +62,7 @@ public abstract class CompilerPhases {
protected Class ADDACCESSORS_PHASE() { return scalac.transformer.AddAccessorsPhase.class; }
protected Class ADDCONSTRUCTORS_PHASE() { return scalac.transformer.AddConstructorsPhase.class; }
protected Class TAILCALL_PHASE() { return scalac.transformer.TailCallPhase.class; }
+ protected Class WHOLEPROG_PHASE() { return scalac.util.EmptyPhase.class; } // No java version
protected Class ADDINTERFACES_PHASE() { return scalac.transformer.AddInterfacesPhase.class; }
protected Class EXPANDMIXIN_PHASE() { return scalac.transformer.ExpandMixinsPhase.class; }
protected Class ERASURE_PHASE() { return scalac.transformer.ErasurePhase.class; }
@@ -136,6 +138,11 @@ public abstract class CompilerPhases {
"add tail-calls",
"added tail-calls",
TAILCALL_PHASE()),
+ this.WHOLEPROG = new PhaseDescriptor(
+ "wholeprog",
+ "perform whole program analysis",
+ "find monomorphic callsites and performs inlining",
+ WHOLEPROG_PHASE()),
this.ADDINTERFACES = new PhaseDescriptor(
"addinterfaces",
"add one interface per class",
diff --git a/sources/scalac/transformer/WholeProgPhase.java b/sources/scalac/transformer/WholeProgPhase.java
new file mode 100644
index 0000000000..5d97f4abdc
--- /dev/null
+++ b/sources/scalac/transformer/WholeProgPhase.java
@@ -0,0 +1,44 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+package scalac.transformer;
+
+import scalac.Global;
+import scalac.Phase;
+import scalac.PhaseDescriptor;
+import scalac.CompilationUnit;
+import scalac.checkers.TreeChecker;
+import scalac.symtab.Definitions;
+
+import ch.epfl.lamp.util.CodePrinter;
+import scalac.atree.ATreePrinter;
+
+
+/**
+ * This class represents the wholeprog phase for the java version
+ * of the compiler. It doesn't do anything but permit to make
+ * a bridge between the java implementation of Socos et the
+ * scala one. See scala.tools.scalac.wholeprog.WholeProgPhase for
+ * implementation
+ */
+public class WholeProgPhase extends Phase {
+
+ /** Initializes this instance. */
+ public WholeProgPhase(Global global, PhaseDescriptor descriptor) {
+ super(global, descriptor);
+
+ }
+
+ //########################################################################
+ // Public Methods
+
+ /** Applies this phase to the given compilation units. */
+ public void apply(CompilationUnit[] units) {
+ // This java version doesn't make anything
+ }
+
+}
+