Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
f3264b83
Commit
f3264b83
authored
Jun 29, 2009
by
Matthias Braun
Browse files
remove unused common/firmwalk.* code
[r26224]
parent
aa26d80f
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/common/firmwalk.c
deleted
100644 → 0
View file @
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
;
}
ir/common/firmwalk.h
deleted
100644 → 0
View file @
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
* @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,