aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.h
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2015-11-08 18:33:42 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2015-11-08 18:33:42 +0000
commitee45a32dae253f7daa966573eb8cb64b2cf7bf52 (patch)
treecf927ff52a6d5ba28290472db09363fe67a835d6 /gcc/tree.h
parenteb11eb157cf07500e2915da8a72f2f3a501cc5ae (diff)
downloadgcc-ee45a32dae253f7daa966573eb8cb64b2cf7bf52.zip
gcc-ee45a32dae253f7daa966573eb8cb64b2cf7bf52.tar.gz
gcc-ee45a32dae253f7daa966573eb8cb64b2cf7bf52.tar.bz2
Merge of the scalar-storage-order branch.
From-SVN: r229965
Diffstat (limited to 'gcc/tree.h')
-rw-r--r--gcc/tree.h85
1 files changed, 82 insertions, 3 deletions
diff --git a/gcc/tree.h b/gcc/tree.h
index 6768b3b..e71eba4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -905,8 +905,29 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \
(IDENTIFIER_NODE_CHECK (NODE)->base.deprecated_flag)
-/* In fixed-point types, means a saturating type. */
-#define TYPE_SATURATING(NODE) (TYPE_CHECK (NODE)->base.u.bits.saturating_flag)
+/* In an aggregate type, indicates that the scalar fields of the type are
+ stored in reverse order from the target order. This effectively
+ toggles BYTES_BIG_ENDIAN and WORDS_BIG_ENDIAN within the type. */
+#define TYPE_REVERSE_STORAGE_ORDER(NODE) \
+ (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->base.u.bits.saturating_flag)
+
+/* In a non-aggregate type, indicates a saturating type. */
+#define TYPE_SATURATING(NODE) \
+ (TREE_NOT_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, ARRAY_TYPE)->base.u.bits.saturating_flag)
+
+/* In a BIT_FIELD_REF and MEM_REF, indicates that the reference is to a group
+ of bits stored in reverse order from the target order. This effectively
+ toggles both BYTES_BIG_ENDIAN and WORDS_BIG_ENDIAN for the reference.
+
+ The overall strategy is to preserve the invariant that every scalar in
+ memory is associated with a single storage order, i.e. all accesses to
+ this scalar are done with the same storage order. This invariant makes
+ it possible to factor out the storage order in most transformations, as
+ only the address and/or the value (in target order) matter for them.
+ But, of course, the storage order must be preserved when the accesses
+ themselves are rewritten or transformed. */
+#define REF_REVERSE_STORAGE_ORDER(NODE) \
+ (TREE_CHECK2 (NODE, BIT_FIELD_REF, MEM_REF)->base.u.bits.saturating_flag)
/* These flags are available for each language front end to use internally. */
#define TREE_LANG_FLAG_0(NODE) \
@@ -4350,6 +4371,64 @@ handled_component_p (const_tree t)
}
}
+/* Return true T is a component with reverse storage order. */
+
+static inline bool
+reverse_storage_order_for_component_p (tree t)
+{
+ /* The storage order only applies to scalar components. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (t)) || VECTOR_TYPE_P (TREE_TYPE (t)))
+ return false;
+
+ if (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR)
+ t = TREE_OPERAND (t, 0);
+
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ case COMPONENT_REF:
+ /* ??? Fortran can take COMPONENT_REF of a void type. */
+ return !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0)))
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (t, 0)));
+
+ case BIT_FIELD_REF:
+ case MEM_REF:
+ return REF_REVERSE_STORAGE_ORDER (t);
+
+ case ARRAY_RANGE_REF:
+ case VIEW_CONVERT_EXPR:
+ default:
+ return false;
+ }
+
+ gcc_unreachable ();
+}
+
+/* Return true if T is a storage order barrier, i.e. a VIEW_CONVERT_EXPR
+ that can modify the storage order of objects. Note that, even if the
+ TYPE_REVERSE_STORAGE_ORDER flag is set on both the inner type and the
+ outer type, a VIEW_CONVERT_EXPR can modify the storage order because
+ it can change the partition of the aggregate object into scalars. */
+
+static inline bool
+storage_order_barrier_p (const_tree t)
+{
+ if (TREE_CODE (t) != VIEW_CONVERT_EXPR)
+ return false;
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (t))
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (t)))
+ return true;
+
+ tree op = TREE_OPERAND (t, 0);
+
+ if (AGGREGATE_TYPE_P (TREE_TYPE (op))
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (op)))
+ return true;
+
+ return false;
+}
+
/* Given a DECL or TYPE, return the scope in which it was declared, or
NUL_TREE if there is no containing scope. */
@@ -5152,7 +5231,7 @@ extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
the access position and size. */
extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
tree *, machine_mode *, int *, int *,
- bool);
+ int *, bool);
extern tree build_personality_function (const char *);