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
f763fa15
Commit
f763fa15
authored
Dec 04, 2012
by
Matthias Braun
Browse files
remove class cast optimization
parent
eb38e825
Changes
8
Hide whitespace changes
Inline
Side-by-side
include/libfirm/iroptimize.h
View file @
f763fa15
...
...
@@ -626,69 +626,6 @@ FIRM_API void opt_tail_recursion(void);
*/
FIRM_API
ir_prog_pass_t
*
opt_tail_recursion_pass
(
const
char
*
name
);
/** This is the type for a method, that returns a pointer type to
* tp. This is needed in the normalization. */
typedef
ir_type
*
(
*
gen_pointer_type_to_func
)(
ir_type
*
tp
);
/** Insert Casts so that class type casts conform exactly with the type hierarchy.
*
* Formulated in Java, this achieves the following:
*
* For a class hierarchy
* class A {}
* class B extends A {}
* class C extends B {}
* we transforms a cast
* (A)new C()
* to
* (A)((B)new C()).
*
* The algorithm works for Casts with class types, but also for Casts
* with all pointer types that point (over several indirections,
* i.e. ***A) to a class type. Normalizes all graphs. Computes type
* information (@see irtypeinfo.h) if not available.
* Invalidates trout information as new casts are generated.
*
* @param gppt_fct A function that returns a pointer type that points
* to the type given as argument. If this parameter is NULL, a default
* function is used that either uses trout information or performs a O(n)
* search to find an existing pointer type. If it can not find a type,
* generates a pointer type with mode_P_mach and suffix "cc_ptr_tp".
*/
FIRM_API
void
normalize_irp_class_casts
(
gen_pointer_type_to_func
gppt_fct
);
/** Insert Casts so that class type casts conform exactly with the type hierarchy
* in given graph.
*
* For more details see normalize_irp_class_casts().
*
* This transformation requires that type information is computed. @see irtypeinfo.h.
*/
FIRM_API
void
normalize_irg_class_casts
(
ir_graph
*
irg
,
gen_pointer_type_to_func
gppt_fct
);
/** Optimize casting between class types.
*
* class A { m(); }
* class B extends A { }
* class C extends B {}
* Performs the following transformations:
* C c = (C)(B)(A)(B)new C() --> C c = (C)(B)newC() --> C c = new C()
* (Optimizing downcasts as A a = (A)(B)(new A()) --> A a = new A() can
* be suppressed by setting the flag opt_suppress_downcast_optimization.
* Downcasting A to B might cause an exception. It is not clear
* whether this is modeled by the Firm Cast node, as it has no exception
* outputs.);
* If there is inh_m() that overwrites m() in B:
* ((A) new B()).m() --> (new B()).inh_m()
* Phi((A)x, (A)y) --> (A) Phi (x, y) if (A) is an upcast.
*
* Computes type information if not available. @see irtypeinfo.h.
* Typeinformation is valid after optimization.
* Invalidates trout information.
*/
FIRM_API
void
optimize_class_casts
(
void
);
/**
* CLiff Click's combo algorithm from
* "Combining Analyses, combining Optimizations".
...
...
ir/common/firm.c
View file @
f763fa15
...
...
@@ -104,8 +104,6 @@ void ir_init(void)
/* Builds a construct allowing to access all information to be constructed
later. */
init_irprog_2
();
/* class cast optimization */
firm_init_class_casts_opt
();
/* memory disambiguation */
firm_init_memory_disambiguator
();
firm_init_loop_opt
();
...
...
ir/ir/irgraph.c
View file @
f763fa15
...
...
@@ -140,7 +140,6 @@ ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc)
res
->
typeinfo_state
=
ir_typeinfo_none
;
set_irp_typeinfo_inconsistent
();
/* there is a new graph with typeinfo_none. */
res
->
callee_info_state
=
irg_callee_info_none
;
res
->
class_cast_state
=
ir_class_casts_transitive
;
res
->
fp_model
=
fp_model_precise
;
res
->
mem_disambig_opt
=
aa_opt_inherited
;
...
...
ir/ir/irprog.c
View file @
f763fa15
...
...
@@ -99,7 +99,6 @@ static void complete_ir_prog(ir_prog *irp, const char *module_name)
set_class_final
(
irp
->
segment_types
[
IR_SEGMENT_GLOBAL
],
1
);
irp
->
const_code_irg
=
new_const_code_irg
();
irp
->
class_cast_state
=
ir_class_casts_transitive
;
irp
->
globals_entity_usage_state
=
ir_entity_usage_not_computed
;
#undef IDENT
}
...
...
ir/ir/irtypes.h
View file @
f763fa15
...
...
@@ -514,7 +514,6 @@ struct ir_graph {
op_pin_state
irg_pinned_state
;
/**< Flag for status of nodes. */
ir_typeinfo_state
typeinfo_state
;
/**< Validity of type information. */
irg_callee_info_state
callee_info_state
;
/**< Validity of callee information. */
ir_class_cast_state
class_cast_state
;
/**< Kind of cast operations in code. */
unsigned
mem_disambig_opt
;
/**< Options for the memory disambiguator. */
unsigned
fp_model
;
/**< floating point model of the graph. */
...
...
@@ -623,7 +622,6 @@ struct ir_prog {
size_t
max_callgraph_recursion_depth
;
/**< needed in callgraph. */
double
max_method_execution_frequency
;
/**< needed in callgraph. */
loop_nesting_depth_state
lnd_state
;
/**< The state of loop nesting depth information. */
ir_class_cast_state
class_cast_state
;
/**< The state of cast operations in code. */
ir_entity_usage_computed_state
globals_entity_usage_state
;
ir_label_t
last_label_nr
;
/**< The highest label number for generating unique labels. */
...
...
ir/opt/opt_init.h
View file @
f763fa15
...
...
@@ -33,8 +33,6 @@ void firm_init_reassociation(void);
void
firm_init_scalar_replace
(
void
);
void
firm_init_class_casts_opt
(
void
);
void
firm_init_loop_opt
(
void
);
#endif
ir/opt/tropt.c
deleted
100644 → 0
View file @
eb38e825
/*
* 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 Perform optimizations of the type representation.
* @date 20.4.2005
* @author Goetz Lindenmaier
*/
#include
"config.h"
#include
<assert.h>
#include
"iroptimize.h"
#include
"irprog.h"
#include
"irtypeinfo.h"
#include
"irgwalk.h"
#include
"trouts.h"
#include
"ircons.h"
#include
"irgmod.h"
#include
"irflag_t.h"
#include
"xmalloc.h"
#include
"debug.h"
#include
"opt_init.h"
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
;)
/* - statistics ---------------------------------------------- */
static
size_t
n_casts_normalized
=
0
;
static
size_t
n_casts_removed
=
0
;
static
size_t
n_sels_concretized
=
0
;
/* - Cast normalization. ------------------------------------- */
static
ir_type
*
default_gen_pointer_type_to
(
ir_type
*
tp
);
#define PTR_TYPE_SUFFIX "cc_ptr_tp"
/* class cast pointer type. */
static
ident
*
ptr_type_suffix
=
NULL
;
static
gen_pointer_type_to_func
gen_pointer_type_to
=
default_gen_pointer_type_to
;
/**
* Find a pointer type to a given type.
* Uses and updates trouts if available.
*/
static
ir_type
*
default_gen_pointer_type_to
(
ir_type
*
tp
)
{
ir_type
*
res
=
find_pointer_type_to_type
(
tp
);
if
(
is_unknown_type
(
res
))
res
=
new_type_pointer
(
tp
);
return
res
;
}
/** Return a type that is a depth times pointer to type. */
static
ir_type
*
pointerize_type
(
ir_type
*
tp
,
size_t
depth
)
{
for
(;
depth
>
0
;
--
depth
)
{
tp
=
gen_pointer_type_to
(
tp
);
}
return
tp
;
}
static
ir_node
*
normalize_values_type
(
ir_type
*
totype
,
ir_node
*
pred
)
{
ir_type
*
fromtype
=
get_irn_typeinfo_type
(
pred
);
ir_node
*
new_cast
=
pred
;
ir_node
*
block
;
size_t
ref_depth
=
0
;
if
(
totype
==
fromtype
)
return
pred
;
/* Case for optimization! */
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
pred
;
if
(
!
is_Class_type
(
fromtype
))
return
pred
;
if
((
get_class_supertype_index
(
totype
,
fromtype
)
!=
(
size_t
)
-
1
)
||
(
get_class_supertype_index
(
fromtype
,
totype
)
!=
(
size_t
)
-
1
)
)
{
/* It's just what we want ... */
return
pred
;
}
block
=
get_nodes_block
(
pred
);
if
(
is_SubClass_of
(
totype
,
fromtype
))
{
/* downcast */
while
(
get_class_subtype_index
(
fromtype
,
totype
)
==
(
size_t
)
-
1
)
{
/* Insert a cast to a subtype of fromtype. */
ir_type
*
new_type
=
NULL
;
ir_node
*
new_cast
;
size_t
i
;
size_t
n_subtypes
=
get_class_n_subtypes
(
fromtype
);
for
(
i
=
0
;
i
<
n_subtypes
&&
!
new_type
;
++
i
)
{
ir_type
*
new_sub
=
get_class_subtype
(
fromtype
,
i
);
if
(
is_SuperClass_of
(
new_sub
,
totype
))
new_type
=
new_sub
;
}
assert
(
new_type
);
fromtype
=
new_type
;
new_type
=
pointerize_type
(
new_type
,
ref_depth
);
new_cast
=
new_r_Cast
(
block
,
pred
,
new_type
);
pred
=
new_cast
;
++
n_casts_normalized
;
set_irn_typeinfo_type
(
new_cast
,
new_type
);
/* keep type information up to date. */
}
}
else
{
assert
(
is_SuperClass_of
(
totype
,
fromtype
));
/* upcast */
while
(
get_class_supertype_index
(
fromtype
,
totype
)
==
(
size_t
)
-
1
)
{
/* Insert a cast to a supertype of fromtype. */
ir_type
*
new_type
=
NULL
;
size_t
i
,
n_supertypes
=
get_class_n_supertypes
(
fromtype
);
for
(
i
=
0
;
i
<
n_supertypes
&&
!
new_type
;
++
i
)
{
ir_type
*
new_super
=
get_class_supertype
(
fromtype
,
i
);
if
(
is_SubClass_of
(
new_super
,
totype
))
new_type
=
new_super
;
}
assert
(
new_type
);
fromtype
=
new_type
;
new_type
=
pointerize_type
(
new_type
,
ref_depth
);
new_cast
=
new_r_Cast
(
block
,
pred
,
new_type
);
pred
=
new_cast
;
++
n_casts_normalized
;
set_irn_typeinfo_type
(
new_cast
,
new_type
);
/* keep type information up to date. */
}
}
return
new_cast
;
}
/**
* Post-Walker.
*/
static
void
normalize_irn_class_cast
(
ir_node
*
n
,
void
*
env
)
{
ir_node
*
res
;
(
void
)
env
;
if
(
is_Cast
(
n
))
{
ir_node
*
pred
=
get_Cast_op
(
n
);
ir_type
*
totype
=
get_Cast_type
(
n
);
res
=
normalize_values_type
(
totype
,
pred
);
set_Cast_op
(
n
,
res
);
}
else
if
(
is_Call
(
n
))
{
size_t
n_params
=
get_Call_n_params
(
n
);
size_t
i
;
ir_type
*
tp
=
get_Call_type
(
n
);
for
(
i
=
0
;
i
<
n_params
;
++
i
)
{
res
=
normalize_values_type
(
get_method_param_type
(
tp
,
i
),
get_Call_param
(
n
,
i
));
set_Call_param
(
n
,
i
,
res
);
}
}
}
static
void
pure_normalize_irg_class_casts
(
ir_graph
*
irg
)
{
assert
(
get_irg_class_cast_state
(
irg
)
!=
ir_class_casts_any
&&
"Cannot normalize irregular casts."
);
if
(
get_irg_class_cast_state
(
irg
)
==
ir_class_casts_normalized
)
{
return
;
}
irg_walk_graph
(
irg
,
NULL
,
normalize_irn_class_cast
,
NULL
);
set_irg_class_cast_state
(
irg
,
ir_class_casts_normalized
);
}
void
normalize_irg_class_casts
(
ir_graph
*
irg
,
gen_pointer_type_to_func
gppt_fct
)
{
assert
(
get_irp_typeinfo_state
()
==
ir_typeinfo_consistent
);
if
(
gppt_fct
)
gen_pointer_type_to
=
gppt_fct
;
if
(
!
ptr_type_suffix
)
ptr_type_suffix
=
new_id_from_str
(
PTR_TYPE_SUFFIX
);
pure_normalize_irg_class_casts
(
irg
);
gen_pointer_type_to
=
default_gen_pointer_type_to
;
}
void
normalize_irp_class_casts
(
gen_pointer_type_to_func
gppt_fct
)
{
size_t
i
,
n
;
if
(
gppt_fct
)
gen_pointer_type_to
=
gppt_fct
;
for
(
i
=
0
,
n
=
get_irp_n_irgs
();
i
<
n
;
++
i
)
{
ir_graph
*
irg
=
get_irp_irg
(
i
);
pure_normalize_irg_class_casts
(
irg
);
}
set_irp_class_cast_state
(
ir_class_casts_normalized
);
gen_pointer_type_to
=
default_gen_pointer_type_to
;
DB
((
dbg
,
SET_LEVEL_1
,
" Cast normalization: %zu Casts inserted.
\n
"
,
n_casts_normalized
));
}
/* - Cast optimization. ------------------------------------------- */
/**
* Optimizes Casts:
*
* (T1)(T2)x<T1> -> x<T1>
*
* (T3)(T2)x<T1> -> (T3)x<T1>
*
* if possible.
*
* @param cast the Cast node
*
* @return 1 if the cast was changed
*/
static
int
cancel_out_casts
(
ir_node
*
cast
)
{
ir_node
*
orig
,
*
pred
=
get_Cast_op
(
cast
);
ir_type
*
tp_cast
,
*
tp_pred
,
*
tp_orig
;
if
(
!
is_Cast
(
pred
))
return
0
;
orig
=
get_Cast_op
(
pred
);
tp_cast
=
get_Cast_type
(
cast
);
tp_pred
=
get_Cast_type
(
pred
);
tp_orig
=
get_irn_typeinfo_type
(
orig
);
while
(
is_Pointer_type
(
tp_cast
)
&&
is_Pointer_type
(
tp_pred
)
&&
is_Pointer_type
(
tp_orig
)
)
{
tp_cast
=
get_pointer_points_to_type
(
tp_cast
);
tp_pred
=
get_pointer_points_to_type
(
tp_pred
);
tp_orig
=
get_pointer_points_to_type
(
tp_orig
);
}
if
(
!
is_Class_type
(
tp_cast
)
||
!
is_Class_type
(
tp_pred
)
||
!
is_Class_type
(
tp_orig
))
return
0
;
if
(
is_SubClass_of
(
tp_pred
,
tp_cast
)
&&
get_opt_suppress_downcast_optimization
())
return
0
;
if
(
tp_cast
==
tp_orig
)
{
exchange
(
cast
,
orig
);
n_casts_removed
+=
2
;
return
1
;
}
if
(
!
(
is_SubClass_of
(
tp_cast
,
tp_orig
)
||
is_SubClass_of
(
tp_orig
,
tp_cast
)))
{
/* Avoid (B2)(A)(new B1()) --> (B2)(new B1())
* if B1 =!> B2 and B2 =!> B1
*/
return
0
;
}
if
((
is_SubClass_of
(
tp_cast
,
tp_pred
)
&&
is_SuperClass_of
(
tp_pred
,
tp_orig
))
||
(
is_SuperClass_of
(
tp_cast
,
tp_pred
)
&&
is_SubClass_of
(
tp_pred
,
tp_orig
)))
{
/* Cast --> Pred --> Orig */
set_Cast_op
(
cast
,
orig
);
++
n_casts_removed
;
return
1
;
}
return
0
;
}
/**
* Optimize Sel(Cast(type, ptr), ent) into Sel(ptr_type, ent_type)
*
* @param sel the Sel node
*
* @return 1 if Cast's where removed
*/
static
int
concretize_selected_entity
(
ir_node
*
sel
)
{
int
res
=
0
;
ir_entity
*
sel_ent
=
get_Sel_entity
(
sel
);
ir_node
*
cast
=
get_Sel_ptr
(
sel
);
while
(
is_Cast
(
cast
))
{
ir_type
*
cast_tp
=
get_Cast_type
(
cast
);
ir_node
*
ptr
=
get_Cast_op
(
cast
);
ir_type
*
orig_tp
=
get_irn_typeinfo_type
(
ptr
);
/* we handle only classes */
if
(
!
is_Pointer_type
(
orig_tp
)
||
!
is_Pointer_type
(
cast_tp
))
return
res
;
orig_tp
=
get_pointer_points_to_type
(
orig_tp
);
cast_tp
=
get_pointer_points_to_type
(
cast_tp
);
if
(
!
is_Class_type
(
orig_tp
)
||
!
is_Class_type
(
cast_tp
))
return
res
;
/* We only want to concretize, but not generalize. */
if
(
!
is_SuperClass_of
(
cast_tp
,
orig_tp
))
return
res
;
/* The sel entity should be a member of the cast_tp, else
the graph was not properly typed. */
if
(
get_class_member_index
(
cast_tp
,
sel_ent
)
==
(
size_t
)
-
1
)
return
res
;
ir_entity
*
new_ent
=
resolve_ent_polymorphy
(
orig_tp
,
sel_ent
);
/* New ent must be member of orig_tp. */
if
(
get_class_member_index
(
orig_tp
,
new_ent
)
==
(
size_t
)
-
1
)
return
res
;
/* all checks done, we can remove the Cast and update the Sel */
set_Sel_entity
(
sel
,
new_ent
);
set_Sel_ptr
(
sel
,
ptr
);
++
n_sels_concretized
;
sel_ent
=
new_ent
;
cast
=
ptr
;
res
=
1
;
}
return
res
;
}
/**
* Move Casts of the same type through a Phi node, i.e.
* Phi(Cast(type, x_0), ..., Cast(type, x_n)) -> Cast(type, Phi(x_0, ..., x_n))
*
* @param phi the Phi node
*
* @return 1 if Cast's where moved
*/
static
int
concretize_Phi_type
(
ir_node
*
phi
)
{
int
n_preds
=
get_Phi_n_preds
(
phi
);
ir_node
**
pred
=
ALLOCAN
(
ir_node
*
,
n_preds
);
ir_node
*
nn
,
*
blk
;
ir_type
*
totype
;
ir_type
*
fromtype
;
int
i
;
if
(
n_preds
==
0
)
return
0
;
pred
[
0
]
=
get_Phi_pred
(
phi
,
0
);
if
(
!
is_Cast
(
pred
[
0
]))
return
0
;
if
(
!
is_Cast_upcast
(
pred
[
0
]))
return
0
;
fromtype
=
get_irn_typeinfo_type
(
get_Cast_op
(
pred
[
0
]));
totype
=
get_Cast_type
(
pred
[
0
]);
pred
[
0
]
=
get_Cast_op
(
pred
[
0
]);
for
(
i
=
1
;
i
<
n_preds
;
++
i
)
{
pred
[
i
]
=
get_Phi_pred
(
phi
,
i
);
if
(
!
is_Cast
(
pred
[
i
]))
return
0
;
if
(
get_irn_typeinfo_type
(
get_Cast_op
(
pred
[
i
]))
!=
fromtype
)
return
0
;
pred
[
i
]
=
get_Cast_op
(
pred
[
i
]);
}
/* Transform Phi */
blk
=
get_nodes_block
(
phi
);
nn
=
new_r_Phi
(
blk
,
n_preds
,
pred
,
get_irn_mode
(
phi
));
set_irn_typeinfo_type
(
nn
,
fromtype
);
nn
=
new_r_Cast
(
blk
,
nn
,
totype
);
set_irn_typeinfo_type
(
nn
,
totype
);
exchange
(
phi
,
nn
);
return
1
;
}
/**
* Remove Casted null checks, i.e.
*
* Cmp(Cast(type, x_orig), NULL_type) -> Cmp(x_orig, NULL_orig)
*
* @param cmp the Cmp node
*
* @return 1 if Cast's where removed
*/
static
int
remove_Cmp_Null_cast
(
ir_node
*
cmp
)
{
ir_graph
*
irg
;
ir_node
*
cast
,
*
null
,
*
new_null
;
int
cast_pos
,
null_pos
;
ir_type
*
fromtype
;
ir_mode
*
mode
;
cast
=
get_Cmp_left
(
cmp
);
if
(
!
is_Cast
(
cast
))
{
null
=
cast
;
null_pos
=
0
;
cast
=
get_Cmp_right
(
cmp
);
cast_pos
=
1
;
if
(
!
is_Cast
(
cast
))
return
0
;
}
else
{
null
=
get_Cmp_right
(
cmp
);
cast_pos
=
0
;
null_pos
=
1
;
}
if
(
!
is_Const
(
null
))
return
0
;
mode
=
get_irn_mode
(
null
);
if
(
!
mode_is_reference
(
mode
))
return
0
;
if
(
get_Const_tarval
(
null
)
!=
get_mode_null
(
mode
))
return
0
;
/* Transform Cmp */
irg
=
get_irn_irg
(
cmp
);
set_irn_n
(
cmp
,
cast_pos
,
get_Cast_op
(
cast
));
fromtype
=
get_irn_typeinfo_type
(
get_Cast_op
(
cast
));
new_null
=
new_r_Const
(
irg
,
get_Const_tarval
(
null
));
set_irn_typeinfo_type
(
new_null
,
fromtype
);
set_irn_n
(
cmp
,
null_pos
,
new_null
);
++
n_casts_removed
;
return
1
;
}
/**
* Post-Walker: Optimize class casts (mostly by trying to remove them)
*/
static
void
irn_optimize_class_cast
(
ir_node
*
n
,
void
*
env
)
{
int
*
changed
=
(
int
*
)
env
;
if
(
is_Cast
(
n
))
*
changed
|=
cancel_out_casts
(
n
);
else
if
(
is_Sel
(
n
))
*
changed
|=
concretize_selected_entity
(
n
);
else
if
(
is_Phi
(
n
))
*
changed
|=
concretize_Phi_type
(
n
);
else
if
(
is_Cmp
(
n
))
*
changed
|=
remove_Cmp_Null_cast
(
n
);
}
void
optimize_class_casts
(
void
)
{
int
changed
;
changed
=
0
;
all_irg_walk
(
NULL
,
irn_optimize_class_cast
,
&
changed
);
DB
((
dbg
,
SET_LEVEL_1
,
" Cast optimization: %zu Casts removed, %zu Sels concretized.
\n
"
,
n_casts_removed
,
n_sels_concretized
));
}
void
firm_init_class_casts_opt
(
void
)
{
FIRM_DBG_REGISTER
(
dbg
,
"firm.opt.tropt"
);
}
ir/tr/tr_inheritance.c
View file @
f763fa15
...
...
@@ -571,38 +571,3 @@ ir_entity *resolve_ent_polymorphy(ir_type *dynamic_class, ir_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
(
const
ir_graph
*
irg
)
{
return
irg
->
class_cast_state
;
}
void
set_irp_class_cast_state
(
ir_class_cast_state
s
)
{
#ifndef NDEBUG
size_t
i
,
n
;
for
(
i
=
0
,
n
=
get_irp_n_irgs
();
i
<
n
;
++
i
)
assert
(
get_irg_class_cast_state
(
get_irp_irg
(
i
))
>=
s
);
#endif
irp
->
class_cast_state
=
s
;
}