seafoam 0.6 → 0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/bin/bgv2isabelle +1 -5
 - data/bin/bgv2json +1 -5
 - data/bin/cfg2asm +1 -5
 - data/bin/seafoam +1 -5
 - data/lib/seafoam/bgv/bgv_parser.rb +10 -2
 - data/lib/seafoam/commands.rb +107 -32
 - data/lib/seafoam/graal/pi.rb +18 -0
 - data/lib/seafoam/graph.rb +33 -1
 - data/lib/seafoam/graphviz_writer.rb +24 -2
 - data/lib/seafoam/json_writer.rb +1 -3
 - data/lib/seafoam/{annotators → passes}/fallback.rb +4 -4
 - data/lib/seafoam/{annotators → passes}/graal.rb +43 -15
 - data/lib/seafoam/passes/truffle.rb +58 -0
 - data/lib/seafoam/passes.rb +61 -0
 - data/lib/seafoam/version.rb +1 -1
 - data/lib/seafoam.rb +5 -4
 - metadata +26 -62
 - data/.github/probots.yml +0 -2
 - data/.github/workflows/workflows.yml +0 -39
 - data/.gitignore +0 -7
 - data/.rubocop.yml +0 -37
 - data/.ruby-version +0 -1
 - data/.seafoam/config +0 -1
 - data/CODE_OF_CONDUCT.md +0 -128
 - data/CONTRIBUTING.md +0 -5
 - data/Gemfile +0 -2
 - data/LICENSE.md +0 -7
 - data/README.md +0 -378
 - data/demos/box-unbox-stats +0 -65
 - data/docs/annotators.md +0 -43
 - data/docs/bgv.md +0 -293
 - data/docs/getting-graphs.md +0 -59
 - data/docs/images/igv.png +0 -0
 - data/docs/images/seafoam.png +0 -0
 - data/docs/images/spotlight-igv.png +0 -0
 - data/docs/images/spotlight-seafoam.png +0 -0
 - data/docs/json.md +0 -35
 - data/examples/Fib.java +0 -24
 - data/examples/MatMult.java +0 -39
 - data/examples/fib-java.bgv.gz +0 -0
 - data/examples/fib.js +0 -15
 - data/examples/fib.rb +0 -15
 - data/examples/identity.rb +0 -13
 - data/examples/java/Irreducible.class +0 -0
 - data/examples/java/Irreducible.j +0 -35
 - data/examples/java/IrreducibleDecompiled.java +0 -21
 - data/examples/java/JavaExamples.java +0 -418
 - data/examples/matmult.rb +0 -29
 - data/examples/overflow.rb +0 -13
 - data/examples/ruby/clamps.rb +0 -20
 - data/examples/ruby/graal.patch +0 -15
 - data/examples/ruby/ruby_examples.rb +0 -278
 - data/lib/seafoam/annotators.rb +0 -54
 - data/lib/seafoam/config.rb +0 -34
 - data/seafoam.gemspec +0 -21
 - data/spec/seafoam/annotators/fallback_spec.rb +0 -69
 - data/spec/seafoam/annotators/graal_spec.rb +0 -96
 - data/spec/seafoam/annotators_spec.rb +0 -61
 - data/spec/seafoam/bgv/bgv_parser_spec.rb +0 -157
 - data/spec/seafoam/binary/io_binary_reader_spec.rb +0 -176
 - data/spec/seafoam/cfg/cfg_parser_spec.rb +0 -21
 - data/spec/seafoam/cfg/disassembler_spec.rb +0 -32
 - data/spec/seafoam/command_spec.rb +0 -316
 - data/spec/seafoam/graph_spec.rb +0 -172
 - data/spec/seafoam/graphviz_writer_spec.rb +0 -63
 - data/spec/seafoam/json_writer_spec.rb +0 -14
 - data/spec/seafoam/spec_helpers.rb +0 -34
 - data/spec/seafoam/spotlight_spec.rb +0 -38
 - data/tools/render-all +0 -36
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: f8665fe768d4900820ca676269cd25028306e8253c2109c71ff4cb31dd7c6e44
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: fd8c52e5cf3daafa9b2673265067b743cc644755c3772c02904c2b815b3a93d2
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 815e7031027718cea7a933b7fc5ad822f754f05e3ae5bdc2066775183a9ca98c841b54e682a148c4437a29b1f95c4ede5833a2a1f2995d2c55296a800e71b269
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 462aaad5134c8b6cce229e8456742151354333c5e7c02283e2e90917fa7ad238f3f4f71770519357117f42b1579928ddb0bba3f04b31ddef68d7e41e92f8c016
         
     | 
    
        data/bin/bgv2isabelle
    CHANGED
    
    | 
         @@ -5,12 +5,8 @@ require 'seafoam' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            # This is the 'bgv2isabelle' command line entry point.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            begin
         
     | 
| 
       8 
     | 
    
         
            -
              # Load configuraiton.
         
     | 
| 
       9 
     | 
    
         
            -
              config = Seafoam::Config.new
         
     | 
| 
       10 
     | 
    
         
            -
              config.load_config
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
8 
     | 
    
         
             
              # Run the command line.
         
     | 
