From: Matthias Braun Date: Fri, 25 Jun 2010 07:21:04 +0000 (+0000) Subject: cleanup and rewrite dumper interface X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=060aa4c91666063f9bb70aaa76f5c819d256a15f;p=libfirm cleanup and rewrite dumper interface [r27653] --- diff --git a/include/libfirm/adt/pqueue.h b/include/libfirm/adt/pqueue.h index 9291629df..81596dedf 100644 --- a/include/libfirm/adt/pqueue.h +++ b/include/libfirm/adt/pqueue.h @@ -21,8 +21,8 @@ * @file * @date 18.04.2007 * @author Christian Wuerdig - * @brief Implementation of a priority queue. This is the ported version of the - * original Java implementation by Matthias Braun. + * @brief Implementation of a priority queue. This is the ported version of + the original Java implementation by Matthias Braun. * @version $Id$ */ #ifndef FIRM_ADT_PQUEUE_H diff --git a/include/libfirm/interval_analysis.h b/include/libfirm/interval_analysis.h index ae7894b36..e587cea74 100644 --- a/include/libfirm/interval_analysis.h +++ b/include/libfirm/interval_analysis.h @@ -74,8 +74,8 @@ FIRM_API void construct_intervals(ir_graph *irg); /** frees interval information of all graphs. */ FIRM_API void free_intervals(void); -/** dump a graph with the intervals. File name suffix "-interval". */ -FIRM_API void dump_interval_graph(ir_graph *irg, const char *suffix); +/** dump a vcg graph with the intervals */ +FIRM_API void dump_interval_graph(FILE *out, ir_graph *irg); #include "end.h" diff --git a/include/libfirm/irdump.h b/include/libfirm/irdump.h index fcb62b948..c22a3eea6 100644 --- a/include/libfirm/irdump.h +++ b/include/libfirm/irdump.h @@ -33,10 +33,7 @@ * http://www.absint.de/aisee/download/index.htm. * * We have developed an own advanced viewer called ycomp: - * http://www.info.uni-karlsruhe.de/software.php/id=6&lang=en - * - * Most routines use the name of the passed entity as the name of the - * file dumped to. + * http://www.info.uni-karlsruhe.de/software/ycomp/ */ #ifndef FIRM_IR_IRDUMP_H #define FIRM_IR_IRDUMP_H @@ -46,212 +43,84 @@ #include "firm_types.h" #include "begin.h" -/* **************************************************************************** */ -/* GRAPH DUMPERS */ -/* **************************************************************************** */ +/** @defgroup convenience_dumper Convenience interface for dumpers */ +/*@{*/ /** - * This hook is called to insert some special nodes into dumped graph - */ -typedef int (*DUMP_IR_GRAPH_FUNC)(FILE *F, ir_graph *irg); -/** - * This hook is called to dump the vcg attributes of a node to a file. - * If this function returns zero, the default attributes are added, else - * removed. - */ -typedef int (*DUMP_NODE_VCGATTR_FUNC)(FILE *F, ir_node *node, ir_node *local); -/** - * This hook is called to dump the vcg attributes of an edge to a file. - * If this function returns zero, the default attributes are added, else - * removed. - */ -typedef int (*DUMP_EDGE_VCGATTR_FUNC)(FILE *F, ir_node *node, int to); - -/** Set the ir graph dump hook. */ -FIRM_API void set_dump_ir_graph_hook(DUMP_IR_GRAPH_FUNC hook); -/** Set the node_vcgattr hook. */ -FIRM_API void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook); -/** Set the edge_vcgattr hook. */ -FIRM_API void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook); - -typedef int (*DUMP_NODE_EDGE_FUNC)(FILE *f, ir_node *node); - -/** - * Set the hook to be called to dump additional edges to a node. - * @param func The hook to be called. - */ -FIRM_API void set_dump_node_edge_hook(DUMP_NODE_EDGE_FUNC func); - -/** - * Get the additional edge dump hook. - * @return The current additional edge dump hook.] + * Convenience interface for dumping a graph as vcg file. + * + * For details on how the filename is constructed see #dump_ir_graph_ext */ -FIRM_API DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void); +FIRM_API void dump_ir_graph(ir_graph *graph, const char *suffix); /** - * Set the hook to be called to dump additional edges to a block. - * @param func The hook to be called. + * type for dumpers that dump information about the whole program */ -FIRM_API void set_dump_block_edge_hook(DUMP_NODE_EDGE_FUNC func); +typedef void (*ir_prog_dump_func)(FILE *out); /** - * Get the additional block edge dump hook. - * @return The current additional block edge dump hook. - */ -FIRM_API DUMP_NODE_EDGE_FUNC get_dump_block_edge_hook(void); - -/** Dump a firm graph. - * - * @param irg The firm graph to be dumped. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the firm graph in vcg format. - * - * Dumps all Firm nodes of a single graph for a single procedure in - * standard xvcg format. Dumps the graph to a file. The file name - * is constructed from the name of the entity describing the - * procedure (irg->entity) and the ending -pure<-ip>.vcg. Eventually - * overwrites existing files. Visits all nodes in - * interprocedural_view. - * - * @see turn_off_edge_labels() - */ -FIRM_API void dump_ir_graph(ir_graph *irg, const char *suffix); -FIRM_API void dump_ir_graph_file(ir_graph *irg, FILE *out); - -/** Dump a firm graph without explicit block nodes. - * - * @param irg The firm graph to be dumped. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the firm graph in vcg format. + * Convenience interface for dumping the whole compilation-unit/program. * - * Dumps all Firm nodes of a single graph for a single procedure in - * extended xvcg format. - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending <-ip>.vcg. Eventually overwrites existing files. Dumps several - * procedures in boxes if interprocedural_view. + * The filename is constructed by combining a counter, the name of the current + * ir_prog and the given @p suffix. The file-extensions is determined by looking + * at @p mime_type. + * The file is stored into the directory specified by #ir_set_dump_path * - * @see turn_off_edge_labels() + * @param func Dumper. Usualle one of #dump_callgraph, #dump_type_graph, + * #dump_class_hierarchy, #dump_types_as_text, + * #dump_globals_as_text + * @param suffix Suffix to append to the name */ -FIRM_API void dump_ir_block_graph(ir_graph *irg, const char *suffix); +FIRM_API void dump_ir_prog_ext(ir_prog_dump_func func, const char *suffix); /** - * Does the same as dump_ir_block_graph but dumps to a stream - * @see dump_ir_block_graph() - */ -FIRM_API void dump_ir_block_graph_file(ir_graph *irg, FILE *out); - -/** Dump a firm graph without explicit block nodes but grouped in extended blocks. - * - * @param irg The firm graph to be dumped. - * @param suffix suffix to append after the irgname (but before the .vcg) - * - * @return - * A file containing the firm graph in vcg format. - * - * Dumps all Firm nodes of a single graph for a single procedure in - * extended xvcg format. - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending <-ip>.vcg. Eventually overwrites existing files. Dumps several - * procedures in boxes if interprocedural_view. - * - * @see turn_off_edge_labels() + * type for graph dumpers */ -FIRM_API void dump_ir_extblock_graph(ir_graph *irg, const char *suffix); +typedef void (*ir_graph_dump_func)(FILE *out, ir_graph *graph); /** - * Does the same as dump_ir_extrblock_graph but dumps to a stream - * @see dump_ir_extblock_graph() - */ -FIRM_API void dump_ir_extblock_graph_file(ir_graph *irg, FILE *out); - -/** Dumps all graphs in interprocedural view to a file named All_graphs\.vcg. + * Convenience interface for dumping graphs. + * The filename is constructed by combining a counter, the name of the graphs + * entity and the given @p suffix. The file-extensions is determined by looking + * at @p mime_type. + * The file is stored into the directory specified by #ir_set_dump_path * - * @param suffix A suffix for the file name. + * @param func Dumper. Usually one of #dump_cfg, #dump_loop_tree, + * #dump_graph_to_file + * @param graph the graph to dump + * @param suffix suffix */ -FIRM_API void dump_all_cg_block_graph(const char *suffix); - -/** Dumps a firm graph and all the type information needed for Calls, - * Sels, ... in this graph. - * - * @param irg The firm graph to be dumped with its type information. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the firm graph and the type information of the firm graph in vcg format. - * - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending -all.vcg. Eventually overwrites existing files. - * - * @see turn_off_edge_labels() - */ -FIRM_API void dump_ir_graph_w_types(ir_graph *irg, const char *suffix); +FIRM_API void dump_ir_graph_ext(ir_graph_dump_func func, ir_graph *graph, + const char *suffix); /** - * Does the same as dump_ir_graph_w_types but dumps to a stream - * @see dump_ir_graph_w_types() - */ -FIRM_API void dump_ir_graph_w_types_file(ir_graph *irg, FILE *out); - -/** Dumps a firm graph and all the type information needed for Calls, - * Sels, ... in this graph. - * - * @param irg The firm graph to be dumped with its type information. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the firm graph and the type information of the firm graph in vcg format. + * A walker that calls a dumper for each graph in the program * - * The graph is in blocked format. - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending -all.vcg. Eventually overwrites existing files. - * - * @see turn_off_edge_labels() + * @param suffix A suffix for the file name. */ -FIRM_API void dump_ir_block_graph_w_types(ir_graph *irg, const char *suffix); +FIRM_API void dump_all_ir_graphs(const char *suffix); /** - * same as @see dump_ir_block_graph_w_types() but dumps to a stream - * @param irg the graph to dump - * @param out stream to dump to - */ -FIRM_API void dump_ir_block_graph_w_types_file(ir_graph *irg, FILE *out); - -/** The type of a dump function that is called for each graph. - * - * @param irg current visited graph - * @param suffix A suffix for the file name. + * Specifies output path for the dump_ir_graph function */ -typedef void dump_graph_func(ir_graph *irg, const char *suffix); +FIRM_API void ir_set_dump_path(const char *path); /** - * A walker that calls a dumper for each graph. - * - * @param dump_graph The dumper to be used for dumping. - * @param suffix A suffix for the file name. - * - * @return - * Whatever the dumper creates. + * Set a prefix filter for output functions. * - * Walks over all firm graphs and calls a dumper for each graph. - * The following dumpers can be passed as arguments: - * - dump_ir_graph() - * - dump_ir_block_graph() - * - dump_cfg() - * - dump_type_graph() - * - dump_ir_graph_w_types() + * All graph dumpers check this name. If the name is != "" and + * not a prefix of the graph to be dumped, the dumper does not + * dump the graph. * - * @see turn_off_edge_labels() + * @param name The prefix of the name of the method entity to be dumped. */ -FIRM_API void dump_all_ir_graphs(dump_graph_func *dump_graph, - const char *suffix); +FIRM_API void ir_set_dump_filter(const char *name); + +/** Returns the prefix filter set with #ir_set_dump_filter */ +FIRM_API const char *ir_get_dump_filter(void); + +/** Returns true if dump file filter is not set, or if it is a prefix of name */ +FIRM_API int ir_should_dump(const char *name); /** * Creates an ir_prog pass for dump_all_ir_graphs(). @@ -262,185 +131,126 @@ FIRM_API void dump_all_ir_graphs(dump_graph_func *dump_graph, * * @return the newly created ir_prog pass */ -FIRM_API ir_prog_pass_t *dump_all_ir_graph_pass( - const char *name, dump_graph_func *dump_graph, const char *suffix); +FIRM_API ir_prog_pass_t *dump_all_ir_graph_pass(const char *name, + const char *suffix); + +/*@}*/ /** - * Dump the control flow graph of a procedure. - * - * @param irg The firm graph whose CFG shall be dumped. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the CFG in vcg format. - * - * Dumps the control flow graph of a procedure in standard xvcg format. - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending -cfg.vcg. Eventually overwrites existing files. - * - * @see turn_off_edge_labels() + * @defgroup dumper Dump information to file + * This is the low-level interface for dumping information as text files + * and xvcg graphs. + * Normally you should use the convenience interface @ref convenience_dumper + * instead of the functions in this group. */ -FIRM_API void dump_cfg(ir_graph *irg, const char *suffix); +/*@{*/ /** - * Dump a node and its predecessors forming a subgraph to a vcg file. + * Dumps all Firm nodes of a single graph for a single procedure in + * standard xvcg format. * - * @param root The node serving as root for the subgraph. - * @param depth Dump nodes on paths starting at root with length depth. - * @param suffix A suffix for the file name. - * - * Dumps the graph to a file. The file name is constructed from the - * name of the entity describing the procedure the passed node is - * in, suffix and the ending -subg_\.vcg. nr is a unique number - * for each graph dumped. Eventually overwrites existing files. - * - * @return - * A file containing the subgraph in vcg format. + * @param graph The firm graph to be dumped. + * @param out Output stream the graph is written to */ -FIRM_API void dump_subgraph(ir_node *root, int depth, const char *suffix); - -/* **************************************************************************** */ -/* CALLGRAPH DUMPERS */ -/* **************************************************************************** */ +FIRM_API void dump_ir_graph_file(FILE *out, ir_graph *graph); - -/** Dump the call graph. - * - * Dumps the callgraph to a file "Callgraph"\".vcg". +/** + * Dump the control flow graph of a procedure. * - * @param suffix A suffix for the file name. + * @param graph The firm graph whose CFG shall be dumped. + * @param out Output stream the CFG is written to * - * @see dump_callgraph_loop_tree(const char *suffix) + * Dumps the control flow graph of a procedure in standard xvcg format. */ -FIRM_API void dump_callgraph(const char *suffix); - -/* **************************************************************************** */ -/* TYPEGRAPH DUMPERS */ -/* **************************************************************************** */ +FIRM_API void dump_cfg(FILE *out, ir_graph *graph); /** - * Dumps all the type information needed for Calls, Sels, ... in this graph. - * Does not dump the graph! - * - * @param irg The firm graph whose type information is to be dumped. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the type information of the firm graph in vcg format. - * - * Dumps this graph to a file. The file name is constructed from the - * name of the entity describing the procedure (irg->entity) and the - * ending -type.vcg. Eventually overwrites existing files. + * Dump the call graph. * - * @see turn_off_edge_labels() + * @param out Output stream the callgraph is written to */ -FIRM_API void dump_type_graph(ir_graph *irg, const char *suffix); +FIRM_API void dump_callgraph(FILE *out); /** * Dumps all type information. * - * @param suffix A suffix for the file name. - * - * @return - * A file containing all type information for the program in standard - * vcg format. + * @param out Output stream the typegraph is written to * * Dumps all type information that is somehow reachable in standard vcg * format. - * Dumps the graph to a file named All_types.vcg. - * - * @see turn_off_edge_labels() */ -FIRM_API void dump_all_types(const char *suffix); +FIRM_API void dump_typegraph(FILE *out); /** * Dumps the class hierarchy with or without entities. * + * @param out Output stream * @param entities Flag whether to dump the entities. - * @param suffix A suffix for the file name. - * - * @return - * A file containing the class hierarchy tree for the program in standard - * vcg format. * * Does not dump the global type. * Dumps a node for all classes and the sub/supertype relations. If * entities is set to true also dumps the entities of classes, but without * any additional information as the entities type. The overwrites relation * is dumped along with the entities. - * Dumps to a file class_hierarchy.vcg */ -FIRM_API void dump_class_hierarchy(int entities, const char *suffix); - -/* **************************************************************************** */ -/* LOOPTREE DUMPERS */ -/* **************************************************************************** */ +FIRM_API void dump_class_hierarchy(FILE *out); /** * Dump a standalone loop tree, which contains the loop nodes and the firm nodes - * belonging to one loop packed together in one subgraph. Dumps to file - * \\-looptree.vcg - * Turns on edge labels by default. - * - * Implementing this dumper was stimulated by Florian Liekwegs similar dumper. + * belonging to one loop packed together in one subgraph. * - * @param irg Dump the loop tree for this graph. - * @param suffix A suffix for the file name. + * @param out Output stream + * @param graph Dump the loop tree for this graph. */ -FIRM_API void dump_loop_tree(ir_graph *irg, const char *suffix); +FIRM_API void dump_loop_tree(FILE *out, ir_graph *graph); -/** Dumps the firm nodes in the sub-loop-tree of loop to a graph. +/** + * Dumps the loop tree over the call graph. * - * Dumps the loop nodes if dump_loop_information() is set. - * The name of the file is loop_\.vcg. + * @param out Output stream + */ +FIRM_API void dump_callgraph_loop_tree(FILE *out); + +/** + * Dump type information as text. * - * @param l Dump the loop tree for this loop. - * @param suffix A suffix for the file name. + * Often type graphs are unhandy in their vcg representation. The text dumper + * represents the information for a single type more compact, but the relations + * between the types only implicitly. Dumps only 'real' types, i.e., those in + * the type list. Does not dump the global type nor frame types or the like. */ -FIRM_API void dump_loop(ir_loop *l, const char *suffix); +FIRM_API void dump_types_as_text(FILE *out); -/** Dumps the loop tree over the call graph. +/** + * Dumps all global variables as text. * - * See for yourself what you can use this for. - * The filename is "Callgraph_looptree\.vcg". + * @param out Output stream + * @param verbosity verbosity flag * - * @param suffix A suffix for the file name. + * Dumps a text representation of the entities in the global type. */ -FIRM_API void dump_callgraph_loop_tree(const char *suffix); - - -/* **************************************************************************** */ -/* TEXT DUMPERS */ -/* **************************************************************************** */ +FIRM_API void dump_globals_as_text(FILE *out); +/** + * Dumps the firm nodes in the sub-loop-tree of loop to a vcg file. + * + * @param out Output stream + * @param l Dump the loop tree for this loop. + */ +FIRM_API void dump_loop(FILE *out, ir_loop *loop); /** Write the irnode and all its attributes to the file passed. */ -FIRM_API int dump_irnode_to_file(FILE *f, ir_node *n); - -/** Write the irnode and all its attributes to stdout. */ -FIRM_API void dump_irnode(ir_node *n); +FIRM_API void dump_irnode_to_file(FILE *out, ir_node *node); /** Write the graph and all its attributes to the file passed. * Does not write the nodes. */ -FIRM_API void dump_graph_to_file(FILE *F, ir_graph *irg); - -/** Write the graph and all its attributes to stdout. - * Does not write the nodes. */ -FIRM_API void dump_graph(ir_graph *g); - +FIRM_API void dump_graph_as_text(FILE *out, ir_graph *graph); -/** Dump graph information as text. - * - * Often graphs are unhandy in their vcg representation. The text - * dumper represents the information for the firm nodes more compact, - * but the relations between the nodes only implicitly. - * - * The file name is the graph name (get_entity_name()), appended by - * \.txt. - */ -FIRM_API void dump_graph_as_text(ir_graph *irg, const char *suffix); +/** Write the entity and all its attributes to the passed file. */ +FIRM_API void dump_entity_to_file(FILE *out, ir_entity *entity); +/** Write the type and all its attributes to the file passed. */ +FIRM_API void dump_type_to_file(FILE *out, ir_type *type); /** Verbosity for text dumpers */ typedef enum { @@ -475,182 +285,126 @@ typedef enum { dump_verbosity_onlyPrimitiveTypes = 0x000BF000, /**< Dump only primitive types. */ dump_verbosity_onlyEnumerationTypes=0x0007F000, /**< Dump only enumeration types. */ - dump_verbosity_max = 0x4FF00FBE /**< Turn on all verbosity. - Do not turn on negative flags! - @@@ Because of a bug in gcc 3.2 we can not set the - first two bits. */ -} dump_verbosity; - - -/** Write the entity and all its attributes to the passed file. - * */ -FIRM_API void dump_entity_to_file(FILE *F, ir_entity *ent, unsigned verbosity); - -/** Write the entity and all its attributes to the stdout. - * - * Calls dump_entity_to_file(). */ -FIRM_API void dump_entity(ir_entity *ent); - -/** Write the type and all its attributes to the file passed. */ -FIRM_API void dump_type_to_file(FILE *f, ir_type *tp, dump_verbosity verbosity); - -/** Write the type and all its attributes to stdout. */ -void dump_type(ir_type *tp); - - -/** Dump type information as text. - * - * Often type graphs are unhandy in their vcg representation. The text - * dumper represents the information for a single type more compact, but - * the relations between the types only implicitly. - * Dumps only 'real' types, i.e., those in the type list. Does not dump - * the global type nor frame types or the like. - * - * The file name is the program name (get_irp_name()), or 'TextTypes' - * if the program name is not set, appended by \-types.txt. - * For verbosity see the documentation of the verbosity flags above. - */ -FIRM_API void dump_types_as_text(unsigned verbosity, const char *suffix); - -/** Dumps all global variables as text. - * - * @param verbosity verbosity flag - * @param suffix A suffix for the file name. - * - * Dumps a text representation of the entities in the global type. - * - * The file name is the program name (get_irp_name()), or 'TextTypes' - * if the program name is not set, appended by \-globals.txt. - * For verbosity see the documentation of the verbosity flags above. - */ -FIRM_API void dump_globals_as_text(unsigned verbosity, const char *suffix); - -/* **************************************************************************** */ -/* FLAGS */ -/* **************************************************************************** */ - -/** Set a prefix filter for output functions. - * - * All graph dumpers check this name. If the name is != "" and - * not a prefix of the graph to be dumped, the dumper does not - * dump the graph. - * - * @param name The prefix of the name (not the ld_name) of the method - * entity to be dumped. - */ -FIRM_API void only_dump_method_with_name(ident *name); - -/** Returns the prefix filter set with only_dump_method_with_name(). */ -FIRM_API ident *get_dump_file_filter_ident(void); - -/** Returns true if dump file filter is not set, or if it is a - * prefix of name. */ -FIRM_API int is_filtered_dump_name(ident *name); + dump_verbosity_max = 0x4FF00FBE /**< Turn everything on */ +} ir_dump_verbosity_t; -/** Sets the vcg flag "display_edge_labels" to no. - * - * This is necessary as xvcg and aisee both fail to display graphs - * with self-edges if these edges have labels. - */ -FIRM_API void turn_off_edge_labels(void); +/** override currently set text dump flags with new ones */ +FIRM_API void ir_set_dump_verbosity(ir_dump_verbosity_t verbosity); +/** return currently set text dump flags */ +FIRM_API ir_dump_verbosity_t ir_get_dump_verbosity(void); /** - * If set to non-zero constants will be replicated for every use. In non - * blocked view edges from constant to block are skipped. Vcg then - * layouts the graphs more compact, this makes them better readable. - * The flag is automatically and temporarily set to false if other - * edges are dumped, as outs, loop, ... - * Default setting: false. + * A bitset indicating various options that affect what information is dumped + * and how exactly it is dumped. This affects the dumpers that produce vcg + * graphs. */ -FIRM_API void dump_consts_local(int flag); +typedef enum { + /** dump basic blocks as subgraphs which contain the nodes in the block */ + ir_dump_flag_blocks_as_subgraphs = 1U << 0, + /** display blocks in extended basic grouped inside a subgraph */ + ir_dump_flag_group_extbb = 1U << 1, + /** dump (parts of) typegraph along with nodes */ + ir_dump_flag_with_typegraph = 1U << 2, + /** Sets the vcg flag "display_edge_labels" to no. + * This is necessary as xvcg and aisee both fail to display graphs + * with self-edges if these edges have labels. */ + ir_dump_flag_disable_edge_labels = 1U << 3, + /** If set constants will be replicated for every use. In non blocked view + * edges from constant to block are skipped. Vcg then layouts the graphs + * more compact, this makes them better readable. */ + ir_dump_flag_consts_local = 1U << 4, + /** if set node idx will be added to node labels */ + ir_dump_flag_idx_label = 1U << 5, + /** if set node number will be added to node labels */ + ir_dump_flag_number_label = 1U << 6, + /** show keepalive edges from the end node */ + ir_dump_flag_keepalive_edges = 1U << 7, + /** dump out edges */ + ir_dump_flag_out_edges = 1U << 8, + /** if set dumps edges from blocks to their immediate dominator */ + ir_dump_flag_dominance = 1U << 9, + /** If set the dumper dumps loop nodes and edges from these nodes to the + * contained ir nodes. Nodes can be missing for interprocedural loops */ + ir_dump_flag_loops = 1U << 10, + /** if set (and backedge info is computed) dump backedges */ + ir_dump_flag_back_edges = 1U << 11, + /** dump type info from ana/irtypeinfo.h in the node labels */ + ir_dump_flag_analysed_types = 1U << 12, + /** dump backedges from iredges.h */ + ir_dump_flag_iredges = 1U << 13, + /** write node addresses into the vcg info */ + ir_dump_flag_node_addresses = 1U << 14, + /** dump all anchor nodes, even the unused ones */ + ir_dump_flag_all_anchors = 1U << 15, + /** dumps macroblock edges from every block to its macroblock */ + ir_dump_flag_macroblock_edges = 1U << 16, + /** dumps marked blocks with an asterisk in the label */ + ir_dump_flag_show_marks = 1U << 17, + + /** turns of dumping of constant entity values in typegraphs */ + ir_dump_flag_no_entity_values = 1U << 20, + /** dumps ld_names of entities instead of their names */ + ir_dump_flag_ld_names = 1U << 21, + /** dump entities in class hierarchies */ + ir_dump_flag_entities_in_hierarchy = 1U << 22, +} ir_dump_flags_t; + +/** override currently set dump flags with new ones */ +FIRM_API void ir_set_dump_flags(ir_dump_flags_t flags); +/** add flags to the currently set dump flags */ +FIRM_API void ir_add_dump_flags(ir_dump_flags_t flags); +/** disable certain dump flags */ +FIRM_API void ir_remove_dump_flags(ir_dump_flags_t flags); +/** return currently set dump flags */ +FIRM_API ir_dump_flags_t ir_get_dump_flags(void); /** - * if set to non-zero node idx will be added to node labels - */ -FIRM_API void dump_node_idx_label(int flag); - -/** Turns off dumping the values of constant entities. Makes type graphs - * better readable. - */ -FIRM_API void dump_constant_entity_values(int flag); - -/** Turns on dumping the edges from the End node to nodes to be kept - * alive. - */ -FIRM_API void dump_keepalive_edges(int flag); -FIRM_API int get_opt_dump_keepalive_edges(void); - -/** Turns on dumping the out edges starting from the Start block in - * dump_ir_graph. - * - * To test the consistency of the out data structure. + * This hook is called to dump the vcg attributes of a node to a file. + * If this function returns zero, the default attributes are added, else + * removed. */ -FIRM_API void dump_out_edges(int flag); +typedef int (*dump_node_vcgattr_func)(FILE *out, ir_node *node, ir_node *local); -/** If this flag is set the dumper dumps edges to immediate dominator in cfg. */ -FIRM_API void dump_dominator_information(int flag); - -/** If this flag is set the dumper dumps loop nodes and edges from - * these nodes to the contained ir nodes. - * - * If the loops are interprocedural nodes can be missing. +/** + * This hook is called to dump the vcg attributes of an edge to a file. + * If this function returns zero, the default attributes are added, else + * removed. */ -FIRM_API void dump_loop_information(int flag); +typedef int (*dump_edge_vcgattr_func)(FILE *out, ir_node *node, int to); -/** If set and backedge info is computed, backedges are dumped dashed - * and as vcg 'backedge' construct. - * - * Default: set. - */ -FIRM_API void dump_backedge_information(int flag); +typedef void (*dump_node_edge_func)(FILE *out, ir_node *node); -/** Dump the information of type field specified in ana/irtypeinfo.h. - * - * If the flag is set, the type name is output in [] in the node label, - * else it is output as info. - */ -FIRM_API void set_opt_dump_analysed_type_info(int flag); +/** Set the node_vcgattr hook. */ +FIRM_API void set_dump_node_vcgattr_hook(dump_node_vcgattr_func hook); +/** Set the edge_vcgattr hook. */ +FIRM_API void set_dump_edge_vcgattr_hook(dump_edge_vcgattr_func hook); /** - * dump iredges (new style out edges) - */ -FIRM_API void dump_new_edges(int flag); - -/** Write the address of a node into the vcg info. - * - * This is off per default for automatic comparisons of - * vcg graphs -- these will differ in the pointer values! - */ -FIRM_API void dump_pointer_values_to_info(int flag); - -/** Dumps ld_names of entities instead of there names. - * - * This option is on per default. + * Set the hook to be called to dump additional edges to a node. + * @param func The hook to be called. */ -FIRM_API void dump_ld_names(int flag); +FIRM_API void set_dump_node_edge_hook(dump_node_edge_func func); -/** Dumps all graph anchor nodes, even if they - * are dead. - * - * This option is off per default. +/** + * Get the additional edge dump hook. + * @return The current additional edge dump hook.] */ -FIRM_API void dump_all_anchors(int flag); +FIRM_API dump_node_edge_func get_dump_node_edge_hook(void); -/** Dumps a MacroBlock edge from every Block to its - * MacroBlock header. - * - * This option is off per default. +/** + * Set the hook to be called to dump additional edges to a block. + * @param func The hook to be called. */ -FIRM_API void dump_macroblock_edges(int flag); +FIRM_API void set_dump_block_edge_hook(dump_node_edge_func func); -/** Dumps a marked blocks with a asterisk in the title. - * - * This option is off per default. +/** + * Get the additional block edge dump hook. + * @return The current additional block edge dump hook. */ -FIRM_API void dump_block_marker_in_title(int flag); +FIRM_API dump_node_edge_func get_dump_block_edge_hook(void); /** A node info dumper callback. */ -typedef void (dump_node_info_cb_t)(void *data, FILE *f, const ir_node *n); +typedef void (dump_node_info_cb_t)(void *data, FILE *out, const ir_node *n); /** * Adds a new node info dumper callback. It is possible to add an unlimited @@ -662,16 +416,19 @@ typedef void (dump_node_info_cb_t)(void *data, FILE *f, const ir_node *n); * * @return A callback handle. * - * @note This functionality is only available, if Firm hooks are enabled (default). + * @note This functionality is only available, if Firm hooks are enabled. */ FIRM_API void *dump_add_node_info_callback(dump_node_info_cb_t *cb, void *data); /** * Remove a previously added info dumper callback. * - * @param handle the callback handle returned from dump_add_node_info_callback() + * @param handle the callback handle returned from + * dump_add_node_info_callback() */ -FIRM_API void dump_remv_node_info_callback(void *handle); +FIRM_API void dump_remove_node_info_callback(void *handle); + +/*@}*/ #include "end.h" diff --git a/include/libfirm/irop.h b/include/libfirm/irop.h index 89fd5fc59..870e62354 100644 --- a/include/libfirm/irop.h +++ b/include/libfirm/irop.h @@ -408,7 +408,7 @@ typedef enum { * Writes several informations requested by reason to * an output file */ -typedef int (*dump_node_func)(ir_node *self, FILE *F, dump_reason_t reason); +typedef void (*dump_node_func)(FILE *out, ir_node *self, dump_reason_t reason); /** * io_op Operations. diff --git a/ir/ana/height.c b/ir/ana/height.c index 2cebd570e..54ca9b1fd 100644 --- a/ir/ana/height.c +++ b/ir/ana/height.c @@ -253,6 +253,6 @@ heights_t *heights_new(ir_graph *irg) void heights_free(heights_t *h) { phase_deinit(&h->ph); - dump_remv_node_info_callback(h->dump_handle); + dump_remove_node_info_callback(h->dump_handle); xfree(h); } diff --git a/ir/ana/interval_analysis.c b/ir/ana/interval_analysis.c index db3a3cfa3..4bb7b6ae0 100644 --- a/ir/ana/interval_analysis.c +++ b/ir/ana/interval_analysis.c @@ -546,7 +546,7 @@ static void dump_interval_block(FILE *F, ir_node *block) fprintf(F, " n_exc_outs: %d", get_region_n_exc_outs(block)); fprintf(F, "\" "); fprintf(F, "info1:\""); - if (dump_dominator_information_flag) + if (ir_get_dump_flags() & ir_dump_flag_dominance) fprintf(F, "dom depth %d\n", get_Block_dom_depth(block)); /* show arity and possible Bad predecessors of the block */ @@ -604,25 +604,14 @@ static void dump_interval_loop(FILE *F, ir_loop *l) fprintf(F, "}\n\n"); } - -void dump_interval_graph(ir_graph *irg, const char *suffix) +void dump_interval_graph(FILE *out, ir_graph *irg) { - FILE *f; - ir_graph *rem; - - if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) - return; - - f = vcg_open(irg, suffix, "-intervals"); - dump_vcg_header(f, get_irg_dump_name(irg), NULL, NULL); - - rem = current_ir_graph; + ir_graph *rem = current_ir_graph; current_ir_graph = irg; - dump_interval_loop(f, get_irg_loop(irg)); - - dump_vcg_footer(f); - fclose(f); + dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL); + dump_interval_loop(out, get_irg_loop(irg)); + dump_vcg_footer(out); current_ir_graph = rem; } diff --git a/ir/ana/structure.c b/ir/ana/structure.c index be4b78458..b4e9ae1a3 100644 --- a/ir/ana/structure.c +++ b/ir/ana/structure.c @@ -1047,8 +1047,6 @@ ir_reg_tree *construct_region_tree(ir_graph *irg) DB((dbg, LEVEL_1, "Structural analysis on %+F starts...\n", irg)); - dump_ir_block_graph(irg, "-structure_start"); - /* we need dominance info */ assure_doms(irg); /* and out edges */ diff --git a/ir/be/TEMPLATE/TEMPLATE_new_nodes.c b/ir/be/TEMPLATE/TEMPLATE_new_nodes.c index 1302ced37..cadba43a8 100644 --- a/ir/be/TEMPLATE/TEMPLATE_new_nodes.c +++ b/ir/be/TEMPLATE/TEMPLATE_new_nodes.c @@ -47,12 +47,11 @@ /** * Dumper interface for dumping TEMPLATE nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int TEMPLATE_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void TEMPLATE_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { ir_mode *mode = NULL; @@ -82,8 +81,6 @@ static int TEMPLATE_dump_node(ir_node *n, FILE *F, dump_reason_t reason) arch_dump_reqs_and_registers(F, n); break; } - - return 0; } const TEMPLATE_attr_t *get_TEMPLATE_attr_const(const ir_node *node) diff --git a/ir/be/TEMPLATE/bearch_TEMPLATE.c b/ir/be/TEMPLATE/bearch_TEMPLATE.c index f0fa0f748..7dbf1a366 100644 --- a/ir/be/TEMPLATE/bearch_TEMPLATE.c +++ b/ir/be/TEMPLATE/bearch_TEMPLATE.c @@ -126,10 +126,7 @@ static void TEMPLATE_prepare_graph(void *self) */ static void TEMPLATE_finish_irg(void *self) { - TEMPLATE_code_gen_t *cg = self; - ir_graph *irg = cg->irg; - - dump_ir_block_graph_sched(irg, "-TEMPLATE-finished"); + (void) self; } diff --git a/ir/be/amd64/amd64_new_nodes.c b/ir/be/amd64/amd64_new_nodes.c index b37aa877a..33a4052fb 100644 --- a/ir/be/amd64/amd64_new_nodes.c +++ b/ir/be/amd64/amd64_new_nodes.c @@ -47,12 +47,11 @@ /** * Dumper interface for dumping amd64 nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int amd64_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void amd64_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { ir_mode *mode = NULL; @@ -82,8 +81,6 @@ static int amd64_dump_node(ir_node *n, FILE *F, dump_reason_t reason) arch_dump_reqs_and_registers(F, n); break; } - - return 0; } const amd64_attr_t *get_amd64_attr_const(const ir_node *node) diff --git a/ir/be/amd64/bearch_amd64.c b/ir/be/amd64/bearch_amd64.c index 9c66da2c9..6fef5d06a 100644 --- a/ir/be/amd64/bearch_amd64.c +++ b/ir/be/amd64/bearch_amd64.c @@ -30,6 +30,7 @@ #include "irprintf.h" #include "ircons.h" #include "irgmod.h" +#include "irdump.h" #include "bitset.h" #include "debug.h" @@ -118,7 +119,7 @@ static void amd64_prepare_graph(void *self) amd64_transform_graph (cg); if (cg->dump) - be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "transformed"); } @@ -131,7 +132,7 @@ static void amd64_finish_irg(void *self) amd64_code_gen_t *cg = self; ir_graph *irg = cg->irg; - dump_ir_block_graph_sched(irg, "-amd64-finished"); + dump_ir_graph(irg, "amd64-finished"); } diff --git a/ir/be/arm/arm_new_nodes.c b/ir/be/arm/arm_new_nodes.c index e20cc413c..3159aeffc 100644 --- a/ir/be/arm/arm_new_nodes.c +++ b/ir/be/arm/arm_new_nodes.c @@ -70,12 +70,11 @@ const char *arm_get_fpa_imm_name(long imm_value) /** * Dumper interface for dumping arm nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { ir_mode *mode = NULL; //arm_attr_t *attr = get_arm_attr(n); @@ -124,8 +123,6 @@ static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) #endif break; } - - return 0; } diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index d4cf7a12d..b01d501ea 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -36,6 +36,7 @@ #include "irgmod.h" #include "irgopt.h" #include "iroptimize.h" +#include "irdump.h" #include "lowering.h" #include "error.h" @@ -153,13 +154,13 @@ static void arm_prepare_graph(void *self) local_optimize_graph(cg->irg); if (cg->dump) - be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "transformed"); /* do code placement, to optimize the position of constants */ place_code(cg->irg); if (cg->dump) - be_dump(cg->irg, "-place", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "place"); } /** diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index a32d509b6..62eb27b8e 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -563,8 +563,8 @@ void be_ra_chordal_color(be_chordal_env_t *chordal_env) dom_tree_walk_irg(irg, constraints, NULL, &env); if (chordal_env->opts->dump_flags & BE_CH_DUMP_CONSTR) { - snprintf(buf, sizeof(buf), "-%s-constr", chordal_env->cls->name); - be_dump(chordal_env->irg, buf, dump_ir_block_graph_sched); + snprintf(buf, sizeof(buf), "%s-constr", chordal_env->cls->name); + dump_ir_graph(chordal_env->irg, buf); } be_timer_pop(T_CONSTR); diff --git a/ir/be/bechordal_main.c b/ir/be/bechordal_main.c index 0a44e9f83..4d4a8dacb 100644 --- a/ir/be/bechordal_main.c +++ b/ir/be/bechordal_main.c @@ -175,17 +175,16 @@ static void be_ra_chordal_coloring(be_chordal_env_t *env) static void dump(unsigned mask, ir_graph *irg, const arch_register_class_t *cls, - const char *suffix, - void (*dump_func)(ir_graph *, const char *)) + const char *suffix) { if ((options.dump_flags & mask) == mask) { if (cls) { char buf[256]; - snprintf(buf, sizeof(buf), "-%s%s", cls->name, suffix); - be_dump(irg, buf, dump_func); + snprintf(buf, sizeof(buf), "%s-%s", cls->name, suffix); + dump_ir_graph(irg, buf); + } else { + dump_ir_graph(irg, suffix); } - else - be_dump(irg, suffix, dump_func); } } @@ -266,7 +265,7 @@ static void pre_spill(post_spill_env_t *pse, const arch_register_class_t *cls) be_pre_spill_prepare_constr(chordal_env->birg, chordal_env->cls); be_timer_pop(T_RA_CONSTR); - dump(BE_CH_DUMP_CONSTR, birg->irg, pse->cls, "-constr-pre", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_CONSTR, birg->irg, pse->cls, "constr-pre"); } /** @@ -314,7 +313,7 @@ static void post_spill(post_spill_env_t *pse, int iteration) be_ra_chordal_coloring(chordal_env); be_timer_pop(T_RA_COLOR); - dump(BE_CH_DUMP_CONSTR, irg, pse->cls, "-color", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_CONSTR, irg, pse->cls, "color"); /* Create the ifg with the selected flavor */ be_timer_push(T_RA_IFG); @@ -359,14 +358,14 @@ static void post_spill(post_spill_env_t *pse, int iteration) co_driver(chordal_env); be_timer_pop(T_RA_COPYMIN); - dump(BE_CH_DUMP_COPYMIN, irg, pse->cls, "-copymin", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_COPYMIN, irg, pse->cls, "copymin"); /* ssa destruction */ be_timer_push(T_RA_SSA); be_ssa_destruction(chordal_env); be_timer_pop(T_RA_SSA); - dump(BE_CH_DUMP_SSADESTR, irg, pse->cls, "-ssadestr", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_SSADESTR, irg, pse->cls, "ssadestr"); if (chordal_env->opts->vrfy_option != BE_CH_VRFY_OFF) { be_timer_push(T_VERIFY); @@ -447,8 +446,7 @@ static void be_ra_chordal_main(be_irg_t *birg) be_do_spill(birg, cls); be_timer_pop(T_RA_SPILL); - dump(BE_CH_DUMP_SPILL, irg, pse.cls, "-spill", - dump_ir_block_graph_sched); + dump(BE_CH_DUMP_SPILL, irg, pse.cls, "spill"); post_spill(&pse, 0); @@ -480,7 +478,7 @@ static void be_ra_chordal_main(be_irg_t *birg) be_timer_push(T_RA_SPILL); arch_code_generator_spill(birg->cg, birg); be_timer_pop(T_RA_SPILL); - dump(BE_CH_DUMP_SPILL, irg, NULL, "-spill", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_SPILL, irg, NULL, "spill"); for (j = 0; j < m; ++j) { post_spill(&pse[j], j); @@ -498,7 +496,7 @@ static void be_ra_chordal_main(be_irg_t *birg) be_timer_push(T_RA_EPILOG); lower_nodes_after_ra(birg, options.lower_perm_opt & BE_CH_LOWER_PERM_COPY ? 1 : 0); - dump(BE_CH_DUMP_LOWER, irg, NULL, "-belower-after-ra", dump_ir_block_graph_sched); + dump(BE_CH_DUMP_LOWER, irg, NULL, "belower-after-ra"); obstack_free(&obst, NULL); be_liveness_invalidate(be_get_birg_liveness(birg)); diff --git a/ir/be/becopystat.c b/ir/be/becopystat.c index 294c372cd..6baefbb89 100644 --- a/ir/be/becopystat.c +++ b/ir/be/becopystat.c @@ -215,6 +215,23 @@ void copystat_add_ilp_iter(int iters) #endif /* WITH_ILP */ +/** + * Opens a file named base.ext with the mode mode. + */ +static FILE *be_ffopen(const char *base, const char *ext, const char *mode) +{ + FILE *out; + char buf[1024]; + + snprintf(buf, sizeof(buf), "%s.%s", base, ext); + buf[sizeof(buf) - 1] = '\0'; + if (! (out = fopen(buf, mode))) { + fprintf(stderr, "Cannot open file %s in mode %s\n", buf, mode); + return NULL; + } + return out; +} + void copystat_dump(ir_graph *irg) { int i; diff --git a/ir/be/beilpsched.c b/ir/be/beilpsched.c index dd8fc9a17..042dcef48 100644 --- a/ir/be/beilpsched.c +++ b/ir/be/beilpsched.c @@ -1948,7 +1948,7 @@ static void create_ilp(ir_node *block, void *walk_env) fclose(f); snprintf(buf, sizeof(buf), "lpp_block_%lu.infeasible.mps", get_irn_node_nr(block)); lpp_dump(lpp, buf); - dump_ir_block_graph(env->irg, "-infeasible"); + dump_ir_graph(env->irg, "infeasible"); } }) diff --git a/ir/be/beinfo.c b/ir/be/beinfo.c index 1cdfcdd71..d27aefcd1 100644 --- a/ir/be/beinfo.c +++ b/ir/be/beinfo.c @@ -29,8 +29,10 @@ #include "beinfo.h" #include "bearch.h" #include "benode.h" +#include "besched.h" #include "irgwalk.h" #include "irnode_t.h" +#include "irdump_t.h" #include "error.h" static copy_attr_func old_phi_copy_attr; @@ -75,8 +77,8 @@ static void new_Phi_copy_attr(ir_graph *irg, const ir_node *old_node, int be_infos_equal(const backend_info_t *info1, const backend_info_t *info2) { - int len = ARR_LEN(info1->out_infos); - int i; + int len = ARR_LEN(info1->out_infos); + int i; if (ARR_LEN(info2->out_infos) != len) return false; @@ -122,9 +124,31 @@ void be_info_init(void) op_Phi->ops.dump_node = be_dump_phi_reg_reqs; } +/** + * Edge hook to dump the schedule edges. + */ +static void sched_edge_hook(FILE *F, ir_node *irn) +{ + if (is_Proj(irn)) + return; + if (get_irn_irg(irn)->be_data == NULL) + return; + + if (sched_is_scheduled(irn) && sched_has_prev(irn)) { + ir_node *prev = sched_prev(irn); + fprintf(F, "edge:{sourcename:\""); + PRINT_NODEID(irn); + fprintf(F, "\" targetname:\""); + PRINT_NODEID(prev); + fprintf(F, "\" color:magenta}\n"); + } +} + void be_info_init_irg(ir_graph *irg) { irg_walk_anchors(irg, init_walker, NULL, NULL); + + set_dump_node_edge_hook(sched_edge_hook); } void be_info_free(void) diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 5cf44ab5f..5ea61114b 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -434,11 +434,10 @@ static void be_done_env(be_main_env_t *env) * @param suffix the suffix for the dumper * @param dumper the dumper to be called */ -static void dump(int mask, ir_graph *irg, const char *suffix, - void (*dumper)(ir_graph *, const char *)) +static void dump(int mask, ir_graph *irg, const char *suffix) { if (be_options.dump_flags & mask) - be_dump(irg, suffix, dumper); + dump_ir_graph(irg, suffix); } /** @@ -446,6 +445,8 @@ static void dump(int mask, ir_graph *irg, const char *suffix, */ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env) { + dump(DUMP_INITIAL, irg, "begin"); + irg->be_data = birg; memset(birg, 0, sizeof(*birg)); @@ -456,8 +457,6 @@ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env) edges_deactivate_kind(irg, EDGE_KIND_DEP); edges_activate_kind(irg, EDGE_KIND_DEP); - dump(DUMP_INITIAL, irg, "-begin", dump_ir_block_graph); - /* set the current graph (this is important for several firm functions) */ current_ir_graph = irg; @@ -477,7 +476,7 @@ static void initialize_birg(be_irg_t *birg, ir_graph *irg, be_main_env_t *env) set_irg_phase_state(irg, phase_backend); be_info_init_irg(irg); - dump(DUMP_INITIAL, irg, "-prepared", dump_ir_block_graph); + dump(DUMP_INITIAL, irg, "prepared"); } #define BE_TIMER_ONLY(code) do { if (be_timing) { code; } } while (0) @@ -637,7 +636,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) birg->abi = be_abi_introduce(birg); be_timer_pop(T_ABI); - dump(DUMP_ABI, irg, "-abi", dump_ir_block_graph); + dump(DUMP_ABI, irg, "abi"); /* do local optimizations */ optimize_graph_df(irg); @@ -653,7 +652,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) edges_deactivate(irg); edges_activate(irg); - dump(DUMP_PREPARED, irg, "-pre_transform", dump_ir_block_graph_sched); + dump(DUMP_PREPARED, irg, "pre_transform"); if (be_options.vrfy_option == BE_VRFY_WARN) { be_check_dominance(irg); @@ -666,7 +665,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) arch_code_generator_prepare_graph(birg->cg); be_timer_pop(T_CODEGEN); - dump(DUMP_PREPARED, irg, "-prepared", dump_ir_block_graph); + dump(DUMP_PREPARED, irg, "prepared"); if (be_options.vrfy_option == BE_VRFY_WARN) { be_check_dominance(irg); @@ -708,7 +707,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) }; be_timer_pop(T_SCHED); - dump(DUMP_SCHED, irg, "-sched", dump_ir_block_graph_sched); + dump(DUMP_SCHED, irg, "sched"); /* check schedule */ be_timer_push(T_VERIFY); @@ -728,7 +727,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) assure_constraints(birg); be_timer_pop(T_CONSTR); - dump(DUMP_SCHED, irg, "-assured", dump_ir_block_graph_sched); + dump(DUMP_SCHED, irg, "assured"); /* stuff needs to be done after scheduling but before register allocation */ be_timer_push(T_RA_PREPARATION); @@ -740,7 +739,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) be_abi_fix_stack_nodes(birg->abi); be_timer_pop(T_ABI); - dump(DUMP_SCHED, irg, "-fix_stack", dump_ir_block_graph_sched); + dump(DUMP_SCHED, irg, "fix_stack"); /* check schedule */ be_timer_push(T_VERIFY); @@ -761,7 +760,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) stat_ev_dbl("bemain_costs_before_ra", be_estimate_irg_costs(irg, birg->exec_freq)); #endif - dump(DUMP_RA, irg, "-ra", dump_ir_block_graph_sched); + dump(DUMP_RA, irg, "ra"); /* let the code generator prepare the graph for emitter */ be_timer_push(T_FINISH); @@ -775,13 +774,13 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) be_abi_fix_stack_bias(birg->abi); be_timer_pop(T_ABI); - dump(DUMP_SCHED, irg, "-fix_stack_after_ra", dump_ir_block_graph_sched); + dump(DUMP_SCHED, irg, "fix_stack_after_ra"); be_timer_push(T_FINISH); arch_code_generator_finish(birg->cg); be_timer_pop(T_FINISH); - dump(DUMP_FINAL, irg, "-finish", dump_ir_block_graph_sched); + dump(DUMP_FINAL, irg, "finish"); stat_ev_if { be_stat_ev("bemain_insns_finish", be_count_insns(irg)); @@ -810,7 +809,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) arch_code_generator_done(birg->cg); be_timer_pop(T_EMIT); - dump(DUMP_FINAL, irg, "-end", dump_ir_block_graph_sched); + dump(DUMP_FINAL, irg, "end"); be_timer_push(T_ABI); be_abi_free(birg->abi); diff --git a/ir/be/benode.c b/ir/be/benode.c index bef1d79b5..36e3ea701 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -1289,7 +1289,7 @@ void be_set_phi_reg_req(ir_node *node, const arch_register_req_t *req) assert(mode_is_datab(get_irn_mode(node))); } -int be_dump_phi_reg_reqs(ir_node *node, FILE *F, dump_reason_t reason) +void be_dump_phi_reg_reqs(FILE *F, ir_node *node, dump_reason_t reason) { switch (reason) { case dump_node_opcode_txt: @@ -1312,8 +1312,6 @@ int be_dump_phi_reg_reqs(ir_node *node, FILE *F, dump_reason_t reason) default: break; } - - return 0; } static const arch_irn_ops_t phi_irn_ops = { @@ -1341,7 +1339,7 @@ static const arch_irn_ops_t phi_irn_ops = { /** * ir_op-Operation: dump a be node to file */ -static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) +static void dump_node(FILE *f, ir_node *irn, dump_reason_t reason) { be_node_attr_t *at = get_irn_attr(irn); @@ -1427,8 +1425,6 @@ static int dump_node(ir_node *irn, FILE *f, dump_reason_t reason) break; } } - - return 0; } /** diff --git a/ir/be/benode.h b/ir/be/benode.h index 4c61c0d3c..901a22c87 100644 --- a/ir/be/benode.h +++ b/ir/be/benode.h @@ -450,7 +450,7 @@ void be_node_set_reg_class_out(ir_node *irn, int pos, const arch_register_class_ */ void be_set_phi_reg_req(ir_node *phi, const arch_register_req_t *req); -int be_dump_phi_reg_reqs(ir_node *node, FILE *F, dump_reason_t reason); +void be_dump_phi_reg_reqs(FILE *out, ir_node *node, dump_reason_t reason); /** * Creates a new phi with associated backend informations diff --git a/ir/be/beprefalloc.c b/ir/be/beprefalloc.c index 6d87e90c3..223081d28 100644 --- a/ir/be/beprefalloc.c +++ b/ir/be/beprefalloc.c @@ -52,6 +52,7 @@ #include "irgwalk.h" #include "irnode_t.h" #include "irprintf.h" +#include "irdump.h" #include "obst.h" #include "raw_bitset.h" #include "unionfind.h" @@ -1920,11 +1921,10 @@ static void be_pref_alloc_cls(void) ir_free_resources(irg, IR_RESOURCE_IRN_LINK); } -static void dump(int mask, ir_graph *irg, const char *suffix, - void (*dumper)(ir_graph *, const char *)) +static void dump(int mask, ir_graph *irg, const char *suffix) { if (birg->main_env->options->dump_flags & mask) - be_dump(irg, suffix, dumper); + dump_ir_graph(irg, suffix); } /** @@ -1937,7 +1937,7 @@ static void spill(void) be_pre_spill_prepare_constr(birg, cls); be_timer_pop(T_RA_CONSTR); - dump(DUMP_RA, irg, "-spillprepare", dump_ir_block_graph_sched); + dump(DUMP_RA, irg, "-spillprepare"); /* spill */ be_timer_push(T_RA_SPILL); @@ -1948,7 +1948,7 @@ static void spill(void) check_for_memory_operands(irg); be_timer_pop(T_RA_SPILL_APPLY); - dump(DUMP_RA, irg, "-spill", dump_ir_block_graph_sched); + dump(DUMP_RA, irg, "-spill"); } /** diff --git a/ir/be/besched.c b/ir/be/besched.c index fbe659964..4f82e46a9 100644 --- a/ir/be/besched.c +++ b/ir/be/besched.c @@ -172,11 +172,6 @@ void be_remove_dead_nodes_from_schedule(be_irg_t *birg) irg_block_walk_graph(irg, remove_dead_nodes_walker, NULL, &env); } -int (have_sched_info)(const ir_graph *irg) -{ - return _have_sched_info(irg); -} - int (sched_get_time_step)(const ir_node *node) { return _sched_get_time_step(node); diff --git a/ir/be/besched.h b/ir/be/besched.h index 439c45e24..0cbe71d42 100644 --- a/ir/be/besched.h +++ b/ir/be/besched.h @@ -41,7 +41,6 @@ void be_sched_dump(FILE *f, ir_graph *irg); * unique to that block. a node schedule before another node has a lower * timestep than this node. */ -int have_sched_info(const ir_graph *irg); int sched_get_time_step(const ir_node *irn); int sched_has_next(const ir_node *irn); int sched_has_prev(const ir_node *irn); @@ -99,16 +98,6 @@ void be_remove_dead_nodes_from_schedule(be_irg_t *birg); #define SCHED_INITIAL_GRANULARITY (1 << 14) #define get_irn_sched_info(irn) (&be_get_info(skip_Proj_const(irn))->sched_info) -/** - * Returns non-zero if schedule information is available - * for a given graph. - * @param irg The graph. - */ -static inline int _have_sched_info(const ir_graph *irg) -{ - return be_info_initialized(irg); -} - /** * Check, if the node is scheduled. * @param irn The node. @@ -411,7 +400,6 @@ int sched_skip_phi_predicator(const ir_node *irn, void *data); */ ir_node *sched_skip(ir_node *from, int forward, sched_predicator_t *predicator, void *data); -#define have_sched_info(irg) _have_sched_info(irg) #define sched_get_time_step(irn) _sched_get_time_step(irn) #define sched_has_next(irn) _sched_has_next(irn) #define sched_has_prev(irn) _sched_has_prev(irn) diff --git a/ir/be/beschedmris.c b/ir/be/beschedmris.c index 6de4f1873..e9e4dfa30 100644 --- a/ir/be/beschedmris.c +++ b/ir/be/beschedmris.c @@ -368,7 +368,7 @@ static void block_walker(ir_node *bl, void *data) fuse_lineages(env); } -static int mris_edge_hook(FILE *F, ir_node *irn) +static void mris_edge_hook(FILE *F, ir_node *irn) { mris_irn_t *mi = get_mris_irn(dump_env, irn); @@ -379,17 +379,15 @@ static int mris_edge_hook(FILE *F, ir_node *irn) PRINT_NODEID(irn); fprintf(F, "\" color:lilac}\n"); } - return 1; } void dump_ir_block_graph_mris(mris_env_t *env, const char *suffix) { - DUMP_NODE_EDGE_FUNC old = get_dump_node_edge_hook(); + dump_node_edge_func old = get_dump_node_edge_hook(); - dump_consts_local(0); set_dump_node_edge_hook(mris_edge_hook); dump_env = env; - dump_ir_block_graph(env->irg, suffix); + dump_ir_graph(env->irg, suffix); set_dump_node_edge_hook(old); } diff --git a/ir/be/beschedrss.c b/ir/be/beschedrss.c index 70091261f..67bc76ebc 100644 --- a/ir/be/beschedrss.c +++ b/ir/be/beschedrss.c @@ -2213,5 +2213,5 @@ void rss_schedule_preparation(be_irg_t *birg) be_liveness_free(rss.liveness); if (birg->main_env->options->dump_flags & DUMP_SCHED) - be_dump(rss.irg, "-rss", dump_ir_block_graph); + dump_ir_graph(rss.irg, "rss"); } diff --git a/ir/be/bessadestr.c b/ir/be/bessadestr.c index 6d6970336..2586a7ebe 100644 --- a/ir/be/bessadestr.c +++ b/ir/be/bessadestr.c @@ -407,7 +407,7 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) be_liveness_invalidate(lv); if (chordal_env->opts->dump_flags & BE_CH_DUMP_SSADESTR) - be_dump(irg, "-ssa_destr_perms_placed", dump_ir_block_graph_sched); + dump_ir_graph(irg, "ssa_destr_perms_placed"); be_liveness_assure_chk(lv); @@ -418,7 +418,7 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) be_liveness_invalidate(lv); if (chordal_env->opts->dump_flags & BE_CH_DUMP_SSADESTR) - be_dump(irg, "-ssa_destr_regs_set", dump_ir_block_graph_sched); + dump_ir_graph(irg, "ssa_destr_regs_set"); pmap_destroy(perm_map); } diff --git a/ir/be/beutil.c b/ir/be/beutil.c index 200faf28a..8819242f2 100644 --- a/ir/be/beutil.c +++ b/ir/be/beutil.c @@ -44,68 +44,6 @@ #include "besched.h" #include "bearch.h" -/** - * Edge hook to dump the schedule edges. - */ -static int sched_edge_hook(FILE *F, ir_node *irn) -{ - if (is_Proj(irn)) - return 1; - if (sched_is_scheduled(irn) && sched_has_prev(irn)) { - ir_node *prev = sched_prev(irn); - fprintf(F, "edge:{sourcename:\""); - PRINT_NODEID(irn); - fprintf(F, "\" targetname:\""); - PRINT_NODEID(prev); - fprintf(F, "\" color:magenta}\n"); - } - return 1; -} - -void dump_ir_block_graph_sched(ir_graph *irg, const char *suffix) -{ - DUMP_NODE_EDGE_FUNC old = get_dump_node_edge_hook(); - - dump_consts_local(0); - if (have_sched_info(irg)) - set_dump_node_edge_hook(sched_edge_hook); - dump_ir_block_graph(irg, suffix); - set_dump_node_edge_hook(old); -} - -void dump_ir_extblock_graph_sched(ir_graph *irg, const char *suffix) -{ - DUMP_NODE_EDGE_FUNC old = get_dump_node_edge_hook(); - - dump_consts_local(0); - if (have_sched_info(irg)) - set_dump_node_edge_hook(sched_edge_hook); - dump_ir_extblock_graph(irg, suffix); - set_dump_node_edge_hook(old); -} - -/** - * Dumps a graph and numbers all dumps. - * @param irg The graph - * @param suffix A suffix to its file name. - * @param dumper The dump function - */ -void be_dump(ir_graph *irg, const char *suffix, void (*dumper)(ir_graph *, const char *)) -{ - static ir_graph *last_irg = NULL; - static int nr = 0; - char buf[128]; - - if (irg != last_irg) { - last_irg = irg; - nr = strcmp(suffix, "-abi") ? 0 : 1; - } - - snprintf(buf, sizeof(buf), "-%02d%s", nr++, suffix); - buf[sizeof(buf) - 1] = '\0'; - dumper(irg, buf); -} - void be_clear_links(ir_graph *irg) { irg_walk_graph(irg, firm_clear_link, NULL, NULL); @@ -144,20 +82,6 @@ ir_node *be_get_Proj_for_pn(const ir_node *irn, long pn) return NULL; } -FILE *be_ffopen(const char *base, const char *ext, const char *mode) -{ - FILE *out; - char buf[1024]; - - snprintf(buf, sizeof(buf), "%s.%s", base, ext); - buf[sizeof(buf) - 1] = '\0'; - if (! (out = fopen(buf, mode))) { - fprintf(stderr, "Cannot open file %s in mode %s\n", buf, mode); - return NULL; - } - return out; -} - static void add_to_postorder(ir_node *block, void *data) { ir_node ***list = (ir_node***) data; diff --git a/ir/be/beutil.h b/ir/be/beutil.h index e33d9bb1a..0404d18b8 100644 --- a/ir/be/beutil.h +++ b/ir/be/beutil.h @@ -86,28 +86,6 @@ static inline int is_data_node(const ir_node *irn) */ void be_clear_links(ir_graph *irg); -/** - * Dump a graph with schedule edges. - * @param irg The graph. - * @param suffix A suffix to its file name. - */ -void dump_ir_block_graph_sched(ir_graph *irg, const char *suffix); - -/** - * Dump a extended block graph with schedule edges. - * @param irg The graph. - * @param suffix A suffix to its file name. - */ -void dump_ir_extblock_graph_sched(ir_graph *irg, const char *suffix); - -/** - * Dumps a graph and numbers all dumps. - * @param irg The graph - * @param suffix A suffix to its file name. - * @param dumper The dump function - */ -void be_dump(ir_graph *irg, const char *suffix, void (*dumper)(ir_graph *, const char *)); - /** * Returns the number of reachable nodes in an irg. * @param irg The irg. @@ -127,11 +105,6 @@ ir_node *be_get_Proj_for_pn(const ir_node *irn, long pn); */ ir_node **be_get_cfgpostorder(ir_graph *irg); -/** - * Opens a file named base.ext with the mode mode. - */ -FILE *be_ffopen(const char *base, const char *ext, const char *mode); - /** * convenience function to return the first successor block * (it is often known that there is exactly 1 successor anyway) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 1228eac7b..171497a16 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -42,6 +42,7 @@ #include "irgopt.h" #include "irbitset.h" #include "irgopt.h" +#include "irdump.h" #include "pdeq.h" #include "pset.h" #include "debug.h" @@ -854,7 +855,7 @@ static void ia32_before_abi(void *self) ir_lower_mode_b(cg->irg, &lower_mode_b_config); if (cg->dump) - be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "lower_modeb"); if (cg->gprof) { if (mcount == NULL) { @@ -900,7 +901,7 @@ static void ia32_prepare_graph(void *self) optimize_graph_df(cg->irg); if (cg->dump) - be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "transformed"); /* optimize address mode */ ia32_optimize_graph(cg); @@ -909,7 +910,7 @@ static void ia32_prepare_graph(void *self) place_code(cg->irg); if (cg->dump) - be_dump(cg->irg, "-place", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "place"); } ir_node *turn_back_am(ir_node *node) diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index a0a1cf6a8..7db5bce8d 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -73,10 +73,9 @@ * @param reason indicates which kind of information should be dumped * @return 0 on success or != 0 on failure */ -static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void ia32_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { - ir_mode *mode = NULL; - int bad = 0; + ir_mode *mode = NULL; switch (reason) { case dump_node_opcode_txt: @@ -250,8 +249,6 @@ static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) break; } - - return bad; } diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 05e1470d7..752a83a01 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -37,6 +37,7 @@ #include "height.h" #include "irbitset.h" #include "irprintf.h" +#include "irdump.h" #include "error.h" #include "../be_t.h" @@ -1477,7 +1478,7 @@ void ia32_optimize_graph(ia32_code_gen_t *cg) irg_walk_blkwise_graph(cg->irg, NULL, optimize_node, cg); if (cg->dump) - be_dump(cg->irg, "-opt", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "opt"); } void ia32_init_optimize(void) diff --git a/ir/be/mips/bearch_mips.c b/ir/be/mips/bearch_mips.c index 47ffc82b8..61adafa1a 100644 --- a/ir/be/mips/bearch_mips.c +++ b/ir/be/mips/bearch_mips.c @@ -200,7 +200,7 @@ static void mips_prepare_graph(void *self) // walk the graph and transform firm nodes into mips nodes where possible mips_transform_graph(cg); - dump_ir_block_graph_sched(cg->irg, "-transformed"); + dump_ir_graph(cg->irg, "transformed"); /* do local optimizations (mainly CSE) */ optimize_graph_df(cg->irg); @@ -208,7 +208,7 @@ static void mips_prepare_graph(void *self) /* do code placement, to optimize the position of constants */ place_code(cg->irg); - be_dump(cg->irg, "-place", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "place"); } /** @@ -223,7 +223,7 @@ static void mips_finish_irg(void *self) * produce critical edges */ cg->block_schedule = be_create_block_schedule(irg); - dump_ir_block_graph_sched(irg, "-mips-finished"); + dump_ir_graph(irg, "mips-finished"); } diff --git a/ir/be/mips/mips_new_nodes.c b/ir/be/mips/mips_new_nodes.c index 130fef89b..087883ab3 100644 --- a/ir/be/mips/mips_new_nodes.c +++ b/ir/be/mips/mips_new_nodes.c @@ -61,12 +61,11 @@ /** * Dumper interface for dumping mips nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int mips_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void mips_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { switch (reason) { case dump_node_opcode_txt: @@ -110,8 +109,6 @@ static int mips_dump_node(ir_node *n, FILE *F, dump_reason_t reason) arch_dump_reqs_and_registers(F, n); break; } - - return 0; } diff --git a/ir/be/ppc32/bearch_ppc32.c b/ir/be/ppc32/bearch_ppc32.c index 19f0a6e3c..11ee9a12f 100644 --- a/ir/be/ppc32/bearch_ppc32.c +++ b/ir/be/ppc32/bearch_ppc32.c @@ -292,11 +292,11 @@ static void ppc32_prepare_graph(void *self) irg_block_walk_graph(cg->irg, NULL, ppc32_search_start_successor, cg); irg_walk_blkwise_graph(cg->irg, NULL, ppc32_pretransform_walk, cg); - be_dump(cg->irg, "-pretransformed", dump_ir_block_graph); + dump_ir_graph(cg->irg, "pretransformed"); ppc32_register_transformers(); irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_node, cg); - be_dump(cg->irg, "-transformed", dump_ir_block_graph); + dump_ir_graph(cg->irg, "transformed"); irg_walk_blkwise_graph(cg->irg, NULL, ppc32_transform_const, cg); } @@ -421,7 +421,7 @@ static void ppc32_emit_and_done(void *self) ppc32_code_gen_t *cg = self; ir_graph *irg = cg->irg; - dump_ir_block_graph_sched(irg, "-ppc-finished"); + dump_ir_graph(irg, "ppc-finished"); ppc32_gen_routine(cg, irg); /* de-allocate code generator */ diff --git a/ir/be/ppc32/ppc32_new_nodes.c b/ir/be/ppc32/ppc32_new_nodes.c index 3ecb8b1fa..b191235c6 100644 --- a/ir/be/ppc32/ppc32_new_nodes.c +++ b/ir/be/ppc32/ppc32_new_nodes.c @@ -61,15 +61,13 @@ /** * Dumper interface for dumping ppc32 nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int ppc32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void ppc32_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { - ir_mode *mode = NULL; - int bad = 0; + ir_mode *mode = NULL; switch (reason) { case dump_node_opcode_txt: @@ -98,9 +96,6 @@ static int ppc32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) arch_dump_reqs_and_registers(F, n); break; } - - - return bad; } diff --git a/ir/be/sparc/bearch_sparc.c b/ir/be/sparc/bearch_sparc.c index 901b86ef0..80ae68d1b 100644 --- a/ir/be/sparc/bearch_sparc.c +++ b/ir/be/sparc/bearch_sparc.c @@ -36,13 +36,14 @@ #include "irgmod.h" #include "irgopt.h" #include "iroptimize.h" +#include "irtools.h" +#include "irdump.h" #include "lowering.h" -#include "error.h" #include "bitset.h" #include "debug.h" #include "array_t.h" -#include "irtools.h" +#include "error.h" #include "../bearch.h" #include "../benode.h" @@ -154,7 +155,7 @@ static void sparc_prepare_graph(void *self) sparc_transform_graph(cg); if (cg->dump) - be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched); + dump_ir_graph(cg->irg, "transformed"); } diff --git a/ir/be/sparc/sparc_new_nodes.c b/ir/be/sparc/sparc_new_nodes.c index 666e6b4e0..77139558b 100644 --- a/ir/be/sparc/sparc_new_nodes.c +++ b/ir/be/sparc/sparc_new_nodes.c @@ -47,12 +47,11 @@ /** * Dumper interface for dumping sparc nodes in vcg. - * @param n the node to dump * @param F the output file + * @param n the node to dump * @param reason indicates which kind of information should be dumped - * @return 0 on success or != 0 on failure */ -static int sparc_dump_node(ir_node *n, FILE *F, dump_reason_t reason) +static void sparc_dump_node(FILE *F, ir_node *n, dump_reason_t reason) { ir_mode *mode = NULL; @@ -93,11 +92,7 @@ static int sparc_dump_node(ir_node *n, FILE *F, dump_reason_t reason) } break; - - } - - return 0; } /* ATTRIBUTE INIT SETTERS / HELPERS */ diff --git a/ir/debug/debugger.c b/ir/debug/debugger.c index 596968723..1a4fa1b00 100644 --- a/ir/debug/debugger.c +++ b/ir/debug/debugger.c @@ -677,10 +677,10 @@ static void show_firm_object(void *firm_thing) fprintf(f, "BAD: (%p)\n", firm_thing); break; case k_entity: - dump_entity_to_file(f, firm_thing, dump_verbosity_max); + dump_entity_to_file(f, firm_thing); break; case k_type: - dump_type_to_file(f, firm_thing, dump_verbosity_max); + dump_type_to_file(f, firm_thing); break; case k_ir_graph: case k_ir_node: diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 6ec36993d..2d5357edb 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -20,7 +20,8 @@ /** * @file * @brief Write vcg representation of firm to file. - * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt + * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt, + * Matthias Braun * @version $Id$ */ #include "config.h" @@ -28,6 +29,8 @@ #include #include #include +#include +#include #include "list.h" @@ -58,6 +61,7 @@ #include "error.h" #include "array.h" #include "pmap.h" +#include "obst.h" #include "eset.h" #include "pset.h" #include "util.h" @@ -65,230 +69,124 @@ /** Dump only irgs with names that start with this prefix. */ static ident *dump_file_filter_id = NULL; -#define ERROR_TXT "" - -/*******************************************************************/ -/* flags to steer output */ -/*******************************************************************/ - -/** An option to turn off edge labels */ -static int edge_label = 1; -/** An option to turn off dumping values of constant entities */ -static int const_entities = 1; -/** An option to dump the keep alive edges */ -static int dump_keepalive = 1; -/** An option to dump the new out edges */ -static int dump_new_edges_flag = 0; -/** An option to dump ld_names instead of names. */ -static int dump_ld_name = 1; -/** Compiler options to dump analysis information in dump_ir_graph */ -static int dump_out_edge_flag = 0; -static int dump_loop_information_flag = 0; -static int dump_backedge_information_flag = 1; -/** An option to dump const-like nodes locally. */ -static int dump_const_local = 1; -/** An option to dump the node index number. */ -static int dump_node_idx_labels = 1; -/** An option to dump the node number */ -static int dump_node_nr = 1; -/** An option to dump all graph anchors */ -static int dump_anchors = 0; -/** An option to dump the macro block edges. */ -static int dump_macro_block_edges = 0; -/** An option to dump block marker in the block title */ -static int dump_block_marker = 0; - -int dump_dominator_information_flag = 0; -int opt_dump_analysed_type_info = 1; -int opt_dump_pointer_values_to_info = 0; /* default off: for test compares!! */ +static ir_dump_flags_t flags = + ir_dump_flag_blocks_as_subgraphs | + ir_dump_flag_keepalive_edges | + ir_dump_flag_ld_names | + ir_dump_flag_back_edges | + ir_dump_flag_consts_local | + ir_dump_flag_analysed_types | + ir_dump_flag_entities_in_hierarchy; static ird_color_t overrule_nodecolor = ird_color_default_node; /** The vcg node attribute hook. */ -static DUMP_IR_GRAPH_FUNC dump_ir_graph_hook = NULL; -/** The vcg node attribute hook. */ -static DUMP_NODE_VCGATTR_FUNC dump_node_vcgattr_hook = NULL; +static dump_node_vcgattr_func dump_node_vcgattr_hook = NULL; /** The vcg edge attribute hook. */ -static DUMP_EDGE_VCGATTR_FUNC dump_edge_vcgattr_hook = NULL; +static dump_edge_vcgattr_func dump_edge_vcgattr_hook = NULL; /** The vcg dump block edge hook */ -static DUMP_NODE_EDGE_FUNC dump_block_edge_hook = NULL; +static dump_node_edge_func dump_block_edge_hook = NULL; /** The vcg dump node edge hook. */ -static DUMP_NODE_EDGE_FUNC dump_node_edge_hook = NULL; +static dump_node_edge_func dump_node_edge_hook = NULL; -/* Set the hook to be called to dump additional edges to a node. */ -void set_dump_node_edge_hook(DUMP_NODE_EDGE_FUNC func) +void set_dump_node_edge_hook(dump_node_edge_func func) { dump_node_edge_hook = func; } -/* Get the additional edge dump hook. */ -DUMP_NODE_EDGE_FUNC get_dump_node_edge_hook(void) +dump_node_edge_func get_dump_node_edge_hook(void) { return dump_node_edge_hook; } -/* Set the hook to be called to dump additional edges to a block. */ -void set_dump_block_edge_hook(DUMP_NODE_EDGE_FUNC func) +void set_dump_block_edge_hook(dump_node_edge_func func) { dump_block_edge_hook = func; } -/* Get the additional block edge dump hook. */ -DUMP_NODE_EDGE_FUNC get_dump_block_edge_hook(void) +dump_node_edge_func get_dump_block_edge_hook(void) { return dump_node_edge_hook; } -/* set the ir graph hook */ -void set_dump_ir_graph_hook(DUMP_IR_GRAPH_FUNC hook) -{ - dump_ir_graph_hook = hook; -} - -/* set the node attribute hook */ -void set_dump_node_vcgattr_hook(DUMP_NODE_VCGATTR_FUNC hook) +void set_dump_node_vcgattr_hook(dump_node_vcgattr_func hook) { dump_node_vcgattr_hook = hook; } -/* set the edge attribute hook */ -void set_dump_edge_vcgattr_hook(DUMP_EDGE_VCGATTR_FUNC hook) +void set_dump_edge_vcgattr_hook(dump_edge_vcgattr_func hook) { dump_edge_vcgattr_hook = hook; } -/** Returns 0 if dump_out_edge_flag or dump_loop_information_flag - * are set, else returns dump_const_local_flag. - */ -static int get_opt_dump_const_local(void) -{ - if (dump_out_edge_flag || dump_loop_information_flag || (dump_new_edges_flag && edges_activated(current_ir_graph))) - return 0; - return dump_const_local; -} - -/* Set a prefix filter for output functions. */ -void only_dump_method_with_name(ident *name) -{ - dump_file_filter_id = name; -} - -/* Returns the prefix filter set with only_dump_method_with_name(). */ -ident *get_dump_file_filter_ident(void) -{ - return dump_file_filter_id; -} - -/* Returns non-zero if dump file filter is not set, or if it is a prefix of name. */ -int is_filtered_dump_name(ident *name) -{ - if (!dump_file_filter_id) return 1; - return id_is_prefix(dump_file_filter_id, name); -} - -/* To turn off display of edge labels. Edge labels often cause xvcg to - abort with a segmentation fault. */ -void turn_off_edge_labels(void) -{ - edge_label = 0; -} - -void dump_consts_local(int flag) -{ - dump_const_local = flag; -} - -void dump_node_idx_label(int flag) -{ - dump_node_idx_labels = flag; -} - -void dump_constant_entity_values(int flag) +void ir_set_dump_flags(ir_dump_flags_t new_flags) { - const_entities = flag; + flags = new_flags; } -void dump_keepalive_edges(int flag) +void ir_add_dump_flags(ir_dump_flags_t new_flags) { - dump_keepalive = flag; + flags |= new_flags; } -void dump_new_edges(int flag) +void ir_remove_dump_flags(ir_dump_flags_t to_remove) { - dump_new_edges_flag = flag; + flags &= ~to_remove; } -int get_opt_dump_keepalive_edges(void) +ir_dump_flags_t ir_get_dump_flags(void) { - return dump_keepalive; + return flags; } -void dump_out_edges(int flag) -{ - dump_out_edge_flag = flag; -} - -void dump_dominator_information(int flag) -{ - dump_dominator_information_flag = flag; -} - -void dump_loop_information(int flag) -{ - dump_loop_information_flag = flag; -} - -void dump_backedge_information(int flag) -{ - dump_backedge_information_flag = flag; -} - -/* Dump the information of type field specified in ana/irtypeinfo.h. - * If the flag is set, the type name is output in [] in the node label, - * else it is output as info. +/** Returns 0 if dump_out_edge_flag or dump_loop_information_flag + * are set, else returns dump_const_local_flag. */ -void set_opt_dump_analysed_type_info(int flag) +static bool get_opt_dump_const_local(void) { - opt_dump_analysed_type_info = flag; + return (flags & ir_dump_flag_out_edges) + || (flags & ir_dump_flag_loops) + || (flags & ir_dump_flag_consts_local) + || (flags & ir_dump_flag_iredges); } -void dump_pointer_values_to_info(int flag) -{ - opt_dump_pointer_values_to_info = flag; -} +static char *dump_filter; -void dump_ld_names(int flag) +void ir_set_dump_filter(const char *new_filter) { - dump_ld_name = flag; + xfree(dump_filter); + dump_filter = xstrdup(new_filter); } -void dump_all_anchors(int flag) +const char *ir_get_dump_filter(void) { - dump_anchors = flag; + return dump_filter; } -void dump_macroblock_edges(int flag) +int ir_should_dump(const char *name) { - dump_macro_block_edges = flag; -} + const char *f, *n; -void dump_block_marker_in_title(int flag) -{ - dump_block_marker = flag; + if (dump_filter == NULL || dump_filter[0] == '\0') + return 1; + + for (n = name, f = dump_filter; *f != '\0' && *n != '\0'; + ++n, ++f) { + if (*n != *f) + return 0; + } + return 1; } /* -------------- some extended helper functions ----------------- */ -/** - * returns the name of a mode or ERROR_TXT if mode is NOT a mode object. - * in the later case, sets bad. - */ const char *get_mode_name_ex(const ir_mode *mode, int *bad) { if (is_mode(mode)) return get_mode_name(mode); - *bad |= 1; - return ERROR_TXT; + if (bad != NULL) + *bad |= 1; + return ""; } #define CUSTOM_COLOR_BASE 100 @@ -345,10 +243,10 @@ static void init_colors(void) /** * Prints the VCG color to a file. */ -static void print_vcg_color(FILE *F, ird_color_t color) +static void print_vcg_color(FILE *out, ird_color_t color) { assert(color < ird_color_count); - fprintf(F, "color:%s", color_names[color]); + fprintf(out, "color:%s", color_names[color]); } /** @@ -356,12 +254,12 @@ static void print_vcg_color(FILE *F, ird_color_t color) * * Projs should be dumped near their predecessor, so they get "nearedge". */ -static void print_node_edge_kind(FILE *F, ir_node *node) +static void print_node_edge_kind(FILE *out, ir_node *node) { if (is_Proj(node)) { - fprintf(F, "nearedge: "); + fprintf(out, "nearedge: "); } else { - fprintf(F, "edge: "); + fprintf(out, "edge: "); } } @@ -505,8 +403,8 @@ static void print_enum_item_edge(FILE *F, const ir_type *tp, int item, const cha /* global and ahead declarations */ /*-----------------------------------------------------------------*/ -static void dump_whole_node(ir_node *n, void *env); -static inline void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg); +static void dump_node_with_edges(ir_node *n, void *env); +static void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg); /*-----------------------------------------------------------------*/ /* Helper functions. */ @@ -595,7 +493,7 @@ static void clear_link(ir_node *node, void *env) * If the entity has a ld_name, returns it if the dump_ld_name is set, * else returns the name of the entity. */ -static const char *_get_ent_dump_name(const ir_entity *ent, int dump_ld_name) +static const char *_get_ent_dump_name(const ir_entity *ent, bool dump_ld_name) { if (ent == NULL) return ""; @@ -607,20 +505,15 @@ static const char *_get_ent_dump_name(const ir_entity *ent, int dump_ld_name) return get_id_str(ent->name); } -/** - * If the entity has a ld_name, returns it if the option dump_ld_name is set, - * else returns the name of the entity. - */ const char *get_ent_dump_name(const ir_entity *ent) { - return _get_ent_dump_name(ent, dump_ld_name); + return _get_ent_dump_name(ent, flags & ir_dump_flag_ld_names); } -/* Returns the name of an IRG. */ const char *get_irg_dump_name(const ir_graph *irg) { /* Don't use get_entity_ld_ident (ent) as it computes the mangled name! */ - return _get_ent_dump_name(get_irg_entity(irg), 1); + return _get_ent_dump_name(get_irg_entity(irg), true); } /** @@ -637,7 +530,8 @@ static int node_floats(const ir_node *n) */ static void ird_walk_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *post, void *env) { - if (dump_anchors || (dump_new_edges_flag && edges_activated(irg))) { + if ((flags & ir_dump_flag_all_anchors) + || ((flags & ir_dump_flag_iredges) && edges_activated(irg))) { irg_walk_anchors(irg, pre, post, env); } else { irg_walk_graph(irg, pre, post, env); @@ -645,7 +539,8 @@ static void ird_walk_graph(ir_graph *irg, irg_walk_func *pre, irg_walk_func *pos } /** - * Walker, allocates an array for all blocks and puts it's nodes non-floating nodes into this array. + * Walker, allocates an array for all blocks and puts it's nodes non-floating + * nodes into this array. */ static void collect_node(ir_node *node, void *env) { @@ -729,9 +624,8 @@ typedef struct _list_tuple { } list_tuple; /** Construct lists to walk IR extended block-wise. - * Free the lists in the tuple with DEL_ARR_F(). - * Sets the irg link field to NULL in all - * graphs not visited. + * Free the lists in the tuple with DEL_ARR_F(). Sets the irg link field to + * NULL in all graphs not visited. */ static list_tuple *construct_extblock_lists(ir_graph *irg) { @@ -766,21 +660,15 @@ static list_tuple *construct_extblock_lists(ir_graph *irg) return lists; } -/*-----------------------------------------------------------------*/ -/* Routines to dump information about a single ir node. */ -/*-----------------------------------------------------------------*/ - -/* - * dump the name of a node n to the File F. - */ -int dump_node_opcode(FILE *F, ir_node *n) +void dump_node_opcode(FILE *F, ir_node *n) { - int bad = 0; const ir_op_ops *ops = get_op_ops(get_irn_op(n)); /* call the dump_node operation if available */ - if (ops->dump_node) - return ops->dump_node(n, F, dump_node_opcode_txt); + if (ops->dump_node) { + ops->dump_node(F, n, dump_node_opcode_txt); + return; + } /* implementation for default nodes */ switch (get_irn_opcode(n)) { @@ -853,7 +741,7 @@ int dump_node_opcode(FILE *F, ir_node *n) case iro_Load: if (get_Load_align(n) == align_non_aligned) fprintf(F, "ua"); - fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), &bad)); + fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Load_mode(n), NULL)); break; case iro_Store: if (get_Store_align(n) == align_non_aligned) @@ -868,7 +756,7 @@ int dump_node_opcode(FILE *F, ir_node *n) if (n == get_irg_end_block(get_irn_irg(n))) fputs("End ", F); fprintf(F, "%s%s", get_irn_opname(n), - dump_block_marker ? (get_Block_mark(n) ? "*" : "") : ""); + (flags & ir_dump_flag_show_marks) ? (get_Block_mark(n) ? "*" : "") : ""); break; case iro_Conv: if (get_Conv_strict(n)) @@ -879,13 +767,13 @@ int dump_node_opcode(FILE *F, ir_node *n) fprintf(F, "%s", get_irn_opname(n)); if (get_Div_no_remainder(n)) fprintf(F, "RL"); - fprintf(F, "[%s]", get_mode_name_ex(get_Div_resmode(n), &bad)); + fprintf(F, "[%s]", get_mode_name_ex(get_Div_resmode(n), NULL)); break; case iro_Mod: - fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Mod_resmode(n), &bad)); + fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_Mod_resmode(n), NULL)); break; case iro_DivMod: - fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), &bad)); + fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), NULL)); break; case iro_Builtin: fprintf(F, "%s[%s]", get_irn_opname(n), get_builtin_kind_name(get_Builtin_kind(n))); @@ -894,25 +782,24 @@ int dump_node_opcode(FILE *F, ir_node *n) default: default_case: fprintf(F, "%s", get_irn_opname(n)); - - } /* end switch */ - return bad; + } } /** * Dump the mode of a node n to a file F. * Ignore modes that are "always known". */ -static int dump_node_mode(FILE *F, ir_node *n) +static void dump_node_mode(FILE *F, ir_node *n) { - int bad = 0; const ir_op_ops *ops = get_op_ops(get_irn_op(n)); ir_opcode iro; ir_mode *mode; /* call the dump_node operation if available */ - if (ops->dump_node) - return ops->dump_node(n, F, dump_node_mode_txt); + if (ops->dump_node) { + ops->dump_node(F, n, dump_node_mode_txt); + return; + } /* default implementation */ iro = get_irn_opcode(n); @@ -931,9 +818,8 @@ static int dump_node_mode(FILE *F, ir_node *n) if (mode != NULL && mode != mode_BB && mode != mode_ANY && mode != mode_BAD && (mode != mode_T || iro == iro_Proj)) - fprintf(F, "%s", get_mode_name_ex(mode, &bad)); + fprintf(F, "%s", get_mode_name_ex(mode, NULL)); } - return bad; } /** @@ -943,7 +829,7 @@ static int dump_node_typeinfo(FILE *F, ir_node *n) { int bad = 0; - if (opt_dump_analysed_type_info) { + if (ir_get_dump_flags() & ir_dump_flag_analysed_types) { if (get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_consistent || get_irg_typeinfo_state(current_ir_graph) == ir_typeinfo_inconsistent) { ir_type *tp = get_irn_typeinfo_type(n); @@ -1127,17 +1013,18 @@ static const proj_lookup_t proj_lut[] = { /** * Dump additional node attributes of some nodes to a file F. */ -static int dump_node_nodeattr(FILE *F, ir_node *n) +static void dump_node_nodeattr(FILE *F, ir_node *n) { - int bad = 0; ir_node *pred; ir_opcode code; long proj_nr; const ir_op_ops *ops = get_op_ops(get_irn_op(n)); /* call the dump_node operation if available */ - if (ops->dump_node) - return ops->dump_node(n, F, dump_node_nodeattr_txt); + if (ops->dump_node) { + ops->dump_node(F, n, dump_node_nodeattr_txt); + return; + } switch (get_irn_opcode(n)) { case iro_Const: @@ -1210,8 +1097,6 @@ handle_lut: default: ; } /* end switch */ - - return bad; } #include @@ -1221,7 +1106,6 @@ static void dump_node_ana_vals(FILE *F, ir_node *n) { (void) F; (void) n; - return; #ifdef INTERPROCEDURAL_VIEW fprintf(F, " %lf*(%2.0lf + %2.0lf) = %2.0lf ", get_irn_exec_freq(n), @@ -1230,36 +1114,30 @@ static void dump_node_ana_vals(FILE *F, ir_node *n) get_irn_exec_freq(n) * (get_irg_method_execution_frequency(get_irn_irg(n)) + pow(5, get_irg_recursion_depth(get_irn_irg(n)))) ); #endif + return; } - -/* Dumps a node label without the enclosing ". */ -int dump_node_label(FILE *F, ir_node *n) +void dump_node_label(FILE *F, ir_node *n) { - int bad = 0; - - bad |= dump_node_opcode(F, n); + dump_node_opcode(F, n); fputs(" ", F); - bad |= dump_node_mode(F, n); + dump_node_mode(F, n); fprintf(F, " "); - bad |= dump_node_typeinfo(F, n); - bad |= dump_node_nodeattr(F, n); - if (dump_node_nr) { + dump_node_typeinfo(F, n); + dump_node_nodeattr(F, n); + if (flags & ir_dump_flag_number_label) { fprintf(F, "%ld", get_irn_node_nr(n)); } - if (dump_node_idx_labels) { + if (flags & ir_dump_flag_idx_label) { fprintf(F, ":%u", get_irn_idx(n)); } - - return bad; } -/* Dumps the vrp information of a node to a file */ -int dump_vrp_info(FILE *F, ir_node *n) +void dump_vrp_info(FILE *F, ir_node *n) { vrp_attr *vrp = vrp_get_info(n); - if (!n) { - return 1; + if (n == NULL) { + return; } fprintf(F, "range_type: %d\n", (int) vrp->range_type); @@ -1270,8 +1148,6 @@ int dump_vrp_info(FILE *F, ir_node *n) } ir_fprintf(F, "bits_set: %T\n", vrp->bits_set); ir_fprintf(F, "bits_not_set: %T\n", vrp->bits_not_set); - - return 0; } /** @@ -1288,9 +1164,10 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) return; } - if (dump_node_vcgattr_hook) - if (dump_node_vcgattr_hook(F, node, local)) - return; + if (dump_node_vcgattr_hook != NULL) { + dump_node_vcgattr_hook(F, node, local); + return; + } n = local ? local : node; @@ -1352,7 +1229,6 @@ static void dump_node_vcgattr(FILE *F, ir_node *node, ir_node *local, int bad) } } -/* Adds a new node info dumper callback. */ void *dump_add_node_info_callback(dump_node_info_cb_t *cb, void *data) { hook_entry_t *info = XMALLOC(hook_entry_t); @@ -1364,8 +1240,7 @@ void *dump_add_node_info_callback(dump_node_info_cb_t *cb, void *data) return info; } -/* Remove a previously added info dumper callback. */ -void dump_remv_node_info_callback(void *handle) +void dump_remove_node_info_callback(void *handle) { hook_entry_t *info = handle; unregister_hook(hook_node_info, info); @@ -1375,25 +1250,22 @@ void dump_remv_node_info_callback(void *handle) /** * Dump the node information of a node n to a file F. */ -static inline int dump_node_info(FILE *F, ir_node *n) +static void dump_node_info(FILE *F, ir_node *n) { - int bad = 0; const ir_op_ops *ops = get_op_ops(get_irn_op(n)); fprintf(F, " info1: \""); - bad = dump_irnode_to_file(F, n); + dump_irnode_to_file(F, n); /* call the dump_node operation if available */ if (ops->dump_node) - bad = ops->dump_node(n, F, dump_node_info_txt); + ops->dump_node(F, n, dump_node_info_txt); /* allow additional info to be added */ hook_node_info(F, n); fprintf(F, "\"\n"); - - return bad; } -static inline int is_constlike_node(const ir_node *node) +static int is_constlike_node(const ir_node *node) { const ir_op *op = get_irn_op(node); return is_op_constlike(op); @@ -1419,17 +1291,15 @@ static void dump_const_node_local(FILE *F, ir_node *n) for (i = 0; i < get_irn_arity(n); i++) { ir_node *con = get_irn_n(n, i); if (is_constlike_node(con) && !irn_visited(con)) { - int bad = 0; - mark_irn_visited(con); /* Generate a new name for the node by appending the names of n and const. */ fprintf(F, "node: {title: "); PRINT_CONSTID(n, con); fprintf(F, " label: \""); - bad |= dump_node_label(F, con); + dump_node_label(F, con); fprintf(F, "\" "); - bad |= dump_node_info(F, con); - dump_node_vcgattr(F, n, con, bad); + dump_node_info(F, con); + dump_node_vcgattr(F, n, con, 0); fprintf(F, "}\n"); } } @@ -1444,16 +1314,14 @@ static void dump_const_block_local(FILE *F, ir_node *n) blk = get_nodes_block(n); if (is_constlike_node(blk)) { - int bad = 0; - /* Generate a new name for the node by appending the names of n and blk. */ fprintf(F, "node: {title: \""); PRINT_CONSTBLKID(n, blk); fprintf(F, "\" label: \""); - bad |= dump_node_label(F, blk); + dump_node_label(F, blk); fprintf(F, "\" "); - bad |= dump_node_info(F, blk); - dump_node_vcgattr(F, n, blk, bad); + dump_node_info(F, blk); + dump_node_vcgattr(F, n, blk, 0); fprintf(F, "}\n"); fprintf(F, "edge: { sourcename: \""); @@ -1524,7 +1392,7 @@ static void dump_node(FILE *F, ir_node *n) fputs(" label: \"", F); bad = ! irn_vrfy_irg_dump(n, current_ir_graph, &p); - bad |= dump_node_label(F, n); + dump_node_label(F, n); dump_node_ana_vals(F, n); //dump_node_ana_info(F, n); fputs("\" ", F); @@ -1533,7 +1401,7 @@ static void dump_node(FILE *F, ir_node *n) //fputs(" node_class:23", F); } - bad |= dump_node_info(F, n); + dump_node_info(F, n); print_node_error(F, p); print_dbg_info(F, get_irn_dbg_info(n)); dump_node_vcgattr(F, n, NULL, bad); @@ -1608,7 +1476,7 @@ static void print_edge_vcgattr(FILE *F, ir_node *from, int to) if (dump_edge_vcgattr_hook(F, from, to)) return; - if (dump_backedge_information_flag && is_backedge(from, to)) + if ((flags & ir_dump_flag_back_edges) && is_backedge(from, to)) fprintf(F, BACK_EDGE_ATTR); switch (get_irn_opcode(from)) { @@ -1647,7 +1515,7 @@ static void dump_ir_data_edges(FILE *F, ir_node *n) { int i, num; - if (!dump_keepalive && is_End(n)) { + if (!(flags & ir_dump_flag_keepalive_edges) && is_End(n)) { /* the End node has only keep-alive edges */ return; } @@ -1684,9 +1552,9 @@ static void dump_ir_data_edges(FILE *F, ir_node *n) continue; /* pred not dumped */ #endif - if (dump_backedge_information_flag && is_backedge(n, i)) + if ((flags & ir_dump_flag_back_edges) && is_backedge(n, i)) { fprintf(F, "backedge: {sourcename: \""); - else { + } else { print_node_edge_kind(F, n); fprintf(F, "{sourcename: \""); } @@ -1702,7 +1570,7 @@ static void dump_ir_data_edges(FILE *F, ir_node *n) fprintf(F, "}\n"); } - if (dump_macro_block_edges && is_Block(n)) { + if ((flags & ir_dump_flag_macroblock_edges) && is_Block(n)) { ir_node *mb = get_Block_MacroBlock(n); fprintf(F, "edge: {sourcename: \""); PRINT_NODEID(n); @@ -1716,17 +1584,18 @@ static void dump_ir_data_edges(FILE *F, ir_node *n) /** * Dump the ir_edges */ -static void dump_ir_edges(FILE *F, ir_node *n) +static void dump_ir_edges(ir_node *node, void *env) { + int i = 0; + FILE *F = env; const ir_edge_t *edge; - int i = 0; - foreach_out_edge(n, edge) { + foreach_out_edge(node, edge) { ir_node *succ = get_edge_src_irn(edge); print_node_edge_kind(F, succ); fprintf(F, "{sourcename: \""); - PRINT_NODEID(n); + PRINT_NODEID(node); fprintf(F, "\" targetname: \""); PRINT_NODEID(succ); fprintf(F, "\""); @@ -1748,14 +1617,12 @@ static void dump_node_wo_blockedge(ir_node *n, void *env) } /** Dumps a node and its edges. */ -static void dump_whole_node(ir_node *n, void *env) +static void dump_node_with_edges(ir_node *n, void *env) { FILE *F = env; dump_node_wo_blockedge(n, env); if (!node_floats(n)) dump_ir_block_edge(F, n); - if (dump_new_edges_flag && edges_activated(current_ir_graph)) - dump_ir_edges(F, n); } /** Dumps a const-like node. */ @@ -1769,21 +1636,22 @@ static void dump_const_node(ir_node *n, void *env) /* the following routines dump the nodes/irgs bracketed to graphs. */ /***********************************************************************/ -/** Dumps a constant expression as entity initializer, array bound ... - */ +/** Dumps a constant expression as entity initializer, array bound ... */ static void dump_const_expression(FILE *F, ir_node *value) { ir_graph *rem = current_ir_graph; - int rem_dump_const_local = dump_const_local; - dump_const_local = 0; + ir_dump_flags_t old_flags = ir_get_dump_flags(); + ir_remove_dump_flags(ir_dump_flag_consts_local); + current_ir_graph = get_const_code_irg(); irg_walk(value, dump_const_node, NULL, F); /* Decrease visited flag so that we walk with the same flag for the next expression. This guarantees that we don't dump the same node twice, as for const expressions cse is performed to save memory. */ set_irg_visited(current_ir_graph, get_irg_visited(current_ir_graph) -1); + + ir_set_dump_flags(old_flags); current_ir_graph = rem; - dump_const_local = rem_dump_const_local; } /** Dump a block as graph containing its nodes. @@ -1858,11 +1726,11 @@ static void dump_block_graph(FILE *F, ir_graph *irg) } dump_ir_data_edges(F, node); } - if (dump_new_edges_flag && edges_activated(irg)) - dump_ir_edges(F, node); + if ((flags & ir_dump_flag_iredges) && edges_activated(irg)) + dump_ir_edges(node, F); } - if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid)) + if ((flags & ir_dump_flag_loops) && (get_irg_loopinfo_state(irg) & loopinfo_valid)) dump_loop_nodes_into_graph(F, irg); current_ir_graph = rem; @@ -1875,7 +1743,7 @@ static void dump_block_graph(FILE *F, ir_graph *irg) static void dump_graph_info(FILE *F, ir_graph *irg) { fprintf(F, "info1: \""); - dump_entity_to_file(F, get_irg_entity(irg), dump_verbosity_entattrs | dump_verbosity_entconsts); + dump_entity_to_file(F, get_irg_entity(irg)); fprintf(F, "\"\n"); } @@ -1900,51 +1768,6 @@ static void dump_graph_from_list(FILE *F, ir_graph *irg) fprintf(F, "}\n\n"); } -/** dumps a graph extended block-wise. Expects all blockless nodes in arr in irgs link. - * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */ -static void dump_extblock_graph(FILE *F, ir_graph *irg) -{ - int i; - ir_graph *rem = current_ir_graph; - ir_extblk **arr = ird_get_irg_link(irg); - current_ir_graph = irg; - - for (i = ARR_LEN(arr) - 1; i >= 0; --i) { - ir_extblk *extbb = arr[i]; - ir_node *leader = get_extbb_leader(extbb); - int j; - - fprintf(F, "graph: { title: \""); - PRINT_EXTBBID(leader); - fprintf(F, "\" label: \"ExtBB %ld\" status:clustered color:lightgreen\n", - get_irn_node_nr(leader)); - - for (j = ARR_LEN(extbb->blks) - 1; j >= 0; --j) { - ir_node * node = extbb->blks[j]; - if (is_Block(node)) { - /* Dumps the block and all the nodes in the block, which are to - be found in Block->link. */ - dump_whole_block(F, node); - } else { - /* Nodes that are not in a Block. */ - dump_node(F, node); - if (is_Bad(get_nodes_block(node)) && !node_floats(node)) { - dump_const_block_local(F, node); - } - dump_ir_data_edges(F, node); - } - } - fprintf(F, "}\n"); - } - - if (dump_loop_information_flag && (get_irg_loopinfo_state(irg) & loopinfo_valid)) - dump_loop_nodes_into_graph(F, irg); - - current_ir_graph = rem; - free_extbb(irg); -} - - /*******************************************************************/ /* Basic type and entity nodes and edges. */ /*******************************************************************/ @@ -2055,10 +1878,8 @@ static void print_typespecific_vcgattr(FILE *F, ir_type *tp) } /* switch type */ } -int dump_type_node(FILE *F, ir_type *tp) +void dump_type_node(FILE *F, ir_type *tp) { - int bad = 0; - fprintf(F, "node: {title: "); PRINT_TYPEID(tp); fprintf(F, " label: \"%s ", get_type_tpop_name(tp)); @@ -2070,16 +1891,13 @@ int dump_type_node(FILE *F, ir_type *tp) ir_fprintf(F, "%+F", tp); } fputs("\" info1: \"", F); - dump_type_to_file(F, tp, dump_verbosity_max); + dump_type_to_file(F, tp); fprintf(F, "\"\n"); print_type_dbg_info(F, get_type_dbg_info(tp)); print_typespecific_vcgattr(F, tp); fprintf(F, "}\n"); - - return bad; } - static void dump_entity_node(FILE *F, ir_entity *ent) { fprintf(F, "node: {title: \""); @@ -2090,7 +1908,7 @@ static void dump_entity_node(FILE *F, ir_entity *ent) print_vcg_color(F, ird_color_entity); fprintf(F, "\n info1: \""); - dump_entity_to_file(F, ent, dump_verbosity_entattrs | dump_verbosity_entconsts); + dump_entity_to_file(F, ent); fprintf(F, "\"\n"); print_dbg_info(F, get_entity_dbg_info(ent)); @@ -2149,7 +1967,7 @@ static void dump_type_info(type_or_ent tore, void *env) print_ent_ent_edge(F,ent, get_entity_overwrites(ent, i), 0, -1, ENT_OVERWRITES_EDGE_ATTR); } /* attached subgraphs */ - if (const_entities) { + if (! (flags & ir_dump_flag_no_entity_values)) { if (ent->initializer != NULL) { /* new style initializers */ dump_entity_initializer(F, ent); @@ -2230,19 +2048,12 @@ static void dump_type_info(type_or_ent tore, void *env) } /* switch kind_or_entity */ } -typedef struct _h_env { - int dump_ent; - FILE *f; -} h_env_t; - /** For dumping class hierarchies. * Dumps a class type node and a superclass edge. - * If env->dump_ent dumps entities of classes and overwrites edges. */ static void dump_class_hierarchy_node(type_or_ent tore, void *ctx) { - h_env_t *env = ctx; - FILE *F = env->f; + FILE *F = ctx; int i = 0; /* to shutup gcc */ /* dump this type or entity */ @@ -2252,7 +2063,8 @@ static void dump_class_hierarchy_node(type_or_ent tore, void *ctx) if (get_entity_owner(ent) == get_glob_type()) break; if (!is_Method_type(get_entity_type(ent))) break; /* GL */ - if (env->dump_ent && is_Class_type(get_entity_owner(ent))) { + if (flags & ir_dump_flag_entities_in_hierarchy + && is_Class_type(get_entity_owner(ent))) { /* The node */ dump_entity_node(F, ent); /* The edges */ @@ -2305,13 +2117,13 @@ static void dump_out_edge(ir_node *n, void *env) } } -static inline void dump_loop_label(FILE *F, ir_loop *loop) +static void dump_loop_label(FILE *F, ir_loop *loop) { fprintf(F, "loop %d, %d sons, %d nodes", get_loop_depth(loop), get_loop_n_sons(loop), get_loop_n_nodes(loop)); } -static inline void dump_loop_info(FILE *F, ir_loop *loop) +static void dump_loop_info(FILE *F, ir_loop *loop) { fprintf(F, " info1: \""); fprintf(F, " loop nr: %d", get_loop_loop_nr(loop)); @@ -2321,7 +2133,7 @@ static inline void dump_loop_info(FILE *F, ir_loop *loop) fprintf(F, "\""); } -static inline void dump_loop_node(FILE *F, ir_loop *loop) +static void dump_loop_node(FILE *F, ir_loop *loop) { fprintf(F, "node: {title: \""); PRINT_LOOPID(loop); @@ -2332,7 +2144,7 @@ static inline void dump_loop_node(FILE *F, ir_loop *loop) fprintf(F, "}\n"); } -static inline void dump_loop_node_edge(FILE *F, ir_loop *loop, int i) +static void dump_loop_node_edge(FILE *F, ir_loop *loop, int i) { assert(loop); fprintf(F, "edge: {sourcename: \""); @@ -2343,7 +2155,7 @@ static inline void dump_loop_node_edge(FILE *F, ir_loop *loop, int i) fprintf(F, "}\n"); } -static inline void dump_loop_son_edge(FILE *F, ir_loop *loop, int i) +static void dump_loop_son_edge(FILE *F, ir_loop *loop, int i) { assert(loop); fprintf(F, "edge: {sourcename: \""); @@ -2372,7 +2184,7 @@ static void dump_loops(FILE *F, ir_loop *loop) } } -static inline void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) +static void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) { ir_loop *loop = get_irg_loop(irg); @@ -2393,11 +2205,11 @@ static inline void dump_loop_nodes_into_graph(FILE *F, ir_graph *irg) void dump_vcg_header(FILE *F, const char *name, const char *layout, const char *orientation) { int i; - char *label; + const char *label + = (flags & ir_dump_flag_disable_edge_labels) ? "no" : "yes"; init_colors(); - label = edge_label ? "yes" : "no"; if (! layout) layout = "Compilergraph"; if (!orientation) orientation = "bottom_to_top"; @@ -2442,98 +2254,7 @@ void dump_vcg_header(FILE *F, const char *name, const char *layout, const char * fprintf(F, "colorentry %s: %s\n", color_names[i], color_rgb[i]); } } - fprintf(F, "\n"); /* a separator */ -} - -/** - * open a vcg file - * - * @param irg The graph to be dumped - * @param suffix1 first filename suffix - * @param suffix2 second filename suffix - */ -FILE *vcg_open(const ir_graph *irg, const char *suffix1, const char *suffix2) -{ - FILE *F; - const char *nm = get_irg_dump_name(irg); - int len = strlen(nm), i, j; - char *fname; /* filename to put the vcg information in */ - - if (!suffix1) suffix1 = ""; - if (!suffix2) suffix2 = ""; - - /* open file for vcg graph */ - fname = XMALLOCN(char, len * 2 + strlen(suffix1) + strlen(suffix2) + 5); - - /* strncpy (fname, nm, len); */ /* copy the filename */ - j = 0; - for (i = 0; i < len; ++i) { /* replace '/' in the name: escape by @. */ - if (nm[i] == '/') { - fname[j] = '@'; j++; fname[j] = '1'; j++; - } else if (nm[i] == '@') { - fname[j] = '@'; j++; fname[j] = '2'; j++; - } else { - fname[j] = nm[i]; j++; - } - } - fname[j] = '\0'; - strcat(fname, suffix1); /* append file suffix */ - strcat(fname, suffix2); /* append file suffix */ - strcat(fname, ".vcg"); /* append the .vcg suffix */ - - /* vcg really expect only a at end of line, so - * the "b"inary mode is what you mean (and even needed for Win32) - */ - F = fopen(fname, "wb"); /* open file for writing */ - if (!F) { - perror(fname); - } - xfree(fname); - - return F; -} - -/** - * open a vcg file - * - * @param name prefix file name - * @param suffix filename suffix - */ -FILE *vcg_open_name(const char *name, const char *suffix) -{ - FILE *F; - char *fname; /* filename to put the vcg information in */ - int i, j, len = strlen(name); - - if (!suffix) suffix = ""; - - /** open file for vcg graph */ - fname = XMALLOCN(char, len * 2 + 5 + strlen(suffix)); - /* strcpy (fname, name);*/ /* copy the filename */ - j = 0; - for (i = 0; i < len; ++i) { /* replace '/' in the name: escape by @. */ - if (name[i] == '/') { - fname[j] = '@'; j++; fname[j] = '1'; j++; - } else if (name[i] == '@') { - fname[j] = '@'; j++; fname[j] = '2'; j++; - } else { - fname[j] = name[i]; j++; - } - } - fname[j] = '\0'; - strcat(fname, suffix); - strcat(fname, ".vcg"); /* append the .vcg suffix */ - - /* vcg really expect only a at end of line, so - * the "b"inary mode is what you mean (and even needed for Win32) - */ - F = fopen(fname, "wb"); /* open file for writing */ - if (!F) { - perror(fname); - } - xfree(fname); - - return F; + fprintf(F, "\n"); } /** @@ -2544,127 +2265,89 @@ void dump_vcg_footer(FILE *F) fprintf(F, "}\n"); } -/************************************************************************/ -/************************************************************************/ -/* Routines that dump all or parts of the firm representation to a file */ -/************************************************************************/ -/************************************************************************/ - -/************************************************************************/ -/* Dump ir graphs, different formats and additional information. */ -/************************************************************************/ -typedef void (*do_dump_graph_func) (ir_graph *irg, FILE *out); -static void do_dump(ir_graph *irg, const char *suffix, const char *suffix_ip, - const char *suffix_nonip, do_dump_graph_func dump_func) +static void dump_blocks_as_subgraphs(FILE *out, ir_graph *irg) { - FILE *out; - ir_graph *rem; - const char *suffix1; + int i; - if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) - return; + construct_block_lists(irg); - rem = current_ir_graph; - current_ir_graph = irg; - (void) suffix_ip; -#ifdef INTERPROCEDURAL_VIEW - if (get_interprocedural_view()) - suffix1 = suffix_ip; - else -#endif - suffix1 = suffix_nonip; - current_ir_graph = rem; + /* + * If we are in the interprocedural view, we dump not + * only the requested irg but also all irgs that can be reached + * from irg. + */ + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_graph *irg = get_irp_irg(i); + ir_node **arr = ird_get_irg_link(irg); + if (arr == NULL) + continue; - out = vcg_open(irg, suffix, suffix1); - if (out != NULL) { - dump_func(irg, out); - fclose(out); + dump_graph_from_list(out, irg); + DEL_ARR_F(arr); } } -void dump_ir_graph_file(ir_graph *irg, FILE *out) +/** dumps a graph extended block-wise. Expects all blockless nodes in arr in irgs link. + * The outermost nodes: blocks and nodes not op_pin_state_pinned, Bad, Unknown. */ +static void dump_extblock_graph(FILE *F, ir_graph *irg) { - if (dump_backedge_information_flag - && get_irg_loopinfo_state(irg) != loopinfo_consistent) { - construct_backedges(irg); - } + int i; + ir_graph *rem = current_ir_graph; + ir_extblk **arr = ird_get_irg_link(irg); + current_ir_graph = irg; - dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL); + for (i = ARR_LEN(arr) - 1; i >= 0; --i) { + ir_extblk *extbb = arr[i]; + ir_node *leader = get_extbb_leader(extbb); + int j; - /* call the dump graph hook */ - if (dump_ir_graph_hook) { - if (dump_ir_graph_hook(out, irg)) { - return; + fprintf(F, "graph: { title: \""); + PRINT_EXTBBID(leader); + fprintf(F, "\" label: \"ExtBB %ld\" status:clustered color:lightgreen\n", + get_irn_node_nr(leader)); + + for (j = ARR_LEN(extbb->blks) - 1; j >= 0; --j) { + ir_node * node = extbb->blks[j]; + if (is_Block(node)) { + /* Dumps the block and all the nodes in the block, which are to + be found in Block->link. */ + dump_whole_block(F, node); + } else { + /* Nodes that are not in a Block. */ + dump_node(F, node); + if (is_Bad(get_nodes_block(node)) && !node_floats(node)) { + dump_const_block_local(F, node); + } + dump_ir_data_edges(F, node); + } } + fprintf(F, "}\n"); } - /* walk over the graph */ - /* dump_whole_node must be called in post visiting predecessors */ - ird_walk_graph(irg, NULL, dump_whole_node, out); - - /* dump the out edges in a separate walk */ - if ((dump_out_edge_flag) && (get_irg_outs_state(irg) != outs_none)) { - irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, out); - } + if ((flags & ir_dump_flag_loops) + && (get_irg_loopinfo_state(irg) & loopinfo_valid)) + dump_loop_nodes_into_graph(F, irg); - dump_vcg_footer(out); + current_ir_graph = rem; + free_extbb(irg); } -/** Routine to dump a graph, blocks as conventional nodes. */ -void dump_ir_graph(ir_graph *irg, const char *suffix ) +static void dump_blocks_extbb_grouped(FILE *F, ir_graph *irg) { - do_dump(irg, suffix, "-pure-ip", "-pure", dump_ir_graph_file); -} + int i; + ir_entity *ent = get_irg_entity(irg); -void dump_ir_block_graph_file(ir_graph *irg, FILE *out) -{ - int i; + if (get_irg_extblk_state(irg) != extblk_valid) + compute_extbb(irg); - dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL); + construct_extblock_lists(irg); - construct_block_lists(irg); - - /* - * If we are in the interprocedural view, we dump not - * only the requested irg but also all irgs that can be reached - * from irg. - */ - for (i = get_irp_n_irgs() - 1; i >= 0; --i) { - ir_graph *g = get_irp_irg(i); - ir_node **arr = ird_get_irg_link(g); - if (arr) { - dump_graph_from_list(out, g); - DEL_ARR_F(arr); - } - } - - dump_vcg_footer(out); -} - -/* Dump a firm graph without explicit block nodes. */ -void dump_ir_block_graph(ir_graph *irg, const char *suffix) -{ - do_dump(irg, suffix, "-ip", "", dump_ir_block_graph_file); -} - -void dump_ir_extblock_graph_file(ir_graph *irg, FILE *F) -{ - int i; - ir_entity *ent = get_irg_entity(irg); - - if (get_irg_extblk_state(irg) != extblk_valid) - compute_extbb(irg); - - dump_vcg_header(F, get_irg_dump_name(irg), NULL, NULL); - - construct_extblock_lists(irg); - - fprintf(F, "graph: { title: \""); - PRINT_IRGID(irg); - fprintf(F, "\" label: \"%s\" status:clustered color: white \n", - get_ent_dump_name(ent)); + fprintf(F, "graph: { title: \""); + PRINT_IRGID(irg); + fprintf(F, "\" label: \"%s\" status:clustered color: white \n", + get_ent_dump_name(ent)); dump_graph_info(F, irg); print_dbg_info(F, get_entity_dbg_info(ent)); @@ -2695,95 +2378,52 @@ void dump_ir_extblock_graph_file(ir_graph *irg, FILE *F) /* Close the vcg information for the irg */ fprintf(F, "}\n\n"); - dump_vcg_footer(F); free_extbb(irg); } -/* Dump a firm graph without explicit block nodes but grouped in extended blocks. */ -void dump_ir_extblock_graph(ir_graph *irg, const char *suffix) +void dump_ir_graph_file(FILE *out, ir_graph *irg) { - do_dump(irg, suffix, "-ip", "", dump_ir_extblock_graph_file); -} - -void dump_ir_graph_w_types_file(ir_graph *irg, FILE *out) -{ - ir_graph *rem = current_ir_graph; - int rem_dump_const_local; - - rem = current_ir_graph; - current_ir_graph = irg; - rem_dump_const_local = dump_const_local; - /* dumping types does not work with local nodes */ - dump_const_local = 0; - dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL); - /* dump common ir graph */ - irg_walk(get_irg_end(irg), NULL, dump_whole_node, out); - /* dump type info */ - type_walk_irg(irg, dump_type_info, NULL, out); - inc_irg_visited(get_const_code_irg()); - /* dump edges from graph to type info */ - irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, out); - - dump_vcg_footer(out); - dump_const_local = rem_dump_const_local; - current_ir_graph = rem; -} - -/* dumps a graph with type information */ -void dump_ir_graph_w_types(ir_graph *irg, const char *suffix) -{ - do_dump(irg, suffix, "-pure-wtypes-ip", "-pure-wtypes", - dump_ir_graph_w_types_file); -} - -void dump_ir_block_graph_w_types_file(ir_graph *irg, FILE *out) -{ - int i; - int rem_dump_const_local; - ir_graph *rem = current_ir_graph; - - rem_dump_const_local = dump_const_local; - /* dumping types does not work with local nodes */ - dump_const_local = 0; + /* dump nodes */ + if (flags & ir_dump_flag_blocks_as_subgraphs) { + if (flags & ir_dump_flag_group_extbb) { + dump_blocks_extbb_grouped(out, irg); + } else { + dump_blocks_as_subgraphs(out, irg); + } + } else { + /* dump_node_with_edges must be called in post visiting predecessors */ + ird_walk_graph(irg, NULL, dump_node_with_edges, out); + } - dump_vcg_header(out, get_irg_dump_name(irg), NULL, NULL); + /* dump type info */ + if (flags & ir_dump_flag_with_typegraph) { + ir_graph *rem = current_ir_graph; + current_ir_graph = irg; - /* dump common blocked ir graph */ - construct_block_lists(irg); + type_walk_irg(irg, dump_type_info, NULL, out); + inc_irg_visited(get_const_code_irg()); + /* dump edges from graph to type info */ + irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, out); - for (i = get_irp_n_irgs() - 1; i >= 0; --i) { - ir_node **arr = ird_get_irg_link(get_irp_irg(i)); - if (arr) { - dump_graph_from_list(out, get_irp_irg(i)); - DEL_ARR_F(arr); - } + current_ir_graph = rem; } - /* dump type info */ - current_ir_graph = irg; - type_walk_irg(irg, dump_type_info, NULL, out); - inc_irg_visited(get_const_code_irg()); + /* dump iredges out edges */ + if ((flags & ir_dump_flag_iredges) && edges_activated(current_ir_graph)) { + irg_walk_edges(get_irg_start_block(irg), dump_ir_edges, NULL, out); + } - /* dump edges from graph to type info */ - irg_walk(get_irg_end(irg), dump_node2type_edges, NULL, out); + /* dump the out edges in a separate walk */ + if ((flags & ir_dump_flag_out_edges) + && (get_irg_outs_state(irg) != outs_none)) { + irg_out_walk(get_irg_start(irg), dump_out_edge, NULL, out); + } dump_vcg_footer(out); - dump_const_local = rem_dump_const_local; - current_ir_graph = rem; -} - -void dump_ir_block_graph_w_types(ir_graph *irg, const char *suffix) -{ - do_dump(irg, suffix, "-wtypes-ip", "-wtypes", - dump_ir_block_graph_w_types_file); } -/*---------------------------------------------------------------------*/ -/* The following routines dump a control flow graph. */ -/*---------------------------------------------------------------------*/ - static void dump_block_to_cfg(ir_node *block, void *env) { FILE *F = env; @@ -2833,7 +2473,7 @@ static void dump_block_to_cfg(ir_node *block, void *env) } /* Dump dominator/postdominator edge */ - if (dump_dominator_information_flag) { + if (ir_get_dump_flags() & ir_dump_flag_dominance) { if (get_irg_dom_state(current_ir_graph) == dom_consistent && get_Block_idom(block)) { pred = get_Block_idom(block); fprintf(F, "edge: { sourcename: \""); @@ -2854,269 +2494,75 @@ static void dump_block_to_cfg(ir_node *block, void *env) } } -void dump_cfg(ir_graph *irg, const char *suffix) +void dump_cfg(FILE *F, ir_graph *irg) { - FILE *f; - /* if a filter is set, dump only the irg's that match the filter */ - if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) - return; - - f = vcg_open(irg, suffix, "-cfg"); - if (f != NULL) { - ir_graph *rem = current_ir_graph; #ifdef INTERPROCEDURAL_VIEW - int ipv = get_interprocedural_view(); + int ipv = get_interprocedural_view(); #endif - current_ir_graph = irg; - dump_vcg_header(f, get_irg_dump_name(irg), NULL, NULL); + dump_vcg_header(F, get_irg_dump_name(irg), NULL, NULL); #ifdef INTERPROCEDURAL_VIEW - if (ipv) { - printf("Warning: dumping cfg not in interprocedural view!\n"); - set_interprocedural_view(0); - } + if (ipv) { + printf("Warning: dumping cfg not in interprocedural view!\n"); + set_interprocedural_view(0); + } #endif - /* walk over the blocks in the graph */ - irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, f); - dump_node(f, get_irg_bad(irg)); + /* walk over the blocks in the graph */ + irg_block_walk(get_irg_end(irg), dump_block_to_cfg, NULL, F); + dump_node(F, get_irg_bad(irg)); #ifdef INTERPROCEDURAL_VIEW - set_interprocedural_view(ipv); + set_interprocedural_view(ipv); #endif - dump_vcg_footer(f); - fclose(f); - current_ir_graph = rem; - } -} - - -static void descend_and_dump(FILE *F, ir_node *n, int depth, pset *mark_set) -{ - if (pset_find_ptr(mark_set, n)) - return; - - pset_insert_ptr(mark_set, n); - - if (depth > 0) { - int i, start = is_Block(n) ? 0 : -1; - dump_whole_node(n, F); - for (i = start; i < get_irn_arity(n); ++i) - descend_and_dump(F, get_irn_n(n, i), depth-1, mark_set); - } else { - dump_node(F, n); - /* Don't dump edges to nodes further out. These might be edges to - nodes we already dumped, if there is a shorter path to these. */ - } -} - -static int subgraph_counter = 0; -void dump_subgraph(ir_node *root, int depth, const char *suffix) -{ - FILE *F; - char buf[32]; - - sprintf(buf, "-subg_%03d", subgraph_counter++); - F = vcg_open(get_irn_irg(root), suffix, buf); - if (F != NULL) { - pset *mark_set = pset_new_ptr(1); - dump_vcg_header(F, get_irg_dump_name(get_irn_irg(root)), NULL, NULL); - descend_and_dump(F, root, depth, mark_set); - dump_vcg_footer(F); - fclose(F); - del_pset(mark_set); - } -} - -void dump_callgraph(const char *suffix) -{ - FILE *F = vcg_open_name("Callgraph", suffix); - - if (F != NULL) { - int i, rem = edge_label; - //int colorize; - edge_label = 1; - dump_vcg_header(F, "Callgraph", "Hierarchiv", NULL); - - for (i = get_irp_n_irgs() - 1; i >= 0; --i) { - ir_graph *irg = get_irp_irg(i); - ir_entity *ent = get_irg_entity(irg); - int j; - int n_callees = get_irg_n_callees(irg); - - dump_entity_node(F, ent); - for (j = 0; j < n_callees; ++j) { - ir_entity *c = get_irg_entity(get_irg_callee(irg, j)); - //if (id_is_prefix(prefix, get_entity_ld_ident(c))) continue; - int be = is_irg_callee_backedge(irg, j); - char *attr; - attr = (be) ? - "label:\"recursion %d\"" : - "label:\"calls %d\""; - print_ent_ent_edge(F, ent, c, be, ird_color_entity, attr, get_irg_callee_loop_depth(irg, j)); - } - } - - edge_label = rem; - dump_vcg_footer(F); - fclose(F); - } + dump_vcg_footer(F); } -#if 0 -/* Dump all irgs in interprocedural view to a single file. */ -void dump_all_cg_block_graph(const char *suffix) +void dump_callgraph(FILE *F) { - FILE *f = vcg_open_name("All_graphs", suffix); - - if (f != NULL) { - int i; - int rem_view = get_interprocedural_view(); + int i; + ir_dump_flags_t old_flags = ir_get_dump_flags(); - set_interprocedural_view(1); - dump_vcg_header(f, "All_graphs", NULL); + ir_remove_dump_flags(ir_dump_flag_disable_edge_labels); + dump_vcg_header(F, "Callgraph", "Hierarchic", NULL); - /* collect nodes in all irgs reachable in call graph*/ - for (i = get_irp_n_irgs() - 1; i >= 0; --i) - ird_set_irg_link(get_irp_irg(i), NULL); - - cg_walk(clear_link, collect_node, NULL); + for (i = get_irp_n_irgs() - 1; i >= 0; --i) { + ir_graph *irg = get_irp_irg(i); + ir_entity *ent = get_irg_entity(irg); + int j; + int n_callees = get_irg_n_callees(irg); - /* dump all graphs */ - for (i = get_irp_n_irgs() - 1; i >= 0; --i) { - current_ir_graph = get_irp_irg(i); - assert(ird_get_irg_link(current_ir_graph)); - dump_graph_from_list(f, current_ir_graph); - DEL_ARR_F(ird_get_irg_link(current_ir_graph)); + dump_entity_node(F, ent); + for (j = 0; j < n_callees; ++j) { + ir_entity *c = get_irg_entity(get_irg_callee(irg, j)); + int be = is_irg_callee_backedge(irg, j); + const char *attr = be + ? "label:\"recursion %d\"" + : "label:\"calls %d\""; + print_ent_ent_edge(F, ent, c, be, ird_color_entity, attr, + get_irg_callee_loop_depth(irg, j)); } - - dump_vcg_footer(f); - fclose(f); - set_interprocedural_view(rem_view); } -} -#endif - -/*---------------------------------------------------------------------*/ -/* the following routines dumps type information without any ir nodes. */ -/*---------------------------------------------------------------------*/ - -void dump_type_graph(ir_graph *irg, const char *suffix) -{ - FILE *f; - - /* if a filter is set, dump only the irg's that match the filter */ - if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) return; - - f = vcg_open(irg, suffix, "-type"); - if (f != NULL) { - ir_graph *rem = current_ir_graph; - current_ir_graph = irg; - dump_vcg_header(f, get_irg_dump_name(irg), "Hierarchic", NULL); - - /* walk over the blocks in the graph */ - type_walk_irg(irg, dump_type_info, NULL, f); - /* The walker for the const code can be called several times for the - same (sub) expression. So that no nodes are dumped several times - we decrease the visited flag of the corresponding graph after each - walk. So now increase it finally. */ - inc_irg_visited(get_const_code_irg()); - - dump_vcg_footer(f); - fclose(f); - current_ir_graph = rem; - } -} - -void dump_all_types(const char *suffix) -{ - FILE *f = vcg_open_name("All_types", suffix); - if (f != NULL) { - dump_vcg_header(f, "All_types", "Hierarchic", NULL); - type_walk(dump_type_info, NULL, f); - inc_irg_visited(get_const_code_irg()); - - dump_vcg_footer(f); - fclose(f); - } -} - -void dump_class_hierarchy(int entities, const char *suffix) -{ - FILE *f = vcg_open_name("class_hierarchy", suffix); - - if (f != NULL) { - h_env_t env; - env.f = f; - env.dump_ent = entities; - dump_vcg_header(f, "class_hierarchy", "Hierarchic", NULL); - type_walk(dump_class_hierarchy_node, NULL, &env); - - dump_vcg_footer(f); - fclose(f); - } -} - -/*---------------------------------------------------------------------*/ -/* dumps all graphs with the graph-dumper passed. Possible dumpers: */ -/* dump_ir_graph */ -/* dump_ir_block_graph */ -/* dump_cfg */ -/* dump_type_graph */ -/* dump_ir_graph_w_types */ -/*---------------------------------------------------------------------*/ - -void dump_all_ir_graphs(dump_graph_func *dmp_grph, const char *suffix) -{ - int i; - for (i = get_irp_n_irgs() - 1; i >= 0; --i) - dmp_grph(get_irp_irg(i), suffix); + ir_set_dump_flags(old_flags); + dump_vcg_footer(F); } -struct pass_t { - ir_prog_pass_t pass; - dump_graph_func *dump_graph; - char suffix[1]; -}; - -/** - * Wrapper around dump_all_ir_graphs(). - */ -static int dump_all_ir_graphs_wrapper(ir_prog *irp, void *context) +void dump_typegraph(FILE *out) { - struct pass_t *pass = context; - - (void)irp; - dump_all_ir_graphs(pass->dump_graph, pass->suffix); - return 0; + dump_vcg_header(out, "All_types", "Hierarchic", NULL); + type_walk(dump_type_info, NULL, out); + dump_vcg_footer(out); } -ir_prog_pass_t *dump_all_ir_graph_pass(const char *name, - dump_graph_func *dump_graph, - const char *suffix) +void dump_class_hierarchy(FILE *out) { - size_t len = strlen(suffix); - struct pass_t *pass = xmalloc(sizeof(*pass) + len); - ir_prog_pass_t *res = def_prog_pass_constructor( - &pass->pass, name ? name : "dump_all_graphs", dump_all_ir_graphs_wrapper); - - /* this pass does not change anything, so neither dump nor verify is needed. */ - res->dump_irprog = ir_prog_no_dump; - res->verify_irprog = ir_prog_no_verify; - - pass->dump_graph = dump_graph; - strcpy(pass->suffix, suffix); - - return res; + dump_vcg_header(out, "class_hierarchy", "Hierarchic", NULL); + type_walk(dump_class_hierarchy_node, NULL, out); + dump_vcg_footer(out); } -/*--------------------------------------------------------------------------------* - * Dumps a stand alone loop graph with firm nodes which belong to one loop node * - * packed together in one subgraph/box * - *--------------------------------------------------------------------------------*/ - static void dump_loops_standalone(FILE *F, ir_loop *loop) { int i = 0, loop_node_started = 0, son_number = 0, first = 0; @@ -3149,8 +2595,6 @@ static void dump_loops_standalone(FILE *F, ir_loop *loop) /* We are a loop node -> Collect firm nodes */ ir_node *n = le.node; - int bad = 0; - if (!loop_node_started) { /* Start a new node which contains all firm nodes of the current loop */ fprintf(F, "node: { title: \""); @@ -3161,7 +2605,7 @@ static void dump_loops_standalone(FILE *F, ir_loop *loop) } else fprintf(F, "\n"); - bad |= dump_node_label(F, n); + dump_node_label(F, n); /* Causes indeterministic output: if (is_Block(n)) fprintf(F, "\t ->%d", (int)get_irn_link(n)); */ if (has_backedges(n)) fprintf(F, "\t loop head!"); } else { /* for callgraph loop tree */ @@ -3195,64 +2639,49 @@ static void dump_loops_standalone(FILE *F, ir_loop *loop) } } -void dump_loop_tree(ir_graph *irg, const char *suffix) +void dump_loop_tree(FILE *out, ir_graph *irg) { - FILE *f; + ir_graph *rem = current_ir_graph; + ir_dump_flags_t old_flags = ir_get_dump_flags(); - /* if a filter is set, dump only the irg's that match the filter */ - if (!is_filtered_dump_name(get_entity_ident(get_irg_entity(irg)))) - return; - - f = vcg_open(irg, suffix, "-looptree"); - if (f != NULL) { - ir_graph *rem = current_ir_graph; - int el_rem = edge_label; - - current_ir_graph = irg; - edge_label = 1; + current_ir_graph = irg; + ir_remove_dump_flags(ir_dump_flag_disable_edge_labels); - dump_vcg_header(f, get_irg_dump_name(irg), "Tree", "top_to_bottom"); + dump_vcg_header(out, get_irg_dump_name(irg), "Tree", "top_to_bottom"); - if (get_irg_loop(irg)) - dump_loops_standalone(f, get_irg_loop(irg)); + if (get_irg_loop(irg)) + dump_loops_standalone(out, get_irg_loop(irg)); - dump_vcg_footer(f); - fclose(f); + dump_vcg_footer(out); - edge_label = el_rem; - current_ir_graph = rem; - } + ir_set_dump_flags(old_flags); + current_ir_graph = rem; } -void dump_callgraph_loop_tree(const char *suffix) +void dump_callgraph_loop_tree(FILE *out) { - FILE *F; - F = vcg_open_name("Callgraph_looptree", suffix); - dump_vcg_header(F, "callgraph looptree", "Tree", "top_to_bottom"); - dump_loops_standalone(F, irp->outermost_cg_loop); - dump_vcg_footer(F); - fclose(F); + dump_vcg_header(out, "callgraph looptree", "Tree", "top_to_bottom"); + dump_loops_standalone(out, irp->outermost_cg_loop); + dump_vcg_footer(out); } - -/*----------------------------------------------------------------------------*/ -/* Dumps the firm nodes in the loop tree to a graph along with the loop nodes.*/ -/*----------------------------------------------------------------------------*/ - static void collect_nodeloop(FILE *F, ir_loop *loop, eset *loopnodes) { int i, son_number = 0, node_number = 0; - if (dump_loop_information_flag) dump_loop_node(F, loop); + if (flags & ir_dump_flag_loops) + dump_loop_node(F, loop); for (i = 0; i < get_loop_n_elements(loop); i++) { loop_element le = get_loop_element(loop, i); if (*(le.kind) == k_ir_loop) { - if (dump_loop_information_flag) dump_loop_son_edge(F, loop, son_number++); + if (flags & ir_dump_flag_loops) + dump_loop_son_edge(F, loop, son_number++); /* Recur */ collect_nodeloop(F, le.son, loopnodes); } else { - if (dump_loop_information_flag) dump_loop_node_edge(F, loop, node_number++); + if (flags & ir_dump_flag_loops) + dump_loop_node_edge(F, loop, node_number++); eset_insert(loopnodes, le.node); } } @@ -3284,99 +2713,251 @@ static void collect_nodeloop_external_nodes(ir_loop *loop, eset *loopnodes, } } -void dump_loop(ir_loop *l, const char *suffix) +void dump_loop(FILE *F, ir_loop *l) { - FILE *F; char name[50]; - snprintf(name, sizeof(name), "loop_%d", get_loop_loop_nr(l)); - F = vcg_open_name(name, suffix); - if (F != NULL) { - eset *loopnodes = eset_create(); - eset *extnodes = eset_create(); - ir_node *n, *b; - - dump_vcg_header(F, name, NULL, NULL); - - /* collect all nodes to dump */ - collect_nodeloop(F, l, loopnodes); - collect_nodeloop_external_nodes(l, loopnodes, extnodes); - - /* build block lists */ - for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes)) - set_irn_link(n, NULL); - for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes)) - set_irn_link(n, NULL); - for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes)) { - if (!is_Block(n)) { - b = get_nodes_block(n); - set_irn_link(n, get_irn_link(b)); - set_irn_link(b, n); - } + + eset *loopnodes = eset_create(); + eset *extnodes = eset_create(); + ir_node *n, *b; + + dump_vcg_header(F, name, NULL, NULL); + + /* collect all nodes to dump */ + collect_nodeloop(F, l, loopnodes); + collect_nodeloop_external_nodes(l, loopnodes, extnodes); + + /* build block lists */ + for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes)) + set_irn_link(n, NULL); + for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes)) + set_irn_link(n, NULL); + for (n = eset_first(loopnodes); n != NULL; n = eset_next(loopnodes)) { + if (!is_Block(n)) { + b = get_nodes_block(n); + set_irn_link(n, get_irn_link(b)); + set_irn_link(b, n); } - for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes)) { - if (!is_Block(n)) { - b = get_nodes_block(n); - set_irn_link(n, get_irn_link(b)); - set_irn_link(b, n); - } + } + for (n = eset_first(extnodes); n != NULL; n = eset_next(extnodes)) { + if (!is_Block(n)) { + b = get_nodes_block(n); + set_irn_link(n, get_irn_link(b)); + set_irn_link(b, n); } + } - for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes)) { - if (is_Block(b)) { - fprintf(F, "graph: { title: \""); - PRINT_NODEID(b); - fprintf(F, "\" label: \""); - dump_node_opcode(F, b); - fprintf(F, " %ld:%d", get_irn_node_nr(b), get_irn_idx(b)); - fprintf(F, "\" status:clustered color:yellow\n"); - - /* dump the blocks edges */ - dump_ir_data_edges(F, b); - - /* dump the nodes that go into the block */ - for (n = get_irn_link(b); n; n = get_irn_link(n)) { - if (eset_contains(extnodes, n)) - overrule_nodecolor = ird_color_block_inout; - dump_node(F, n); - overrule_nodecolor = ird_color_default_node; - if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n); - } + for (b = eset_first(loopnodes); b != NULL; b = eset_next(loopnodes)) { + if (is_Block(b)) { + fprintf(F, "graph: { title: \""); + PRINT_NODEID(b); + fprintf(F, "\" label: \""); + dump_node_opcode(F, b); + fprintf(F, " %ld:%d", get_irn_node_nr(b), get_irn_idx(b)); + fprintf(F, "\" status:clustered color:yellow\n"); + + /* dump the blocks edges */ + dump_ir_data_edges(F, b); + + /* dump the nodes that go into the block */ + for (n = get_irn_link(b); n; n = get_irn_link(n)) { + if (eset_contains(extnodes, n)) + overrule_nodecolor = ird_color_block_inout; + dump_node(F, n); + overrule_nodecolor = ird_color_default_node; + if (!eset_contains(extnodes, n)) dump_ir_data_edges(F, n); + } - /* Close the vcg information for the block */ - fprintf(F, "}\n"); - dump_const_node_local(F, b); - fprintf(F, "\n"); + /* Close the vcg information for the block */ + fprintf(F, "}\n"); + dump_const_node_local(F, b); + fprintf(F, "\n"); + } + } + for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes)) { + if (is_Block(b)) { + fprintf(F, "graph: { title: \""); + PRINT_NODEID(b); + fprintf(F, "\" label: \""); + dump_node_opcode(F, b); + fprintf(F, " %ld:%d", get_irn_node_nr(b), get_irn_idx(b)); + fprintf(F, "\" status:clustered color:lightblue\n"); + + /* dump the nodes that go into the block */ + for (n = get_irn_link(b); n; n = get_irn_link(n)) { + if (!eset_contains(loopnodes, n)) + overrule_nodecolor = ird_color_block_inout; + dump_node(F, n); + overrule_nodecolor = ird_color_default_node; + if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n); } + + /* Close the vcg information for the block */ + fprintf(F, "}\n"); + dump_const_node_local(F, b); + fprintf(F, "\n"); } - for (b = eset_first(extnodes); b != NULL; b = eset_next(extnodes)) { - if (is_Block(b)) { - fprintf(F, "graph: { title: \""); - PRINT_NODEID(b); - fprintf(F, "\" label: \""); - dump_node_opcode(F, b); - fprintf(F, " %ld:%d", get_irn_node_nr(b), get_irn_idx(b)); - fprintf(F, "\" status:clustered color:lightblue\n"); - - /* dump the nodes that go into the block */ - for (n = get_irn_link(b); n; n = get_irn_link(n)) { - if (!eset_contains(loopnodes, n)) - overrule_nodecolor = ird_color_block_inout; - dump_node(F, n); - overrule_nodecolor = ird_color_default_node; - if (eset_contains(loopnodes, n)) dump_ir_data_edges(F, n); - } + } + eset_destroy(loopnodes); + eset_destroy(extnodes); - /* Close the vcg information for the block */ - fprintf(F, "}\n"); - dump_const_node_local(F, b); - fprintf(F, "\n"); - } + dump_vcg_footer(F); +} + +static bool obstack_init; +static struct obstack obst; +static char *dump_path; + +void ir_set_dump_path(const char *path) +{ + xfree(dump_path); + dump_path = xstrdup(path); +} + +static void add_string_escaped(const char *string) +{ + const char *p; + for (p = string; *p != '\0'; ++p) { + char c = *p; + if (c == '/') { + obstack_1grow(&obst, '@'); + obstack_1grow(&obst, '1'); + } else if (c == '@') { + obstack_1grow(&obst, '@'); + obstack_1grow(&obst, '2'); + } else { + obstack_1grow(&obst, c); } - eset_destroy(loopnodes); - eset_destroy(extnodes); + } +} + +static void add_dump_path(void) +{ + if (!obstack_init) { + obstack_init(&obst); + obstack_init = true; + } + + if (dump_path != NULL) { + size_t len = strlen(dump_path); + obstack_grow(&obst, dump_path, len); + if (len > 0 && dump_path[len-1] != '/') + obstack_1grow(&obst, '/'); + } +} + +void dump_ir_graph_ext(ir_graph_dump_func func, ir_graph *graph, + const char *suffix) +{ + const char *dump_name = get_irg_dump_name(graph); + char *file_name; + FILE *out; + + if (!ir_should_dump(dump_name)) + return; + + add_dump_path(); + + add_string_escaped(dump_name); + obstack_printf(&obst, "-%02u", graph->dump_nr++); + + if (suffix != NULL) { + if (suffix[0] != '.') + obstack_1grow(&obst, '-'); + add_string_escaped(suffix); + } + obstack_1grow(&obst, '\0'); + + file_name = obstack_finish(&obst); + /* xvcg expects only so we need "b"inary mode (for win32) */ + out = fopen(file_name, "wb"); + obstack_free(&obst, file_name); + + if (out == NULL) { + fprintf(stderr, "Couldn't open '%s': %s\n", file_name, strerror(errno)); + return; + } + + func(out, graph); + fclose(out); +} + +void dump_ir_prog_ext(ir_prog_dump_func func, const char *suffix) +{ + char *file_name; + FILE *out; + + add_dump_path(); + + obstack_printf(&obst, "%02u", irp->dump_nr++); + if (suffix != NULL) { + if (suffix[0] != '.') + obstack_1grow(&obst, '-'); + add_string_escaped(suffix); + } + obstack_1grow(&obst, '\0'); + + file_name = obstack_finish(&obst); + out = fopen(file_name, "wb"); + obstack_free(&obst, file_name); + + if (out == NULL) { + fprintf(stderr, "Couldn't open '%s': %s\n", file_name, strerror(errno)); + return; + } + func(out); + fclose(out); +} - dump_vcg_footer(F); - fclose(F); +void dump_ir_graph(ir_graph *graph, const char *suffix) +{ + char buf[256]; + + snprintf(buf, sizeof(buf), "%s.vcg", suffix); + dump_ir_graph_ext(dump_ir_graph_file, graph, buf); +} + +void dump_all_ir_graphs(const char *suffix) +{ + int n_irgs = get_irp_n_irgs(); + int i; + + for (i = 0; i < n_irgs; ++i) { + ir_graph *irg = get_irp_irg(i); + dump_ir_graph(irg, suffix); } } + +struct pass_t { + ir_prog_pass_t pass; + char suffix[1]; +}; + +/** + * Wrapper around dump_all_ir_graphs(). + */ +static int dump_all_ir_graphs_wrapper(ir_prog *irp, void *context) +{ + struct pass_t *pass = context; + + (void)irp; + dump_all_ir_graphs(pass->suffix); + return 0; +} + +ir_prog_pass_t *dump_all_ir_graph_pass(const char *name, const char *suffix) +{ + size_t len = strlen(suffix); + struct pass_t *pass = xmalloc(sizeof(*pass) + len); + ir_prog_pass_t *res = def_prog_pass_constructor( + &pass->pass, name ? name : "dump_all_graphs", dump_all_ir_graphs_wrapper); + + /* this pass does not change anything, so neither dump nor verify is needed. */ + res->dump_irprog = ir_prog_no_dump; + res->verify_irprog = ir_prog_no_verify; + + memcpy(pass->suffix, suffix, len+1); + + return res; +} diff --git a/ir/ir/irdump_t.h b/ir/ir/irdump_t.h index b99976558..a9116b360 100644 --- a/ir/ir/irdump_t.h +++ b/ir/ir/irdump_t.h @@ -141,29 +141,25 @@ typedef enum { #define PRINT_ITEMID(X,Y) fprintf(F, "i%ldT%d", get_type_nr(X), (Y)) #define PRINT_EXTBBID(X) fprintf(F, "x%ld", get_irn_node_nr(X)) -extern int dump_dominator_information_flag; -extern int opt_dump_pointer_values_to_info; -extern int opt_dump_analysed_type_info; - -FILE *vcg_open(const ir_graph *irg, const char * suffix1, const char *suffix2); -FILE *vcg_open_name(const char *name, const char *suffix); -void dump_vcg_header(FILE *F, const char *name, const char *layout, const char *orientation); -void dump_vcg_footer(FILE *F); +void dump_vcg_header(FILE *out, const char *name, const char *layout, const char *orientation); +void dump_vcg_footer(FILE *out); const char *get_irg_dump_name(const ir_graph *irg); - const char *get_ent_dump_name(const ir_entity *ent); -const char *get_mode_name_ex(const ir_mode *mode, int *bad); + /** - * dump the name of a node n to the File F. + * returns the name of a mode or "" if mode is NOT a mode object. + * in the later case, sets bad. */ -int dump_node_opcode(FILE *F, ir_node *n); +const char *get_mode_name_ex(const ir_mode *mode, int *bad); +/** dump the name of a node n to the File F. */ +void dump_node_opcode(FILE *out, ir_node *n); -int dump_node_label(FILE *F, ir_node *n); +void dump_node_label(FILE *out, ir_node *n); -int dump_vrp_info(FILE *F, ir_node *n); +void dump_vrp_info(FILE *out, ir_node *n); /** Writes vcg representation with title "PRINT_TYPEID(tp)" to file F. */ -int dump_type_node(FILE *F, ir_type *tp); +void dump_type_node(FILE *out, ir_type *tp); -#endif /* FIRM_IR_IRDUMPT_T_H */ +#endif diff --git a/ir/ir/irdumptxt.c b/ir/ir/irdumptxt.c index 2437fc8e8..30ca45141 100644 --- a/ir/ir/irdumptxt.c +++ b/ir/ir/irdumptxt.c @@ -19,8 +19,9 @@ /** * @file - * @brief Write vcg representation of firm to file. - * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt + * @brief Write text representation of firm to file. + * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Hubert Schmidt, + * Matthias Braun * @version $Id$ */ #include "config.h" @@ -28,6 +29,7 @@ #include #include #include +#include #include "irdump_t.h" #include "irgraph_t.h" @@ -44,58 +46,19 @@ #include "irdom.h" #include "field_temperature.h" -#define MY_SIZE 1024 /* Size of an array that actually should be computed. */ +static ir_dump_verbosity_t verbosity = dump_verbosity_max; -/** - * Just opens a file, mangling a file name. - * - * The file name results from the concatenation of the following parts: - * - * @param basename The basis of the name telling about the content. - * @param suffix1 The first suffix. - * @param suffix2 The second suffix. - * @param suffix3 The third suffix. - */ -static FILE *text_open(const char *basename, const char * suffix1, const char *suffix2, const char *suffix3) +void ir_set_dump_verbosity(ir_dump_verbosity_t new_verbosity) { - FILE *F; - int len = strlen(basename), i, j; - char *fname; /* filename to put the vcg information in */ - - if (!basename) assert(basename); - if (!suffix1) suffix1 = ""; - if (!suffix2) suffix2 = ""; - if (!suffix3) suffix3 = ".txt"; - - /* open file for vcg graph */ - fname = XMALLOCN(char, strlen(basename)*2 + strlen(suffix1) + strlen(suffix2) + 5); /* *2: space for escapes. */ - - j = 0; - for (i = 0; i < len; ++i) { /* replace '/' in the name: escape by @. */ - if (basename[i] == '/') { - fname[j] = '@'; j++; fname[j] = '1'; j++; - } else if (basename[i] == '@') { - fname[j] = '@'; j++; fname[j] = '2'; j++; - } else { - fname[j] = basename[i]; j++; - } - } - fname[j] = '\0'; - strcat(fname, suffix1); /* append file suffix */ - strcat(fname, suffix2); /* append file suffix */ - strcat(fname, suffix3); /* append the .txt suffix */ - - F = fopen(fname, "w"); /* open file for writing */ - if (!F) { - perror(fname); - abort(); - } - free(fname); + verbosity = new_verbosity; +} - return F; +ir_dump_verbosity_t ir_get_dump_verbosity(void) +{ + return verbosity; } -static inline int is_ip_Filter(ir_node *n) +static inline bool is_ip_Filter(ir_node *n) { #ifdef INTERPROCEDURAL_VIEW return is_Filter(n) && get_interprocedural_view(); @@ -106,9 +69,9 @@ static inline int is_ip_Filter(ir_node *n) } /* Write the irnode and all its attributes to the file passed. */ -int dump_irnode_to_file(FILE *F, ir_node *n) +void dump_irnode_to_file(FILE *F, ir_node *n) { - int i, bad = 0; + int i; char comma; ir_graph *irg; vrp_attr *vrp_info; @@ -117,7 +80,7 @@ int dump_irnode_to_file(FILE *F, ir_node *n) fprintf(F, " %ld\n", get_irn_node_nr(n)); fprintf(F, " index: %u\n", get_irn_idx(n)); - if (opt_dump_pointer_values_to_info) + if (ir_get_dump_flags() & ir_dump_flag_analysed_types) fprintf (F, " addr: %p\n", (void *)n); fprintf (F, " mode: %s\n", get_mode_name(get_irn_mode(n))); fprintf (F, " visited: %ld\n", get_irn_visited(n)); @@ -276,10 +239,8 @@ int dump_irnode_to_file(FILE *F, ir_node *n) fprintf(F, " Selecting entity %s (%ld)\n", get_entity_name(ent), get_entity_nr(ent)); ir_fprintf(F, " of type %+F\n", get_entity_type(ent)); ir_fprintf(F, " with owner %+F.\n", get_entity_owner(ent)); - } - else { + } else { fprintf(F, " \n"); - bad = 1; } } break; case iro_Call: { @@ -336,27 +297,27 @@ int dump_irnode_to_file(FILE *F, ir_node *n) case symconst_addr_ent: fprintf(F, " kind: addr_ent\n"); fprintf(F, " entity: "); - dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames); + dump_entity_to_file(F, get_SymConst_entity(n)); break; case symconst_ofs_ent: fprintf(F, " kind: offset\n"); fprintf(F, " entity: "); - dump_entity_to_file(F, get_SymConst_entity(n), dump_verbosity_onlynames); + dump_entity_to_file(F, get_SymConst_entity(n)); break; case symconst_type_tag: fprintf(F, " kind: type_tag\n"); fprintf(F, " type: "); - dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames); + dump_type_to_file(F, get_SymConst_type(n)); break; case symconst_type_size: fprintf(F, " kind: size\n"); fprintf(F, " type: "); - dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames); + dump_type_to_file(F, get_SymConst_type(n)); break; case symconst_type_align: fprintf(F, " kind: alignment\n"); fprintf(F, " type: "); - dump_type_to_file(F, get_SymConst_type(n), dump_verbosity_onlynames); + dump_type_to_file(F, get_SymConst_type(n)); break; case symconst_enum_const: fprintf(F, " kind: enumeration\n"); @@ -366,7 +327,7 @@ int dump_irnode_to_file(FILE *F, ir_node *n) ir_fprintf(F, " type of value: %+F\n", get_SymConst_value_type(n)); } break; case iro_Load: - fprintf(F, " mode of loaded value: %s\n", get_mode_name_ex(get_Load_mode(n), &bad)); + fprintf(F, " mode of loaded value: %s\n", get_mode_name_ex(get_Load_mode(n), NULL)); fprintf(F, " volatility: %s\n", get_volatility_name(get_Load_volatility(n))); fprintf(F, " align: %s\n", get_align_name(get_Load_align(n))); break; @@ -422,97 +383,12 @@ int dump_irnode_to_file(FILE *F, ir_node *n) get_irg_typeinfo_state(get_irn_irg(n)) == ir_typeinfo_inconsistent ) if (get_irn_typeinfo_type(n) != firm_none_type) ir_fprintf (F, " Analysed type: %s\n", get_irn_typeinfo_type(n)); - - return bad; -} - - - -void dump_irnode(ir_node *n) -{ - dump_irnode_to_file(stdout, n); -} - - -void dump_graph_to_file(FILE *F, ir_graph *irg) -{ - fprintf(F, "graph %s\n", get_irg_dump_name(irg)); -} - -void dump_graph(ir_graph *g) -{ - dump_graph_to_file(stdout, g); } -static void dump_node_to_graph_file(ir_node *n, void *env) +void dump_graph_as_text(FILE *out, ir_graph *irg) { - FILE *F = (FILE *)env; - - dump_irnode_to_file(F, n); - fprintf(F, "\n"); -} - -void dump_graph_as_text(ir_graph *irg, const char *suffix) -{ - const char *basename = get_irg_dump_name(irg); - FILE *F; - - F = text_open(basename, suffix, "", ".txt"); - - dump_graph_to_file(F, irg); - fprintf(F, "\n\n"); - irg_walk_graph(irg, NULL, dump_node_to_graph_file, F); - - fclose (F); -} - -#ifdef EXTENDED_ACCESS_STATS -static int addr_is_alloc(ir_node *acc) -{ - ir_node *addr = NULL; - ir_opcode addr_op; - if (is_memop(acc)) { - addr = get_memop_ptr(acc); - } else { - assert(is_Call(acc)); - addr = get_Call_ptr(acc); - } - - addr_op = get_irn_opcode(addr); - - while (addr_op != iro_Alloc) { - switch (addr_op) { - case iro_Sel: - addr = get_Sel_ptr(addr); - break; - case iro_Cast: - addr = get_Cast_op(addr); - break; - case iro_Proj: - addr = get_Proj_pred(addr); - break; - case iro_SymConst: - case iro_Const: - return 0; - break; - case iro_Phi: - case iro_Load: - case iro_Call: - case iro_Start: - return 0; - break; - - default: - //assert(0 && "unexpected address node"); - ; - } - addr_op = get_irn_opcode(addr); - } - - /* In addition, the alloc must be in the same loop. */ - return 1; + fprintf(out, "graph %s\n", get_irg_dump_name(irg)); } -#endif /** dumps something like: * @@ -530,16 +406,12 @@ static void dump_node_list(FILE *F, firm_kind *k, char *prefix, fprintf(F, "%s %s (%d):", prefix, name, n_nodes); for (i = 0; i < n_nodes; ++i) { - int rem; if (i > 7 && !(i & 7)) { /* line break every eight node. */ fprintf(F, ",\n%s ", prefix); comma = ""; } fprintf(F, "%s ", comma); - rem = opt_dump_analysed_type_info; - opt_dump_analysed_type_info = 0; dump_node_label(F, get_entity_node(k, i)); - opt_dump_analysed_type_info = rem; comma = ","; } fprintf(F, "\n"); @@ -577,7 +449,8 @@ static int need_nl = 1; * Dump initializers. */ static void dump_ir_initializers_to_file(FILE *F, const char *prefix, - const ir_initializer_t *initializer, ir_type *type) + const ir_initializer_t *initializer, + ir_type *type) { tarval *tv; ir_node *value; @@ -658,8 +531,7 @@ static void dump_entity_linkage(FILE *F, const ir_entity *entity) fprintf(F, " hidden_user"); } -static void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, - unsigned verbosity) +static void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix) { int i, j; ir_type *owner, *type; @@ -839,108 +711,6 @@ static void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, } if (verbosity & dump_verbosity_accessStats) { -#ifdef EXTENDED_ACCESS_STATS - int n_acc = get_entity_n_accesses(ent); - int max_depth = 0; - int max_L_freq = -1; - int max_S_freq = -1; - int max_LA_freq = -1; - int max_SA_freq = -1; - int *L_freq; - int *S_freq; - int *LA_freq; - int *SA_freq; - - /* Find maximal depth */ - for (i = 0; i < n_acc; ++i) { - ir_node *acc = get_entity_access(ent, i); - int depth = get_weighted_loop_depth(acc); - max_depth = (depth > max_depth) ? depth : max_depth ; - } - - L_freq = XMALLOCNZ(int, 4 * max_depth); - - S_freq = L_freq + 1*max_depth; - LA_freq = L_freq + 2*max_depth; - SA_freq = L_freq + 3*max_depth; - - for (i = 0; i < n_acc; ++i) { - ir_node *acc = get_entity_access(ent, i); - int depth = get_weighted_loop_depth(acc); - assert(depth < max_depth); - if (is_Load(acc) || is_Call(acc)) { - L_freq[depth]++; - max_L_freq = (depth > max_L_freq) ? depth : max_L_freq; - if (addr_is_alloc(acc)) { - LA_freq[depth]++; - max_LA_freq = (depth > max_LA_freq) ? depth : max_LA_freq; - } - } else if (is_Store(acc)) { - S_freq[depth]++; - max_S_freq = (depth > max_S_freq) ? depth : max_S_freq; - if (addr_is_alloc(acc)) { - SA_freq[depth]++; - max_SA_freq = (depth > max_SA_freq) ? depth : max_SA_freq; - } - } else { - assert(0); - } - } - - if (max_L_freq >= 0) { - char comma = ':'; - - fprintf(F, "%s Load Stats", prefix); - for (i = 0; i <= max_L_freq; ++i) { - if (L_freq[i]) - fprintf(F, "%c %d x L%d", comma, L_freq[i], i); - else - fprintf(F, " "); - comma = ','; - } - fprintf(F, "\n"); - } - if (max_LA_freq >= 0) { - //fprintf(F, "%s LoadA Stats", prefix); - char comma = ':'; - for (i = 0; i <= max_LA_freq; ++i) { - //if (LA_freq[i]) - //fprintf(F, "%c %d x LA%d", comma, LA_freq[i], i); - //else - //fprintf(F, " "); - comma = ','; - } - fprintf(F, "\n"); - } - if (max_S_freq >= 0) { - char comma = ':'; - - fprintf(F, "%s Store Stats", prefix); - for (i = 0; i <= max_S_freq; ++i) { - if (S_freq[i]) - fprintf(F, "%c %d x S%d", comma, S_freq[i], i); - else - fprintf(F, " "); - comma = ','; - } - fprintf(F, "\n"); - } - if (max_SA_freq >= 0) { - //fprintf(F, "%s StoreAStats", prefix); - char comma = ':'; - for (i = 0; i <= max_SA_freq; ++i) { - //if (SA_freq[i]) - //fprintf(F, "%c %d x SA%d", comma, SA_freq[i], i); - //else - //fprintf(F, " "); - comma = ','; - } - fprintf(F, "\n"); - } - - /* free allocated space */ - free(L_freq); -#endif if (get_trouts_state() != outs_none) { #ifdef INTERPROCEDURAL_VIEW if (is_Method_type(get_entity_type(ent))) { @@ -955,18 +725,13 @@ static void dump_entity_to_file_prefix(FILE *F, ir_entity *ent, char *prefix, } } -void dump_entity_to_file (FILE *F, ir_entity *ent, unsigned verbosity) +void dump_entity_to_file(FILE *out, ir_entity *ent) { - dump_entity_to_file_prefix (F, ent, "", verbosity); - fprintf(F, "\n"); + dump_entity_to_file_prefix(out, ent, ""); + fprintf(out, "\n"); } -void dump_entity(ir_entity *ent) -{ - dump_entity_to_file(stdout, ent, dump_verbosity_max); -} - -void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) +void dump_type_to_file(FILE *F, ir_type *tp) { int i; @@ -993,7 +758,7 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) if (((verbosity & dump_verbosity_methods) && is_Method_type(get_entity_type(mem))) || ((verbosity & dump_verbosity_fields) && !is_Method_type(get_entity_type(mem))) ) { if (!(verbosity & dump_verbosity_nostatic)) { - dump_entity_to_file_prefix(F, mem, " ", verbosity); + dump_entity_to_file_prefix(F, mem, " "); } } } @@ -1042,7 +807,7 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) for (i = 0; i < get_compound_n_members(tp); ++i) { ir_entity *mem = get_compound_member(tp, i); if (verbosity & dump_verbosity_fields) { - dump_entity_to_file_prefix(F, mem, " ", verbosity); + dump_entity_to_file_prefix(F, mem, " "); } } break; @@ -1087,7 +852,7 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) if (verbosity & dump_verbosity_fields) { dump_entity_to_file_prefix(F, get_array_element_entity(tp), - " ", verbosity); + " "); } } break; @@ -1157,43 +922,6 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) if (verbosity & dump_verbosity_accessStats) { -#if 0 - int n_all = get_type_n_allocs(tp); - int max_depth = 0; - int max_freq = -1; - int *freq; - - /* Find maximal depth */ - for (i = 0; i < n_all; ++i) { - ir_node *all = get_type_alloc(tp, i); - int depth = get_weighted_loop_depth(all); - max_depth = (depth > max_depth) ? depth : max_depth ; - } - - freq = XMALLOCNZ(int, max_depth + 1); - - for (i = 0; i < n_all; ++i) { - ir_node *all = get_type_alloc(tp, i); - int depth = get_weighted_loop_depth(all); - assert(depth <= max_depth); - freq[depth]++; - max_freq = (depth > max_freq) ? depth : max_freq; - assert(is_Alloc(all)); - } - - if (max_freq >= 0) { - char comma = ':'; - - fprintf(F, " Alloc Stats"); - for (i = 0; i <= max_freq; ++i) { - fprintf(F, "%c %d x A%d", comma, freq[i], i); - comma = ','; - } - fprintf(F, "\n"); - } - - free(freq); -#endif #ifdef INTERPROCEDURAL_VIEW if (get_trouts_state() != outs_none) { fprintf(F, " Estimated #Instances: %lf\n", get_type_estimated_n_instances(tp)); @@ -1211,44 +939,25 @@ void dump_type_to_file(FILE *F, ir_type *tp, dump_verbosity verbosity) fprintf(F, "\n\n"); } -void dump_type(ir_type *tp) -{ - dump_type_to_file (stdout, tp, dump_verbosity_max); -} - -void dump_types_as_text(unsigned verbosity, const char *suffix) +void dump_types_as_text(FILE *out) { - const char *basename; - FILE *F; - int i, n_types = get_irp_n_types(); - - basename = irp_prog_name_is_set() ? get_irp_name() : "TextTypes"; - F = text_open(basename, suffix, "-types", ".txt"); + int i; + int n_types = get_irp_n_types(); for (i = 0; i < n_types; ++i) { - ir_type *t = get_irp_type(i); - - dump_type_to_file(F, t, verbosity); + ir_type *type = get_irp_type(i); + dump_type_to_file(out, type); } - - fclose(F); } -void dump_globals_as_text(unsigned verbosity, const char *suffix) +void dump_globals_as_text(FILE *out) { - const char *basename; - FILE *F; - ir_type *g = get_glob_type(); - int i, n_mems = get_class_n_members(g); + ir_type *global_type = get_glob_type(); + int n_members = get_class_n_members(global_type); + int i; - basename = irp_prog_name_is_set() ? get_irp_name() : "TextGlobals"; - F = text_open (basename, suffix, "-globals", ".txt"); - - for (i = 0; i < n_mems; ++i) { - ir_entity *e = get_class_member(g, i); - - dump_entity_to_file(F, e, verbosity); + for (i = 0; i < n_members; ++i) { + ir_entity *entity = get_class_member(global_type, i); + dump_entity_to_file(out, entity); } - - fclose (F); } diff --git a/ir/ir/irpass.c b/ir/ir/irpass.c index 36c007a64..201ac4172 100644 --- a/ir/ir/irpass.c +++ b/ir/ir/irpass.c @@ -157,13 +157,9 @@ void ir_prog_pass_mgr_add_graph_mgr( ir_prog_pass_mgr_add(mgr, pass); } -/** - * Create a suffix for dumping. - */ -static void create_suffix(char *suffix, size_t n, const char *pass_name, - unsigned index) +static void create_suffix(char *suffix, size_t n, const char *pass_name) { - snprintf(suffix, n, "-%02u_%s", index, pass_name); + snprintf(suffix, n, "%s.svg", pass_name); } /* Run all passes of an ir_graph pass manager. */ @@ -195,9 +191,9 @@ int ir_graph_pass_mgr_run(ir_graph_pass_manager_t *mgr) if (pass->dump_irg) { pass->dump_irg(irg, pass->context, idx); } else { - char suffix[1024]; - create_suffix(suffix, sizeof(suffix), pass->name, idx); - dump_ir_block_graph(irg, suffix); + char buf[1024]; + create_suffix(buf, sizeof(buf), pass->name); + dump_ir_graph(irg, buf); } } ++idx; @@ -244,9 +240,9 @@ int ir_prog_pass_mgr_run(ir_prog_pass_manager_t *mgr) if (pass->dump_irprog) { pass->dump_irprog(irp, pass->context, idx); } else { - char suffix[1024]; - create_suffix(suffix, sizeof(suffix), pass->name, idx); - dump_all_ir_graphs(dump_ir_block_graph, suffix); + char buf[1024]; + create_suffix(buf, sizeof(buf), pass->name); + dump_all_ir_graphs(buf); } } if (pass->is_wrapper) { diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index 194084c71..8171fffea 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -519,6 +519,8 @@ struct ir_graph { int index; /**< a unique number for each graph */ ir_phase *phases[PHASE_LAST+1]; /**< Phase information. */ void *be_data; /**< backend can put in private data here */ + + unsigned dump_nr; /**< number of graph dumps */ #ifdef DEBUG_libfirm int n_outs; /**< Size wasted for outs */ long graph_nr; /**< a unique graph number for each @@ -594,6 +596,7 @@ struct ir_prog { ir_label_t last_label_nr; /**< The highest label number for generating unique labels. */ int max_irg_idx; /**< highest unused irg index */ long max_node_nr; /**< to generate unique numbers for nodes. */ + unsigned dump_nr; /**< number of program info dumps */ #ifndef NDEBUG ir_resources_t reserved_resources; /**< Bitset for tracking used global resources. */ #endif diff --git a/ir/ir/irvrfy.c b/ir/ir/irvrfy.c index 855babaf6..75fd3ed0e 100644 --- a/ir/ir/irvrfy.c +++ b/ir/ir/irvrfy.c @@ -2214,7 +2214,7 @@ static void check_bads(ir_node *node, void *env) fprintf(stderr, "irg_vrfy_bads: Block %ld has Bad predecessor\n", get_irn_node_nr(node)); } if (get_node_verification_mode() == FIRM_VERIFICATION_ON) { - dump_ir_block_graph_sched(current_ir_graph, "-assert"); + dump_ir_graph(current_ir_graph, "-assert"); assert(0 && "Bad CF detected"); } } @@ -2231,7 +2231,7 @@ static void check_bads(ir_node *node, void *env) fprintf(stderr, "irg_vrfy_bads: node %ld has Bad Block\n", get_irn_node_nr(node)); } if (get_node_verification_mode() == FIRM_VERIFICATION_ON) { - dump_ir_block_graph_sched(current_ir_graph, "-assert"); + dump_ir_graph(current_ir_graph, "-assert"); assert(0 && "Bad CF detected"); } } @@ -2245,7 +2245,7 @@ static void check_bads(ir_node *node, void *env) fprintf(stderr, "irg_vrfy_bads: node %ld is a Tuple\n", get_irn_node_nr(node)); } if (get_node_verification_mode() == FIRM_VERIFICATION_ON) { - dump_ir_block_graph_sched(current_ir_graph, "-assert"); + dump_ir_graph(current_ir_graph, "-assert"); assert(0 && "Tuple detected"); } } @@ -2266,7 +2266,7 @@ static void check_bads(ir_node *node, void *env) fprintf(stderr, "irg_vrfy_bads: Phi %ld has Bad Input\n", get_irn_node_nr(node)); } if (get_node_verification_mode() == FIRM_VERIFICATION_ON) { - dump_ir_block_graph_sched(current_ir_graph, "-assert"); + dump_ir_graph(current_ir_graph, "-assert"); assert(0 && "Bad CF detected"); } } @@ -2280,7 +2280,7 @@ static void check_bads(ir_node *node, void *env) fprintf(stderr, "irg_vrfy_bads: node %ld has Bad Input\n", get_irn_node_nr(node)); } if (get_node_verification_mode() == FIRM_VERIFICATION_ON) { - dump_ir_block_graph_sched(current_ir_graph, "-assert"); + dump_ir_graph(current_ir_graph, "-assert"); assert(0 && "Bad NON-CF detected"); } } diff --git a/ir/ir/irvrfy_t.h b/ir/ir/irvrfy_t.h index e4675c49c..db91db321 100644 --- a/ir/ir/irvrfy_t.h +++ b/ir/ir/irvrfy_t.h @@ -51,7 +51,7 @@ extern const char *firm_vrfy_failure_msg; do { \ if (opt_do_node_verification == FIRM_VERIFICATION_ON) {\ if (!(expr) && current_ir_graph != get_const_code_irg()) \ - dump_ir_block_graph_sched(current_ir_graph, "-assert"); \ + dump_ir_graph(current_ir_graph, "-assert"); \ assert((expr) && string); } \ if (!(expr)) { \ if (opt_do_node_verification == FIRM_VERIFICATION_REPORT) \ @@ -70,7 +70,7 @@ do { \ fprintf(stderr, #expr " : " string "\n"); \ else if (opt_do_node_verification == FIRM_VERIFICATION_ON) { \ if (!(expr) && current_ir_graph != get_const_code_irg()) \ - dump_ir_block_graph_sched(current_ir_graph, "-assert"); \ + dump_ir_graph(current_ir_graph, "-assert"); \ assert((expr) && string); \ } \ return (ret); \ diff --git a/ir/opt/cfopt.c b/ir/opt/cfopt.c index e2a658a43..35b68e1dd 100644 --- a/ir/opt/cfopt.c +++ b/ir/opt/cfopt.c @@ -876,7 +876,6 @@ restart: if (get_irg_pinned(irg) == op_pin_state_pinned) { /* after optimize_cf(), only Bad data flow may remain. */ if (irg_vrfy_bads(irg, BAD_DF | BAD_BLOCK | TUPLE)) { - dump_ir_block_graph(irg, "-vrfy-cf"); dump_ir_graph(irg, "-vrfy-cf"); fprintf(stderr, "VRFY_BAD in optimize_cf()\n"); } diff --git a/ir/stat/dags.c b/ir/stat/dags.c index 005ffa87f..debb813bc 100644 --- a/ir/stat/dags.c +++ b/ir/stat/dags.c @@ -399,7 +399,7 @@ void count_dags_in_graph(graph_entry_t *global, graph_entry_t *graph) /* dump for test */ mark_options = root_env.options; set_dump_node_vcgattr_hook(stat_dag_mark_hook); - dump_ir_block_graph(graph->irg, "-dag"); + dump_ir_graph(graph->irg, "-dag"); set_dump_node_vcgattr_hook(NULL); #endif