Skip to content

Allow phases to give restrictions on pipeline position. #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,24 @@ object Phases {
*/
private def squashPhases(phasess: List[List[Phase]]): Array[Phase] = {
val squashedPhases = ListBuffer[Phase]()
var prevPhases: Set[String] = Set.empty
var postTyperEmmited = false
var i = 0
while (i < phasess.length) {
if (phasess(i).length > 1) {
assert(phasess(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed")
val phasesInBlock: Set[String] = phasess(i).map(_.name).toSet
for(phase<-phasess(i)) {
phase match {
case p: TreeTransform =>

val unmetRequirements = p.runsAfterGroupsOf &~ prevPhases
assert(unmetRequirements.isEmpty,
s"${phase.name} requires ${unmetRequirements.mkString(", ")} to be in different TreeTransformer")

case _ =>
assert(false, s"Only tree transforms can be squashed, ${phase.name} can not be squashed")
}
}
val transforms = phasess(i).asInstanceOf[List[TreeTransform]]
val block =
if (!postTyperEmmited) {
Expand All @@ -93,6 +105,7 @@ object Phases {
override def transformations: Array[TreeTransform] = transforms.toArray
}
squashedPhases += block
prevPhases ++= phasess(i).map(_.name)
block.init(this, phasess(i).head.id, phasess(i).last.id)
} else squashedPhases += phasess(i).head
i += 1
Expand All @@ -106,11 +119,16 @@ object Phases {
*/
def usePhases(phasess: List[List[Phase]], squash: Boolean = true) = {
phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray
var phasesAfter:Set[String] = Set.empty
nextDenotTransformerId = new Array[Int](phases.length)
denotTransformers = new Array[DenotTransformer](phases.length)
var i = 0
while (i < phases.length) {
phases(i).init(this, i)
val unmetPreceedeRequirements = phases(i).runsAfter -- phasesAfter
assert(unmetPreceedeRequirements.isEmpty,
s"phase ${phases(i)} has unmet requirement: ${unmetPreceedeRequirements.mkString(", ")} should precede this phase")
phasesAfter += phases(i).name
i += 1
}
var lastTransformerId = i
Expand Down Expand Up @@ -170,6 +188,9 @@ object Phases {

def name: String

/** List of names of phases that should precede this phase */
def runsAfter: Set[String] = Set.empty

def run(implicit ctx: Context): Unit

def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit =
Expand Down
3 changes: 3 additions & 0 deletions src/dotty/tools/dotc/transform/Erasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class Erasure extends Phase with DenotTransformer {

override def name: String = "erasure"

/** List of names of phases that should precede this phase */
override def runsAfter: Set[String] = Set("typeTestsCasts", "intercepted", "splitter")

def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
case ref: SymDenotation =>
assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}")
Expand Down
11 changes: 11 additions & 0 deletions src/dotty/tools/dotc/transform/LazyVals.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ class LazyValTranformContext {

override def name: String = "LazyVals"

/** List of names of phases that should have finished their processing of all compilation units
* before this phase starts */
override def runsAfterGroupsOf: Set[String] = Set("lazyValsModules")
/** List of names of phases that should have finished their processing of all compilation units
* before this phase starts */
override def runsAfter: Set[String] = Set("lazyValsModules")

/** List of names of phases that should have finished processing of tree
* before this phase starts processing same tree */
// override def ensureAfter: Set[String] = Set("mixin")

def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
ref match {
case ref: SymDenotation if ref.symbol.isClass =>
Expand Down
4 changes: 4 additions & 0 deletions src/dotty/tools/dotc/transform/TreeTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ object TreeTransforms {
/** id of this treeTransform in group */
var idx: Int = _

/** List of names of phases that should have finished their processing of all compilation units
* before this phase starts */
def runsAfterGroupsOf: Set[String] = Set.empty

def prepareForIdent(tree: Ident)(implicit ctx: Context) = this
def prepareForSelect(tree: Select)(implicit ctx: Context) = this
def prepareForThis(tree: This)(implicit ctx: Context) = this
Expand Down