diff options
Diffstat (limited to 'gcc/tree.cc')
-rw-r--r-- | gcc/tree.cc | 122 |
1 files changed, 91 insertions, 31 deletions
diff --git a/gcc/tree.cc b/gcc/tree.cc index 98575a5..6a055c8 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -326,6 +326,7 @@ unsigned const char omp_clause_num_ops[] = 2, /* OMP_CLAUSE_MAP */ 1, /* OMP_CLAUSE_HAS_DEVICE_ADDR */ 1, /* OMP_CLAUSE_DOACROSS */ + 3, /* OMP_CLAUSE__MAPPER_BINDING_ */ 2, /* OMP_CLAUSE__CACHE_ */ 1, /* OMP_CLAUSE_DESTROY */ 2, /* OMP_CLAUSE_INIT */ @@ -428,6 +429,7 @@ const char * const omp_clause_code_name[] = "map", "has_device_addr", "doacross", + "_mapper_binding_", "_cache_", "destroy", "init", @@ -786,6 +788,57 @@ init_ttree (void) } +/* Mapping from prefix to label number. */ + +struct identifier_hash : ggc_ptr_hash <tree_node> +{ + static inline hashval_t hash (tree t) + { + return IDENTIFIER_HASH_VALUE (t); + } +}; +struct identifier_count_traits + : simple_hashmap_traits<identifier_hash, long> {}; +typedef hash_map<tree, long, identifier_count_traits> internal_label_map; +static GTY(()) internal_label_map *internal_label_nums; + +/* Generates an identifier intended to be used internally with the + given PREFIX. This is intended to be used by the frontend so that + C++ modules can regenerate appropriate (non-clashing) identifiers on + stream-in. */ + +tree +generate_internal_label (const char *prefix) +{ + tree prefix_id = get_identifier (prefix); + if (!internal_label_nums) + internal_label_nums = internal_label_map::create_ggc(); + long &num = internal_label_nums->get_or_insert (prefix_id); + + char tmp[32]; + ASM_GENERATE_INTERNAL_LABEL (tmp, prefix, num++); + + tree id = get_identifier (tmp); + IDENTIFIER_INTERNAL_P (id) = true; + + /* Cache the prefix on the identifier so we can retrieve it later. */ + TREE_CHAIN (id) = prefix_id; + + return id; +} + +/* Get the PREFIX we created the internal identifier LABEL with. */ + +const char * +prefix_for_internal_label (tree label) +{ + gcc_assert (IDENTIFIER_INTERNAL_P (label) + && !IDENTIFIER_TRANSPARENT_ALIAS (label) + && TREE_CHAIN (label) + && TREE_CODE (TREE_CHAIN (label)) == IDENTIFIER_NODE); + return IDENTIFIER_POINTER (TREE_CHAIN (label)); +} + /* The name of the object as the assembler will see it (but before any translations made by ASM_OUTPUT_LABELREF). Often this is the same as DECL_NAME. It is an IDENTIFIER_NODE. */ @@ -3962,6 +4015,38 @@ decl_address_ip_invariant_p (const_tree op) return false; } +/* Return true if T is an object with invariant address. */ + +bool +address_invariant_p (tree t) +{ + while (handled_component_p (t)) + { + switch (TREE_CODE (t)) + { + case ARRAY_REF: + case ARRAY_RANGE_REF: + if (!tree_invariant_p (TREE_OPERAND (t, 1)) + || TREE_OPERAND (t, 2) != NULL_TREE + || TREE_OPERAND (t, 3) != NULL_TREE) + return false; + break; + + case COMPONENT_REF: + if (TREE_OPERAND (t, 2) != NULL_TREE) + return false; + break; + + default: + break; + } + t = TREE_OPERAND (t, 0); + } + + STRIP_ANY_LOCATION_WRAPPER (t); + return CONSTANT_CLASS_P (t) || decl_address_invariant_p (t); +} + /* Return true if T is function-invariant (internal function, does not handle arithmetic; that's handled in skip_simple_arithmetic and @@ -3970,10 +4055,7 @@ decl_address_ip_invariant_p (const_tree op) static bool tree_invariant_p_1 (tree t) { - tree op; - - if (TREE_CONSTANT (t) - || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))) + if (TREE_CONSTANT (t) || (TREE_READONLY (t) && !TREE_SIDE_EFFECTS (t))) return true; switch (TREE_CODE (t)) @@ -3983,30 +4065,7 @@ tree_invariant_p_1 (tree t) return true; case ADDR_EXPR: - op = TREE_OPERAND (t, 0); - while (handled_component_p (op)) - { - switch (TREE_CODE (op)) - { - case ARRAY_REF: - case ARRAY_RANGE_REF: - if (!tree_invariant_p (TREE_OPERAND (op, 1)) - || TREE_OPERAND (op, 2) != NULL_TREE - || TREE_OPERAND (op, 3) != NULL_TREE) - return false; - break; - - case COMPONENT_REF: - if (TREE_OPERAND (op, 2) != NULL_TREE) - return false; - break; - - default:; - } - op = TREE_OPERAND (op, 0); - } - - return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op); + return address_invariant_p (TREE_OPERAND (t, 0)); default: break; @@ -14611,10 +14670,11 @@ verify_type (const_tree t) /* Return 1 if ARG interpreted as signed in its precision is known to be always non-negative or 2 if ARG is known to be always negative, or 3 if - ARG may be non-negative or negative. */ + ARG may be non-negative or negative. STMT if specified is the statement + on which it is being tested. */ int -get_range_pos_neg (tree arg) +get_range_pos_neg (tree arg, gimple *stmt) { if (arg == error_mark_node) return 3; @@ -14647,7 +14707,7 @@ get_range_pos_neg (tree arg) if (TREE_CODE (arg) != SSA_NAME) return 3; int_range_max r; - while (!get_global_range_query ()->range_of_expr (r, arg) + while (!get_range_query (cfun)->range_of_expr (r, arg, stmt) || r.undefined_p () || r.varying_p ()) { gimple *g = SSA_NAME_DEF_STMT (arg); |