Skip to content
This repository has been archived by the owner on Nov 2, 2019. It is now read-only.

Commit

Permalink
Add constant propagation pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
whitequark committed Aug 19, 2012
1 parent 02968b9 commit 432e8c1
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 34 deletions.
6 changes: 6 additions & 0 deletions lib/furnace-avm2/abc/metadata/method_body_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ def code_to_cfg(options={})
Furnace::AVM2::Transform::DataflowInvariantCodeMotion.new,
Furnace::AVM2::Transform::PartialEvaluation.new,
Furnace::AVM2::Transform::SSAOptimize.new,

Furnace::AVM2::Transform::LivenessAnalysis.new,
Furnace::AVM2::Transform::FoldBooleanShortcuts.new,
Furnace::AVM2::Transform::FoldTernaryOperators.new,
Furnace::AVM2::Transform::FoldIncrementDecrement.new,
Furnace::AVM2::Transform::SSAOptimize.new,
]),

Furnace::AVM2::Transform::LivenessAnalysis.new(idempotent: true),
Furnace::AVM2::Transform::PropagateConstants.new,

Furnace::AVM2::Transform::UpdateExceptionVariables.new,
Furnace::AVM2::Transform::FoldPassthroughAssignments.new,
])
Expand Down
1 change: 1 addition & 0 deletions lib/furnace-avm2/transform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Furnace::AVM2::Transform
require_relative "transform/liveness_analysis"
require_relative "transform/dataflow_invariant_code_motion"
require_relative "transform/partial_evaluation"
require_relative "transform/propagate_constants"
require_relative "transform/fold_ternary_operators"
require_relative "transform/fold_boolean_shortcuts"
require_relative "transform/fold_passthrough_assignments"
Expand Down
6 changes: 5 additions & 1 deletion lib/furnace-avm2/transform/liveness_analysis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ class LivenessAnalysis
# Avoid creating too much literals.
EMPTY_SET = Set[]

def initialize(options={})
@idempotent = options[:idempotent] || false
end

def transform(cfg)
dom = cfg.dominators
loops = cfg.identify_loops
Expand Down Expand Up @@ -83,7 +87,7 @@ def transform(cfg)

# This transform does not change CFG in any way,
# it just rebuilds the metadata.
nil
cfg if @idempotent
end
end
end
Expand Down
29 changes: 0 additions & 29 deletions lib/furnace-avm2/transform/phi_node_reduction.rb

This file was deleted.

20 changes: 20 additions & 0 deletions lib/furnace-avm2/transform/propagate_constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ class PropagateConstants
include SubgraphOperations

def transform(cfg)
changed = false

evaluator = Evaluator.new

cfg.nodes.each do |block|
block.metadata.sets.each do |id|
set = block.metadata.set_map[id]
_, set_value = set.children

# TODO add options for folding complex constants
if evaluator.immediate?(set_value)
replace_r_nodes(cfg, block, id, set_value)
block.metadata.remove_set(id)
block.insns.delete set

changed = true
end
end
end

cfg
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/furnace-avm2/transform/subgraph_operations.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Furnace::AVM2
module Transform
module SubgraphOperations
def walk_live_nodes(cfg, root)
def walk_live_nodes(cfg, root, id)
worklist = Set[ root ]
visited = Set[]

Expand All @@ -13,15 +13,15 @@ def walk_live_nodes(cfg, root)
yield block

block.targets.each do |target|
if target.metadata.live.include? target_id
if target.metadata.live.include? id
worklist.add target unless visited.include? target
end
end
end
end

def reduce_phi_nodes(cfg, root, target_id, supplementary_id)
walk_live_nodes(cfg, root) do |block|
walk_live_nodes(cfg, root, target_id) do |block|
gets = block.metadata.gets_map[target_id]
gets.each do |get|
if get.children.include? supplementary_id
Expand All @@ -32,7 +32,7 @@ def reduce_phi_nodes(cfg, root, target_id, supplementary_id)
end

def replace_r_nodes(cfg, root, target_id, replacement)
walk_live_nodes(cfg, root) do |block|
walk_live_nodes(cfg, root, target_id) do |block|
gets = block.metadata.gets_map[target_id]
gets.each do |get|
get.update(replacement.type,
Expand Down

0 comments on commit 432e8c1

Please sign in to comment.