Commit f008ef14 authored by Matthias Braun's avatar Matthias Braun
Browse files

introduce ir_bk_may_alias

This can be used to effectively test aliasing in libfirm.
parent 372eb440
......@@ -276,23 +276,28 @@ typedef struct ir_asm_constraint {
* @ingroup Builtin
*/
typedef enum ir_builtin_kind {
ir_bk_trap, /**< GCC __builtin_trap(): insert trap */
ir_bk_debugbreak, /**< MS __debugbreak(): insert debug break */
ir_bk_return_address, /**< GCC __builtin_return_address() */
ir_bk_frame_address, /**< GCC __builtin_frame_address() */
ir_bk_prefetch, /**< GCC __builtin_prefetch() */
ir_bk_ffs, /**< GCC __builtin_ffs(): find first (least) significant 1 bit */
ir_bk_clz, /**< GCC __builtin_clz(): count leading zero */
ir_bk_ctz, /**< GCC __builtin_ctz(): count trailing zero */
ir_bk_popcount, /**< GCC __builtin_popcount(): population count */
ir_bk_parity, /**< GCC __builtin_parity(): parity */
ir_bk_bswap, /**< byte swap */
ir_bk_inport, /**< in port */
ir_bk_outport, /**< out port */
ir_bk_inner_trampoline, /**< address of a trampoline for GCC inner functions */
ir_bk_saturating_increment, /**< saturating increment */
ir_bk_compare_swap, /**< compare exchange (aka. compare and swap) */
ir_bk_last = ir_bk_compare_swap,
ir_bk_trap, /**< GCC __builtin_trap(): insert trap */
ir_bk_debugbreak, /**< MS __debugbreak(): insert debug break */
ir_bk_return_address, /**< GCC __builtin_return_address() */
ir_bk_frame_address, /**< GCC __builtin_frame_address() */
ir_bk_prefetch, /**< GCC __builtin_prefetch() */
ir_bk_ffs, /**< GCC __builtin_ffs(): find first (least)
significant 1 bit */
ir_bk_clz, /**< GCC __builtin_clz(): count leading zero */
ir_bk_ctz, /**< GCC __builtin_ctz(): count trailing zero */
ir_bk_popcount, /**< GCC __builtin_popcount(): population
count */
ir_bk_parity, /**< GCC __builtin_parity(): parity */
ir_bk_bswap, /**< byte swap */
ir_bk_inport, /**< in port */
ir_bk_outport, /**< out port */
ir_bk_inner_trampoline, /**< address of a trampoline for GCC inner
functions */
ir_bk_saturating_increment, /**< saturating increment */
ir_bk_compare_swap, /**< compare exchange (aka. compare and swap) */
ir_bk_may_alias, /**< replaced by 0 if args cannot alias,
1 otherwise */
ir_bk_last = ir_bk_may_alias,
} ir_builtin_kind;
/**
......
......@@ -1175,6 +1175,7 @@ static ir_node *gen_Builtin(ir_node *node)
case ir_bk_inner_trampoline:
case ir_bk_saturating_increment:
case ir_bk_compare_swap:
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
......@@ -1210,6 +1211,7 @@ static ir_node *gen_Proj_Builtin(ir_node *proj)
case ir_bk_inner_trampoline:
case ir_bk_saturating_increment:
case ir_bk_compare_swap:
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
......
......@@ -5124,6 +5124,8 @@ static ir_node *gen_Builtin(ir_node *node)
return gen_saturating_increment(node);
case ir_bk_compare_swap:
return gen_compare_swap(node);
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
......@@ -5177,6 +5179,8 @@ static ir_node *gen_Proj_Builtin(ir_node *proj)
assert(get_Proj_proj(proj) == pn_Builtin_max+1);
return new_r_Proj(new_node, ia32_mode_gp, pn_ia32_CmpXChgMem_res);
}
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
......
......@@ -2426,6 +2426,8 @@ static ir_node *gen_Builtin(ir_node *node)
return gen_compare_swap(node);
case ir_bk_saturating_increment:
return gen_saturating_increment(node);
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
......@@ -2467,6 +2469,8 @@ static ir_node *gen_Proj_Builtin(ir_node *proj)
assert(pn == pn_Builtin_max+1);
return new_r_Proj(new_pred, mode_gp, pn_sparc_Cas_res);
}
case ir_bk_may_alias:
break;
}
panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
......
......@@ -678,6 +678,7 @@ const char *get_builtin_kind_name(ir_builtin_kind kind)
X(ir_bk_inner_trampoline);
X(ir_bk_saturating_increment);
X(ir_bk_compare_swap);
X(ir_bk_may_alias);
}
return "<unknown>";
#undef X
......
......@@ -42,6 +42,7 @@ static const char *get_builtin_name(ir_builtin_kind kind)
case ir_bk_inner_trampoline:
case ir_bk_saturating_increment:
case ir_bk_compare_swap:
case ir_bk_may_alias:
break;
}
abort();
......@@ -103,6 +104,33 @@ static void replace_with_call(ir_node *node)
turn_into_tuple(node, ARRAY_SIZE(in), in);
}
static void replace_may_alias(ir_node *node)
{
ir_node *in0 = get_Builtin_param(node, 0);
ir_node *in1 = get_Builtin_param(node, 1);
ir_type *type = get_Builtin_type(node);
ir_type *type0 = get_pointer_points_to_type(get_method_param_type(type, 0));
ir_type *type1 = get_pointer_points_to_type(get_method_param_type(type, 1));
if (is_unknown_type(type0))
type0 = get_type_for_mode(mode_P);
if (is_unknown_type(type1))
type1 = get_type_for_mode(mode_P);
ir_type *rtype = get_method_res_type(type, 0);
ir_mode *rmode = get_type_mode(rtype);
ir_alias_relation alias = get_alias_relation(in0, type0, in1, type1);
ir_graph *irg = get_irn_irg(node);
ir_tarval *resval = alias == ir_no_alias
? get_mode_null(rmode) : get_mode_one(rmode);
ir_node *result = new_r_Const(irg, resval);
ir_node *const in[] = {
[pn_Builtin_M] = get_Builtin_mem(node),
[pn_Builtin_max+1] = result,
};
turn_into_tuple(node, ARRAY_SIZE(in), in);
}
static void lower_builtin(ir_node *node, void *env)
{
ir_builtin_kind kind;
......@@ -133,6 +161,10 @@ static void lower_builtin(ir_node *node, void *env)
replace_with_call(node);
return;
case ir_bk_may_alias:
replace_may_alias(node);
return;
case ir_bk_trap:
case ir_bk_debugbreak:
case ir_bk_return_address:
......
......@@ -2509,6 +2509,7 @@ static void lower_Builtin(ir_node *builtin, ir_mode *mode)
case ir_bk_inner_trampoline:
case ir_bk_saturating_increment:
case ir_bk_compare_swap:
case ir_bk_may_alias:
/* Nothing to do/impossible to lower in a generic way */
return;
case ir_bk_bswap:
......
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