本文整理汇总了C++中INTEGRAL_TYPE_P函数的典型用法代码示例。如果您正苦于以下问题:C++ INTEGRAL_TYPE_P函数的具体用法?C++ INTEGRAL_TYPE_P怎么用?C++ INTEGRAL_TYPE_P使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了INTEGRAL_TYPE_P函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ccmp_candidate_p
/* Check whether G is a potential conditional compare candidate. */
static bool
ccmp_candidate_p (gimple *g)
{
tree rhs = gimple_assign_rhs_to_tree (g);
tree lhs, op0, op1;
gimple *gs0, *gs1;
enum tree_code tcode, tcode0, tcode1;
tcode = TREE_CODE (rhs);
if (tcode != BIT_AND_EXPR && tcode != BIT_IOR_EXPR)
return false;
lhs = gimple_assign_lhs (g);
op0 = TREE_OPERAND (rhs, 0);
op1 = TREE_OPERAND (rhs, 1);
if ((TREE_CODE (op0) != SSA_NAME) || (TREE_CODE (op1) != SSA_NAME)
|| !has_single_use (lhs))
return false;
gs0 = get_gimple_for_ssa_name (op0);
gs1 = get_gimple_for_ssa_name (op1);
if (!gs0 || !gs1 || !is_gimple_assign (gs0) || !is_gimple_assign (gs1)
/* g, gs0 and gs1 must be in the same basic block, since current stage
is out-of-ssa. We can not guarantee the correctness when forwording
the gs0 and gs1 into g whithout DATAFLOW analysis. */
|| gimple_bb (gs0) != gimple_bb (gs1)
|| gimple_bb (gs0) != gimple_bb (g))
return false;
if (!(INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs0)))
|| POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs0))))
|| !(INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs1)))
|| POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs1)))))
return false;
tcode0 = gimple_assign_rhs_code (gs0);
tcode1 = gimple_assign_rhs_code (gs1);
if (TREE_CODE_CLASS (tcode0) == tcc_comparison
&& TREE_CODE_CLASS (tcode1) == tcc_comparison)
return true;
if (TREE_CODE_CLASS (tcode0) == tcc_comparison
&& ccmp_candidate_p (gs1))
return true;
else if (TREE_CODE_CLASS (tcode1) == tcc_comparison
&& ccmp_candidate_p (gs0))
return true;
/* We skip ccmp_candidate_p (gs1) && ccmp_candidate_p (gs0) since
there is no way to set the CC flag. */
return false;
}
示例2: cilkplus_an_triplet_types_ok_p
bool
cilkplus_an_triplet_types_ok_p (location_t loc, tree start_index, tree length,
tree stride, tree type)
{
size_t stride_rank = 0, length_rank = 0, start_rank = 0;
if (!TREE_TYPE (start_index) || !INTEGRAL_TYPE_P (TREE_TYPE (start_index)))
{
error_at (loc, "start-index of array notation triplet is not an integer");
return false;
}
if (!TREE_TYPE (length) || !INTEGRAL_TYPE_P (TREE_TYPE (length)))
{
error_at (loc, "length of array notation triplet is not an integer");
return false;
}
if (!TREE_TYPE (stride) || !INTEGRAL_TYPE_P (TREE_TYPE (stride)))
{
error_at (loc, "stride of array notation triplet is not an integer");
return false;
}
if (TREE_CODE (type) == FUNCTION_TYPE)
{
error_at (loc, "array notation cannot be used with function type");
return false;
}
if (!find_rank (loc, start_index, start_index, false, &start_rank)
|| !find_rank (loc, length, length, false, &length_rank)
|| !find_rank (loc, stride, stride, false, &stride_rank))
return false;
if (start_rank != 0)
{
error_at (loc, "rank of an array notation triplet%'s start-index is not "
"zero");
return false;
}
if (length_rank != 0)
{
error_at (loc, "rank of an array notation triplet%'s length is not zero");
return false;
}
if (stride_rank != 0)
{
error_at (loc, "rank of array notation triplet%'s stride is not zero");
return false;
}
return true;
}
示例3: build_real_imag_expr
tree
build_real_imag_expr (location_t location, enum tree_code code, tree arg)
{
tree ret;
tree arg_type = TREE_TYPE (arg);
gcc_assert (code == REALPART_EXPR || code == IMAGPART_EXPR);
if (TREE_CODE (arg_type) == COMPLEX_TYPE)
{
ret = build1 (code, TREE_TYPE (TREE_TYPE (arg)), arg);
SET_EXPR_LOCATION (ret, location);
}
else if (INTEGRAL_TYPE_P (arg_type) || SCALAR_FLOAT_TYPE_P (arg_type))
{
ret = (code == REALPART_EXPR
? arg
: omit_one_operand_loc (location, arg_type,
integer_zero_node, arg));
}
else
{
error_at (location, "wrong type argument to %s",
code == REALPART_EXPR ? "__real" : "__imag");
ret = error_mark_node;
}
return ret;
}
示例4: c_finish_omp_atomic
tree
c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
{
tree x, type, addr;
if (lhs == error_mark_node || rhs == error_mark_node)
return error_mark_node;
/* ??? According to one reading of the OpenMP spec, complex type are
supported, but there are no atomic stores for any architecture.
But at least icc 9.0 doesn't support complex types here either.
And lets not even talk about vector types... */
type = TREE_TYPE (lhs);
if (!INTEGRAL_TYPE_P (type)
&& !POINTER_TYPE_P (type)
&& !SCALAR_FLOAT_TYPE_P (type))
{
error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
return error_mark_node;
}
/* ??? Validate that rhs does not overlap lhs. */
/* Take and save the address of the lhs. From then on we'll reference it
via indirection. */
addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
return error_mark_node;
addr = save_expr (addr);
if (TREE_CODE (addr) != SAVE_EXPR
&& (TREE_CODE (addr) != ADDR_EXPR
|| TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
{
/* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
it even after unsharing function body. */
tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
DECL_CONTEXT (var) = current_function_decl;
addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
}
lhs = build_indirect_ref (loc, addr, RO_NULL);
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
to do this, and then take it apart again. */
x = build_modify_expr (input_location, lhs, NULL_TREE, code,
input_location, rhs, NULL_TREE);
if (x == error_mark_node)
return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
rhs = TREE_OPERAND (x, 1);
/* Punt the actual generation of atomic operations to common code. */
x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
SET_EXPR_LOCATION (x, loc);
return x;
}
示例5: insert_trap_and_remove_trailing_statements
static void
insert_trap_and_remove_trailing_statements (gimple_stmt_iterator *si_p, tree op)
{
/* We want the NULL pointer dereference to actually occur so that
code that wishes to catch the signal can do so.
If the dereference is a load, then there's nothing to do as the
LHS will be a throw-away SSA_NAME and the RHS is the NULL dereference.
If the dereference is a store and we can easily transform the RHS,
then simplify the RHS to enable more DCE. Note that we require the
statement to be a GIMPLE_ASSIGN which filters out calls on the RHS. */
gimple stmt = gsi_stmt (*si_p);
if (walk_stmt_load_store_ops (stmt, (void *)op, NULL, check_loadstore)
&& is_gimple_assign (stmt)
&& INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
{
/* We just need to turn the RHS into zero converted to the proper
type. */
tree type = TREE_TYPE (gimple_assign_lhs (stmt));
gimple_assign_set_rhs_code (stmt, INTEGER_CST);
gimple_assign_set_rhs1 (stmt, fold_convert (type, integer_zero_node));
update_stmt (stmt);
}
gimple new_stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
gimple_seq seq = NULL;
gimple_seq_add_stmt (&seq, new_stmt);
/* If we had a NULL pointer dereference, then we want to insert the
__builtin_trap after the statement, for the other cases we want
to insert before the statement. */
if (walk_stmt_load_store_ops (stmt, (void *)op,
check_loadstore,
check_loadstore))
gsi_insert_after (si_p, seq, GSI_NEW_STMT);
else
gsi_insert_before (si_p, seq, GSI_NEW_STMT);
/* We must remove statements from the end of the block so that we
never reference a released SSA_NAME. */
basic_block bb = gimple_bb (gsi_stmt (*si_p));
for (gimple_stmt_iterator si = gsi_last_bb (bb);
gsi_stmt (si) != gsi_stmt (*si_p);
si = gsi_last_bb (bb))
{
stmt = gsi_stmt (si);
unlink_stmt_vdef (stmt);
gsi_remove (&si, true);
release_defs (stmt);
}
}
示例6: instrument_si_overflow
static void
instrument_si_overflow (gimple_stmt_iterator gsi)
{
gimple stmt = gsi_stmt (gsi);
tree_code code = gimple_assign_rhs_code (stmt);
tree lhs = gimple_assign_lhs (stmt);
tree lhstype = TREE_TYPE (lhs);
tree a, b;
gimple g;
/* If this is not a signed operation, don't instrument anything here.
Also punt on bit-fields. */
if (!INTEGRAL_TYPE_P (lhstype)
|| TYPE_OVERFLOW_WRAPS (lhstype)
|| GET_MODE_BITSIZE (TYPE_MODE (lhstype)) != TYPE_PRECISION (lhstype))
return;
switch (code)
{
case MINUS_EXPR:
case PLUS_EXPR:
case MULT_EXPR:
/* Transform
i = u {+,-,*} 5;
into
i = UBSAN_CHECK_{ADD,SUB,MUL} (u, 5); */
a = gimple_assign_rhs1 (stmt);
b = gimple_assign_rhs2 (stmt);
g = gimple_build_call_internal (code == PLUS_EXPR
? IFN_UBSAN_CHECK_ADD
: code == MINUS_EXPR
? IFN_UBSAN_CHECK_SUB
: IFN_UBSAN_CHECK_MUL, 2, a, b);
gimple_call_set_lhs (g, lhs);
gsi_replace (&gsi, g, false);
break;
case NEGATE_EXPR:
/* Represent i = -u;
as
i = UBSAN_CHECK_SUB (0, u); */
a = build_int_cst (lhstype, 0);
b = gimple_assign_rhs1 (stmt);
g = gimple_build_call_internal (IFN_UBSAN_CHECK_SUB, 2, a, b);
gimple_call_set_lhs (g, lhs);
gsi_replace (&gsi, g, false);
break;
default:
break;
}
}
示例7: get_ubsan_type_info_for_type
static unsigned short
get_ubsan_type_info_for_type (tree type)
{
gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
if (TREE_CODE (type) == REAL_TYPE)
return tree_to_uhwi (TYPE_SIZE (type));
else if (INTEGRAL_TYPE_P (type))
{
int prec = exact_log2 (tree_to_uhwi (TYPE_SIZE (type)));
gcc_assert (prec != -1);
return (prec << 1) | !TYPE_UNSIGNED (type);
}
else
return 0;
}
示例8: check_omp_for_incr_expr
static tree
check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
{
tree t;
if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
|| TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
return error_mark_node;
if (exp == decl)
return build_int_cst (TREE_TYPE (exp), 0);
switch (TREE_CODE (exp))
{
CASE_CONVERT:
t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
if (t != error_mark_node)
return fold_convert_loc (loc, TREE_TYPE (exp), t);
break;
case MINUS_EXPR:
t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
if (t != error_mark_node)
return fold_build2_loc (loc, MINUS_EXPR,
TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
break;
case PLUS_EXPR:
t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
if (t != error_mark_node)
return fold_build2_loc (loc, PLUS_EXPR,
TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
if (t != error_mark_node)
return fold_build2_loc (loc, PLUS_EXPR,
TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
break;
default:
break;
}
return error_mark_node;
}
示例9: ubsan_instrument_shift
tree
ubsan_instrument_shift (location_t loc, enum tree_code code,
tree op0, tree op1)
{
tree t, tt = NULL_TREE;
tree type0 = TREE_TYPE (op0);
tree type1 = TREE_TYPE (op1);
if (!INTEGRAL_TYPE_P (type0))
return NULL_TREE;
tree op1_utype = unsigned_type_for (type1);
HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
op0 = unshare_expr (op0);
op1 = unshare_expr (op1);
t = fold_convert_loc (loc, op1_utype, op1);
t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
/* If this is not a signed operation, don't perform overflow checks.
Also punt on bit-fields. */
if (TYPE_OVERFLOW_WRAPS (type0)
|| GET_MODE_BITSIZE (TYPE_MODE (type0)) != TYPE_PRECISION (type0)
|| (flag_sanitize & SANITIZE_SHIFT_BASE) == 0)
;
/* For signed x << y, in C99/C11, the following:
(unsigned) x >> (uprecm1 - y)
if non-zero, is undefined. */
else if (code == LSHIFT_EXPR && flag_isoc99 && cxx_dialect < cxx11)
{
tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
fold_convert (op1_utype, unshare_expr (op1)));
tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
build_int_cst (TREE_TYPE (tt), 0));
}
/* For signed x << y, in C++11 and later, the following:
x < 0 || ((unsigned) x >> (uprecm1 - y))
if > 1, is undefined. */
else if (code == LSHIFT_EXPR && cxx_dialect >= cxx11)
{
tree x = fold_build2 (MINUS_EXPR, op1_utype, uprecm1,
fold_convert (op1_utype, unshare_expr (op1)));
tt = fold_convert_loc (loc, unsigned_type_for (type0),
unshare_expr (op0));
tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
build_int_cst (TREE_TYPE (tt), 1));
x = fold_build2 (LT_EXPR, boolean_type_node, unshare_expr (op0),
build_int_cst (type0, 0));
tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
}
/* If the condition was folded to 0, no need to instrument
this expression. */
if (integer_zerop (t) && (tt == NULL_TREE || integer_zerop (tt)))
return NULL_TREE;
/* In case we have a SAVE_EXPR in a conditional context, we need to
make sure it gets evaluated before the condition. */
t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), unshare_expr (op0), t);
enum sanitize_code recover_kind = SANITIZE_SHIFT_EXPONENT;
tree else_t = void_node;
if (tt)
{
if ((flag_sanitize & SANITIZE_SHIFT_EXPONENT) == 0)
{
t = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, t);
t = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, t, tt);
recover_kind = SANITIZE_SHIFT_BASE;
}
else
{
if (flag_sanitize_undefined_trap_on_error
|| ((!(flag_sanitize_recover & SANITIZE_SHIFT_EXPONENT))
== (!(flag_sanitize_recover & SANITIZE_SHIFT_BASE))))
t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt);
else
else_t = tt;
}
}
if (flag_sanitize_undefined_trap_on_error)
tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
else
{
tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc,
ubsan_type_descriptor (type0),
ubsan_type_descriptor (type1), NULL_TREE,
NULL_TREE);
data = build_fold_addr_expr_loc (loc, data);
enum built_in_function bcode
= (flag_sanitize_recover & recover_kind)
? BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS
//.........这里部分代码省略.........
示例10: process_assignment
static bool
process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
tree *a, tree *ass_var)
{
tree op0, op1 = NULL_TREE, non_ass_var = NULL_TREE;
tree dest = gimple_assign_lhs (stmt);
enum tree_code code = gimple_assign_rhs_code (stmt);
enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code);
tree src_var = gimple_assign_rhs1 (stmt);
/* See if this is a simple copy operation of an SSA name to the function
result. In that case we may have a simple tail call. Ignore type
conversions that can never produce extra code between the function
call and the function return. */
if ((rhs_class == GIMPLE_SINGLE_RHS || gimple_assign_cast_p (stmt))
&& (TREE_CODE (src_var) == SSA_NAME))
{
/* Reject a tailcall if the type conversion might need
additional code. */
if (gimple_assign_cast_p (stmt))
{
if (TYPE_MODE (TREE_TYPE (dest)) != TYPE_MODE (TREE_TYPE (src_var)))
return false;
/* Even if the type modes are the same, if the precision of the
type is smaller than mode's precision,
reduce_to_bit_field_precision would generate additional code. */
if (INTEGRAL_TYPE_P (TREE_TYPE (dest))
&& (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (dest)))
> TYPE_PRECISION (TREE_TYPE (dest))))
return false;
}
if (src_var != *ass_var)
return false;
*ass_var = dest;
return true;
}
switch (rhs_class)
{
case GIMPLE_BINARY_RHS:
op1 = gimple_assign_rhs2 (stmt);
/* Fall through. */
case GIMPLE_UNARY_RHS:
op0 = gimple_assign_rhs1 (stmt);
break;
default:
return false;
}
/* Accumulator optimizations will reverse the order of operations.
We can only do that for floating-point types if we're assuming
that addition and multiplication are associative. */
if (!flag_associative_math)
if (FLOAT_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
return false;
if (rhs_class == GIMPLE_UNARY_RHS)
;
else if (op0 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
;
else if (op1 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
;
else
return false;
switch (code)
{
case PLUS_EXPR:
*a = non_ass_var;
*ass_var = dest;
return true;
case POINTER_PLUS_EXPR:
if (op0 != *ass_var)
return false;
*a = non_ass_var;
*ass_var = dest;
return true;
case MULT_EXPR:
*m = non_ass_var;
*ass_var = dest;
return true;
case NEGATE_EXPR:
*m = build_minus_one_cst (TREE_TYPE (op0));
*ass_var = dest;
return true;
case MINUS_EXPR:
if (*ass_var == op0)
*a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var);
//.........这里部分代码省略.........
示例11: c_finish_omp_for
tree
c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
tree incr, tree body, tree pre_body)
{
location_t elocus = locus;
bool fail = false;
if (EXPR_HAS_LOCATION (init))
elocus = EXPR_LOCATION (init);
/* Validate the iteration variable. */
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
{
error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
fail = true;
}
if (TYPE_UNSIGNED (TREE_TYPE (decl)))
warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
/* In the case of "for (int i = 0...)", init will be a decl. It should
have a DECL_INITIAL that we can turn into an assignment. */
if (init == decl)
{
elocus = DECL_SOURCE_LOCATION (decl);
init = DECL_INITIAL (decl);
if (init == NULL)
{
error ("%H%qE is not initialized", &elocus, decl);
init = integer_zero_node;
fail = true;
}
init = build_modify_expr (decl, NOP_EXPR, init);
SET_EXPR_LOCATION (init, elocus);
}
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
gcc_assert (TREE_OPERAND (init, 0) == decl);
if (cond == NULL_TREE)
{
error ("%Hmissing controlling predicate", &elocus);
fail = true;
}
else
{
bool cond_ok = false;
if (EXPR_HAS_LOCATION (cond))
elocus = EXPR_LOCATION (cond);
if (TREE_CODE (cond) == LT_EXPR
|| TREE_CODE (cond) == LE_EXPR
|| TREE_CODE (cond) == GT_EXPR
|| TREE_CODE (cond) == GE_EXPR)
{
tree op0 = TREE_OPERAND (cond, 0);
tree op1 = TREE_OPERAND (cond, 1);
/* 2.5.1. The comparison in the condition is computed in the type
of DECL, otherwise the behavior is undefined.
For example:
long n; int i;
i < n;
according to ISO will be evaluated as:
(long)i < n;
We want to force:
i < (int)n; */
if (TREE_CODE (op0) == NOP_EXPR
&& decl == TREE_OPERAND (op0, 0))
{
TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
TREE_OPERAND (cond, 1));
}
else if (TREE_CODE (op1) == NOP_EXPR
&& decl == TREE_OPERAND (op1, 0))
{
TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
TREE_OPERAND (cond, 0));
}
if (decl == TREE_OPERAND (cond, 0))
cond_ok = true;
else if (decl == TREE_OPERAND (cond, 1))
{
TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
TREE_OPERAND (cond, 0) = decl;
cond_ok = true;
}
}
if (!cond_ok)
{
error ("%Hinvalid controlling predicate", &elocus);
//.........这里部分代码省略.........
示例12: forward_propagate_addr_expr_1
static bool
forward_propagate_addr_expr_1 (tree name, tree def_rhs,
gimple_stmt_iterator *use_stmt_gsi,
bool single_use_p)
{
tree lhs, rhs, rhs2, array_ref;
tree *rhsp, *lhsp;
gimple use_stmt = gsi_stmt (*use_stmt_gsi);
enum tree_code rhs_code;
bool res = true;
gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
lhs = gimple_assign_lhs (use_stmt);
rhs_code = gimple_assign_rhs_code (use_stmt);
rhs = gimple_assign_rhs1 (use_stmt);
/* Trivial cases. The use statement could be a trivial copy or a
useless conversion. Recurse to the uses of the lhs as copyprop does
not copy through different variant pointers and FRE does not catch
all useless conversions. Treat the case of a single-use name and
a conversion to def_rhs type separate, though. */
if (TREE_CODE (lhs) == SSA_NAME
&& ((rhs_code == SSA_NAME && rhs == name)
|| CONVERT_EXPR_CODE_P (rhs_code)))
{
/* Only recurse if we don't deal with a single use or we cannot
do the propagation to the current statement. In particular
we can end up with a conversion needed for a non-invariant
address which we cannot do in a single statement. */
if (!single_use_p
|| (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))
&& (!is_gimple_min_invariant (def_rhs)
|| (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
&& POINTER_TYPE_P (TREE_TYPE (def_rhs))
&& (TYPE_PRECISION (TREE_TYPE (lhs))
> TYPE_PRECISION (TREE_TYPE (def_rhs)))))))
return forward_propagate_addr_expr (lhs, def_rhs);
gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
else
gimple_assign_set_rhs_code (use_stmt, NOP_EXPR);
return true;
}
/* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
ADDR_EXPR will not appear on the LHS. */
lhsp = gimple_assign_lhs_ptr (use_stmt);
while (handled_component_p (*lhsp))
lhsp = &TREE_OPERAND (*lhsp, 0);
lhs = *lhsp;
/* Now see if the LHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (lhs) == INDIRECT_REF
&& TREE_OPERAND (lhs, 0) == name)
{
if (may_propagate_address_into_dereference (def_rhs, lhs)
&& (lhsp != gimple_assign_lhs_ptr (use_stmt)
|| useless_type_conversion_p
(TREE_TYPE (TREE_OPERAND (def_rhs, 0)), TREE_TYPE (rhs))))
{
*lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
/* Continue propagating into the RHS if this was not the only use. */
if (single_use_p)
return true;
}
else
/* We can have a struct assignment dereferencing our name twice.
Note that we didn't propagate into the lhs to not falsely
claim we did when propagating into the rhs. */
res = false;
}
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
nodes from the RHS. */
rhsp = gimple_assign_rhs1_ptr (use_stmt);
while (handled_component_p (*rhsp)
|| TREE_CODE (*rhsp) == ADDR_EXPR)
rhsp = &TREE_OPERAND (*rhsp, 0);
rhs = *rhsp;
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (rhs) == INDIRECT_REF
&& TREE_OPERAND (rhs, 0) == name
&& may_propagate_address_into_dereference (def_rhs, rhs))
{
*rhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
return res;
}
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
//.........这里部分代码省略.........
示例13: browse_tree
void
browse_tree (tree begin)
{
tree head;
TB_CODE tbc = TB_UNUSED_COMMAND;
ssize_t rd;
char *input = NULL;
long input_size = 0;
fprintf (TB_OUT_FILE, "\nTree Browser\n");
#define TB_SET_HEAD(N) do { \
vec_safe_push (TB_history_stack, N); \
head = N; \
if (TB_verbose) \
if (head) \
{ \
print_generic_expr (TB_OUT_FILE, head, 0); \
fprintf (TB_OUT_FILE, "\n"); \
} \
} while (0)
TB_SET_HEAD (begin);
/* Store in a hashtable information about previous and upper statements. */
{
TB_up_ht = new hash_table<tree_upper_hasher> (1023);
TB_update_up (head);
}
while (24)
{
fprintf (TB_OUT_FILE, "TB> ");
rd = TB_getline (&input, &input_size, TB_IN_FILE);
if (rd == -1)
/* EOF. */
goto ret;
if (rd != 1)
/* Get a new command. Otherwise the user just pressed enter, and thus
she expects the last command to be reexecuted. */
tbc = TB_get_command (input);
switch (tbc)
{
case TB_UPDATE_UP:
TB_update_up (head);
break;
case TB_MAX:
if (head && (INTEGRAL_TYPE_P (head)
|| TREE_CODE (head) == REAL_TYPE
|| TREE_CODE (head) == FIXED_POINT_TYPE))
TB_SET_HEAD (TYPE_MAX_VALUE (head));
else
TB_WF;
break;
case TB_MIN:
if (head && (INTEGRAL_TYPE_P (head)
|| TREE_CODE (head) == REAL_TYPE
|| TREE_CODE (head) == FIXED_POINT_TYPE))
TB_SET_HEAD (TYPE_MIN_VALUE (head));
else
TB_WF;
break;
case TB_ELT:
if (head && TREE_CODE (head) == TREE_VEC)
{
/* This command takes another argument: the element number:
for example "elt 1". */
TB_NIY;
}
else if (head && TREE_CODE (head) == VECTOR_CST)
{
/* This command takes another argument: the element number:
for example "elt 1". */
TB_NIY;
}
else
TB_WF;
break;
case TB_VALUE:
if (head && TREE_CODE (head) == TREE_LIST)
TB_SET_HEAD (TREE_VALUE (head));
else
TB_WF;
break;
case TB_PURPOSE:
if (head && TREE_CODE (head) == TREE_LIST)
TB_SET_HEAD (TREE_PURPOSE (head));
else
TB_WF;
break;
case TB_IMAG:
//.........这里部分代码省略.........
示例14: build_array_notation_ref
tree
build_array_notation_ref (location_t loc, tree array, tree start_index,
tree length, tree stride, tree type)
{
tree array_ntn_tree = NULL_TREE;
size_t stride_rank = 0, length_rank = 0, start_rank = 0;
if (!INTEGRAL_TYPE_P (TREE_TYPE (start_index)))
{
error_at (loc,
"start-index of array notation triplet is not an integer");
return error_mark_node;
}
if (!INTEGRAL_TYPE_P (TREE_TYPE (length)))
{
error_at (loc, "length of array notation triplet is not an integer");
return error_mark_node;
}
/* The stride is an optional field. */
if (stride && !INTEGRAL_TYPE_P (TREE_TYPE (stride)))
{
error_at (loc, "stride of array notation triplet is not an integer");
return error_mark_node;
}
if (!stride)
{
if (TREE_CONSTANT (start_index) && TREE_CONSTANT (length)
&& tree_int_cst_lt (length, start_index))
stride = build_int_cst (TREE_TYPE (start_index), -1);
else
stride = build_int_cst (TREE_TYPE (start_index), 1);
}
if (!find_rank (loc, start_index, start_index, false, &start_rank))
return error_mark_node;
if (!find_rank (loc, length, length, false, &length_rank))
return error_mark_node;
if (!find_rank (loc, stride, stride, false, &stride_rank))
return error_mark_node;
if (start_rank != 0)
{
error_at (loc, "rank of an array notation triplet's start-index is not "
"zero");
return error_mark_node;
}
if (length_rank != 0)
{
error_at (loc, "rank of an array notation triplet's length is not zero");
return error_mark_node;
}
if (stride_rank != 0)
{
error_at (loc, "rank of array notation triplet's stride is not zero");
return error_mark_node;
}
array_ntn_tree = build4 (ARRAY_NOTATION_REF, NULL_TREE, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
ARRAY_NOTATION_ARRAY (array_ntn_tree) = array;
ARRAY_NOTATION_START (array_ntn_tree) = start_index;
ARRAY_NOTATION_LENGTH (array_ntn_tree) = length;
ARRAY_NOTATION_STRIDE (array_ntn_tree) = stride;
TREE_TYPE (array_ntn_tree) = type;
return array_ntn_tree;
}
示例15: usable
//.........这里部分代码省略.........
case REDUC_MAX_EXPR:
return TYPE_UNSIGNED (type)
? reduc_umax_scal_optab : reduc_smax_scal_optab;
case REDUC_MIN_EXPR:
return TYPE_UNSIGNED (type)
? reduc_umin_scal_optab : reduc_smin_scal_optab;
case REDUC_PLUS_EXPR:
return reduc_plus_scal_optab;
case VEC_WIDEN_MULT_HI_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
case VEC_WIDEN_MULT_LO_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
case VEC_WIDEN_MULT_EVEN_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_umult_even_optab : vec_widen_smult_even_optab;
case VEC_WIDEN_MULT_ODD_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
case VEC_WIDEN_LSHIFT_HI_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab;
case VEC_WIDEN_LSHIFT_LO_EXPR:
return TYPE_UNSIGNED (type) ?
vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab;
case VEC_UNPACK_HI_EXPR:
return TYPE_UNSIGNED (type) ?
vec_unpacku_hi_optab : vec_unpacks_hi_optab;
case VEC_UNPACK_LO_EXPR:
return TYPE_UNSIGNED (type) ?
vec_unpacku_lo_optab : vec_unpacks_lo_optab;
case VEC_UNPACK_FLOAT_HI_EXPR:
/* The signedness is determined from input operand. */
return TYPE_UNSIGNED (type) ?
vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
case VEC_UNPACK_FLOAT_LO_EXPR:
/* The signedness is determined from input operand. */
return TYPE_UNSIGNED (type) ?
vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
case VEC_PACK_TRUNC_EXPR:
return vec_pack_trunc_optab;
case VEC_PACK_SAT_EXPR:
return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
case VEC_PACK_FIX_TRUNC_EXPR:
/* The signedness is determined from output operand. */
return TYPE_UNSIGNED (type) ?
vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
default:
break;
}
trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
switch (code)
{
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
if (TYPE_SATURATING (type))
return TYPE_UNSIGNED (type) ? usadd_optab : ssadd_optab;
return trapv ? addv_optab : add_optab;
case MINUS_EXPR:
if (TYPE_SATURATING (type))
return TYPE_UNSIGNED (type) ? ussub_optab : sssub_optab;
return trapv ? subv_optab : sub_optab;
case MULT_EXPR:
if (TYPE_SATURATING (type))
return TYPE_UNSIGNED (type) ? usmul_optab : ssmul_optab;
return trapv ? smulv_optab : smul_optab;
case NEGATE_EXPR:
if (TYPE_SATURATING (type))
return TYPE_UNSIGNED (type) ? usneg_optab : ssneg_optab;
return trapv ? negv_optab : neg_optab;
case ABS_EXPR:
return trapv ? absv_optab : abs_optab;
default:
return unknown_optab;
}
}