Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
35a87ce1
Commit
35a87ce1
authored
Sep 22, 2011
by
Matthias Braun
Browse files
remove old+unused rta code
parent
1553e921
Changes
4
Hide whitespace changes
Inline
Side-by-side
include/libfirm/firm.h
View file @
35a87ce1
...
...
@@ -105,7 +105,6 @@
#include
"irtypeinfo.h"
#include
"irverify.h"
#include
"lowering.h"
#include
"rta.h"
#include
"structure.h"
#include
"timing.h"
#include
"trouts.h"
...
...
include/libfirm/rta.h
deleted
100644 → 0
View file @
1553e921
/*
* 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 Interprocedural analysis to improve the call graph estimate.
* @author Florian
* @date 09.06.2002
* @version $Id$
* @brief
* (TODO translate to english)
* Intraprozedurale Analyse zur Absch�tzung der Aufrufrelation. Es wird
* die Menge der instantiierten Klassen bestimmt, und daraus eine Absch�tzung
* der aufgerufenen Methoden.
*
* Voraussetzung ist, dass das Programm keine Methodenzeiger handhaben kann.
* In diesem Fall koennten Methoden verloren gehen. Oder wir muessen nach
* allen "freien" Methoden suchen (siehe cgana).
*
* @@@ Die Analyse sollte wissen, von welchen Klassen Instanzen ausserhalb
* der Uebersetzungseinheit alloziert werden koennen. Diese muessen in
* die initiale Menge allozierter Klassen aufgenommern werden.
*
* Nach: David F. Bacon and Peter F. Sweeney,
* Fast static analysis of C++ virtual function calls
* OOPSLA 1996
*/
#ifndef FIRM_ANA_RTA_H
#define FIRM_ANA_RTA_H
#include
"firm_types.h"
#include
"begin.h"
/**
* Initialise the RTA data structures and perform RTA.
* Expects that all allocations are done by Alloc nodes.
*/
FIRM_API
void
rta_init
(
void
);
/**
* Delete all graphs that have been found to be dead.
*/
FIRM_API
void
rta_delete_dead_graphs
(
void
);
/** Clean up our data structures.
* Finishes the RTA.
*/
FIRM_API
void
rta_cleanup
(
void
);
/** Returns non-zero if the given class is alive. */
FIRM_API
int
rta_is_alive_class
(
ir_type
*
clazz
);
/** Returns non-zero if the given graph is alive. */
FIRM_API
int
rta_is_alive_graph
(
ir_graph
*
graph
);
/** report for all graphs and types whether they are alive */
FIRM_API
void
rta_report
(
void
);
#include
"end.h"
#endif
ir/ana/cgana.c
View file @
35a87ce1
...
...
@@ -36,7 +36,6 @@
#include
<string.h>
#include
"cgana.h"
#include
"rta.h"
#include
"xmalloc.h"
#include
"irnode_t.h"
...
...
ir/ana/rta.c
deleted
100644 → 0
View file @
1553e921
/*
* Copyright (C) 1995-2011 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 Interprocedural analysis to improve the call graph estimate.
* @author Florian Liekweg
* @version 09.06.2002
* @version $Id$
*/
#include
"config.h"
#include
"rta.h"
#include
<stdlib.h>
#include
<stdbool.h>
#include
"irnode_t.h"
#include
"irprog_t.h"
#include
"irgraph_t.h"
#include
"pset_new.h"
#include
"irgwalk.h"
#include
"irgmod.h"
#include
"irverify.h"
#include
"irprintf.h"
#include
"debug.h"
#include
"error.h"
/** The debug handle. */
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
=
NULL
;)
/* base data */
static
pset_new_t
*
_live_classes
=
NULL
;
/* cache computed results */
static
pset_new_t
*
_live_graphs
=
NULL
;
/**
* Add a graph to the set of live graphs.
*
* @param graph the graph to add
* @return non-zero if the graph was added, zero
* if it was already in the live set
*/
static
bool
add_graph
(
ir_graph
*
graph
)
{
if
(
!
pset_new_contains
(
_live_graphs
,
graph
))
{
DB
((
dbg
,
LEVEL_2
,
"RTA: new graph of %+F
\n
"
,
graph
));
pset_new_insert
(
_live_graphs
,
graph
);
return
true
;
}
return
false
;
}
/**
* Add a class to the set of live classes.
*
* @param clazz the class to add
* @return non-zero if the graph was added, zero
* if it was already in the live set
*/
static
bool
add_class
(
ir_type
*
clazz
)
{
if
(
!
pset_new_contains
(
_live_classes
,
clazz
))
{
DB
((
dbg
,
LEVEL_2
,
"RTA: new class: %+F
\n
"
,
clazz
));
pset_new_insert
(
_live_classes
,
clazz
);
return
true
;
}
return
false
;
}
/** Given an entity, add all implementing graphs that belong to live classes
* to _live_graphs.
*
* Iff additions occurred, return true, else false.
*/
static
bool
add_implementing_graphs
(
ir_entity
*
method
)
{
size_t
i
;
size_t
n_over
=
get_entity_n_overwrittenby
(
method
);
ir_graph
*
graph
=
get_entity_irg
(
method
);
bool
change
=
false
;
if
(
NULL
==
graph
)
graph
=
get_entity_irg
(
method
);
DB
((
dbg
,
LEVEL_2
,
"RTA: new call to %+F
\n
"
,
method
));
if
(
rta_is_alive_class
(
get_entity_owner
(
method
)))
{
if
(
NULL
!=
graph
)
change
=
add_graph
(
graph
);
}
for
(
i
=
0
;
i
<
n_over
;
++
i
)
{
ir_entity
*
over
=
get_entity_overwrittenby
(
method
,
i
);
change
|=
add_implementing_graphs
(
over
);
}
return
change
;
}
/**
* Walker: Enter all method accesses and all class allocations into
* our tables.
*
* Set *(int*)env to true iff (possibly) new graphs have been found.
*/
static
void
rta_act
(
ir_node
*
node
,
void
*
env
)
{
bool
*
change
=
(
bool
*
)
env
;
unsigned
op
=
get_irn_opcode
(
node
);
if
(
iro_Call
==
op
)
{
/* CALL */
ir_entity
*
ent
=
NULL
;
ir_node
*
ptr
=
get_Call_ptr
(
node
);
/* CALL SEL */
if
(
iro_Sel
==
get_irn_opcode
(
ptr
))
{
ent
=
get_Sel_entity
(
ptr
);
*
change
|=
add_implementing_graphs
(
ent
);
/* CALL SYMCONST */
}
else
if
(
iro_SymConst
==
get_irn_opcode
(
ptr
))
{
if
(
get_SymConst_kind
(
ptr
)
==
symconst_addr_ent
)
{
ir_graph
*
graph
;
ent
=
get_SymConst_entity
(
ptr
);
graph
=
get_entity_irg
(
ent
);
if
(
graph
)
{
*
change
|=
add_graph
(
graph
);
}
else
{
/* it's an external allocated thing. */
}
}
else
{
/* other symconst. */
panic
(
"This SymConst can not be an address for a method call."
);
}
/* STRANGE */
}
else
{
panic
(
"Unexpected address expression: can not analyse, therefore can not do correct rta!"
);
}
}
else
if
(
iro_Alloc
==
op
)
{
/* ALLOC */
ir_type
*
type
=
get_Alloc_type
(
node
);
*
change
|=
add_class
(
type
);
}
}
/**
Traverse the given graph to collect method accesses and
object allocations.
*/
static
bool
rta_fill_graph
(
ir_graph
*
graph
)
{
bool
change
=
false
;
irg_walk_graph
(
graph
,
rta_act
,
NULL
,
&
change
);
return
change
;
}
/**
* Traverse all graphs to collect method accesses and object allocations.
*/
static
int
rta_fill_incremental
(
void
)
{
size_t
i
,
n
;
int
n_runs
=
0
;
bool
rerun
=
true
;
/* init_tables has added main_irg to _live_graphs */
/* Need to take care of graphs that are externally
visible or sticky. Pretend that they are called: */
for
(
i
=
0
,
n
=
get_irp_n_irgs
();
i
<
n
;
++
i
)
{
ir_graph
*
graph
=
get_irp_irg
(
i
);
ir_entity
*
ent
=
get_irg_entity
(
graph
);
ir_linkage
linkage
=
get_entity_linkage
(
ent
);
if
((
linkage
&
IR_LINKAGE_HIDDEN_USER
)
||
entity_is_externally_visible
(
ent
))
pset_new_insert
(
_live_graphs
,
graph
);
}
while
(
rerun
)
{
ir_graph
*
graph
;
pset_new_iterator_t
iter
;
/* start off new */
pset_new_t
*
live_graphs
=
_live_graphs
;
_live_graphs
=
XMALLOC
(
pset_new_t
);
pset_new_init
(
_live_graphs
);
DB
((
dbg
,
LEVEL_2
,
"RTA: RUN %i
\n
"
,
n_runs
));
/* collect what we have found previously */
foreach_pset_new
(
live_graphs
,
ir_graph
*
,
graph
,
iter
)
{
pset_new_insert
(
_live_graphs
,
graph
);
}
rerun
=
false
;
foreach_pset_new
(
live_graphs
,
ir_graph
*
,
graph
,
iter
)
{
DB
((
dbg
,
LEVEL_2
,
"RTA: RUN %i: considering graph of %+F
\n
"
,
n_runs
,
graph
));
rerun
|=
rta_fill_graph
(
graph
);
}
pset_new_destroy
(
live_graphs
);
free
(
live_graphs
);
++
n_runs
;
}
return
n_runs
;
}
#ifdef DEBUG_libfirm
/**
* Count the number of graphs that we have found to be live.
*/
static
size_t
stats
(
void
)
{
size_t
i
,
n
;
size_t
n_live_graphs
=
0
;
for
(
i
=
0
,
n
=
get_irp_n_irgs
();
i
<
n
;
++
i
)
{
ir_graph
*
graph
=
get_irp_irg
(
i
);
if
(
rta_is_alive_graph
(
graph
))
++
n_live_graphs
;
}
return
n_live_graphs
;
}
#endif
/* remove a graph, part I */
/*
We removed the first graph to implement the entity, so we're
abstract now. Pretend that it wasn't there at all, and every
entity that used to inherit this entity's graph is now abstract.
*/
/**
Initialize the static data structures.
*/
static
void
init_tables
(
void
)
{
ir_graph
*
irg
;
ir_segment_t
segment
;
_live_classes
=
XMALLOC
(
pset_new_t
);
pset_new_init
(
_live_classes
);
_live_graphs
=
XMALLOC
(
pset_new_t
);
pset_new_init
(
_live_graphs
);
irg
=
get_irp_main_irg
();
if
(
irg
!=
NULL
)
{
/* add the main irg to the live set if one is specified */
pset_new_insert
(
_live_graphs
,
irg
);
}
/* Find static allocated classes in all segments */
for
(
segment
=
IR_SEGMENT_FIRST
;
segment
<=
IR_SEGMENT_LAST
;
++
segment
)
{
ir_type
*
tp
=
get_segment_type
(
segment
);
size_t
n
=
get_compound_n_members
(
tp
);
size_t
i
;
for
(
i
=
0
;
i
<
n
;
++
i
)
{
ir_type
*
member_type
=
get_entity_type
(
get_compound_member
(
tp
,
i
));
if
(
is_Class_type
(
member_type
))
pset_new_insert
(
_live_classes
,
member_type
);
}
}
}
/*
* Initialize the RTA data structures, and perform RTA.
*/
void
rta_init
(
void
)
{
int
n_runs
=
0
;
FIRM_DBG_REGISTER
(
dbg
,
"firm.ana.rta"
);
# ifdef DEBUG_libfirm
{
size_t
i
;
for
(
i
=
get_irp_n_irgs
();
i
>
0
;)
{
irg_verify
(
get_irp_irg
(
--
i
),
0
);
}
tr_verify
();
}
# endif
/* defined DEBUG_libfirm */
init_tables
();
n_runs
=
rta_fill_incremental
();
DB
((
dbg
,
LEVEL_1
,
"RTA: n_graphs = %zu
\n
"
,
get_irp_n_irgs
()));
DB
((
dbg
,
LEVEL_1
,
"RTA: n_live_graphs = %zu
\n
"
,
stats
()));
DB
((
dbg
,
LEVEL_1
,
"RTA: n_runs = %i
\n
"
,
n_runs
));
# ifdef DEBUG_libfirm
{
size_t
i
;
for
(
i
=
get_irp_n_irgs
();
i
>
0
;)
{
irg_verify
(
get_irp_irg
(
--
i
),
0
);
}
tr_verify
();
}
# endif
/* defined DEBUG_libfirm */
}
/**
* walker for all types and entities
*
* Changes the peculiarity of entities that represents
* dead graphs to peculiarity_description.
*/
static
void
make_entity_to_description
(
type_or_ent
tore
,
void
*
env
)
{
(
void
)
env
;
if
(
is_entity
(
tore
.
ent
))
{
ir_entity
*
ent
=
tore
.
ent
;
if
((
is_Method_type
(
get_entity_type
(
ent
)))
&&
!
entity_is_externally_visible
(
ent
))
{
ir_graph
*
irg
=
get_entity_irg
(
ent
);
if
(
irg
!=
NULL
&&
!
pset_new_contains
(
_live_graphs
,
irg
))
{
set_entity_peculiarity
(
ent
,
peculiarity_description
);
set_entity_irg
(
ent
,
NULL
);
}
}
}
}
/* Delete all graphs that we have found to be dead from the program
If verbose == 1, print statistics, if > 1, chatter about every detail
*/
void
rta_delete_dead_graphs
(
void
)
{
size_t
i
,
n_dead_irgs
,
n_graphs
=
get_irp_n_irgs
();
ir_graph
*
irg
,
*
next_irg
,
*
dead_irgs
;
irp_reserve_resources
(
irp
,
IRP_RESOURCE_IRG_LINK
);
n_dead_irgs
=
0
;
dead_irgs
=
NULL
;
for
(
i
=
n_graphs
;
i
>
0
;)
{
irg
=
get_irp_irg
(
--
i
);
if
(
!
rta_is_alive_graph
(
irg
))
{
set_irg_link
(
irg
,
dead_irgs
);
dead_irgs
=
irg
;
++
n_dead_irgs
;
}
}
/* Hmm, probably we need to run this only if dead_irgs is non-NULL */
type_walk
(
make_entity_to_description
,
NULL
,
NULL
);
for
(
irg
=
dead_irgs
;
irg
!=
NULL
;
irg
=
next_irg
)
{
next_irg
=
(
ir_graph
*
)
get_irg_link
(
irg
);
remove_irp_irg
(
irg
);
}
DB
((
dbg
,
LEVEL_1
,
"RTA: dead methods = %zu
\n
"
,
n_dead_irgs
));
irp_free_resources
(
irp
,
IRP_RESOURCE_IRG_LINK
);
}
/* Clean up the RTA data structures. Call this after calling rta_init */
void
rta_cleanup
(
void
)
{
# ifdef DEBUG_libfirm
size_t
i
;
for
(
i
=
get_irp_n_irgs
();
i
>
0
;)
{
irg_verify
(
get_irp_irg
(
--
i
),
0
);
}
tr_verify
();
# endif
/* defined DEBUG_libfirm */
if
(
_live_classes
!=
NULL
)
{
pset_new_destroy
(
_live_classes
);
free
(
_live_classes
);
_live_classes
=
NULL
;
}
if
(
_live_graphs
!=
NULL
)
{
pset_new_destroy
(
_live_graphs
);
free
(
_live_graphs
);
_live_graphs
=
NULL
;
}
}
/* Say whether this class might be instantiated at any point in the program: */
int
rta_is_alive_class
(
ir_type
*
clazz
)
{
return
pset_new_contains
(
_live_classes
,
clazz
);
}
/* Say whether this graph might be run at any time in the program: */
int
rta_is_alive_graph
(
ir_graph
*
graph
)
{
return
pset_new_contains
(
_live_graphs
,
graph
);
}
/* dump our opinion */
void
rta_report
(
void
)
{
size_t
i
,
n
;
n
=
get_irp_n_types
();
for
(
i
=
0
;
i
<
n
;
++
i
)
{
ir_type
*
tp
=
get_irp_type
(
i
);
if
(
is_Class_type
(
tp
)
&&
rta_is_alive_class
(
tp
))
{
ir_printf
(
"RTA: considered allocated: %+F
\n
"
,
tp
);
}
}
n
=
get_irp_n_irgs
();
for
(
i
=
0
;
i
<
n
;
i
++
)
{
ir_graph
*
irg
=
get_irp_irg
(
i
);
if
(
rta_is_alive_graph
(
irg
))
{
ir_printf
(
"RTA: considered called: graph of %+F
\n
"
,
irg
);
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment