b0e84cf75a
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
231 lines
6.2 KiB
Python
Executable File
231 lines
6.2 KiB
Python
Executable File
#! /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",
|
|
"insn_modes_h",
|
|
"signop_h",
|
|
"wide_int_h",
|
|
"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)
|
|
|
|
|