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
f56e0464
Commit
f56e0464
authored
Jun 28, 2002
by
Götz Lindenmaier
Browse files
Improved support for multiple inheritance
[r419]
parent
1bea052f
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/ana/cgana.c
View file @
f56e0464
...
@@ -37,7 +37,8 @@ static eset * entities = NULL;
...
@@ -37,7 +37,8 @@ static eset * entities = NULL;
* bergebenene (dynamischen) Typ berschreibt. */
* bergebenene (dynamischen) Typ berschreibt. */
static
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
static
entity
*
get_implementation
(
type
*
class
,
entity
*
method
)
{
int
i
;
int
i
;
if
(
get_entity_peculiarity
(
method
)
!=
description
&&
get_entity_owner
(
method
)
==
class
)
{
if
(
get_entity_peculiarity
(
method
)
!=
description
&&
get_entity_owner
(
method
)
==
class
)
{
return
method
;
return
method
;
}
}
for
(
i
=
get_entity_n_overwrittenby
(
method
)
-
1
;
i
>=
0
;
--
i
)
{
for
(
i
=
get_entity_n_overwrittenby
(
method
)
-
1
;
i
>=
0
;
--
i
)
{
...
@@ -55,6 +56,54 @@ static entity * get_implementation(type * class, entity * method) {
...
@@ -55,6 +56,54 @@ static entity * get_implementation(type * class, entity * method) {
assert
(
0
&&
"implemenation not found"
);
assert
(
0
&&
"implemenation not found"
);
}
}
/* Returns the entity that contains the implementation of the inherited
entity if available, else returns the entity passed. */
entity
*
get_inherited_methods_implementation
(
entity
*
inh_meth
)
{
entity
*
impl_meth
=
NULL
;
ir_node
*
addr
=
get_atomic_ent_value
(
inh_meth
);
assert
(
addr
&&
"constant entity without value"
);
if
(
get_irn_op
(
addr
)
==
op_Const
)
{
impl_meth
=
get_tv_entity
(
get_Const_tarval
(
addr
));
}
assert
(
!
impl_meth
||
get_entity_peculiarity
(
impl_meth
)
==
existent
);
return
impl_meth
?
impl_meth
:
inh_meth
;
}
/* A recursive descend in the overwritten relation.
Cycle-free, therefore must terminate. */
void
collect_impls
(
entity
*
method
,
eset
*
set
,
int
*
size
,
bool
*
open
)
{
int
i
;
if
(
get_entity_peculiarity
(
method
)
==
existent
)
{
if
(
get_entity_visibility
(
method
)
==
external_allocated
)
{
assert
(
get_entity_irg
(
method
)
==
NULL
);
*
open
=
true
;
}
else
{
assert
(
get_entity_irg
(
method
)
!=
NULL
);
eset_insert
(
set
,
method
);
++
(
*
size
);
}
}
if
(
get_entity_peculiarity
(
method
)
==
inherited
)
{
entity
*
impl_ent
=
get_inherited_methods_implementation
(
method
);
assert
(
impl_ent
&&
"no implementation for inherited entity"
);
if
(
get_entity_visibility
(
impl_ent
)
==
external_allocated
)
{
assert
(
get_entity_irg
(
impl_ent
)
==
NULL
);
*
open
=
true
;
}
else
{
assert
(
get_entity_irg
(
impl_ent
)
!=
NULL
);
if
(
!
eset_contains
(
set
,
impl_ent
))
{
eset_insert
(
set
,
impl_ent
);
++
(
*
size
);
}
}
}
/** recursive descend **/
for
(
i
=
get_entity_n_overwrittenby
(
method
)
-
1
;
i
>=
0
;
--
i
)
collect_impls
(
get_entity_overwrittenby
(
method
,
i
)
,
set
,
size
,
open
);
}
/* Alle Methoden bestimmen, die die bergebene Methode berschreiben
/* Alle Methoden bestimmen, die die bergebene Methode berschreiben
* (und implementieren). In der zurckgegebenen Reihung kommt jede
* (und implementieren). In der zurckgegebenen Reihung kommt jede
...
@@ -69,43 +118,26 @@ static entity ** get_impl_methods(entity * method) {
...
@@ -69,43 +118,26 @@ static entity ** get_impl_methods(entity * method) {
int
i
;
int
i
;
entity
**
arr
;
entity
**
arr
;
bool
open
=
false
;
bool
open
=
false
;
if
(
get_entity_peculiarity
(
method
)
==
existent
)
{
if
(
get_entity_visibility
(
method
)
==
external_allocated
)
{
/** Collect all method entities that can be called here **/
assert
(
get_entity_irg
(
method
)
==
NULL
);
collect_impls
(
method
,
set
,
&
size
,
&
open
);
open
=
true
;
}
else
{
/** Gefunden Entitaeten in ein Feld kopieren, ev. Unbekannten
assert
(
get_entity_irg
(
method
)
!=
NULL
);
Vorgaenger einfuegen. **/
eset_insert
(
set
,
method
);
++
size
;
}
}
for
(
i
=
get_entity_n_overwrittenby
(
method
)
-
1
;
i
>=
0
;
--
i
)
{
entity
*
ent
=
get_entity_overwrittenby
(
method
,
i
);
if
(
get_entity_peculiarity
(
ent
)
==
existent
)
{
if
(
get_entity_visibility
(
ent
)
==
external_allocated
)
{
assert
(
get_entity_irg
(
ent
)
==
NULL
);
open
=
true
;
}
else
{
assert
(
get_entity_irg
(
ent
)
!=
NULL
);
if
(
!
eset_contains
(
set
,
ent
))
{
eset_insert
(
set
,
ent
);
++
size
;
}
}
}
}
if
(
size
==
0
&&
!
open
)
{
if
(
size
==
0
&&
!
open
)
{
/* keine implementierte berschriebene Methode */
/* keine implementierte berschriebene Methode */
arr
=
NULL
;
arr
=
NULL
;
}
else
if
(
open
)
{
}
else
if
(
open
)
{
entity
*
ent
;
entity
*
ent
;
arr
=
NEW_ARR_F
(
entity
*
,
size
+
1
);
arr
=
NEW_ARR_F
(
entity
*
,
size
+
1
);
arr
[
0
]
=
NULL
;
arr
[
0
]
=
NULL
;
/* Represents open method */
for
(
ent
=
eset_first
(
set
);
size
>
0
;
ent
=
eset_next
(
set
),
--
size
)
arr
[
size
]
=
ent
;
for
(
ent
=
eset_first
(
set
);
size
>
0
;
ent
=
eset_next
(
set
),
--
size
)
arr
[
size
]
=
ent
;
}
else
{
}
else
{
entity
*
ent
;
entity
*
ent
;
arr
=
NEW_ARR_F
(
entity
*
,
size
);
arr
=
NEW_ARR_F
(
entity
*
,
size
);
for
(
size
-=
1
,
ent
=
eset_first
(
set
);
size
>=
0
;
ent
=
eset_next
(
set
),
--
size
)
arr
[
size
]
=
ent
;
for
(
size
-=
1
,
ent
=
eset_first
(
set
);
size
>=
0
;
ent
=
eset_next
(
set
),
--
size
)
arr
[
size
]
=
ent
;
}
}
eset_destroy
(
set
);
eset_destroy
(
set
);
return
arr
;
return
arr
;
...
@@ -118,25 +150,26 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
...
@@ -118,25 +150,26 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
* ersetzen. */
* ersetzen. */
if
(
get_SymConst_kind
(
node
)
==
linkage_ptr_info
)
{
if
(
get_SymConst_kind
(
node
)
==
linkage_ptr_info
)
{
pmap_entry
*
entry
=
pmap_find
(
ldname_map
,
(
void
*
)
get_SymConst_ptrinfo
(
node
));
pmap_entry
*
entry
=
pmap_find
(
ldname_map
,
(
void
*
)
get_SymConst_ptrinfo
(
node
));
if
(
entry
!=
NULL
)
{
if
(
entry
!=
NULL
)
{
/* Method is declared in the compiled code */
entity
*
ent
=
entry
->
value
;
entity
*
ent
=
entry
->
value
;
if
(
get_entity_visibility
(
ent
)
!=
external_allocated
)
{
if
(
get_entity_visibility
(
ent
)
!=
external_allocated
)
{
/* Meth. is defined */
assert
(
get_entity_irg
(
ent
));
assert
(
get_entity_irg
(
ent
));
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
exchange
(
node
,
new_Const
(
mode_p
,
tarval_p_from_entity
(
ent
)));
exchange
(
node
,
new_d_Const
(
get_irn_dbg_info
(
node
),
mode_p
,
tarval_p_from_entity
(
ent
)));
}
}
}
}
}
}
}
else
if
(
get_irn_op
(
node
)
==
op_Sel
&&
is_method_type
(
get_entity_type
(
get_Sel_entity
(
node
))))
{
}
else
if
(
get_irn_op
(
node
)
==
op_Sel
&&
is_method_type
(
get_entity_type
(
get_Sel_entity
(
node
))))
{
entity
*
ent
=
get_Sel_entity
(
node
);
entity
*
ent
=
get_Sel_entity
(
node
);
if
(
get_irn_op
(
skip_Proj
(
get_Sel_ptr
(
node
)))
==
op_Alloc
)
{
if
(
get_irn_op
(
skip_Proj
(
get_Sel_ptr
(
node
)))
==
op_Alloc
)
{
ent
=
get_implementation
(
get_Alloc_type
(
skip_Proj
(
get_Sel_ptr
(
node
))),
ent
);
/* We know which method will be called, no dispatch necessary. */
if
(
get_entity_visibility
(
ent
)
==
external_allocated
)
{
assert
(
get_entity_peculiarity
(
ent
)
!=
description
);
exchange
(
node
,
new_SymConst
((
type_or_id_p
)
get_entity_ld_ident
(
ent
),
linkage_ptr_info
));
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
}
else
{
exchange
(
node
,
copy_const_value
(
get_atomic_ent_value
(
ent
)));
exchange
(
node
,
new_Const
(
mode_p
,
tarval_p_from_entity
(
ent
)));
}
}
else
{
}
else
{
assert
(
get_entity_peculiarity
(
ent
)
!=
inherited
);
if
(
!
eset_contains
(
entities
,
ent
))
{
if
(
!
eset_contains
(
entities
,
ent
))
{
/* Entity noch nicht behandelt. Alle (intern oder extern)
/* Entity noch nicht behandelt. Alle (intern oder extern)
* implementierten Methoden suchen, die diese Entity
* implementierten Methoden suchen, die diese Entity
...
@@ -160,17 +193,26 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
...
@@ -160,17 +193,26 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
}
}
}
else
{
}
else
{
entity
**
arr
=
get_entity_link
(
ent
);
entity
**
arr
=
get_entity_link
(
ent
);
#if 0
int i;
printf("\nCall site "); DDMN(node);
printf(" in "); DDME(get_irg_ent(current_ir_graph));
printf(" can call:\n");
for (i = 0; i < ARR_LEN(arr); i++) {
printf(" - "); DDME(arr[i]);
printf(" with owner "); DDMT(get_entity_owner(arr[i]));
}
printf("\n");
#endif
if
(
ARR_LEN
(
arr
)
==
1
&&
arr
[
0
]
!=
NULL
)
{
if
(
ARR_LEN
(
arr
)
==
1
&&
arr
[
0
]
!=
NULL
)
{
/* Die Sel-Operation kann immer nur einen Wert auf eine
/* Die Sel-Operation kann immer nur einen Wert auf eine
* interne Methode zurckgeben. Wir knnen daher die
* interne Methode zurckgeben. Wir knnen daher die
* Sel-Operation durch eine Const- bzw. SymConst-Operation
* Sel-Operation durch eine Const- bzw. SymConst-Operation
* ersetzen. */
* ersetzen. */
if
(
get_entity_visibility
(
arr
[
0
])
==
external_allocated
)
{
set_irg_current_block
(
current_ir_graph
,
get_nodes_Block
(
node
));
exchange
(
node
,
new_SymConst
((
type_or_id_p
)
get_entity_ld_ident
(
arr
[
0
]),
exchange
(
node
,
copy_const_value
(
get_atomic_ent_value
(
arr
[
0
])));
linkage_ptr_info
));
}
else
{
exchange
(
node
,
new_Const
(
mode_p
,
tarval_p_from_entity
(
arr
[
0
])));
}
}
}
}
}
}
}
...
@@ -179,7 +221,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
...
@@ -179,7 +221,7 @@ static void sel_methods_walker(ir_node * node, pmap * ldname_map) {
/* Datenstruktur initialisieren. Zustzlich werden alle
/* Datenstruktur initialisieren. Zustzlich werden alle
* SymConst-Operationen, die auf interne Methode verweisen, durch
* SymConst-Operationen, die auf interne Methode
n
verweisen, durch
* Const-Operationen ersetzt. */
* Const-Operationen ersetzt. */
static
void
sel_methods_init
(
void
)
{
static
void
sel_methods_init
(
void
)
{
int
i
;
int
i
;
...
@@ -198,6 +240,7 @@ static void sel_methods_init(void) {
...
@@ -198,6 +240,7 @@ static void sel_methods_init(void) {
pmap_destroy
(
ldname_map
);
pmap_destroy
(
ldname_map
);
}
}
/*****************************************************************************/
/* Datenstruktur freigeben. */
/* Datenstruktur freigeben. */
static
void
sel_methods_dispose
(
void
)
{
static
void
sel_methods_dispose
(
void
)
{
...
@@ -302,7 +345,7 @@ static void callee_ana_proj(ir_node * node, long n, eset * methods) {
...
@@ -302,7 +345,7 @@ static void callee_ana_proj(ir_node * node, long n, eset * methods) {
static
void
callee_ana_node
(
ir_node
*
node
,
eset
*
methods
)
{
static
void
callee_ana_node
(
ir_node
*
node
,
eset
*
methods
)
{
int
i
;
int
i
;
assert
(
get_irn_mode
(
node
)
==
mode_p
);
assert
(
(
get_irn_mode
(
node
)
==
mode_p
)
||
is_Bad
(
node
))
;
/* rekursion verhindern */
/* rekursion verhindern */
if
(
get_irn_link
(
node
)
==
MARK
)
{
if
(
get_irn_link
(
node
)
==
MARK
)
{
/* already visited */
/* already visited */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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