Commit fe1e62d9 authored by Götz Lindenmaier's avatar Götz Lindenmaier
Browse files

Addded interprocedureal view.

[r408]
parent e0ae3612
/* -------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------
* Intraprozedurale Analyse zur Abschätzung der Aufrulrelation. Es
* wird eine Menge von freien Methoden und anschließend die an den
* Call-Operationen aufrufbaren Methoden bestimmt.
*
* Erstellt: Hubert Schmid, 09.06.2002
* ---------------------------------------------------------------- */
#ifndef _CGANA_H_
#define _CGANA_H_
#include "entity.h"
/* Methoden sind "frei", wenn ihr Funktionszeiger (potentiell)
*"explizit" bekannt ist, d.h.:
*
* - die Methode ist von außen sichtbar (external_visible).
*
* - ihr Funktionszeiger ist "frei", d.h. der Funktionszeiger wurde
* nicht ausschließlich an den entsprechenden Eingang eines
* Call-Knotens weitergegeben, sondern z.B. in den Speicher
* geschrieben, als Parameter übergeben, ...
*
* Die main-Methode ist immer in der Menge enthalten.
*
* Die Links an den "ir_node"s werden gelöscht. */
/* Bestimmt für jede Call-Operation die Menge der aufrufbaren Methode
* und speichert das Ergebnis in der Call-Operation. (siehe
* "set_Call_callee"). Die Methode gibt die Menge der
* "freien" Methoden zurück, die vom Aufrufer wieder freigegeben
* werden muss (free).
*
* Performs some optimizations possible by the analysed information:
* - Replace SymConst nodes by Const nodes if possible,
* - Replace (Sel-method(Alloc)) by Const method,
* - Replaces unreachable Sel nodes by Bad (@@@ was genau meint unreachable?)
* - Replaces Sel-method by Const if the Method is never overwritten */
void cgana(int *len, entity ***free_methods);
#endif /* _CGANA_H_ */
This diff is collapsed.
/* -------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------
* Auf- und Abbau der interprozeduralen Darstellung (Explizite
* interprozedurale Abhängigkeiten).
*
* Erstellt: Hubert Schmid, 09.06.2002
* ---------------------------------------------------------------- */
#ifndef _CONSTRUCT_H_
#define _CONSTRUCT_H_
#include "entity.h"
/* Aufbau der interprozeduralen Darstellung. Das Analyseergebnis muss
* in den Call-Operationen gespeichert sein. */
void cg_construct(int arr_len, entity ** free_methods_arr);
/* Abbau der interprozeduralen (Sichten-) Darstellung, in eine
* gewöhnliche intraprozedurale Darstellung */
void cg_destruct(void);
#endif /* _CONSTRUCT_H_ */
/* -------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------
* Entfernen von nicht erreichbaren (aufrufbaren) Methoden. Die Menge
* der nicht erreichbaren Methoden wird aus der Abschtzung der
* Aufrufrelation bestimmt.
*
* Erstellt: Hubert Schmid, 09.06.2002
* ---------------------------------------------------------------- */
#include "ircgopt.h"
#include "array.h"
#include "irprog.h"
#include "irgwalk.h"
static void clear_link(ir_node * node, void * env) {
set_irn_link(node, NULL);
}
/* Call-Operationen an die "link"-Liste von "call_head" anhngen. */
static void collect_call(ir_node * node, ir_node * head) {
if (get_irn_op(node) == op_Call) {
set_irn_link(node, get_irn_link(head));
set_irn_link(head, node);
}
}
/* garbage collect methods: mark and remove */
void gc_irgs(int n_keep, entity ** keep_arr) {
void * MARK = &MARK;
int i;
/* mark */
if (n_keep > 0) {
entity ** marked = NEW_ARR_F(entity *, n_keep);
for (i = 0; i < n_keep; ++i) {
marked[i] = keep_arr[i];
set_entity_link(marked[i], MARK);
}
for (i = 0; i < ARR_LEN(marked); ++i) {
ir_graph * irg = get_entity_irg(marked[i]);
ir_node * node = get_irg_end(irg);
/* collect calls */
irg_walk_graph(irg, clear_link, (irg_walk_func) collect_call, node);
/* iterate calls */
for (node = get_irn_link(node); node; node = get_irn_link(node)) {
int i;
assert(get_irn_op(node) == op_Call);
for (i = get_Call_n_callees(node) - 1; i >= 0; --i) {
entity * ent = get_Call_callee(node, i);
if (ent && get_entity_irg(ent) && get_entity_link(ent) != MARK) {
set_entity_link(ent, MARK);
ARR_APP1(entity *, marked, ent);
}
}
}
}
DEL_ARR_F(marked);
}
/* clean */
for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
ir_graph * irg = get_irp_irg(i);
entity * ent = get_irg_ent(irg);
if (get_entity_link(ent) != MARK) {
remove_irp_irg(irg);
set_entity_peculiarity(ent, description);
}
set_entity_link(ent, NULL);
}
}
/* -------------------------------------------------------------------
* $Id$
* -------------------------------------------------------------------
* Entfernen von nicht erreichbaren (aufrufbaren) Methoden. Die Menge
* der nicht erreichbaren Methoden wird aus der Abschätzung der
* Aufrufrelation bestimmt.
*
* Erstellt: Hubert Schmid, 09.06.2002
* ---------------------------------------------------------------- */
#ifndef _GC_IRGS_H_
#define _GC_IRGS_H_
#include "entity.h"
/* Entfernt alle Methoden, die von den Methoden aus "keep_arr"
* (bezgl. der Abschätzung get_Call_callee) nicht erreichbar sind. Die
* Abschätzung der Aufrufrelation muss entsprechend an den
* Call-Operationen gespeichert sein. Die "entity->link"s werden dabei
* überschrieben. */
void gc_irgs(int n_keep, entity ** keep_arr);
#endif /* _GC_IRGS_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment