diff options
Diffstat (limited to 'tools/eliminator/eliminator.coffee')
-rw-r--r-- | tools/eliminator/eliminator.coffee | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/tools/eliminator/eliminator.coffee b/tools/eliminator/eliminator.coffee index a4c98930..f83b4a52 100644 --- a/tools/eliminator/eliminator.coffee +++ b/tools/eliminator/eliminator.coffee @@ -107,8 +107,8 @@ class Eliminator # Maps a given single-def variable to the AST expression of its initial value. @initialValue = {} # Maps identifiers to single-def variables which reference it in their - # initial value. - @dependsOn = {} + # initial value, i.e., which other variables it affects. + @affects = {} # Runs the eliminator on a given function body updating the AST in-place. # @returns: The number of variables eliminated, or undefined if skipped. @@ -157,7 +157,7 @@ class Eliminator # Analyzes the initial values of single-def variables. Requires basic variable # stats to have been calculated. Fills the following member variables: - # dependsOn + # affects # dependsOnAGlobal # usesOnlySimpleNodes analyzeInitialValues: -> @@ -170,25 +170,38 @@ class Eliminator else if type is 'name' reference = node[1] if reference != 'undefined' - if not @dependsOn[reference]? then @dependsOn[reference] = {} + if not @affects[reference]? then @affects[reference] = {} if not @isLocal[reference] then @dependsOnAGlobal[varName] = true - @dependsOn[reference][varName] = true + @affects[reference][varName] = true return undefined return undefined - # Updates the dependency graph (@dependsOn) to its transitive closure and + # Updates the dependency graph (@affects) to its transitive closure and # synchronizes @dependsOnAGlobal to the new dependencies. calculateTransitiveDependencies: -> incomplete = true + todo = {} + for element of @affects + todo[element] = 1 + + #process.stdout.write 'pre ' + JSON.stringify(@affects, null, ' ') + '\n' + while incomplete incomplete = false - for target, sources of @dependsOn - for source of sources - for source2 of @dependsOn[source] - if not @dependsOn[target][source2] - if not @isLocal[target] then @dependsOnAGlobal[source2] = true - @dependsOn[target][source2] = true - incomplete = true + nextTodo = {} + for source, targets of @affects + for target of targets + if todo[target] + for target2 of @affects[target] + if not targets[target2] + if not @isLocal[source] then @dependsOnAGlobal[target2] = true + targets[target2] = true + nextTodo[source] = 1 + incomplete = true + todo = nextTodo + + #process.stdout.write 'post ' + JSON.stringify(@affects, null, ' ') + '\n' + return undefined # Analyzes the live ranges of single-def variables. Requires dependencies to @@ -211,8 +224,8 @@ class Eliminator while reference[0] != 'name' reference = reference[1] reference = reference[1] - if @dependsOn[reference]? - for varName of @dependsOn[reference] + if @affects[reference]? + for varName of @affects[reference] if isLive[varName] isLive[varName] = false @@ -264,8 +277,8 @@ class Eliminator if @isSingleDef[varName] isLive[varName] = true # Mark variables that depend on it as no longer live - if @dependsOn[varName]? - for varNameDep of @dependsOn[varName] + if @affects[varName]? + for varNameDep of @affects[varName] if isLive[varNameDep] isLive[varNameDep] = false return node |