gcc/contrib/header-tools/graph-header-logs

231 lines
6.2 KiB
Plaintext
Raw Normal View History

#! /usr/bin/python2
import os.path
import sys
import shlex
import re
from headerutils import *
header_roots = { }
extra_edges = list()
verbose = False
verbosity = 0
nodes = list()
def unpretty (name):
if name[-2:] == "_h":
name = name[:-2] + ".h"
return name.replace("_", "-")
def pretty_name (name):
name = os.path.basename (name)
return name.replace(".","_").replace("-","_").replace("/","_").replace("+","_");
depstring = ("In file included from", " from")
# indentation indicates nesting levels of included files
ignore = [ "coretypes_h",
Reorganise machmode.h headers This patch splits the auto-generated inline functions out of insn-modes.h and puts them in a new header file, insn-modes-inline.h. It also makes coretypes.h include these files directly, rather than indirectly via machmode.h. This in turn allows insn-modes-inline.h and machmode.h to come later in the include list, after wide-int.h. This is useful for later patches. insn-modes.h itself still needs to come first, since it provides configuration information like MAX_BITSIZE_MODE_ANY_INT, which is used to control the size of a wide_int. The patch also makes the generator files include machmode.h via coretypes.h. Previously they did it by more indirect means. Finally, the patch makes wide-int-print.h available via coretypes.h too. There didn't seem to be any reason to force only the print routines to be included directly, and it would be painful to extend that approach to the SVE patches. [Based on the code ARM contributed in branches/ARM/sve-branch@242100] 2017-07-02 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> contrib/header-tools/ * graph-header-logs (ignore): Update coretypes.h header list. gcc/ * Makefile.in (MACHMODE_H): Remove insn-modes.h (CORETYPES_H): New define. (MOSTLYCLEANFILES): Add insn-modes-inline.h. (insn-modes-inline.h, s-modes-inline-h): New rules. (generated_files): Add insn-modes-inline.h. (RTL_BASE_H, TREE_CORE_H): Use CORETYPES_H instead of coretypes.h. (build/gensupport.o, build/ggc-none.o, build/print-rtl.o): Likewise. (build/read-md.o, build/read-rtl.o, build/rtl.o): Likewise. (build/vec.o, build/hash-table.o, build/inchash.o): Likewise. (build/gencondmd.o, build/genattr.o, build/genattr-common.o): Likewise. (build/genattrtab.o, build/genautomata.o, build/gencheck.o): Likewise. (build/gencodes.o, build/genconditions.o): Likewise. (build/genconfig.o, build/genconstants.o, build/genemit.o): Likewise. (build/genenums.o, build/genextract.o, build/genflags.o): Likewise. (build/gentarget-def.o, build/genmddeps.o, build/genopinit.o) (build/genoutput.o, build/genpeep.o, build/genpreds.o): Likewise. (build/genrecog.o, build/genmddump.o, build/genmatch.o): Likewise. (build/gencfn-macros.o, build/gcov-iov.o): Likewise. * coretypes.h: Include everything up to real.h for generators. Include insn-modes.h first. Include wide-int-print.h after wide-int.h. Include insn-modes-inline.h and then machmode.h. * machmode.h: Don't include insn-modes.h here. * function-tests.c: Remove includes of signop.h, machmode.h, double-int.h and wide-int.h. * rtl.h: Likewise. * gcc-rich-location.c: Remove includes of machmode.h, double-int.h and wide-int.h. * optc-save-gen.awk: Likewise. * gencheck.c (BITS_PER_UNIT): Delete dummy definition. * godump.c: Remove include of wide-int-print.h. * pretty-print.h: Likewise. * wide-int-print.cc: Likewise. * wide-int.cc: Likewise. * hash-map-tests.c: Remove include of signop.h. * hash-set-tests.c: Likewise. * rtl-tests.c: Likewise. * mkconfig.sh: Remove include of machmode.h. * genmodes.c (emit_insn_modes_h): Split emission of inline functions into... (emit_insn_modes_inline_h): ...this new function. Emit the code into an insn-modes-inline.h header file, adding appropriate include guards and end comments. (emit_insn_modes_c_header): Remove include of machmode.h. (emit_min_insn_modes_c_header): Include coretypes.h rather than machmode.h. (main): Handle -i flag and call emit_insn_modes_inline_h when it is passed. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r249881
2017-07-02 11:06:10 +02:00
"insn_modes_h",
"signop_h",
"wide_int_h",
Reorganise machmode.h headers This patch splits the auto-generated inline functions out of insn-modes.h and puts them in a new header file, insn-modes-inline.h. It also makes coretypes.h include these files directly, rather than indirectly via machmode.h. This in turn allows insn-modes-inline.h and machmode.h to come later in the include list, after wide-int.h. This is useful for later patches. insn-modes.h itself still needs to come first, since it provides configuration information like MAX_BITSIZE_MODE_ANY_INT, which is used to control the size of a wide_int. The patch also makes the generator files include machmode.h via coretypes.h. Previously they did it by more indirect means. Finally, the patch makes wide-int-print.h available via coretypes.h too. There didn't seem to be any reason to force only the print routines to be included directly, and it would be painful to extend that approach to the SVE patches. [Based on the code ARM contributed in branches/ARM/sve-branch@242100] 2017-07-02 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> contrib/header-tools/ * graph-header-logs (ignore): Update coretypes.h header list. gcc/ * Makefile.in (MACHMODE_H): Remove insn-modes.h (CORETYPES_H): New define. (MOSTLYCLEANFILES): Add insn-modes-inline.h. (insn-modes-inline.h, s-modes-inline-h): New rules. (generated_files): Add insn-modes-inline.h. (RTL_BASE_H, TREE_CORE_H): Use CORETYPES_H instead of coretypes.h. (build/gensupport.o, build/ggc-none.o, build/print-rtl.o): Likewise. (build/read-md.o, build/read-rtl.o, build/rtl.o): Likewise. (build/vec.o, build/hash-table.o, build/inchash.o): Likewise. (build/gencondmd.o, build/genattr.o, build/genattr-common.o): Likewise. (build/genattrtab.o, build/genautomata.o, build/gencheck.o): Likewise. (build/gencodes.o, build/genconditions.o): Likewise. (build/genconfig.o, build/genconstants.o, build/genemit.o): Likewise. (build/genenums.o, build/genextract.o, build/genflags.o): Likewise. (build/gentarget-def.o, build/genmddeps.o, build/genopinit.o) (build/genoutput.o, build/genpeep.o, build/genpreds.o): Likewise. (build/genrecog.o, build/genmddump.o, build/genmatch.o): Likewise. (build/gencfn-macros.o, build/gcov-iov.o): Likewise. * coretypes.h: Include everything up to real.h for generators. Include insn-modes.h first. Include wide-int-print.h after wide-int.h. Include insn-modes-inline.h and then machmode.h. * machmode.h: Don't include insn-modes.h here. * function-tests.c: Remove includes of signop.h, machmode.h, double-int.h and wide-int.h. * rtl.h: Likewise. * gcc-rich-location.c: Remove includes of machmode.h, double-int.h and wide-int.h. * optc-save-gen.awk: Likewise. * gencheck.c (BITS_PER_UNIT): Delete dummy definition. * godump.c: Remove include of wide-int-print.h. * pretty-print.h: Likewise. * wide-int-print.cc: Likewise. * wide-int.cc: Likewise. * hash-map-tests.c: Remove include of signop.h. * hash-set-tests.c: Likewise. * rtl-tests.c: Likewise. * mkconfig.sh: Remove include of machmode.h. * genmodes.c (emit_insn_modes_h): Split emission of inline functions into... (emit_insn_modes_inline_h): ...this new function. Emit the code into an insn-modes-inline.h header file, adding appropriate include guards and end comments. (emit_insn_modes_c_header): Remove include of machmode.h. (emit_min_insn_modes_c_header): Include coretypes.h rather than machmode.h. (main): Handle -i flag and call emit_insn_modes_inline_h when it is passed. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r249881
2017-07-02 11:06:10 +02:00
"wide_int_print_h",
"insn_modes_inline_h",
"machmode_h",
"double_int_h",
"real_h",
"fixed_value_h",
"hash_table_h",
"statistics_h",
"ggc_h",
"vec_h",
"hashtab_h",
"inchash_h",
"mem_stats_traits_h",
"hash_map_traits_h",
"mem_stats_h",
"hash_map_h",
"hash_set_h",
"input_h",
"line_map_h",
"is_a_h",
"system_h",
"config_h" ]
def process_log_file (header, logfile):
if header_roots.get (header) != None:
print "Error: already processed log file: " + header + ".log"
return
hname = pretty_name (header)
header_roots[hname] = { }
sline = list();
incfrom = list()
newinc = True
for line in logfile:
if len (line) > 21 and line[:21] in depstring:
if newinc:
incfrom = list()
newinc = False
fn = re.findall(ur".*/(.*?):", line)
if len(fn) != 1:
continue
if fn[0][-2:] != ".h":
continue
n = pretty_name (fn[0])
if n not in ignore:
incfrom.append (n)
continue
newinc = True
note = re.findall (ur"^.*note: (.*)", line)
if len(note) > 0:
sline.append (("note", note[0]))
else:
err_msg = re.findall (ur"^.*: error: (.*)", line)
if len(err_msg) == 1:
msg = err_msg[0]
if (len (re.findall("error: forward declaration", line))) != 0:
continue
path = re.findall (ur"^(.*?):.*error: ", line)
if len(path) != 1:
continue
if path[0][-2:] != ".h":
continue
fname = pretty_name (path[0])
if fname in ignore or fname[0:3] == "gt_":
continue
sline.append (("error", msg, fname, incfrom))
print str(len(sline)) + " lines to process"
lastline = "note"
for line in sline:
if line[0] != "note" and lastline[0] == "error":
fname = lastline[2]
msg = lastline[1]
incfrom = lastline[3]
string = ""
ofname = fname
if len(incfrom) != 0:
for t in incfrom:
string = string + t + " : "
ee = (fname, t)
if ee not in extra_edges:
extra_edges.append (ee)
fname = t
print string
if hname not in nodes:
nodes.append(hname)
if fname not in nodes:
nodes.append (ofname)
for y in incfrom:
if y not in nodes:
nodes.append (y)
if header_roots[hname].get(fname) == None:
header_roots[hname][fname] = list()
if msg not in header_roots[hname][fname]:
print string + ofname + " : " +msg
header_roots[hname][fname].append (msg)
lastline = line;
dotname = "graph.dot"
graphname = "graph.png"
def build_dot_file (file_list):
output = open(dotname, "w")
output.write ("digraph incweb {\n");
for x in file_list:
if os.path.exists (x) and x[-4:] == ".log":
header = x[:-4]
logfile = open(x).read().splitlines()
process_log_file (header, logfile)
elif os.path.exists (x + ".log"):
logfile = open(x + ".log").read().splitlines()
process_log_file (x, logfile)
for n in nodes:
fn = unpretty(n)
label = n + " [ label = \"" + fn + "\" ];"
output.write (label + "\n")
if os.path.exists (fn):
h = open(fn).read().splitlines()
for l in h:
t = find_pound_include (l, True, False)
if t != "":
t = pretty_name (t)
if t in ignore or t[-2:] != "_h":
continue
if t not in nodes:
nodes.append (t)
ee = (t, n)
if ee not in extra_edges:
extra_edges.append (ee)
depcount = list()
for h in header_roots:
for dep in header_roots[h]:
label = " [ label = "+ str(len(header_roots[h][dep])) + " ];"
string = h + " -> " + dep + label
output.write (string + "\n");
if verbose:
depcount.append ((h, dep, len(header_roots[h][dep])))
for ee in extra_edges:
string = ee[0] + " -> " + ee[1] + "[ color=red ];"
output.write (string + "\n");
if verbose:
depcount.sort(key=lambda tup:tup[2])
for x in depcount:
print " ("+str(x[2])+ ") : " + x[0] + " -> " + x[1]
if (x[2] <= verbosity):
for l in header_roots[x[0]][x[1]]:
print " " + l
output.write ("}\n");
files = list()
dohelp = False
edge_thresh = 0
for arg in sys.argv[1:]:
if arg[0:2] == "-o":
dotname = arg[2:]+".dot"
graphname = arg[2:]+".png"
elif arg[0:2] == "-h":
dohelp = True
elif arg[0:2] == "-v":
verbose = True
if len(arg) > 2:
verbosity = int (arg[2:])
if (verbosity == 9):
verbosity = 9999
elif arg[0:1] == "-":
print "Unrecognized option " + arg
dohelp = True
else:
files.append (arg)
if len(sys.argv) == 1:
dohelp = True
if dohelp:
print "Parses the log files from the reduce-headers tool to generate"
print "dependency graphs for the include web for specified files."
print "Usage: [-nnum] [-h] [-v[n]] [-ooutput] file1 [[file2] ... [filen]]"
print " -ooutput : Specifies output to output.dot and output.png"
print " Defaults to 'graph.dot and graph.png"
print " -vn : verbose mode, shows the number of connections, and if n"
print " is specified, show the messages if # < n. 9 is infinity"
print " -h : help"
else:
print files
build_dot_file (files)
os.system ("dot -Tpng " + dotname + " -o" + graphname)