/* Gimple decl, type, and expression support functions.
- Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ Copyright (C) 2007-2020 Free Software Foundation, Inc.
Contributed by Aldy Hernandez <aldyh@redhat.com>
This file is part of GCC.
#include "demangle.h"
#include "hash-set.h"
#include "rtl.h"
+#include "tree-pass.h"
+#include "stringpool.h"
+#include "attribs.h"
/* ----- Type related ----- */
/* Fixed point types with the same mode are compatible. */
else if (FIXED_POINT_TYPE_P (inner_type)
&& FIXED_POINT_TYPE_P (outer_type))
- return true;
+ return TYPE_SATURATING (inner_type) == TYPE_SATURATING (outer_type);
/* We need to take special care recursing to pointed-to types. */
else if (POINTER_TYPE_P (inner_type)
gimple_has_body_p (tree fndecl)
{
struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
- return (gimple_body (fndecl) || (fn && fn->cfg));
+ return (gimple_body (fndecl) || (fn && fn->cfg && !(fn->curr_properties & PROP_rtl)));
}
/* Return a printable name for symbol DECL. */
if (!DECL_NAME (decl))
return NULL;
- if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ if (HAS_DECL_ASSEMBLER_NAME_P (decl) && DECL_ASSEMBLER_NAME_SET_P (decl))
{
- const char *str, *mangled_str;
int dmgl_opts = DMGL_NO_OPTS;
if (verbosity >= 2)
dmgl_opts |= DMGL_PARAMS;
}
- mangled_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- str = cplus_demangle_v3 (mangled_str, dmgl_opts);
- return (str) ? str : mangled_str;
+ const char *mangled_str
+ = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME_RAW (decl));
+ const char *str = cplus_demangle_v3 (mangled_str, dmgl_opts);
+ return str ? str : mangled_str;
}
return IDENTIFIER_POINTER (DECL_NAME (decl));
/* Strip off a legitimate source ending from the input string NAME of
length LEN. Rather than having to know the names used by all of
our front ends, we strip off an ending of a period followed by
- up to five characters. (Java uses ".class".) */
+ up to four characters. (like ".cpp".) */
static inline void
remove_suffix (char *name, int len)
{
int i;
- for (i = 2; i < 8 && len > i; i++)
+ for (i = 2; i < 7 && len > i; i++)
{
if (name[len - i] == '.')
{
DECL_ARTIFICIAL (tmp_var) = 1;
/* And we don't want debug info for it. */
DECL_IGNORED_P (tmp_var) = 1;
+ /* And we don't want even the fancy names of those printed in
+ -fdump-final-insns= dumps. */
+ DECL_NAMELESS (tmp_var) = 1;
/* Make the variable writable. */
TREE_READONLY (tmp_var) = 0;
extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
tree *op2_p, tree *op3_p)
{
- enum gimple_rhs_class grhs_class;
-
*subcode_p = TREE_CODE (expr);
- grhs_class = get_gimple_rhs_class (*subcode_p);
-
- if (grhs_class == GIMPLE_TERNARY_RHS)
+ switch (get_gimple_rhs_class (*subcode_p))
{
- *op1_p = TREE_OPERAND (expr, 0);
- *op2_p = TREE_OPERAND (expr, 1);
- *op3_p = TREE_OPERAND (expr, 2);
- }
- else if (grhs_class == GIMPLE_BINARY_RHS)
- {
- *op1_p = TREE_OPERAND (expr, 0);
- *op2_p = TREE_OPERAND (expr, 1);
- *op3_p = NULL_TREE;
- }
- else if (grhs_class == GIMPLE_UNARY_RHS)
- {
- *op1_p = TREE_OPERAND (expr, 0);
- *op2_p = NULL_TREE;
- *op3_p = NULL_TREE;
- }
- else if (grhs_class == GIMPLE_SINGLE_RHS)
- {
- *op1_p = expr;
- *op2_p = NULL_TREE;
- *op3_p = NULL_TREE;
+ case GIMPLE_TERNARY_RHS:
+ {
+ *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = TREE_OPERAND (expr, 1);
+ *op3_p = TREE_OPERAND (expr, 2);
+ break;
+ }
+ case GIMPLE_BINARY_RHS:
+ {
+ *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = TREE_OPERAND (expr, 1);
+ *op3_p = NULL_TREE;
+ break;
+ }
+ case GIMPLE_UNARY_RHS:
+ {
+ *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = NULL_TREE;
+ *op3_p = NULL_TREE;
+ break;
+ }
+ case GIMPLE_SINGLE_RHS:
+ {
+ *op1_p = expr;
+ *op2_p = NULL_TREE;
+ *op3_p = NULL_TREE;
+ break;
+ }
+ default:
+ gcc_unreachable ();
}
- else
- gcc_unreachable ();
}
/* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */
|| TREE_CODE (cond) == TRUTH_NOT_EXPR
|| is_gimple_min_invariant (cond)
|| SSA_VAR_P (cond));
+ gcc_checking_assert (!tree_could_throw_p (cond));
extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
|| TREE_CODE (t) == BIT_FIELD_REF);
}
-/* Return true if T is a GIMPLE condition. */
+/* Helper for is_gimple_condexpr and is_gimple_condexpr_for_cond. */
-bool
-is_gimple_condexpr (tree t)
+static bool
+is_gimple_condexpr_1 (tree t, bool allow_traps)
{
return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
- && !tree_could_throw_p (t)
+ && (allow_traps || !tree_could_throw_p (t))
&& is_gimple_val (TREE_OPERAND (t, 0))
&& is_gimple_val (TREE_OPERAND (t, 1))));
}
+/* Return true if T is a GIMPLE condition. */
+
+bool
+is_gimple_condexpr (tree t)
+{
+ return is_gimple_condexpr_1 (t, true);
+}
+
+/* Like is_gimple_condexpr, but does not allow T to trap. */
+
+bool
+is_gimple_condexpr_for_cond (tree t)
+{
+ return is_gimple_condexpr_1 (t, false);
+}
+
/* Return true if T is a gimple address. */
bool
op = TREE_OPERAND (op, 0);
}
- if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF)
+ if (CONSTANT_CLASS_P (op)
+ || TREE_CODE (op) == TARGET_MEM_REF
+ || TREE_CODE (op) == MEM_REF)
return true;
switch (TREE_CODE (op))
if (TREE_CODE (x) == MEM_REF
&& TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
- if (TREE_CODE (x) != VAR_DECL
+ if (!VAR_P (x)
&& TREE_CODE (x) != PARM_DECL
&& TREE_CODE (x) != RESULT_DECL)
return;