#   Copyright 2011 David Malcolm <dmalcolm@redhat.com>
#   Copyright 2011 Red Hat, Inc.
#
#   This is free software: you can redistribute it and/or modify it
#   under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful, but
#   WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see
#   <http://www.gnu.org/licenses/>.

# We use this script to regenerate docs/tables-of-passes.rst
import gcc
import sys
import six

from gccutils import Table

pass_prop_flags = ['PROP_gimple_any', 'PROP_gimple_lcf', 'PROP_gimple_leh',
                   'PROP_cfg', 'PROP_referenced_vars', 'PROP_ssa',
                   'PROP_no_crit_edges', 'PROP_rtl', 'PROP_gimple_lomp',
                   'PROP_cfglayout', 'PROP_gimple_lcx']
# PROP_referenced_vars went away in GCC 4.8 (in r190067)
if not hasattr(gcc, 'PROP_referenced_vars'):
    pass_prop_flags.remove('PROP_referenced_vars')

def pass_properties_to_str(bitfield):
    result = []

    for attrname in pass_prop_flags:
        flag = getattr(gcc, attrname)
        if bitfield & flag:
            result.append(attrname[5:]) # drop the 'PROP_'
    return ', '.join(result)

p_to_s = pass_properties_to_str

def foo(t, ps, indent):
    name = ps.name.replace('*', '\\*')
    t.add_row(('%s%s' % (six.u('> ') * indent, name),
               p_to_s(ps.properties_required),
               p_to_s(ps.properties_provided),
               p_to_s(ps.properties_destroyed)))
    if ps.sub:
        foo(t, ps.sub, indent + 1)
    if ps.next:
        foo(t, ps.next, indent)

print('.. This file is autogenerated, using:')
print('   ./gcc-with-python generate-tables-of-passes-rst.py test.c')
print
print("All of GCC's passes")
print("===================")
print
print('''
This diagram shows the various GCC optimization passes, arranged vertically,
showing child passes via indentation.

The lifetime of the various properties that they maintain is shown, giving
the pass that initially creates the data (if any), the pass that destroys it
(if any), and each pass that requires a particular property (based on the
PROP_* flags).

.. image:: passes.svg
   :width: 550px
   :height: 3302px
   :scale: 50%
''')
print("""
These tables contain the same information.  The diagram and tables were
autogenerated, using GCC %s""" % gcc.get_gcc_version().basever)
print
for rootname, reflabel, ps in zip(('The lowering passes',
                                   'The "small IPA" passes',
                                   'The "regular IPA" passes',
                                   'Passes generating Link-Time Optimization data',
                                   'The "all other passes" catch-all'),
                                  ('all_lowering_passes',
                                   'all_small_ipa_passes',
                                   'all_regular_ipa_passes',
                                   'all_lto_gen_passes',
                                   'all_passes'),
                                  gcc.Pass.get_roots()):
    print('.. _%s:' % reflabel)
    print
    print(rootname)
    print('-' * len(rootname))
    print

    t = Table(['Pass Name', 'Required properties', 'Provided properties', 'Destroyed properties'],
              sepchar='=')
    foo(t, ps, 0)
    s = six.StringIO()
    t.write(s)
    for line in s.getvalue().splitlines():
        print('   ' + line.rstrip())
    print('\n')
