lib/atp/processors/flag_optimizer.rb in atp-1.0.0 vs lib/atp/processors/flag_optimizer.rb in atp-1.1.0
- old
+ new
@@ -23,11 +23,11 @@
# s(:on_fail,
# s(:test,
# s(:name, "test2")))))
#
class FlagOptimizer < Processor
- attr_reader :run_flag_table
+ attr_reader :run_flag_table, :optimize_when_continue
class ExtractRunFlagTable < Processor
# Hash table of run_flag name with number of times used
attr_reader :run_flag_table
@@ -51,11 +51,15 @@
process_all(node.children)
end
alias_method :on_unless_flag, :on_if_flag
end
- def run(node)
+ def run(node, options = {})
+ options = {
+ optimize_when_continue: true
+ }.merge(options)
+ @optimize_when_continue = options[:optimize_when_continue]
# Pre-process the AST for # of occurrences of each run-flag used
t = ExtractRunFlagTable.new
t.process(node)
@run_flag_table = t.run_flag_table
extract_volatiles(node)
@@ -68,15 +72,20 @@
end
alias_method :on_flow, :on_named_collection
alias_method :on_group, :on_named_collection
alias_method :on_unless_flag, :on_named_collection
+ def on_unnamed_collection(node)
+ node.updated(nil, optimize(process_all(node.children)))
+ end
+ alias_method :on_else, :on_unnamed_collection
+
def on_if_flag(node)
name, *nodes = *node
# Remove this node and return its children if required
if if_run_flag_to_remove.last == node.to_a[0]
- node.updated(:inline, node.to_a[1..-1])
+ node.updated(:inline, optimize(process_all(node.to_a[1..-1])))
else
node.updated(nil, [name] + optimize(process_all(nodes)))
end
end
@@ -122,11 +131,14 @@
results << node1 if node1
results
end
def can_be_combined?(node1, node2)
- if node1.type == :test && (node2.type == :if_flag || node2.type == :unless_flag)
+ if node1.type == :test && (node2.type == :if_flag || node2.type == :unless_flag) &&
+ # Don't optimize tests which are marked as continue if told not to
+ !(node1.find(:on_fail) && node1.find(:on_fail).find(:continue) && !optimize_when_continue)
+
if node1.find_all(:on_fail, :on_pass).any? do |node|
if n = node.find(:set_flag)
# Inline instead of setting a flag if...
gated_by_set?(n.to_a[0], node2) && # The flag set by node1 is gating node2
n.to_a[1] == 'auto_generated' && # The flag has been generated and not specified by the user
@@ -139,10 +151,10 @@
end
false
end
def combine(node1, node2)
- nodes_to_inline_on_pass_or_fail << node2
+ nodes_to_inline_on_pass_or_fail << node2 # .updated(nil, process_all(node2.children))
node1 = node1.updated(nil, process_all(node1.children))
nodes_to_inline_on_pass_or_fail.pop
node1
end