Skip to content
Browse files

Fix constant propagation and propagate params in Local2SSA.

  • Loading branch information...
1 parent 781ba18 commit 7fe05c9c2459977a4b142334dde0a0e375b1acb9 @whitequark committed Sep 1, 2012
View
2 Gemfile
@@ -5,4 +5,4 @@ gemspec
gem "pry"
gem "ruby-prof", :platforms => :mri
-gem "furnace", :github => 'whitequark/furnace'
+gem "furnace", :github => 'whitequark/furnace', :branch => 'master'
View
3 lib/furnace-avm2/source/decompiler.rb
@@ -465,7 +465,8 @@ def local_token(node)
end
end
end
- alias :expr_this :local_token
+ alias :expr_this :local_token
+ alias :expr_param :local_token
def expr_get(node)
index, = node.children
View
29 lib/furnace-avm2/transform/convert_locals_to_ssa.rb
@@ -30,19 +30,32 @@ def on_get_local(node)
end
end
+ def initialize(options={})
+ @method = options[:method]
+ end
+
def transform(cfg)
next_id = 0
variable_map = Hash.new { |h, k| h[k] = Set[] }
- # Prepend implicit `this'.
- this_set = AST::Node.new(:set_local, [
- 0, AST::Node.new(:this)
- ], {
- read_barrier: Set[],
- write_barrier: Set[],
- })
+ # Prepend implicit `this' and params.
+ implicit = 0.upto(1 + @method.param_count).map do |local|
+ case local
+ when 0
+ inner_node = AST::Node.new(:this)
+ else
+ inner_node = AST::Node.new(:param, [ local - 1 ])
+ end
+
+ AST::Node.new(:set_local, [
+ local, inner_node
+ ], {
+ read_barrier: Set[],
+ write_barrier: Set[],
+ })
+ end
- cfg.entry.insns.insert(0, this_set)
+ cfg.entry.insns.insert(0, *implicit)
# Convert (set-local) to (s).
cfg.nodes.each do |block|
View
11 lib/furnace-avm2/transform/propagate_constants.rb
@@ -16,14 +16,15 @@ def transform(cfg)
# TODO add options for folding complex constants
if evaluator.immediate?(set_value) ||
set_value.type == :this ||
+ set_value.type == :param ||
set_value.type == :find_property_strict
- replace_r_nodes(cfg, block, id, set_value) do |child_block|
- child_block.metadata.live.delete id
- end
+ replaced_all = replace_r_nodes(cfg, block, id, set_value)
- block.metadata.remove_set id
- block.insns.delete set
+ if replaced_all
+ block.metadata.remove_set id
+ block.insns.delete set
+ end
changed = true
end
View
20 lib/furnace-avm2/transform/subgraph_operations.rb
@@ -85,18 +85,30 @@ def reduce_phi_nodes(cfg, root, target_id, supplementary_id)
end
def replace_r_nodes(cfg, root, target_id, replacement)
+ replaced_all = true
+
walk_live_nodes(cfg, root, target_id) do |block|
gets = block.metadata.gets_map[target_id]
gets.each do |get|
- get.update(replacement.type,
- replacement.children,
- replacement.metadata)
+ if get.children.one?
+ get.update(replacement.type,
+ replacement.children,
+ replacement.metadata)
+ else
+ replaced_all = false
+ end
end
block.metadata.unregister_get target_id
+ end
- yield block if block_given?
+ if replaced_all
+ walk_live_nodes(cfg, root, target_id) do |block|
+ block.metadata.live.delete target_id
+ end
end
+
+ replaced_all
end
end
end

0 comments on commit 7fe05c9

Please sign in to comment.
Something went wrong with that request. Please try again.