Commit f3264b83 authored by Matthias Braun's avatar Matthias Braun
Browse files

remove unused common/firmwalk.* code

[r26224]
parent aa26d80f
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief Walker that touches all Firm data structures
* @author Sebastian Felis
* @date 7.2003
* @version $Id$
*/
#include "config.h"
#include <string.h>
#include "firmwalk.h"
#include "entity_t.h"
#include "irnode_t.h"
#include "irprog_t.h"
#include "irgwalk.h"
#include "irtools.h"
#include "array.h"
#include "obst.h"
#include "pmap.h"
/** obstack for firm walker */
static struct obstack fw_obst;
/** This map stores all types of firm */
static pmap *type_map = NULL;
/** This map stores all entities of firm */
static pmap *entity_map = NULL;
/** Internal data structure of firm walker to collect
* some information of firm ir. The collected data will be stored
* into the link field of ir node. All graphs have a list of its
* blocks and all blocks have a list of their nodes. */
typedef struct {
ir_node **list; /**< List of blocks or nodes */
void *link; /**< Public link field. The public link field of firm nodes
is wrapped by set_firm_walk_link and
get_firm_walk_link. */
} fw_data;
/*@{ */
/** Access macros to fw_data structure */
#define FW_GET_DATA_LIST(s) ((s)->list)
#define FW_SET_DATA_LIST(s, t) ((s)->list = (t))
#define FW_GET_DATA_LINK(s) ((s)->link)
#define FW_SET_DATA_LINK(s, t) ((s)->link = (t))
/*@} */
/** Returns own data struct of the firm walker.
*
* If no structure defined (firm link is NULL) allocate a new
* struct to the fgd obstack. Only ir graph and block nodes
* will allocate this structure.
* - ir graph collect its block
* - block collect its nodes
*/
static
fw_data *fw_get_data(void *thing)
{
fw_data *data = NULL;
assert(thing);
switch (get_kind(thing)) {
case k_ir_graph:
data = get_irg_link(thing);
/* init block list of graph */
if (NULL == data)
{
/* allocate new firm walk structure */
data = obstack_alloc(&fw_obst, sizeof(fw_data));
memset(data, 0, sizeof(fw_data));
set_irg_link(thing, data);
/* allocate block list */
FW_GET_DATA_LIST(data) = NEW_ARR_F(ir_node *, 0);
}
break;
case k_ir_node:
/* init node list of block */
if (is_Block(thing))
{
data = get_irn_link(thing);
if (NULL == data)
{
/* allocate new firm walk structure */
data = obstack_alloc(&fw_obst, sizeof(fw_data));
memset(data, 0, sizeof(fw_data));
set_irn_link(thing, data);
/* allocate node list */
FW_GET_DATA_LIST(data) = NEW_ARR_F(ir_node *, 0);
}
}
break;
default: {} /* other kinds of firm nodes */
}
return data;
}
/** Free all collected data in ir graphs and nodes.
* An ir graph or an ir block node has a list as a
* dynamic array, which will be deleted here. */
static
void fw_free_data(void *thing)
{
fw_data *data = NULL;
assert(thing);
switch (get_kind(thing)) {
case k_ir_graph:
data = get_irg_link(thing);
/* delete block list of graph */
if (NULL != data)
{
DEL_ARR_F(FW_GET_DATA_LIST(data));
set_irg_link(thing, NULL);
}
break;
case k_ir_node:
/* delete node list of block */
if (is_Block(thing))
{
data = get_irn_link(thing);
if (NULL != data)
{
DEL_ARR_F(FW_GET_DATA_LIST(data));
set_irn_link(thing, NULL);
}
}
break;
default: {} /* other kinds of firm nodes */
}
}
/* documentation in header file */
void set_firm_walk_link(void *thing, void *link)
{
fw_data *data;
assert(thing);
switch (get_kind(thing)) {
case k_entity:
set_entity_link(thing, link);
break;
case k_type:
set_type_link(thing, link);
break;
case k_ir_graph:
data = fw_get_data(thing);
FW_SET_DATA_LINK(data, link);
break;
case k_ir_node:
if (is_Block(thing))
{
data = fw_get_data(thing);
FW_SET_DATA_LINK(data, link);
}
else
set_irn_link(thing, link);
break;
case k_ir_mode:
set_mode_link(thing, link);
break;
default: {} /* other kinds of firm nodes */
}
}
/* documentation in header file */
void *get_firm_walk_link(void *thing)
{
fw_data *data;
assert(thing);
switch (get_kind(thing)) {
case k_entity:
return get_entity_link(thing);
case k_type:
return get_type_link(thing);
case k_ir_graph:
data = fw_get_data(thing);
return FW_GET_DATA_LINK(data);
case k_ir_node:
if (is_Block(thing))
{
data = fw_get_data(thing);
return FW_GET_DATA_LINK(data);
}
else
return get_irn_link(thing);
case k_ir_mode:
return get_mode_link(thing);
default:
return NULL;
}
}
/** Fill maps of type and entity.
* This function will be called by the firm walk initializer
* to collect all types and entities of program's firm ir.
* All types will be collected in the hash table type_map
* and all entity are stored in entity_map. The mode of an
* type will be collected as well.
*
* @param tore Type or entity
* @param env Environment pointer (currently unused)
*/
static
void fw_collect_tore(type_or_ent tore, void *env)
{
ir_type *tp;
ir_entity *ent;
switch (get_kind(tore.ent)) {
case k_entity:
ent = tore.ent;
/* append entity to list */
set_entity_link(ent, NULL);
if (!pmap_contains(entity_map, ent))
pmap_insert(entity_map, ent, env);
break;
case k_type:
tp = tore.typ;
/* append type to list */
set_type_link(tp, NULL);
if (!pmap_contains(type_map, tp))
pmap_insert(type_map, tp, env);
break;
default: break;
}
}
/** Collect all data from nodes. Block appends itself to
* the corresponding ir graph and other nodes appends itself
* to block list. Collects also the modes of each node to get
* non-type modes.
*
* @param irn IR node pointer.
* @param env Environment pointer (currently unused)
*/
static
void fw_collect_irn(ir_node *irn, void *env)
{
fw_data *data;
(void) env;
/* block nodes. */
if (is_Block(irn)) {
/* add this block to ir graph's block list */
data = fw_get_data(get_current_ir_graph());
ARR_APP1(ir_node *, FW_GET_DATA_LIST(data), irn);
}
/* non block nodes */
else {
/* add this node to block's node list */
ir_node *block = get_nodes_block(irn);
data = fw_get_data(block);
ARR_APP1(ir_node *, FW_GET_DATA_LIST(data), irn);
}
}
/** Irg walker function to free all collected data from nodes */
static
void fw_free_colleted_data(ir_node *irn, void *env)
{
(void) env;
/* Free node list from blocks */
if (is_Block(irn))
{
fw_free_data(irn);
}
}
/** Initialize all walking data.
*
* Collect all specific data like types, entities, ir graphs, blocks, nodes
* from current firm structures.
*/
void firm_walk_init(firm_walk_flags flags)
{
int i;
/* init obstack */
obstack_init(&fw_obst);
/* Init map of type and entity. If map or list
already exists, free it. */
if (type_map)
pmap_destroy(type_map);
type_map = pmap_create();
if (entity_map)
pmap_destroy(entity_map);
entity_map = pmap_create();
/* Collect all types (also unused types) if flag is set */
if (FW_WITH_ALL_TYPES & flags)
type_walk(fw_collect_tore, NULL, NULL);
/* for each ir graph */
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
ir_graph *irg = get_irp_irg(i);
set_irg_link(irg, NULL);
type_walk_irg(irg, fw_collect_tore, NULL, NULL);
irg_walk_graph(irg, firm_clear_link, fw_collect_irn, NULL);
}
}
/** This function should call after using the firm walker to free
* all collected data and frees the used obstack */
void firm_walk_finalize(void)
{
int i;
/* free all used maps and lists */
pmap_destroy(type_map);
type_map = NULL;
pmap_destroy(entity_map);
entity_map = NULL;
/* free all collected data from ir graphs and nodes */
for (i = 0; i < get_irp_n_irgs(); i++)
{
ir_graph *irg = get_irp_irg(i);
fw_free_data(irg);
irg_walk_graph(get_irp_irg(i), NULL, fw_free_colleted_data, NULL);
}
/* free obstack */
obstack_free(&fw_obst, NULL);
}
/** Dumps the firm ir.
*
* After initializing the firm walker by calling firm_walk_init()
* the firm structure could be accessed by defining the firm walk interface
* wif. This function could be called several times to customize the
* walk order or definitions.
*
* @param wif Walk interface which contains the callback function
*
* @see firm_walk_interface */
void firm_walk(firm_walk_interface *wif)
{
int mode_i, irg_i, block_i, block_list_len, irn_i, irn_list_len;
pmap_entry *entry;
fw_data *data;
ir_node *block, **block_list, **irn_list;
ir_graph *saved_irg = current_ir_graph;
assert(wif && "firm_walk() in firmwalk.c: No walking interface defined!");
/* walk over all modes */
if (wif->do_mode_init) wif->do_mode_init(wif->env);
if (wif->do_mode)
{
for (mode_i = get_irp_n_modes() - 1; mode_i >= 0; --mode_i)
wif->do_mode(get_irp_mode(mode_i), wif->env);
}
if (wif->do_mode_finalize) wif->do_mode_finalize(wif->env);
/* walk over all types */
if (wif->do_type_init) wif->do_type_init(wif->env);
if (wif->do_type)
{
for (entry = pmap_first(type_map); entry; entry = pmap_next(type_map))
wif->do_type((ir_type *)entry->key, wif->env);
}
if (wif->do_type_finalize) wif->do_type_finalize(wif->env);
/* walk over all entities */
if (wif->do_entity_init) wif->do_entity_init(wif->env);
if (wif->do_entity)
{
for (entry = pmap_first(entity_map); entry; entry = pmap_next(entity_map))
wif->do_entity((ir_entity *)entry->key, wif->env);
}
if (wif->do_entity_finalize) wif->do_entity_finalize(wif->env);
/* Dump graphs ================================================= */
if (wif->do_graph_init) wif->do_graph_init(wif->env);
for (irg_i = 0; irg_i < get_irp_n_irgs(); irg_i++)
{
current_ir_graph = get_irp_irg(irg_i);
/* walk over all ir graph */
if (wif->do_graph) wif->do_graph(current_ir_graph, wif->env);
/* walk over all irg's block nested ========================== */
data = fw_get_data(current_ir_graph);
block_list = FW_GET_DATA_LIST(data);
block_list_len = ARR_LEN(block_list);
for (block_i = 0; block_i < block_list_len; block_i++)
{
if (wif->do_block_init) wif->do_block_init(current_ir_graph, wif->env);
block = (ir_node *)block_list[block_i];
if (wif->do_block) wif->do_block(block, wif->env);
/* walk over all block's ir nodes nested =================== */
data = fw_get_data(block);
irn_list = FW_GET_DATA_LIST(data);
irn_list_len = ARR_LEN(irn_list);
/* call block as prefix ir node */
if ((wif->do_node) &&
(wif->flags & (FW_DUMP_BLOCK_AS_IRN | FW_DUMP_IRN_IN_PREFIX)))
wif->do_node(block, wif->env);
/* do ir nodes in prefix or postfix order? */
if (wif->flags & FW_DUMP_IRN_IN_PREFIX)
irn_i = irn_list_len-1;
else
irn_i = 0;
while (irn_i >= 0 && irn_i < irn_list_len)
{
if (wif->do_node) wif->do_node((ir_node *)irn_list[irn_i], wif->env);
/* do ir nodes in prefix or postfix order? */
if (wif->flags & FW_DUMP_IRN_IN_PREFIX)
irn_i--;
else
irn_i++;
}
/* call block as postfix ir node */
if ((wif->do_node) &&
((wif->flags & (FW_DUMP_BLOCK_AS_IRN | FW_DUMP_IRN_IN_PREFIX))
== FW_DUMP_BLOCK_AS_IRN))
wif->do_node(block, wif->env);
/* wall over all block's ir nodes nested end =============== */
if(wif->do_block_post)
wif->do_block_post(block, wif->env);
} /* for each block */
if (wif->do_block_finalize)
wif->do_block_finalize(current_ir_graph, wif->env);
/* walk over all irg's block nested end ====================== */
if(wif->do_graph_post)
wif->do_graph_post(current_ir_graph, wif->env);
} /* for each ir graph irg */
if(wif->do_graph_finalize)
wif->do_graph_finalize(wif->env);
/** ### ToDo: Dump const_code_irg ?? No! Dump const code with entities, types etc. */
/* restore the state of current_ir_graph */
current_ir_graph = saved_irg;
}
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @biref Walker that touches all Firm data structures
* @author Sebastian Felis
* @date 7.2003
* @version $Id$
* @summary
* Firm walker over intermediate representation.
*
* To initialize the walker, call firm_walk_init(). This function
* collects all specific data from the firm represenation. After
* building the walker information firm_walk() could be called
* serveral times with different flags (options) from specific walker
* or dumper. At least firm_walk_finalizer() should be called to free
* the stored data.
*
* This walker could be used for a dumper e.g. a vcg or xml dumper.
*
* @note If a specific walker or dumper which uses the link field
* of any firm node, the the wrapper functions set_firm_walk_link()
* and get_firm_walk_link() should be used, because the firm walker
* make use of the link field to store its own data.
* @note Deprecated, better use the stuff in irgwalk.h, typewalk.h
*/
#ifndef FIRM_COMMON_FIRM_WALK_H
#define FIRM_COMMON_FIRM_WALK_H
#include "firm_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Returns the link of a firm node.
* Possible firm structures are: entity, type, ir_graph, ir_node and
* ir_mode. Otherwise this function has no effect
*
* Derived walker or dumper have to call this function to store data
* to a firm structure. The real link field of firm structure is used
* by this firm walker to collect walking data.
*
* @param thing Pointer to a firm structure
* @return Link pointer
*
* @note After calling firm_walk_finalize() the stored link
* information may be invalid. */
void *get_firm_walk_link(void *thing);
/** Set the link field of a firm structure.
* Possible firm structures are: entity, type, ir_graph, ir_node and
* ir_mode. Otherwise this function has no effect
*
* Derived walker or dumper have to call this function to store data
* to a firm structure. The real link field of firm structure is used
* by this firm walker to collect walking data.
*
* @param thing firm structure
* @param link Pointer to link field
*
* @note After calling firm_walk_finalize() the stored link
* information may be invalid. */
void set_firm_walk_link(void *thing, void *link);
/** Initialisation function for firm walker callbacks */
typedef void firm_walk_init_func(void *env);
/** Finalisation function for firm walker callbacks */
typedef void firm_walk_finalize_func(void *env);
/** Mode callback function definition */
typedef void firm_walk_mode_func(ir_mode *mode, void *env);
/** Type callback function definition */
typedef void firm_walk_type_func(ir_type *tp, void *env);
/** Entity callback function definition */
typedef void firm_walk_entity_func(ir_entity *ent, void *env);
/** Graph callback function definition */
typedef void firm_walk_graph_func(ir_graph *irg, void *env);
/* @{ */
/** Block callback function definition */
typedef void firm_walk_block_init_func(ir_graph *irg, void *env);
typedef void firm_walk_block_func(ir_node *block, void *env);
typedef void firm_walk_block_finalize_func(ir_graph *irg, void *env);
/* @} */
/** Node callback function definition */
typedef void firm_walk_node_func (ir_node *irn, void *env);
/** @enum firm_walk_flags
*
* Flags for the firm walker to modify some dumping behavior
*/
typedef enum
{
FW_WITH_ALL_TYPES = 1<<0, /**< Collect and dump all types, especially
unused types.
@note This flag could be set in
firm_dumper_init() and is unused in
firm_dump() */
FW_WITH_DOMINATOR = 1<<1, /**< nyi */
FW_WITH_OUTEDGES = 1<<2, /**< nyi */
FW_WITH_LOOPS = 1<<3, /**< nyi */
FW_DUMP_BLOCK_AS_IRN = 1<<4, /**< Dump all block nodes as irn nodes
additionally */
FW_DUMP_IRN_IN_PREFIX = 1<<5 /**< Dumps all ir nodes in prefix order
according to the internal firm graph
structure */
} firm_walk_flags;
/** Interface of the firm walker */
typedef struct
{
/* @{ */
/** Interface function to dump all used and internal modes.
Internal modes are: BB, X, M and T */
firm_walk_init_func *do_mode_init;
firm_walk_mode_func *do_mode;
firm_walk_finalize_func *do_mode_finalize;
/* @} */
/* @{ */
/** Interface to dump all collected types.
*
* @note To dump all (not only used types by default) a special walk
* flag must be set for the walker initializer */
firm_walk_init_func *do_type_init;
firm_walk_type_func *do_type;
firm_walk_finalize_func *do_type_finalize;
/* @} */
/* @{ */
/** Dumping interface for entities */
firm_walk_init_func *do_entity_init;
firm_walk_entity_func *do_entity;
firm_walk_finalize_func *do_entity_finalize;
/* @} */
/** Dumps all graphs and subnodes.
*
* The firm walker dump a graph with its blocks and nodes nested.
* Fist do_graph_init will be called (if defined). For each graph
* do_graph will be call in a loop.
* After all blocks in a graph are dumped, do_graph_post() is called.
* After dumped all graphs, do_graph_finalize will be called.
*
* Within do_graph each block will be dumped. First do_block_init,