* @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
/** 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"
* 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
#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\<suffix\>.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().
*
* @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_\<nr\>.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"\<suffix\>".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
- * \<name of irg\>\<suffix\>-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_<loop_nr>\<suffix\>.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\<suffix\>.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
- * \<suffix\>.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 {
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 \<suffix\>-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 \<suffix\>-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
*
* @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"
* 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.
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);
}
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 */
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;
}
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 */
/**
* 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;
arch_dump_reqs_and_registers(F, n);
break;
}
-
- return 0;
}
const TEMPLATE_attr_t *get_TEMPLATE_attr_const(const ir_node *node)
*/
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;
}
/**
* 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;
arch_dump_reqs_and_registers(F, n);
break;
}
-
- return 0;
}
const amd64_attr_t *get_amd64_attr_const(const ir_node *node)
#include "irprintf.h"
#include "ircons.h"
#include "irgmod.h"
+#include "irdump.h"
#include "bitset.h"
#include "debug.h"
amd64_transform_graph (cg);
if (cg->dump)
- be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
+ dump_ir_graph(cg->irg, "transformed");
}
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");
}
/**
* 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);
#endif
break;
}
-
- return 0;
}
#include "irgmod.h"
#include "irgopt.h"
#include "iroptimize.h"
+#include "irdump.h"
#include "lowering.h"
#include "error.h"
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");
}
/**
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);
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);
}
}
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");
}
/**
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);
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);
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);
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);
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));
#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;
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");
}
})
#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;
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;
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)
* @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);
}
/**
*/
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));
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;
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)
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);
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);
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);
};
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);
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);
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);
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);
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));
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);
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:
default:
break;
}
-
- return 0;
}
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);
break;
}
}
-
- return 0;
}
/**
*/
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
#include "irgwalk.h"
#include "irnode_t.h"
#include "irprintf.h"
+#include "irdump.h"
#include "obst.h"
#include "raw_bitset.h"
#include "unionfind.h"
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);
}
/**
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);
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");
}
/**
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);
* 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);
#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.
*/
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)
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);
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);
}
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");
}
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);
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);
}
#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);
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;
*/
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.
*/
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)
#include "irgopt.h"
#include "irbitset.h"
#include "irgopt.h"
+#include "irdump.h"
#include "pdeq.h"
#include "pset.h"
#include "debug.h"
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) {
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);
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)
* @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:
break;
}
-
- return bad;
}
#include "height.h"
#include "irbitset.h"
#include "irprintf.h"
+#include "irdump.h"
#include "error.h"
#include "../be_t.h"
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)
// 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);
/* 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");
}
/**
* 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");
}
/**
* 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:
arch_dump_reqs_and_registers(F, n);
break;
}
-
- return 0;
}
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);
}
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 */
/**
* 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:
arch_dump_reqs_and_registers(F, n);
break;
}
-
-
- return bad;
}
#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"
sparc_transform_graph(cg);
if (cg->dump)
- be_dump(cg->irg, "-transformed", dump_ir_block_graph_sched);
+ dump_ir_graph(cg->irg, "transformed");
}
/**
* 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;
}
break;
-
-
}
-
- return 0;
}
/* ATTRIBUTE INIT SETTERS / HELPERS */
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:
/**
* @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"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdbool.h>
+#include <errno.h>
#include "list.h"
#include "error.h"
#include "array.h"
#include "pmap.h"
+#include "obst.h"
#include "eset.h"
#include "pset.h"
#include "util.h"
/** Dump only irgs with names that start with this prefix. */
static ident *dump_file_filter_id = NULL;
-#define ERROR_TXT "<ERROR>"
-
-/*******************************************************************/
-/* 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 "<ERROR>";
}
#define CUSTOM_COLOR_BASE 100
/**
* 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]);
}
/**
*
* 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: ");
}
}
/* 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. */
* 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 "<NULL entity>";
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);
}
/**
*/
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);
}
/**
- * 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)
{
} 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)
{
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)) {
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)
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))
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)));
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);
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;
}
/**
{
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);
/**
* 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:
default:
;
} /* end switch */
-
- return bad;
}
#include <math.h>
{
(void) F;
(void) n;
- return;
#ifdef INTERPROCEDURAL_VIEW
fprintf(F, " %lf*(%2.0lf + %2.0lf) = %2.0lf ",
get_irn_exec_freq(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);
}
ir_fprintf(F, "bits_set: %T\n", vrp->bits_set);
ir_fprintf(F, "bits_not_set: %T\n", vrp->bits_not_set);
-
- return 0;
}
/**
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;
}
}
-/* 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);
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);
/**
* 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);
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");
}
}
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: \"");
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);
//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);
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)) {
{
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;
}
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: \"");
}
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);
/**
* 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, "\"");
}
/** 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. */
/* 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.
}
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;
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");
}
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. */
/*******************************************************************/
} /* 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));
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: \"");
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));
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);
} /* 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 */
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 */
}
}
-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));
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);
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: \"");
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: \"");
}
}
-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);
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";
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 <CR> 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 <CR> 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");
}
/**
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));
/* 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;
}
/* 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: \"");
}
}
-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;
/* 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: \"");
} 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 */
}
}
-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);
}
}
}
}
-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 <CR> 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;
+}
#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 "<ERROR>" 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
/**
* @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"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <stdbool.h>
#include "irdump_t.h"
#include "irgraph_t.h"
#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();
}
/* 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;
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));
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, " <NULL entity>\n");
- bad = 1;
}
} break;
case iro_Call: {
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");
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;
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:
*
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");
* 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;
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;
}
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))) {
}
}
-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;
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, " ");
}
}
}
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;
if (verbosity & dump_verbosity_fields) {
dump_entity_to_file_prefix(F, get_array_element_entity(tp),
- " ", verbosity);
+ " ");
}
}
break;
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));
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);
}
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. */
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;
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) {
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
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
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");
}
}
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");
}
}
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");
}
}
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");
}
}
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");
}
}
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) \
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); \
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");
}
/* 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