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
70128011
Commit
70128011
authored
Apr 29, 2005
by
Götz Lindenmaier
Browse files
class cast states implemented
[r5742]
parent
98e74915
Changes
2
Hide whitespace changes
Inline
Side-by-side
ir/tr/tr_inheritance.c
View file @
70128011
...
...
@@ -20,10 +20,13 @@
#include
"type.h"
#include
"entity.h"
#include
"typewalk.h"
#include
"irgraph_t.h"
#include
"irprog_t.h"
#include
"pset.h"
#include
"set.h"
#include
"mangle.h"
#include
"irgwalk.h"
#include
"irflag.h"
//#include ".h"
...
...
@@ -411,6 +414,11 @@ type *get_class_trans_subtype_next (type *tp) {
return
pset_next
(
get_type_map
(
tp
,
d_down
));
}
int
is_class_trans_subtype
(
type
*
tp
,
type
*
subtp
)
{
assert_valid_state
();
return
(
pset_find_ptr
(
get_type_map
(
tp
,
d_down
),
subtp
)
!=
NULL
);
}
/* - supertype ----------------------------------------------------------- */
type
*
get_class_trans_supertype_first
(
type
*
tp
)
{
...
...
@@ -480,6 +488,10 @@ int is_subclass_of(type *low, type *high) {
return
0
;
}
int
is_superclass_of
(
type
*
high
,
type
*
low
)
{
return
is_subclass_of
(
low
,
high
);
}
int
is_overwritten_by
(
entity
*
high
,
entity
*
low
)
{
int
i
,
n_overwrittenby
;
assert
(
is_entity
(
low
)
&&
is_entity
(
high
));
...
...
@@ -532,3 +544,101 @@ entity *resolve_ent_polymorphy(type *dynamic_class, entity *static_ent) {
return
res
;
}
/* ----------------------------------------------------------------------- */
/* Class cast state handling. */
/* ----------------------------------------------------------------------- */
/* - State handling. ----------------------------------------- */
void
set_irg_class_cast_state
(
ir_graph
*
irg
,
ir_class_cast_state
s
)
{
if
(
get_irp_class_cast_state
()
>
s
)
set_irp_class_cast_state
(
s
);
irg
->
class_cast_state
=
s
;
}
ir_class_cast_state
get_irg_class_cast_state
(
ir_graph
*
irg
)
{
return
irg
->
class_cast_state
;
}
void
set_irp_class_cast_state
(
ir_class_cast_state
s
)
{
int
i
;
for
(
i
=
0
;
i
<
get_irp_n_irgs
();
++
i
)
assert
(
get_irg_class_cast_state
(
get_irp_irg
(
i
))
>=
s
);
irp
->
class_cast_state
=
s
;
}
ir_class_cast_state
get_irp_class_cast_state
(
void
)
{
return
irp
->
class_cast_state
;
}
char
*
get_class_cast_state_string
(
ir_class_cast_state
s
)
{
#define X(a) case a: return #a
switch
(
s
)
{
X
(
ir_class_casts_any
);
X
(
ir_class_casts_transitive
);
X
(
ir_class_casts_normalized
);
X
(
ir_class_casts_state_max
);
default:
return
"invalid class cast state"
;
}
#undef X
}
/* - State verification. ------------------------------------- */
typedef
struct
ccs_env
{
ir_class_cast_state
expected_state
;
ir_class_cast_state
worst_situation
;
}
ccs_env
;
void
verify_irn_class_cast_state
(
ir_node
*
n
,
void
*
env
)
{
ccs_env
*
ccs
=
(
ccs_env
*
)
env
;
ir_class_cast_state
this_state
=
ir_class_casts_any
;
type
*
fromtype
=
get_irn_typeinfo_type
(
get_Cast_op
(
n
));
type
*
totype
=
get_Cast_type
(
n
);
int
ref_depth
=
0
;
while
(
is_Pointer_type
(
totype
)
&&
is_Pointer_type
(
fromtype
))
{
totype
=
get_pointer_points_to_type
(
totype
);
fromtype
=
get_pointer_points_to_type
(
fromtype
);
ref_depth
++
;
}
if
(
!
is_Class_type
(
totype
))
return
;
if
(
is_subclass_of
(
totype
,
fromtype
)
||
is_subclass_of
(
fromtype
,
totype
)
)
{
this_state
=
ir_class_casts_transitive
;
if
((
get_class_supertype_index
(
totype
,
fromtype
)
==
-
1
)
&&
(
get_class_supertype_index
(
fromtype
,
totype
)
==
-
1
)
)
{
this_state
=
ir_class_casts_normalized
;
}
}
assert
(
this_state
>=
ccs
->
expected_state
&&
"invalid state class cast state setting in graph"
);
if
(
this_state
<
ccs
->
worst_situation
)
ccs
->
worst_situation
=
this_state
;
}
/** Verify that the graph meets reqirements of state set. */
void
verify_irg_class_cast_state
(
ir_graph
*
irg
)
{
ccs_env
env
;
env
.
expected_state
=
get_irg_class_cast_state
(
irg
);
env
.
worst_situation
=
ir_class_casts_normalized
;
irg_walk_graph
(
irg
,
NULL
,
verify_irn_class_cast_state
,
&
env
);
if
((
env
.
worst_situation
>
env
.
expected_state
)
&&
get_firm_verbosity
())
{
printf
(
"Note: class cast state is set lower than reqired in graph
\n
"
);
DDMG
(
irg
);
printf
(
" state is %s, reqired is %s
\n
"
,
get_class_cast_state_string
(
env
.
expected_state
),
get_class_cast_state_string
(
env
.
worst_situation
));
}
}
ir/tr/tr_inheritance.h
View file @
70128011
...
...
@@ -30,9 +30,16 @@
#define _TR_INHERITANCE_H_
#include
"type.h"
/*
#include "entity.h"
*/
/*#include "entity.h"*/
#include
"ident.h"
/* to resolve recursion between entity.h and irgraph.h */
#ifndef _IR_GRAPH_TYPEDEF_
#define _IR_GRAPH_TYPEDEF_
typedef
struct
ir_graph
ir_graph
;
#endif
/* ----------------------------------------------------------------------- */
/* Classify pairs of types/entities in the inheritance relations. */
/* ----------------------------------------------------------------------- */
...
...
@@ -45,6 +52,14 @@
* subclasses of high. */
int
is_subclass_of
(
type
*
low
,
type
*
high
);
/** Returns true if high is superclass of low.
*
* Low is a subclass of high if low == high or if low is a subclass of
* a subclass of high. I.e, we search in all subtypes of high for low.
* @@@ this can be implemented more efficient if we know the set of all
* subclasses of high. */
int
is_superclass_of
(
type
*
high
,
type
*
low
);
/** Returns true if high is (transitive) overwritten by low.
*
* Returns false if high == low. */
...
...
@@ -52,9 +67,9 @@ int is_overwritten_by(entity *high, entity *low);
/** Resolve polymorphy in the inheritance relation.
*
* Returns the dynamically referenced entity if the static entity and the
* dynamic type are given.
* Searches downwards in overwritten tree. */
*
Returns the dynamically referenced entity if the static entity and the
*
dynamic type are given.
*
Searches downwards in overwritten tree. */
entity
*
resolve_ent_polymorphy
(
type
*
dynamic_class
,
entity
*
static_ent
);
/* ----------------------------------------------------------------------- */
...
...
@@ -119,8 +134,8 @@ typedef enum {
inh_transitive_closure_max
/**< Invalid value. */
}
inh_transitive_closure_state
;
void
set_irp_inh_transitive_closure_state
(
inh_transitive_closure_state
s
);
void
invalidate_irp_inh_transitive_closure_state
(
void
);
void
set_irp_inh_transitive_closure_state
(
inh_transitive_closure_state
s
);
void
invalidate_irp_inh_transitive_closure_state
(
void
);
inh_transitive_closure_state
get_irp_inh_transitive_closure_state
(
void
);
...
...
@@ -140,6 +155,7 @@ void free_inh_transitive_closure(void);
/** Iterate over all transitive subtypes. */
type
*
get_class_trans_subtype_first
(
type
*
tp
);
type
*
get_class_trans_subtype_next
(
type
*
tp
);
int
is_class_trans_subtype
(
type
*
tp
,
type
*
subtp
);
/* - supertype ----------------------------------------------------------- */
...
...
@@ -159,4 +175,54 @@ entity *get_entity_trans_overwrittenby_next (entity *ent);
entity
*
get_entity_trans_overwrites_first
(
entity
*
ent
);
entity
*
get_entity_trans_overwrites_next
(
entity
*
ent
);
/* ----------------------------------------------------------------------- */
/** The state of Cast operations that cast class types or pointers to class
* types.
*
* The state expresses, how far Cast operations conform with the class
* hierarchy.
*
* class A {}
* class B1 extends A {}
* class B2 extends A {}
* class C extends B1 {}
* normalized: Cast operations conform with the inheritance relation.
* I.e., the type of the operand of a Cast is either a super= or a sub-
* type of the type casted to. Example: (A)((B2) (new C())).
* transitive: Cast operations conform with the transitive inheritance
* relation. Example: (A)(new C()).
* any: Cast operations do not conform with the transitive inheritance
* relation. Example: (B2)(new B1())
*
* @see: tropt.h
*/
/* ----------------------------------------------------------------------- */
/** Flags for class cast state.
*
* The state in irp is allways smaller or equal to the state of any
* irg.
*
* We rely on the ordering of the enum. */
typedef
enum
{
ir_class_casts_any
=
0
,
/**< There are class casts that do not cast in conformance with
the class hierarchy. @@@ So far this does not happen in Firm. */
ir_class_casts_transitive
=
1
,
/**< Class casts conform to transitive inheritance edges. Default. */
ir_class_casts_normalized
=
2
,
/**< Class casts conform to inheritance edges. */
ir_class_casts_state_max
,
}
ir_class_cast_state
;
char
*
get_class_cast_state_string
(
ir_class_cast_state
s
);
void
set_irg_class_cast_state
(
ir_graph
*
irg
,
ir_class_cast_state
s
);
ir_class_cast_state
get_irg_class_cast_state
(
ir_graph
*
irg
);
void
set_irp_class_cast_state
(
ir_class_cast_state
s
);
ir_class_cast_state
get_irp_class_cast_state
(
void
);
/** Verify the class cast state of an irg.
*
* Asserts if state is to high, outputs warning if state is to low
* and firm verbosity is set.
*/
void
verify_irg_class_cast_state
(
ir_graph
*
irg
);
#endif
/* _TR_INHERITANCE_H_ */
Write
Preview
Supports
Markdown
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