| 
       13 
     | 
    
         
            -
              commands = Seafoam::Commands.new($stdout 
     | 
| 
      
 9 
     | 
    
         
            +
              commands = Seafoam::Commands.new($stdout)
         
     | 
| 
       14 
10 
     | 
    
         
             
              commands.bgv2isabelle(*ARGV)
         
     | 
| 
       15 
11 
     | 
    
         
             
            rescue StandardError => e
         
     | 
| 
       16 
12 
     | 
    
         
             
              if $DEBUG
         
     | 
    
        data/bin/bgv2json
    CHANGED
    
    | 
         @@ -5,12 +5,8 @@ require 'seafoam' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            # This is the 'bgv2json' command line entry point.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            begin
         
     | 
| 
       8 
     | 
    
         
            -
              # Load configuraiton.
         
     | 
| 
       9 
     | 
    
         
            -
              config = Seafoam::Config.new
         
     | 
| 
       10 
     | 
    
         
            -
              config.load_config
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
8 
     | 
    
         
             
              # Run the command line.
         
     | 
| 
       13 
     | 
    
         
            -
              commands = Seafoam::Commands.new($stdout 
     | 
| 
      
 9 
     | 
    
         
            +
              commands = Seafoam::Commands.new($stdout)
         
     | 
| 
       14 
10 
     | 
    
         
             
              commands.bgv2json(*ARGV)
         
     | 
| 
       15 
11 
     | 
    
         
             
            rescue StandardError => e
         
     | 
| 
       16 
12 
     | 
    
         
             
              if $DEBUG
         
     | 
    
        data/bin/cfg2asm
    CHANGED
    
    | 
         @@ -5,12 +5,8 @@ require 'seafoam' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            # This is the 'cfg2asm' command line entry point.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            begin
         
     | 
| 
       8 
     | 
    
         
            -
              # Load configuraiton.
         
     | 
| 
       9 
     | 
    
         
            -
              config = Seafoam::Config.new
         
     | 
| 
       10 
     | 
    
         
            -
              config.load_config
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
8 
     | 
    
         
             
              # Run the command line.
         
     | 
| 
       13 
     | 
    
         
            -
              commands = Seafoam::Commands.new($stdout 
     | 
| 
      
 9 
     | 
    
         
            +
              commands = Seafoam::Commands.new($stdout)
         
     | 
| 
       14 
10 
     | 
    
         
             
              commands.cfg2asm(*ARGV)
         
     | 
| 
       15 
11 
     | 
    
         
             
            rescue StandardError => e
         
     | 
| 
       16 
12 
     | 
    
         
             
              if $DEBUG
         
     | 
    
        data/bin/seafoam
    CHANGED
    
    | 
         @@ -5,12 +5,8 @@ require 'seafoam' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            # This is the 'seafoam' command line entry point.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            begin
         
     | 
| 
       8 
     | 
    
         
            -
              # Load configuraiton.
         
     | 
| 
       9 
     | 
    
         
            -
              config = Seafoam::Config.new
         
     | 
| 
       10 
     | 
    
         
            -
              config.load_config
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
8 
     | 
    
         
             
              # Run the command line.
         
     | 
| 
       13 
     | 
    
         
            -
              commands = Seafoam::Commands.new($stdout 
     | 
| 
      
 9 
     | 
    
         
            +
              commands = Seafoam::Commands.new($stdout)
         
     | 
| 
       14 
10 
     | 
    
         
             
              commands.seafoam(*ARGV)
         
     | 
| 
       15 
11 
     | 
    
         
             
            rescue StandardError => e
         
     | 
| 
       16 
12 
     | 
    
         
             
              if $DEBUG
         
     | 
| 
         @@ -127,13 +127,21 @@ module Seafoam 
     | 
|
| 
       127 
127 
     | 
    
         
             
                        end
         
     | 
| 
       128 
128 
     | 
    
         
             
                      end
         
     | 
| 
       129 
129 
     | 
    
         
             
                    end
         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                    # Read block information.
         
     | 
| 
      
 132 
     | 
    
         
            +
                    @reader.read_sint32.times do
         
     | 
| 
      
 133 
     | 
    
         
            +
                      block_id = @reader.read_sint32
         
     | 
| 
      
 134 
     | 
    
         
            +
                      block_nodes = @reader.read_sint32.times.map { @reader.read_sint32 }
         
     | 
| 
      
 135 
     | 
    
         
            +
                      # Followers aren't used but could be.
         
     | 
| 
      
 136 
     | 
    
         
            +
                      @reader.read_sint32.times.map { @reader.read_sint32 }
         
     | 
| 
      
 137 
     | 
    
         
            +
                      graph.create_block block_id, block_nodes
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
       131 
139 
     | 
    
         
             
                    graph
         
     | 
| 
       132 
140 
     | 
    
         
             
                  end
         
     | 
| 
       133 
141 
     | 
    
         | 
| 
       134 
142 
     | 
    
         
             
                  # Skip over a graph, having read or skipped its headers.
         
     | 
| 
       135 
143 
     | 
    
         
             
                  def skip_graph
         
     | 
| 
       136 
     | 
    
         
            -
                    # Already read BEGIN_GRAPH, id, format, args, and props
         
     | 
| 
      
 144 
     | 
    
         
            +
                    # Already read BEGIN_GRAPH, id, format, args, and props.
         
     | 
| 
       137 
145 
     | 
    
         
             
                    @reader.read_sint32.times do
         
     | 
| 
       138 
146 
     | 
    
         
             
                      @reader.skip_int32
         
     | 
| 
       139 
147 
     | 
    
         
             
                      node_class = read_pool_object
         
     | 
    
        data/lib/seafoam/commands.rb
    CHANGED
    
    | 
         @@ -1,11 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'json'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'set'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Seafoam
         
     | 
| 
       4 
5 
     | 
    
         
             
              # Implementations of the command-line commands that you can run in Seafoam.
         
     | 
| 
       5 
6 
     | 
    
         
             
              class Commands
         
     | 
| 
       6 
     | 
    
         
            -
                def initialize(out 
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(out)
         
     | 
| 
       7 
8 
     | 
    
         
             
                  @out = out
         
     | 
| 
       8 
     | 
    
         
            -
                  @config = config
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
                # Run the general seafoam command.
         
     | 
| 
         @@ -15,24 +15,7 @@ module Seafoam 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  when nil, 'help', '-h', '--help', '-help'
         
     | 
| 
       16 
16 
     | 
    
         
             
                    raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                     
     | 
| 
       19 
     | 
    
         
            -
                    @out.puts '        file.bgv list'
         
     | 
| 
       20 
     | 
    
         
            -
                    @out.puts '        file.bgv[:graph][:node[-edge]] search term...'
         
     | 
| 
       21 
     | 
    
         
            -
                    @out.puts '        file.bgv[:graph][:node[-edge]] edges'
         
     | 
| 
       22 
     | 
    
         
            -
                    @out.puts '        file.bgv[:graph][:node[-edge]] props'
         
     | 
| 
       23 
     | 
    
         
            -
                    @out.puts '        file.bgv:graph:node source'
         
     | 
| 
       24 
     | 
    
         
            -
                    @out.puts '        file.bgv:graph render'
         
     | 
| 
       25 
     | 
    
         
            -
                    @out.puts '              --spotlight n,n,n...'
         
     | 
| 
       26 
     | 
    
         
            -
                    @out.puts '              --out graph.pdf'
         
     | 
| 
       27 
     | 
    
         
            -
                    @out.puts '                    graph.svg'
         
     | 
| 
       28 
     | 
    
         
            -
                    @out.puts '                    graph.png'
         
     | 
| 
       29 
     | 
    
         
            -
                    @out.puts '                    graph.dot'
         
     | 
| 
       30 
     | 
    
         
            -
                    @out.puts '               --show-frame-state'
         
     | 
| 
       31 
     | 
    
         
            -
                    @out.puts '               --hide-floating'
         
     | 
| 
       32 
     | 
    
         
            -
                    @out.puts '               --no-reduce-edges'
         
     | 
| 
       33 
     | 
    
         
            -
                    @out.puts '               --option key value'
         
     | 
| 
       34 
     | 
    
         
            -
                    @out.puts '        --help'
         
     | 
| 
       35 
     | 
    
         
            -
                    @out.puts '        --version'
         
     | 
| 
      
 18 
     | 
    
         
            +
                    help(*args)
         
     | 
| 
       36 
19 
     | 
    
         
             
                  when 'version', '-v', '-version', '--version'
         
     | 
| 
       37 
20 
     | 
    
         
             
                    version(*args)
         
     | 
| 
       38 
21 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -57,6 +40,8 @@ module Seafoam 
     | 
|
| 
       57 
40 
     | 
    
         
             
                      render name, *args
         
     | 
| 
       58 
41 
     | 
    
         
             
                    when 'debug'
         
     | 
| 
       59 
42 
     | 
    
         
             
                      debug name, *args
         
     | 
| 
      
 43 
     | 
    
         
            +
                    when 'describe'
         
     | 
| 
      
 44 
     | 
    
         
            +
                      describe name, *args
         
     | 
| 
       60 
45 
     | 
    
         
             
                    else
         
     | 
| 
       61 
46 
     | 
    
         
             
                      raise ArgumentError, "unknown command #{command}"
         
     | 
| 
       62 
47 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -262,7 +247,7 @@ module Seafoam 
     | 
|
| 
       262 
247 
     | 
    
         
             
                end
         
     | 
| 
       263 
248 
     | 
    
         | 
| 
       264 
249 
     | 
    
         
             
                def search_object(tag, object, terms)
         
     | 
| 
       265 
     | 
    
         
            -
                  full_text = JSON.generate(object)
         
     | 
| 
      
 250 
     | 
    
         
            +
                  full_text = JSON.generate(JSONWriter.prepare_json(object))
         
     | 
| 
       266 
251 
     | 
    
         
             
                  full_text_down = full_text.downcase
         
     | 
| 
       267 
252 
     | 
    
         
             
                  start = 0
         
     | 
| 
       268 
253 
     | 
    
         
             
                  terms.each do |t|
         
     | 
| 
         @@ -298,7 +283,7 @@ module Seafoam 
     | 
|
| 
       298 
283 
     | 
    
         
             
                    parser.read_graph_header
         
     | 
| 
       299 
284 
     | 
    
         
             
                    graph = parser.read_graph
         
     | 
| 
       300 
285 
     | 
    
         
             
                    if node_id
         
     | 
| 
       301 
     | 
    
         
            -
                       
     | 
| 
      
 286 
     | 
    
         
            +
                      Passes.apply graph
         
     | 
| 
       302 
287 
     | 
    
         
             
                      node = graph.nodes[node_id]
         
     | 
| 
       303 
288 
     | 
    
         
             
                      raise ArgumentError, 'node not found' unless node
         
     | 
| 
       304 
289 
     | 
    
         | 
| 
         @@ -391,14 +376,66 @@ module Seafoam 
     | 
|
| 
       391 
376 
     | 
    
         
             
                  end
         
     | 
| 
       392 
377 
     | 
    
         
             
                end
         
     | 
| 
       393 
378 
     | 
    
         | 
| 
      
 379 
     | 
    
         
            +
                # seafoam file.bgv:n describe
         
     | 
| 
      
 380 
     | 
    
         
            +
                def describe(name, *args)
         
     | 
| 
      
 381 
     | 
    
         
            +
                  file, graph_index, *rest = parse_name(name)
         
     | 
| 
      
 382 
     | 
    
         
            +
             
     | 
| 
      
 383 
     | 
    
         
            +
                  if graph_index.nil? || !rest.all?(&:nil?)
         
     | 
| 
      
 384 
     | 
    
         
            +
                    raise ArgumentError, 'describe only works with a graph'
         
     | 
| 
      
 385 
     | 
    
         
            +
                  end
         
     | 
| 
      
 386 
     | 
    
         
            +
                  raise ArgumentError, 'describe does not take arguments' unless args.empty?
         
     | 
| 
      
 387 
     | 
    
         
            +
             
     | 
| 
      
 388 
     | 
    
         
            +
                  parser = BGV::BGVParser.new(file)
         
     | 
| 
      
 389 
     | 
    
         
            +
                  parser.read_file_header
         
     | 
| 
      
 390 
     | 
    
         
            +
                  parser.skip_document_props
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 393 
     | 
    
         
            +
                    index, = parser.read_graph_preheader
         
     | 
| 
      
 394 
     | 
    
         
            +
                    break unless index
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
                    parser.skip_graph_header
         
     | 
| 
      
 397 
     | 
    
         
            +
             
     | 
| 
      
 398 
     | 
    
         
            +
                    if index != graph_index
         
     | 
| 
      
 399 
     | 
    
         
            +
                      parser.skip_graph
         
     | 
| 
      
 400 
     | 
    
         
            +
                      next
         
     | 
| 
      
 401 
     | 
    
         
            +
                    end
         
     | 
| 
      
 402 
     | 
    
         
            +
             
     | 
| 
      
 403 
     | 
    
         
            +
                    graph = parser.read_graph
         
     | 
| 
      
 404 
     | 
    
         
            +
                    notes = Set.new
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
                    graph.nodes.each_value do |node|
         
     | 
| 
      
 407 
     | 
    
         
            +
                      node_class = node.props.dig(:node_class, :node_class)
         
     | 
| 
      
 408 
     | 
    
         
            +
                      case node_class
         
     | 
| 
      
 409 
     | 
    
         
            +
                      when 'org.graalvm.compiler.nodes.IfNode'
         
     | 
| 
      
 410 
     | 
    
         
            +
                        notes.add 'branches'
         
     | 
| 
      
 411 
     | 
    
         
            +
                      when 'org.graalvm.compiler.nodes.LoopBeginNode'
         
     | 
| 
      
 412 
     | 
    
         
            +
                        notes.add 'loops'
         
     | 
| 
      
 413 
     | 
    
         
            +
                      when 'org.graalvm.compiler.nodes.InvokeNode', 'org.graalvm.compiler.nodes.InvokeWithExceptionNode'
         
     | 
| 
      
 414 
     | 
    
         
            +
                        notes.add 'calls'
         
     | 
| 
      
 415 
     | 
    
         
            +
                      end
         
     | 
| 
      
 416 
     | 
    
         
            +
                    end
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
      
 418 
     | 
    
         
            +
                    notes.add 'deopts' if graph.nodes[0].outputs.map(&:to)
         
     | 
| 
      
 419 
     | 
    
         
            +
                                               .all? { |t| t.props.dig(:node_class, :node_class) == 'org.graalvm.compiler.nodes.DeoptimizeNode' }
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
                    notes.add 'linear' unless notes.include?('branches') || notes.include?('loops')
         
     | 
| 
      
 422 
     | 
    
         
            +
             
     | 
| 
      
 423 
     | 
    
         
            +
                    @out.puts ["#{graph.nodes.size} nodes", *notes].join(', ')
         
     | 
| 
      
 424 
     | 
    
         
            +
             
     | 
| 
      
 425 
     | 
    
         
            +
                    break
         
     | 
| 
      
 426 
     | 
    
         
            +
                  end
         
     | 
| 
      
 427 
     | 
    
         
            +
                end
         
     | 
| 
      
 428 
     | 
    
         
            +
             
     | 
| 
       394 
429 
     | 
    
         
             
                # seafoam file.bgv:n render options...
         
     | 
| 
       395 
430 
     | 
    
         
             
                def render(name, *args)
         
     | 
| 
       396 
431 
     | 
    
         
             
                  file, graph_index, *rest = parse_name(name)
         
     | 
| 
       397 
432 
     | 
    
         
             
                  raise ArgumentError, 'render needs at least a graph' unless graph_index
         
     | 
| 
       398 
433 
     | 
    
         
             
                  raise ArgumentError, 'render only works with a graph' unless rest == [nil, nil]
         
     | 
| 
       399 
434 
     | 
    
         | 
| 
       400 
     | 
    
         
            -
                   
     | 
| 
      
 435 
     | 
    
         
            +
                  pass_options = {
         
     | 
| 
      
 436 
     | 
    
         
            +
                    simplify_truffle_args: true,
         
     | 
| 
       401 
437 
     | 
    
         
             
                    hide_frame_state: true,
         
     | 
| 
      
 438 
     | 
    
         
            +
                    hide_pi: true,
         
     | 
| 
       402 
439 
     | 
    
         
             
                    hide_floating: false,
         
     | 
| 
       403 
440 
     | 
    
         
             
                    reduce_edges: true
         
     | 
| 
       404 
441 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -406,6 +443,7 @@ module Seafoam 
     | 
|
| 
       406 
443 
     | 
    
         
             
                  args = args.dup
         
     | 
| 
       407 
444 
     | 
    
         
             
                  out_file = nil
         
     | 
| 
       408 
445 
     | 
    
         
             
                  explicit_out_file = false
         
     | 
| 
      
 446 
     | 
    
         
            +
                  draw_blocks = false
         
     | 
| 
       409 
447 
     | 
    
         
             
                  until args.empty?
         
     | 
| 
       410 
448 
     | 
    
         
             
                    arg = args.shift
         
     | 
| 
       411 
449 
     | 
    
         
             
                    case arg
         
     | 
| 
         @@ -418,12 +456,18 @@ module Seafoam 
     | 
|
| 
       418 
456 
     | 
    
         
             
                      raise ArgumentError, 'no list for --spotlight' unless spotlight_arg
         
     | 
| 
       419 
457 
     | 
    
         | 
| 
       420 
458 
     | 
    
         
             
                      spotlight_nodes = spotlight_arg.split(',').map { |n| Integer(n) }
         
     | 
| 
      
 459 
     | 
    
         
            +
                    when '--full-truffle-args'
         
     | 
| 
      
 460 
     | 
    
         
            +
                      pass_options[:simplify_truffle_args] = false
         
     | 
| 
       421 
461 
     | 
    
         
             
                    when '--show-frame-state'
         
     | 
| 
       422 
     | 
    
         
            -
                       
     | 
| 
      
 462 
     | 
    
         
            +
                      pass_options[:hide_frame_state] = false
         
     | 
| 
      
 463 
     | 
    
         
            +
                    when '--show-pi'
         
     | 
| 
      
 464 
     | 
    
         
            +
                      pass_options[:hide_pi] = false
         
     | 
| 
       423 
465 
     | 
    
         
             
                    when '--hide-floating'
         
     | 
| 
       424 
     | 
    
         
            -
                       
     | 
| 
      
 466 
     | 
    
         
            +
                      pass_options[:hide_floating] = true
         
     | 
| 
       425 
467 
     | 
    
         
             
                    when '--no-reduce-edges'
         
     | 
| 
       426 
     | 
    
         
            -
                       
     | 
| 
      
 468 
     | 
    
         
            +
                      pass_options[:reduce_edges] = false
         
     | 
| 
      
 469 
     | 
    
         
            +
                    when '--draw-blocks'
         
     | 
| 
      
 470 
     | 
    
         
            +
                      draw_blocks = true
         
     | 
| 
       427 
471 
     | 
    
         
             
                    when '--option'
         
     | 
| 
       428 
472 
     | 
    
         
             
                      key = args.shift
         
     | 
| 
       429 
473 
     | 
    
         
             
                      raise ArgumentError, 'no key for --option' unless key
         
     | 
| 
         @@ -432,7 +476,7 @@ module Seafoam 
     | 
|
| 
       432 
476 
     | 
    
         
             
                      raise ArgumentError, "no value for --option #{key}" unless out_file
         
     | 
| 
       433 
477 
     | 
    
         | 
| 
       434 
478 
     | 
    
         
             
                      value = { 'true' => true, 'false' => 'false' }.fetch(key, value)
         
     | 
| 
       435 
     | 
    
         
            -
                       
     | 
| 
      
 479 
     | 
    
         
            +
                      pass_options[key.to_sym] = value
         
     | 
| 
       436 
480 
     | 
    
         
             
                    else
         
     | 
| 
       437 
481 
     | 
    
         
             
                      raise ArgumentError, "unexpected option #{arg}"
         
     | 
| 
       438 
482 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -455,7 +499,7 @@ module Seafoam 
     | 
|
| 
       455 
499 
     | 
    
         
             
                  with_graph(file, graph_index) do |parser|
         
     | 
| 
       456 
500 
     | 
    
         
             
                    parser.skip_graph_header
         
     | 
| 
       457 
501 
     | 
    
         
             
                    graph = parser.read_graph
         
     | 
| 
       458 
     | 
    
         
            -
                     
     | 
| 
      
 502 
     | 
    
         
            +
                    Passes.apply graph, pass_options
         
     | 
| 
       459 
503 
     | 
    
         
             
                    if spotlight_nodes
         
     | 
| 
       460 
504 
     | 
    
         
             
                      spotlight = Spotlight.new(graph)
         
     | 
| 
       461 
505 
     | 
    
         
             
                      spotlight_nodes.each do |node_id|
         
     | 
| 
         @@ -469,14 +513,14 @@ module Seafoam 
     | 
|
| 
       469 
513 
     | 
    
         
             
                    if out_format == :dot
         
     | 
| 
       470 
514 
     | 
    
         
             
                      File.open(out_file, 'w') do |stream|
         
     | 
| 
       471 
515 
     | 
    
         
             
                        writer = GraphvizWriter.new(stream)
         
     | 
| 
       472 
     | 
    
         
            -
                        writer.write_graph graph
         
     | 
| 
      
 516 
     | 
    
         
            +
                        writer.write_graph graph, false, draw_blocks
         
     | 
| 
       473 
517 
     | 
    
         
             
                      end
         
     | 
| 
       474 
518 
     | 
    
         
             
                    else
         
     | 
| 
       475 
519 
     | 
    
         
             
                      begin
         
     | 
| 
       476 
520 
     | 
    
         
             
                        IO.popen(['dot', "-T#{out_format}", '-o', out_file], 'w') do |stream|
         
     | 
| 
       477 
521 
     | 
    
         
             
                          writer = GraphvizWriter.new(stream)
         
     | 
| 
       478 
522 
     | 
    
         
             
                          hidpi = out_format == :png
         
     | 
| 
       479 
     | 
    
         
            -
                          writer.write_graph graph, hidpi
         
     | 
| 
      
 523 
     | 
    
         
            +
                          writer.write_graph graph, hidpi, draw_blocks
         
     | 
| 
       480 
524 
     | 
    
         
             
                        end
         
     | 
| 
       481 
525 
     | 
    
         
             
                      rescue Errno::ENOENT
         
     | 
| 
       482 
526 
     | 
    
         
             
                        raise 'Could not run Graphviz - is it installed?'
         
     | 
| 
         @@ -565,6 +609,32 @@ module Seafoam 
     | 
|
| 
       565 
609 
     | 
    
         
             
                  raise ArgumentError, 'graph not found' unless graph_found
         
     | 
| 
       566 
610 
     | 
    
         
             
                end
         
     | 
| 
       567 
611 
     | 
    
         | 
| 
      
 612 
     | 
    
         
            +
                # Prints help.
         
     | 
| 
      
 613 
     | 
    
         
            +
                def help(*_args)
         
     | 
| 
      
 614 
     | 
    
         
            +
                  @out.puts 'seafoam file.bgv info'
         
     | 
| 
      
 615 
     | 
    
         
            +
                  @out.puts '        file.bgv list'
         
     | 
| 
      
 616 
     | 
    
         
            +
                  @out.puts '        file.bgv[:graph][:node[-edge]] search term...'
         
     | 
| 
      
 617 
     | 
    
         
            +
                  @out.puts '        file.bgv[:graph][:node[-edge]] edges'
         
     | 
| 
      
 618 
     | 
    
         
            +
                  @out.puts '        file.bgv[:graph][:node[-edge]] props'
         
     | 
| 
      
 619 
     | 
    
         
            +
                  @out.puts '        file.bgv:graph:node source'
         
     | 
| 
      
 620 
     | 
    
         
            +
                  @out.puts '        file.bgv:graph describe'
         
     | 
| 
      
 621 
     | 
    
         
            +
                  @out.puts '        file.bgv:graph render'
         
     | 
| 
      
 622 
     | 
    
         
            +
                  @out.puts '              --spotlight n,n,n...'
         
     | 
| 
      
 623 
     | 
    
         
            +
                  @out.puts '              --out graph.pdf'
         
     | 
| 
      
 624 
     | 
    
         
            +
                  @out.puts '                    graph.svg'
         
     | 
| 
      
 625 
     | 
    
         
            +
                  @out.puts '                    graph.png'
         
     | 
| 
      
 626 
     | 
    
         
            +
                  @out.puts '                    graph.dot'
         
     | 
| 
      
 627 
     | 
    
         
            +
                  @out.puts '               --full-truffle-args'
         
     | 
| 
      
 628 
     | 
    
         
            +
                  @out.puts '               --show-frame-state'
         
     | 
| 
      
 629 
     | 
    
         
            +
                  @out.puts '               --show-pi'
         
     | 
| 
      
 630 
     | 
    
         
            +
                  @out.puts '               --hide-floating'
         
     | 
| 
      
 631 
     | 
    
         
            +
                  @out.puts '               --no-reduce-edges'
         
     | 
| 
      
 632 
     | 
    
         
            +
                  @out.puts '               --draw-blocks'
         
     | 
| 
      
 633 
     | 
    
         
            +
                  @out.puts '               --option key value'
         
     | 
| 
      
 634 
     | 
    
         
            +
                  @out.puts '        --help'
         
     | 
| 
      
 635 
     | 
    
         
            +
                  @out.puts '        --version'
         
     | 
| 
      
 636 
     | 
    
         
            +
                end
         
     | 
| 
      
 637 
     | 
    
         
            +
             
     | 
| 
       568 
638 
     | 
    
         
             
                # Prints the version.
         
     | 
| 
       569 
639 
     | 
    
         
             
                def version(*args)
         
     | 
| 
       570 
640 
     | 
    
         
             
                  raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
         
     | 
| 
         @@ -598,10 +668,15 @@ module Seafoam 
     | 
|
| 
       598 
668 
     | 
    
         | 
| 
       599 
669 
     | 
    
         
             
                # Open a file for the user if possible.
         
     | 
| 
       600 
670 
     | 
    
         
             
                def autoopen(file)
         
     | 
| 
       601 
     | 
    
         
            -
                   
     | 
| 
      
 671 
     | 
    
         
            +
                  return unless @out.tty?
         
     | 
| 
      
 672 
     | 
    
         
            +
             
     | 
| 
      
 673 
     | 
    
         
            +
                  case RUBY_PLATFORM
         
     | 
| 
      
 674 
     | 
    
         
            +
                  when /darwin/
         
     | 
| 
       602 
675 
     | 
    
         
             
                    system 'open', file
         
     | 
| 
       603 
     | 
    
         
            -
             
     | 
| 
      
 676 
     | 
    
         
            +
                  when /linux/
         
     | 
| 
      
 677 
     | 
    
         
            +
                    system 'xdg-open', file
         
     | 
| 
       604 
678 
     | 
    
         
             
                  end
         
     | 
| 
      
 679 
     | 
    
         
            +
                  # Don't worry if it fails.
         
     | 
| 
       605 
680 
     | 
    
         
             
                end
         
     | 
| 
       606 
681 
     | 
    
         
             
              end
         
     | 
| 
       607 
682 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Seafoam
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Graal
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Routines for understanding pi nodes in Graal.
         
     | 
| 
      
 4 
     | 
    
         
            +
                module Pi
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # Find the actual value behind potentially a chain of pi nodes.
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def self.follow_pi_object(node)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    node = node.edges.find { |edge| edge.props[:name] == 'object' }.from while PI_NODES.include?(node.props.dig(:node_class, :node_class))
         
     | 
| 
      
 8 
     | 
    
         
            +
                    node
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  # Pi nodes add type information.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  PI_NODES = [
         
     | 
| 
      
 13 
     | 
    
         
            +
                    'org.graalvm.compiler.nodes.PiNode',
         
     | 
| 
      
 14 
     | 
    
         
            +
                    'org.graalvm.compiler.nodes.PiArrayNode'
         
     | 
| 
      
 15 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/seafoam/graph.rb
    CHANGED
    
    | 
         @@ -2,12 +2,14 @@ module Seafoam 
     | 
|
| 
       2 
2 
     | 
    
         
             
              # A graph, with properties, nodes, and edges. We don't encapsulate the graph
         
     | 
| 
       3 
3 
     | 
    
         
             
              # too much - be careful.
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Graph
         
     | 
| 
       5 
     | 
    
         
            -
                attr_reader :props, :nodes, :edges
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :props, :nodes, :edges, :blocks, :new_id
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                def initialize(props = nil)
         
     | 
| 
       8 
8 
     | 
    
         
             
                  @props = props || {}
         
     | 
| 
       9 
9 
     | 
    
         
             
                  @nodes = {}
         
     | 
| 
       10 
10 
     | 
    
         
             
                  @edges = []
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @blocks = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @new_id = 0
         
     | 
| 
       11 
13 
     | 
    
         
             
                end
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
       13 
15 
     | 
    
         
             
                # Create a node.
         
     | 
| 
         @@ -15,6 +17,7 @@ module Seafoam 
     | 
|
| 
       15 
17 
     | 
    
         
             
                  props ||= {}
         
     | 
| 
       16 
18 
     | 
    
         
             
                  node = Node.new(id, props)
         
     | 
| 
       17 
19 
     | 
    
         
             
                  @nodes[id] = node
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @new_id = id + 1
         
     | 
| 
       18 
21 
     | 
    
         
             
                  node
         
     | 
| 
       19 
22 
     | 
    
         
             
                end
         
     | 
| 
       20 
23 
     | 
    
         | 
| 
         @@ -27,6 +30,20 @@ module Seafoam 
     | 
|
| 
       27 
30 
     | 
    
         
             
                  to.inputs.push edge
         
     | 
| 
       28 
31 
     | 
    
         
             
                  edge
         
     | 
| 
       29 
32 
     | 
    
         
             
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                # Add a new basic block with given id and node id list.
         
     | 
| 
      
 35 
     | 
    
         
            +
                def create_block(id, node_ids)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  nodes = node_ids.select { |n| @nodes.key? n }.map { |n| @nodes[n] }
         
     | 
| 
      
 37 
     | 
    
         
            +
                  block = Block.new(id, nodes)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @blocks.push block
         
     | 
| 
      
 39 
     | 
    
         
            +
                  block
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def remove_edge(edge)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  edge.from.outputs.delete edge
         
     | 
| 
      
 44 
     | 
    
         
            +
                  edge.to.inputs.delete edge
         
     | 
| 
      
 45 
     | 
    
         
            +
                  edges.delete edge
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
       30 
47 
     | 
    
         
             
              end
         
     | 
| 
       31 
48 
     | 
    
         | 
| 
       32 
49 
     | 
    
         
             
              # A node, with properties, input edges, and output edges.
         
     | 
| 
         @@ -88,4 +105,19 @@ module Seafoam 
     | 
|
| 
       88 
105 
     | 
    
         
             
                  "<Edge #{from.id} -> #{to.id}>"
         
     | 
| 
       89 
106 
     | 
    
         
             
                end
         
     | 
| 
       90 
107 
     | 
    
         
             
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
              # A control-flow basic block
         
     | 
| 
      
 110 
     | 
    
         
            +
              class Block
         
     | 
| 
      
 111 
     | 
    
         
            +
                attr_reader :id, :nodes
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def initialize(id, nodes)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @id = id
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @nodes = nodes
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # Inspect.
         
     | 
| 
      
 119 
     | 
    
         
            +
                def inspect
         
     | 
| 
      
 120 
     | 
    
         
            +
                  "<Block #{id}>"
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
              end
         
     | 
| 
       91 
123 
     | 
    
         
             
            end
         
     | 
| 
         @@ -7,15 +7,16 @@ module Seafoam 
     | 
|
| 
       7 
7 
     | 
    
         
             
                end
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                # Write a graph.
         
     | 
| 
       10 
     | 
    
         
            -
                def write_graph(graph, hidpi = false)
         
     | 
| 
      
 10 
     | 
    
         
            +
                def write_graph(graph, hidpi = false, draw_blocks = false)
         
     | 
| 
       11 
11 
     | 
    
         
             
                  inline_attrs = {}
         
     | 
| 
       12 
12 
     | 
    
         
             
                  attrs = {}
         
     | 
| 
       13 
13 
     | 
    
         
             
                  attrs[:dpi] = 200 if hidpi
         
     | 
| 
       14 
     | 
    
         
            -
                  attrs[:bgcolor] = ' 
     | 
| 
      
 14 
     | 
    
         
            +
                  attrs[:bgcolor] = 'white'
         
     | 
| 
       15 
15 
     | 
    
         
             
                  @stream.puts 'digraph G {'
         
     | 
| 
       16 
16 
     | 
    
         
             
                  @stream.puts "  graph #{write_attrs(attrs)};"
         
     | 
| 
       17 
17 
     | 
    
         
             
                  write_nodes inline_attrs, graph
         
     | 
| 
       18 
18 
     | 
    
         
             
                  write_edges inline_attrs, graph
         
     | 
| 
      
 19 
     | 
    
         
            +
                  write_blocks graph if draw_blocks
         
     | 
| 
       19 
20 
     | 
    
         
             
                  @stream.puts '}'
         
     | 
| 
       20 
21 
     | 
    
         
             
                end
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
         @@ -99,6 +100,9 @@ module Seafoam 
     | 
|
| 
       99 
100 
     | 
    
         
             
                    # from a shaded node.
         
     | 
| 
       100 
101 
     | 
    
         
             
                    next if edge.to.props[:hidden] && edge.from.props[:spotlight] != 'shaded'
         
     | 
| 
       101 
102 
     | 
    
         | 
| 
      
 103 
     | 
    
         
            +
                    # Skip the edge if it's hidden itself
         
     | 
| 
      
 104 
     | 
    
         
            +
                    next if edge.props[:hidden]
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
       102 
106 
     | 
    
         
             
                    write_edge inline_attrs, edge
         
     | 
| 
       103 
107 
     | 
    
         
             
                  end
         
     | 
| 
       104 
108 
     | 
    
         
             
                end
         
     | 
| 
         @@ -166,6 +170,24 @@ module Seafoam 
     | 
|
| 
       166 
170 
     | 
    
         
             
                  end
         
     | 
| 
       167 
171 
     | 
    
         
             
                end
         
     | 
| 
       168 
172 
     | 
    
         | 
| 
      
 173 
     | 
    
         
            +
                # Write basic block outlines.
         
     | 
| 
      
 174 
     | 
    
         
            +
                def write_blocks(graph)
         
     | 
| 
      
 175 
     | 
    
         
            +
                  graph.blocks.each do |block|
         
     | 
| 
      
 176 
     | 
    
         
            +
                    @stream.puts "  subgraph cluster_block#{block.id} {"
         
     | 
| 
      
 177 
     | 
    
         
            +
                    @stream.puts '    fontname = "Arial";'
         
     | 
| 
      
 178 
     | 
    
         
            +
                    @stream.puts "    label = \"B#{block.id}\";"
         
     | 
| 
      
 179 
     | 
    
         
            +
                    @stream.puts '    style=dotted;'
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                    block.nodes.each do |node|
         
     | 
| 
      
 182 
     | 
    
         
            +
                      next if node.props[:hidden] || node.props[:inlined]
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                      @stream.puts "    node#{node.id};"
         
     | 
| 
      
 185 
     | 
    
         
            +
                    end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                    @stream.puts '  }'
         
     | 
| 
      
 188 
     | 
    
         
            +
                  end
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
       169 
191 
     | 
    
         
             
                # Return attributes for a node or edge modified to 'shade' them in terms
         
     | 
| 
       170 
192 
     | 
    
         
             
                # the spotlight functionality - so basically make them light grey.
         
     | 
| 
       171 
193 
     | 
    
         
             
                def shade(attrs)
         
     | 
    
        data/lib/seafoam/json_writer.rb
    CHANGED
    
    
| 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Seafoam
         
     | 
| 
       2 
     | 
    
         
            -
              module  
     | 
| 
       3 
     | 
    
         
            -
                # The fallback  
     | 
| 
      
 2 
     | 
    
         
            +
              module Passes
         
     | 
| 
      
 3 
     | 
    
         
            +
                # The fallback pass always applies, and adds some basic properties.
         
     | 
| 
       4 
4 
     | 
    
         
             
                # Works for example with Truffle AST and call graphs, but also means anyone
         
     | 
| 
       5 
5 
     | 
    
         
             
                # can emit a graph with 'label' properties and we can do something useful
         
     | 
| 
       6 
6 
     | 
    
         
             
                # with it.
         
     | 
| 
       7 
     | 
    
         
            -
                class  
     | 
| 
      
 7 
     | 
    
         
            +
                class FallbackPass < Pass
         
     | 
| 
       8 
8 
     | 
    
         
             
                  def self.applies?(_graph)
         
     | 
| 
       9 
9 
     | 
    
         
             
                    true
         
     | 
| 
       10 
10 
     | 
    
         
             
                  end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  def  
     | 
| 
      
 12 
     | 
    
         
            +
                  def apply(graph)
         
     | 
| 
       13 
13 
     | 
    
         
             
                    graph.nodes.each_value do |node|
         
     | 
| 
       14 
14 
     | 
    
         
             
                      if node.props[:label].nil? && node.props['label']
         
     | 
| 
       15 
15 
     | 
    
         
             
                        node.props[:label] = node.props['label']
         
     | 
| 
         @@ -1,18 +1,19 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Seafoam
         
     | 
| 
       2 
     | 
    
         
            -
              module  
     | 
| 
       3 
     | 
    
         
            -
                # The Graal  
     | 
| 
      
 2 
     | 
    
         
            +
              module Passes
         
     | 
| 
      
 3 
     | 
    
         
            +
                # The Graal pass applies if it looks like it was compiled by Graal or
         
     | 
| 
       4 
4 
     | 
    
         
             
                # Truffle.
         
     | 
| 
       5 
     | 
    
         
            -
                class  
     | 
| 
      
 5 
     | 
    
         
            +
                class GraalPass < Pass
         
     | 
| 
       6 
6 
     | 
    
         
             
                  def self.applies?(graph)
         
     | 
| 
       7 
7 
     | 
    
         
             
                    graph.props.values.any? do |v|
         
     | 
| 
       8 
8 
     | 
    
         
             
                      TRIGGERS.any? { |t| v.to_s.include?(t) }
         
     | 
| 
       9 
9 
     | 
    
         
             
                    end
         
     | 
| 
       10 
10 
     | 
    
         
             
                  end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                  def  
     | 
| 
       13 
     | 
    
         
            -
                     
     | 
| 
       14 
     | 
    
         
            -
                     
     | 
| 
      
 12 
     | 
    
         
            +
                  def apply(graph)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    apply_nodes graph
         
     | 
| 
      
 14 
     | 
    
         
            +
                    apply_edges graph
         
     | 
| 
       15 
15 
     | 
    
         
             
                    hide_frame_state graph if @options[:hide_frame_state]
         
     | 
| 
      
 16 
     | 
    
         
            +
                    hide_pi graph if @options[:hide_pi]
         
     | 
| 
       16 
17 
     | 
    
         
             
                    hide_floating graph if @options[:hide_floating]
         
     | 
| 
       17 
18 
     | 
    
         
             
                    reduce_edges graph if @options[:reduce_edges]
         
     | 
| 
       18 
19 
     | 
    
         
             
                    hide_unused_nodes graph
         
     | 
| 
         @@ -21,8 +22,10 @@ module Seafoam 
     | 
|
| 
       21 
22 
     | 
    
         
             
                  private
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
                  # Annotate nodes with their label and kind
         
     | 
| 
       24 
     | 
    
         
            -
                  def  
     | 
| 
      
 25 
     | 
    
         
            +
                  def apply_nodes(graph)
         
     | 
| 
       25 
26 
     | 
    
         
             
                    graph.nodes.each_value do |node|
         
     | 
| 
      
 27 
     | 
    
         
            +
                      next if node.props[:label]
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       26 
29 
     | 
    
         
             
                      # The Java class of the node.
         
     | 
| 
       27 
30 
     | 
    
         
             
                      node_class = node.props.dig(:node_class, :node_class)
         
     | 
| 
       28 
31 
     | 
    
         | 
| 
         @@ -93,6 +96,11 @@ module Seafoam 
     | 
|
| 
       93 
96 
     | 
    
         
             
                        name_template = 'π'
         
     | 
| 
       94 
97 
     | 
    
         
             
                      end
         
     | 
| 
       95 
98 
     | 
    
         | 
| 
      
 99 
     | 
    
         
            +
                      # Use a symbol for PiArrayNode.
         
     | 
| 
      
 100 
     | 
    
         
            +
                      if node_class == 'org.graalvm.compiler.nodes.PiArrayNode'
         
     | 
| 
      
 101 
     | 
    
         
            +
                        name_template = '[π]'
         
     | 
| 
      
 102 
     | 
    
         
            +
                      end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       96 
104 
     | 
    
         
             
                      # Use a symbol for PhiNode.
         
     | 
| 
       97 
105 
     | 
    
         
             
                      if node_class == 'org.graalvm.compiler.nodes.ValuePhiNode'
         
     | 
| 
       98 
106 
     | 
    
         
             
                        name_template = 'ϕ'
         
     | 
| 
         @@ -208,7 +216,7 @@ module Seafoam 
     | 
|
| 
       208 
216 
     | 
    
         
             
                  end
         
     | 
| 
       209 
217 
     | 
    
         | 
| 
       210 
218 
     | 
    
         
             
                  # Annotate edges with their label and kind.
         
     | 
| 
       211 
     | 
    
         
            -
                  def  
     | 
| 
      
 219 
     | 
    
         
            +
                  def apply_edges(graph)
         
     | 
| 
       212 
220 
     | 
    
         
             
                    graph.edges.each do |edge|
         
     | 
| 
       213 
221 
     | 
    
         
             
                      if edge.to.props.dig(:node_class, :node_class) == 'org.graalvm.compiler.nodes.ValuePhiNode' && edge.props[:name] == 'values'
         
     | 
| 
       214 
222 
     | 
    
         
             
                        merge_node = edge.to.edges.find { |e| e.props[:name] == 'merge' }.from
         
     | 
| 
         @@ -254,8 +262,6 @@ module Seafoam 
     | 
|
| 
       254 
262 
     | 
    
         
             
                      # loopBegin edges point from LoopEndNode (continue) and LoopExitNode
         
     | 
| 
       255 
263 
     | 
    
         
             
                      # (break) to the LoopBeginNode. Both are drawn reversed.
         
     | 
| 
       256 
264 
     | 
    
         
             
                      when 'loopBegin'
         
     | 
| 
       257 
     | 
    
         
            -
                        edge.props[:hidden] = true
         
     | 
| 
       258 
     | 
    
         
            -
             
     | 
| 
       259 
265 
     | 
    
         
             
                        case edge.to.props.dig(:node_class, :node_class)
         
     | 
| 
       260 
266 
     | 
    
         
             
                        when 'org.graalvm.compiler.nodes.LoopEndNode'
         
     | 
| 
       261 
267 
     | 
    
         
             
                          # If it's from the LoopEnd then it's the control edge to follow.
         
     | 
| 
         @@ -311,6 +317,24 @@ module Seafoam 
     | 
|
| 
       311 
317 
     | 
    
         
             
                    end
         
     | 
| 
       312 
318 
     | 
    
         
             
                  end
         
     | 
| 
       313 
319 
     | 
    
         | 
| 
      
 320 
     | 
    
         
            +
                  # Hide pi nodes - they add information for optimisation, but not generally
         
     | 
| 
      
 321 
     | 
    
         
            +
                  # useful day-to-day for understanding the graph. Connect the user to the
         
     | 
| 
      
 322 
     | 
    
         
            +
                  # actual object, which may be several steps away.
         
     | 
| 
      
 323 
     | 
    
         
            +
                  def hide_pi(graph)
         
     | 
| 
      
 324 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 325 
     | 
    
         
            +
                      umodified = true
         
     | 
| 
      
 326 
     | 
    
         
            +
                      graph.edges.each do |edge|
         
     | 
| 
      
 327 
     | 
    
         
            +
                        next unless Graal::Pi::PI_NODES.include?(edge.from.props.dig(:node_class, :node_class))
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
                        object = Graal::Pi.follow_pi_object(edge.from)
         
     | 
| 
      
 330 
     | 
    
         
            +
                        graph.create_edge object, edge.to, edge.props.merge({ synthetic: true })
         
     | 
| 
      
 331 
     | 
    
         
            +
                        graph.remove_edge edge
         
     | 
| 
      
 332 
     | 
    
         
            +
                        umodified = false
         
     | 
| 
      
 333 
     | 
    
         
            +
                      end
         
     | 
| 
      
 334 
     | 
    
         
            +
                      break if umodified
         
     | 
| 
      
 335 
     | 
    
         
            +
                    end
         
     | 
| 
      
 336 
     | 
    
         
            +
                  end
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
       314 
338 
     | 
    
         
             
                  # Hide floating nodes. This highlights just the control flow backbone.
         
     | 
| 
       315 
339 
     | 
    
         
             
                  def hide_floating(graph)
         
     | 
| 
       316 
340 
     | 
    
         
             
                    graph.nodes.each_value do |node|
         
     | 
| 
         @@ -332,15 +356,19 @@ module Seafoam 
     | 
|
| 
       332 
356 
     | 
    
         
             
                    end
         
     | 
| 
       333 
357 
     | 
    
         
             
                  end
         
     | 
| 
       334 
358 
     | 
    
         | 
| 
       335 
     | 
    
         
            -
                  # Hide nodes that have no non-hidden users and no control flow 
     | 
| 
       336 
     | 
    
         
            -
                  # would display as a node floating unconnected to the rest of 
     | 
| 
       337 
     | 
    
         
            -
                  # otherwise. An exception is made for node with an anchor edge 
     | 
| 
       338 
     | 
    
         
            -
                  # as some guards are anchored like this.
         
     | 
| 
      
 359 
     | 
    
         
            +
                  # Hide nodes that have no non-hidden users or edges and no control flow
         
     | 
| 
      
 360 
     | 
    
         
            +
                  # in. These would display as a node floating unconnected to the rest of
         
     | 
| 
      
 361 
     | 
    
         
            +
                  # the graph otherwise. An exception is made for node with an anchor edge
         
     | 
| 
      
 362 
     | 
    
         
            +
                  # coming in, as some guards are anchored like this.
         
     | 
| 
       339 
363 
     | 
    
         
             
                  def hide_unused_nodes(graph)
         
     | 
| 
       340 
364 
     | 
    
         
             
                    loop do
         
     | 
| 
       341 
365 
     | 
    
         
             
                      modified = false
         
     | 
| 
       342 
366 
     | 
    
         
             
                      graph.nodes.each_value do |node|
         
     | 
| 
       343 
     | 
    
         
            -
                         
     | 
| 
      
 367 
     | 
    
         
            +
                        # Call trees are like Graal graphs but don't have these edges -
         
     | 
| 
      
 368 
     | 
    
         
            +
                        # don't hide them.
         
     | 
| 
      
 369 
     | 
    
         
            +
                        next if node.props['truffleCallees']
         
     | 
| 
      
 370 
     | 
    
         
            +
             
     | 
| 
      
 371 
     | 
    
         
            +
                        next unless node.outputs.all? { |edge| edge.to.props[:hidden] || edge.props[:hidden] } &&
         
     | 
| 
       344 
372 
     | 
    
         
             
                                    node.inputs.none? { |edge| edge.props[:kind] == 'control' } &&
         
     | 
| 
       345 
373 
     | 
    
         
             
                                    node.inputs.none? { |edge| edge.props[:name] == 'anchor' }
         
     | 
| 
       346 
374 
     | 
    
         |