*/
FIRM_API void set_opt_global_cse(int value);
-/** Restricts the behavior of cast optimization.
- *
- * If set, downcast are not optimized if they might be
- * illegal as in (Super)(Sub) (new Super()). Default:
- * 0 == not suppressed.
- */
-FIRM_API void set_opt_suppress_downcast_optimization(int value);
-/** Returns suppred_downcast flag.
- * @see set_opt_suppress_downcast_optimization() */
-FIRM_API int get_opt_suppress_downcast_optimization(void);
-
/**
* Enable/Disable Global Null Pointer Test Elimination.
*
/** Calculates the inversed (R^-1) relation, i.e., "<" --> ">" */
FIRM_API ir_relation get_inversed_relation(ir_relation relation);
-/**
- * @addtogroup Cast
- * @{
- */
-
-/** Checks for upcast.
- *
- * Returns true if the Cast node casts a class type to a super type.
- * Works also for pointers to classes (recursively).
- *
- * Needs typeinfo calculated.
- */
-FIRM_API int is_Cast_upcast(ir_node *node);
-
-/** Checks for downcast.
- *
- * Returns true if the Cast node casts a class type to a sub type.
- * Works also for pointers to classes (recursively).
- *
- * Needs typeinfo calculated.
- */
-FIRM_API int is_Cast_downcast(ir_node *node);
-
-/** @} */
-
/**
* @addtogroup Phi
* @{
FIRM_API ir_node *skip_Id(ir_node *node);
/** Returns corresponding operand of Tuple if node is a Proj from a Tuple. */
FIRM_API ir_node *skip_Tuple(ir_node *node);
-/** Returns operand of node if node is a Cast. */
-FIRM_API ir_node *skip_Cast(ir_node *node);
-/** Returns operand of node if node is a Cast. */
-FIRM_API const ir_node *skip_Cast_const(const ir_node *node);
/** Returns operand of node if node is a Pin. */
FIRM_API ir_node *skip_Pin(ir_node *node);
/** Returns operand of node if node is a Confirm */
FIRM_API ir_node *skip_Confirm(ir_node *node);
-/** Skip all high-level Operations (including Cast, Confirm). */
+/** Skip all high-level Operations (including Confirm). */
FIRM_API ir_node *skip_HighLevel_ops(ir_node *node);
/** Returns true if the operation manipulates control flow */
FIRM_API int is_cfop(const ir_node *node);
*/
FIRM_API void copy_node_attr(ir_graph *irg, const ir_node *old_node, ir_node *new_node);
-/** Returns the type attribute of a node n (SymConst, Call, Alloc, Free,
- * Cast) or NULL.*/
+/** Returns the type attribute of a node n (SymConst, Call, Alloc, Free)
+ * or NULL.*/
FIRM_API ir_type *get_irn_type_attr(ir_node *n);
/** Returns the entity attribute of a node n (SymConst, Sel) or NULL. */
/** Returns Alloc node number @p pos that create an instance of type @p type. */
FIRM_API ir_node *get_type_alloc(const ir_type *type, size_t pos);
-/** Returns number of Cast nodes that cast a pointer to type @p type. */
-FIRM_API size_t get_type_n_casts(const ir_type *type);
-/** Cast node that cast a pointer to this type. */
-FIRM_API ir_node *get_type_cast(const ir_type *type, size_t pos);
-/** Returns number of upcasts. O(\#casts). */
-FIRM_API size_t get_class_n_upcasts(const ir_type *clss);
-/** Returns number of downcasts. O(\#casts). */
-FIRM_API size_t get_class_n_downcasts(const ir_type *clss);
-
/** Returns number of pointertypes that point to type @p type. */
FIRM_API size_t get_type_n_pointertypes_to(const ir_type *type);
/** Returns pointer type number @p pos that points to type @p type. */
FIRM_API ir_entity *get_entity_trans_overwrites_next(const ir_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())
- *
- * Flags for class cast state.
- *
- * The state in irp is always 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;
-
-/** Sets class cast state for graph @p irg to @p state. */
-FIRM_API void set_irg_class_cast_state(ir_graph *irg,
- ir_class_cast_state state);
-/** Returns class cast state for graph @p irg. */
-FIRM_API ir_class_cast_state get_irg_class_cast_state(const ir_graph *irg);
-/** Sets class cast state for the whole program to @p state. */
-FIRM_API void set_irp_class_cast_state(ir_class_cast_state state);
-/** Returns class cast state for the whole program. */
-FIRM_API ir_class_cast_state get_irp_class_cast_state(void);
-
/**
* Checks a type.
*
static pmap *entity_access_map = NULL;
static pmap *entity_reference_map = NULL;
static pmap *type_alloc_map = NULL;
-static pmap *type_cast_map = NULL;
static pmap *type_pointertype_map = NULL;
static pmap *type_arraytype_map = NULL;
pmap_insert(type_alloc_map, tp, (void *)alls);
}
-/**
- * Return a flexible array containing all Cast-nodes
- * that "create" a given type.
- */
-static ir_node **get_type_cast_array(const ir_type *tp)
-{
- if (!type_cast_map) type_cast_map = pmap_create();
-
- ir_node **res = pmap_get(ir_node*, type_cast_map, tp);
- if (!res) {
- res = NEW_ARR_F(ir_node *, 0);
- pmap_insert(type_cast_map, tp, (void *)res);
- }
- return res;
-}
-
-static void set_type_cast_array(const ir_type *tp, ir_node **alls)
-{
- pmap_insert(type_cast_map, tp, (void *)alls);
-}
-
/**
* Return a flexible array containing all pointer
* types that points-to a given type.
set_type_alloc_array(tp, allocs);
}
-/* Number of Cast nodes that create an instance of this type */
-size_t get_type_n_casts(const ir_type *tp)
-{
- ir_node **casts;
-
- assert(tp && is_type(tp));
-
- casts = get_type_cast_array(tp);
- return ARR_LEN(casts);
-}
-
-
-size_t get_class_n_upcasts(const ir_type *clss)
-{
- size_t i, n_casts = get_type_n_casts(clss);
- size_t n_instances = 0;
- for (i = 0; i < n_casts; ++i) {
- ir_node *cast = get_type_cast(clss, i);
- if (is_Cast_upcast(cast))
- ++n_instances;
- }
- return n_instances;
-}
-
-size_t get_class_n_downcasts(const ir_type *clss)
-{
- size_t i, n_casts = get_type_n_casts(clss);
- size_t n_instances = 0;
- for (i = 0; i < n_casts; ++i) {
- ir_node *cast = get_type_cast(clss, i);
- if (is_Cast_downcast(cast))
- ++n_instances;
- }
- return n_instances;
-}
-
-ir_node *get_type_cast(const ir_type *tp, size_t pos)
-{
- ir_node **casts;
- assert(pos < get_type_n_casts(tp));
-
- casts = get_type_cast_array(tp);
- return casts[pos];
-}
-
-void add_type_cast(const ir_type *tp, ir_node *n)
-{
- ir_node **casts;
-
- assert(tp && is_type(tp));
- assert(n && is_ir_node(n));
-
- casts = get_type_cast_array(tp);
- ARR_APP1(ir_node *, casts, n);
- set_type_cast_array(tp, casts);
-}
-
/*------------------------------------------------------------------*/
size_t get_type_n_pointertypes_to(const ir_type *tp)
if (is_Alloc(n)) {
add_type_alloc(get_Alloc_type(n), n);
return;
- } else if (is_Cast(n)) {
- add_type_cast(get_Cast_type(n), n);
- return;
} else if (is_Sel(n)) {
add_entity_reference(get_Sel_entity(n), n);
return;
type_alloc_map = NULL;
}
- if (type_cast_map) {
- ir_node **casts;
- for (casts = (ir_node **)pmap_first(type_cast_map);
- casts;
- casts = (ir_node **)pmap_next(type_cast_map)) {
- /* DEL_ARR_F(alls); */
- }
- pmap_destroy(type_cast_map);
- type_cast_map = NULL;
- }
-
if (type_pointertype_map) {
ir_node **pts;
for (pts = (ir_node **)pmap_first(type_pointertype_map);
#include "trouts.h"
-void add_type_cast(const ir_type *tp, ir_node *cast);
void add_type_pointertype_to(const ir_type *tp, ir_type *ptp);
void add_type_arraytype_of(const ir_type *tp, ir_type *atp);
/* TODO: Check, if there can be information derived from any of these:
is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
is_Break(node) is_Builtin(node) is_Call(node)
- is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
+ is_Carry(node) is_Cmp(node) is_Cond(node)
is_CopyB(node) is_Div(node) is_Dummy(node)
is_End(node) is_Free(node)
is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
init = skip_Id(init);
switch (get_irn_opcode(init)) {
- case iro_Cast:
- emit_init_expression(env, get_Cast_op(init));
- return;
-
case iro_Conv:
emit_init_expression(env, get_Conv_op(init));
return;
case iro_Sel:
fprintf(F, "%s ", get_ent_dump_name(get_Sel_entity(n)));
break;
- case iro_Cast:
- ir_fprintf(F, "(%+F)", get_Cast_type(n));
- break;
case iro_Cmp:
fprintf(F, "%s ", get_relation_string(get_Cmp_relation(n)));
break;
case iro_Free:
print_node_type_edge(F,n,get_Free_type(n),NODE2TYPE_EDGE_ATTR);
break;
- case iro_Cast:
- print_node_type_edge(F,n,get_Cast_type(n),NODE2TYPE_EDGE_ATTR);
- break;
default:
break;
}
}
}
} break;
- case iro_Cast: {
- ir_fprintf(F, " cast to type: %+F\n", get_Cast_type(n));
- } break;
case iro_Cmp: {
ir_relation relation = get_Cmp_relation(n);
ir_fprintf(F, " relation: %s\n", get_relation_string(relation));
/** Use Global Null Pointer Test elimination. */
I_FLAG(global_null_ptr_elimination , 5, ON)
-/** Optimize cast nodes. */
-E_FLAG(suppress_downcast_optimization , 7, OFF)
-
/** Automatically create Sync node during construction. */
I_FLAG(auto_create_sync , 10, OFF)
#define get_optimize() get_optimize_()
#define get_opt_cse() get_opt_cse_()
-#define get_opt_suppress_downcast_optimization() get_opt_suppress_downcast_optimization_()
#endif
node->attr.call.callee_arr = NULL;
}
-int is_Cast_upcast(ir_node *node)
-{
- ir_type *totype = get_Cast_type(node);
- ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
-
- assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
- assert(fromtype);
-
- while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
- totype = get_pointer_points_to_type(totype);
- fromtype = get_pointer_points_to_type(fromtype);
- }
-
- assert(fromtype);
-
- if (!is_Class_type(totype)) return 0;
- return is_SubClass_of(fromtype, totype);
-}
-
-int is_Cast_downcast(ir_node *node)
-{
- ir_type *totype = get_Cast_type(node);
- ir_type *fromtype = get_irn_typeinfo_type(get_Cast_op(node));
-
- assert(get_irg_typeinfo_state(get_irn_irg(node)) == ir_typeinfo_consistent);
- assert(fromtype);
-
- while (is_Pointer_type(totype) && is_Pointer_type(fromtype)) {
- totype = get_pointer_points_to_type(totype);
- fromtype = get_pointer_points_to_type(fromtype);
- }
-
- assert(fromtype);
-
- if (!is_Class_type(totype)) return 0;
- return is_SubClass_of(totype, fromtype);
-}
-
int (is_unop)(const ir_node *node)
{
return is_unop_(node);
return node;
}
-ir_node *skip_Cast(ir_node *node)
-{
- if (is_Cast(node))
- return get_Cast_op(node);
- return node;
-}
-
-const ir_node *skip_Cast_const(const ir_node *node)
-{
- if (is_Cast(node))
- return get_Cast_op(node);
- return node;
-}
-
ir_node *skip_Pin(ir_node *node)
{
if (is_Pin(node))
register_get_type_func(op_Alloc, get_Alloc_type);
register_get_type_func(op_Builtin, get_Builtin_type);
register_get_type_func(op_Call, get_Call_type);
- register_get_type_func(op_Cast, get_Cast_type);
register_get_type_func(op_CopyB, get_CopyB_type);
register_get_type_func(op_Free, get_Free_type);
register_get_type_func(op_InstOf, get_InstOf_type);
return 0;
}
-/** Compares the attributes of two Cast nodes. */
-static int node_cmp_attr_Cast(const ir_node *a, const ir_node *b)
-{
- return get_Cast_type(a) != get_Cast_type(b);
-}
-
/** Compares the attributes of two Load nodes. */
static int node_cmp_attr_Load(const ir_node *a, const ir_node *b)
{
register_node_cmp_func(op_Alloc, node_cmp_attr_Alloc);
register_node_cmp_func(op_Builtin, node_cmp_attr_Builtin);
register_node_cmp_func(op_Call, node_cmp_attr_Call);
- register_node_cmp_func(op_Cast, node_cmp_attr_Cast);
register_node_cmp_func(op_Cmp, node_cmp_attr_Cmp);
register_node_cmp_func(op_Confirm, node_cmp_attr_Confirm);
register_node_cmp_func(op_Const, node_cmp_attr_Const);
ir_type *type; /**< the type of which the object pointer must be */
} io_attr;
-/** Cast attributes. */
-typedef struct cast_attr {
- ir_type *type; /**< Type of the casted node. */
-} cast_attr;
-
/** Load attributes. */
typedef struct load_attr {
except_attr exc; /**< The exception attribute. MUST be the first one. */
alloc_attr alloc; /**< For Alloc. */
free_attr free; /**< For Free. */
io_attr instof; /**< For InstOf */
- cast_attr cast; /**< For Cast. */
load_attr load; /**< For Load. */
store_attr store; /**< For Store. */
phi_attr phi; /**< For Phi. */
return 1;
}
-/**
- * verify a Cast node
- */
-static int verify_node_Cast(const ir_node *n)
-{
- ir_mode *mymode = get_irn_mode(n);
- ir_mode *op1mode = get_irn_mode(get_Cast_op(n));
-
- ASSERT_AND_RET_DBG(
- /* Conv: BB x datab1 --> datab2 */
- mode_is_data(op1mode) && op1mode == mymode,
- "Cast node", 0,
- show_unop_failure(n, "/* Conv: BB x datab1 --> datab2 */");
- );
- return 1;
-}
-
/**
* verify a Phi node
*/
register_verify_node_func(op_And, verify_node_And);
register_verify_node_func(op_Block, verify_node_Block);
register_verify_node_func(op_Call, verify_node_Call);
- register_verify_node_func(op_Cast, verify_node_Cast);
register_verify_node_func(op_Cmp, verify_node_Cmp);
register_verify_node_func(op_Cond, verify_node_Cond);
register_verify_node_func(op_Confirm, verify_node_Confirm);
case iro_SymConst:
lower_symconst(irn);
break;
- case iro_Cast:
- exchange(irn, get_Cast_op(irn));
- break;
default:
break;
}
*/
void lower_highlevel_graph(ir_graph *irg)
{
- /* Finally: lower SymConst-Size and Sel nodes, Casts, unaligned Load/Stores. */
+ /* Finally: lower SymConst-Size and Sel nodes, unaligned Load/Stores. */
irg_walk_graph(irg, NULL, lower_irnode, NULL);
}
/* ok if its only the address input */
break;
case iro_Sel:
- case iro_Cast:
case iro_Confirm:
if (is_stored(succ))
return true;
for (size_t j = get_Return_n_ress(pred); j > 0;) {
ir_node *res = get_Return_res(pred, --j);
- /* skip Confirms and Casts */
+ /* skip Confirms */
res = skip_HighLevel_ops(res);
/* skip Proj's */
while (is_Proj(res))
/*
* Check, if the value of a node cannot represent a NULL pointer.
*
- * - Casts are skipped, Sels are skipped
+ * - Sels are skipped
* - A SymConst(entity) is NEVER a NULL pointer
* - Confirms are evaluated
*/
ir_tarval *tv;
*confirm = NULL;
- n = skip_Cast_const(n);
tv = value_of(n);
if (tarval_is_constant(tv) && ! tarval_is_null(tv))
return 1;
assert(mode_is_reference(get_irn_mode(n)));
- /* skip all Sel nodes and Cast's */
+ /* skip all Sel nodes */
while (is_Sel(n)) {
- n = skip_Cast(get_Sel_ptr(n));
+ n = get_Sel_ptr(n);
}
while (1) {
- if (is_Cast(n)) { n = get_Cast_op(n); continue; }
if (is_Proj(n)) { n = get_Proj_pred(n); continue; }
break;
}
return 1;
} else {
/* check for more Confirms */
- for (; is_Confirm(n); n = skip_Cast(get_Confirm_value(n))) {
+ for (; is_Confirm(n); n = get_Confirm_value(n)) {
if (get_Confirm_relation(n) == ir_relation_less_greater) {
ir_node *bound = get_Confirm_bound(n);
ir_tarval *tv = value_of(bound);
{
address_entry *entry;
- /* skip Confirms and Casts */
+ /* skip Confirms */
restart:
if (is_Confirm(adr)) {
adr = get_Confirm_value(adr);
goto restart;
}
- if (is_Cast(adr)) {
- adr = get_Cast_op(adr);
- goto restart;
- }
entry = ir_nodehashmap_get(address_entry, &env.adr_map, adr);
FS_OPT_SHIFT_OR, /**< (a SHF c) OR (b SHF c) = (a OR b) SHF c */
FS_OPT_SHIFT_EOR, /**< (a SHF c) XOR (b SHF c) = (a XOR b) SHF c */
FS_OPT_CONV, /**< a Conv could be removed */
- FS_OPT_CAST, /**< a Cast could be removed */
FS_OPT_MIN_MAX_EQ, /**< Min(a,a) = Max(a,a) = a */
FS_OPT_MUX_COMBINE, /**< two Mux nodes where combined into one */
FS_OPT_MUX_CONV, /**< MuxI(sel, 1, 0) = (I)sel */
{ (hook_opt_kind)FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
{ (hook_opt_kind)FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
{ (hook_opt_kind)FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
- { (hook_opt_kind)FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
{ (hook_opt_kind)FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
{ (hook_opt_kind)FS_OPT_MUX_COMBINE, "boolean simplification: two Mux nodes where combined into one" },
{ (hook_opt_kind)FS_OPT_MUX_CONV, "boolean simplification: MuxI(sel, 1, 0) = (I)sel" },
case iro_Unknown:
return 1;
case iro_Conv:
- case iro_Cast:
return is_irn_const_expression(get_irn_n(n, 0));
default:
break;
copy_const_value(dbg, get_Eor_left(n), block),
copy_const_value(dbg, get_Eor_right(n), block), m);
break;
- case iro_Cast:
- nn = new_rd_Cast(dbg, block,
- copy_const_value(dbg, get_Cast_op(n), block),
- get_Cast_type(n));
- break;
case iro_Conv:
nn = new_rd_Conv(dbg, block,
copy_const_value(dbg, get_Conv_op(n), block), m);
assert((get_unknown_type() == type) || is_Method_type(type));
'''
-@op
-class Cast(Unop):
- """perform a high-level type cast"""
- mode = "get_irn_mode(irn_op)"
- flags = [ "highlevel" ]
- attrs = [
- dict(
- type = "ir_type*",
- name = "type",
- comment = "target type of the case",
- )
- ]
- attr_struct = "cast_attr"
- init = "assert(is_atomic_type(type));"
-
@op
class Cmp(Binop):
"""Compares its two operands and checks whether a specified