diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 142 |
1 files changed, 142 insertions, 0 deletions
@@ -237,7 +237,13 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_COPYIN */ 1, /* OMP_CLAUSE_COPYPRIVATE */ 2, /* OMP_CLAUSE_LINEAR */ + 2, /* OMP_CLAUSE_ALIGNED */ + 1, /* OMP_CLAUSE_DEPEND */ 1, /* OMP_CLAUSE_UNIFORM */ + 2, /* OMP_CLAUSE_FROM */ + 2, /* OMP_CLAUSE_TO */ + 2, /* OMP_CLAUSE_MAP */ + 1, /* OMP_CLAUSE__LOOPTEMP_ */ 1, /* OMP_CLAUSE_IF */ 1, /* OMP_CLAUSE_NUM_THREADS */ 1, /* OMP_CLAUSE_SCHEDULE */ @@ -248,7 +254,19 @@ unsigned const char omp_clause_num_ops[] = 0, /* OMP_CLAUSE_UNTIED */ 1, /* OMP_CLAUSE_FINAL */ 0, /* OMP_CLAUSE_MERGEABLE */ + 1, /* OMP_CLAUSE_DEVICE */ + 1, /* OMP_CLAUSE_DIST_SCHEDULE */ + 0, /* OMP_CLAUSE_INBRANCH */ + 0, /* OMP_CLAUSE_NOTINBRANCH */ + 1, /* OMP_CLAUSE_NUM_TEAMS */ + 1, /* OMP_CLAUSE_THREAD_LIMIT */ + 0, /* OMP_CLAUSE_PROC_BIND */ 1, /* OMP_CLAUSE_SAFELEN */ + 1, /* OMP_CLAUSE_SIMDLEN */ + 0, /* OMP_CLAUSE_FOR */ + 0, /* OMP_CLAUSE_PARALLEL */ + 0, /* OMP_CLAUSE_SECTIONS */ + 0, /* OMP_CLAUSE_TASKGROUP */ 1, /* OMP_CLAUSE__SIMDUID_ */ }; @@ -263,7 +281,13 @@ const char * const omp_clause_code_name[] = "copyin", "copyprivate", "linear", + "aligned", + "depend", "uniform", + "from", + "to", + "map", + "_looptemp_", "if", "num_threads", "schedule", @@ -274,7 +298,19 @@ const char * const omp_clause_code_name[] = "untied", "final", "mergeable", + "device", + "dist_schedule", + "inbranch", + "notinbranch", + "num_teams", + "thread_limit", + "proc_bind", "safelen", + "simdlen", + "for", + "parallel", + "sections", + "taskgroup", "_simduid_" }; @@ -4560,6 +4596,87 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) return ttype; } +/* Check if "omp declare simd" attribute arguments, CLAUSES1 and CLAUSES2, are + the same. */ + +static bool +omp_declare_simd_clauses_equal (tree clauses1, tree clauses2) +{ + tree cl1, cl2; + for (cl1 = clauses1, cl2 = clauses2; + cl1 && cl2; + cl1 = OMP_CLAUSE_CHAIN (cl1), cl2 = OMP_CLAUSE_CHAIN (cl2)) + { + if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_CODE (cl2)) + return false; + if (OMP_CLAUSE_CODE (cl1) != OMP_CLAUSE_SIMDLEN) + { + if (simple_cst_equal (OMP_CLAUSE_DECL (cl1), + OMP_CLAUSE_DECL (cl2)) != 1) + return false; + } + switch (OMP_CLAUSE_CODE (cl1)) + { + case OMP_CLAUSE_ALIGNED: + if (simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (cl1), + OMP_CLAUSE_ALIGNED_ALIGNMENT (cl2)) != 1) + return false; + break; + case OMP_CLAUSE_LINEAR: + if (simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (cl1), + OMP_CLAUSE_LINEAR_STEP (cl2)) != 1) + return false; + break; + case OMP_CLAUSE_SIMDLEN: + if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1), + OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1) + return false; + default: + break; + } + } + return true; +} + +/* Remove duplicate "omp declare simd" attributes. */ + +void +omp_remove_redundant_declare_simd_attrs (tree fndecl) +{ + tree attr, end_attr = NULL_TREE, last_attr = NULL_TREE; + for (attr = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (fndecl)); + attr; + attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))) + { + tree *pc; + for (pc = &TREE_CHAIN (attr); *pc && *pc != end_attr; ) + { + if (is_attribute_p ("omp declare simd", TREE_PURPOSE (*pc))) + { + last_attr = TREE_CHAIN (*pc); + if (TREE_VALUE (attr) == NULL_TREE) + { + if (TREE_VALUE (*pc) == NULL_TREE) + { + *pc = TREE_CHAIN (*pc); + continue; + } + } + else if (TREE_VALUE (*pc) != NULL_TREE + && omp_declare_simd_clauses_equal + (TREE_VALUE (TREE_VALUE (*pc)), + TREE_VALUE (TREE_VALUE (attr)))) + { + *pc = TREE_CHAIN (*pc); + continue; + } + } + pc = &TREE_CHAIN (*pc); + } + end_attr = last_attr; + } +} + /* Compare two attributes for their value identity. Return true if the attribute values are known to be equal; otherwise return false. */ @@ -4577,6 +4694,13 @@ attribute_value_equal (const_tree attr1, const_tree attr2) return (simple_cst_list_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1); + if (flag_openmp + && TREE_VALUE (attr1) && TREE_VALUE (attr2) + && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE + && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE) + return omp_declare_simd_clauses_equal (TREE_VALUE (attr1), + TREE_VALUE (attr2)); + return (simple_cst_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)) == 1); } @@ -11047,7 +11171,14 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_UNIFORM: + case OMP_CLAUSE_DEPEND: + case OMP_CLAUSE_NUM_TEAMS: + case OMP_CLAUSE_THREAD_LIMIT: + case OMP_CLAUSE_DEVICE: + case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_SAFELEN: + case OMP_CLAUSE_SIMDLEN: + case OMP_CLAUSE__LOOPTEMP_: case OMP_CLAUSE__SIMDUID_: WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0)); /* FALLTHRU */ @@ -11057,6 +11188,13 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_DEFAULT: case OMP_CLAUSE_UNTIED: case OMP_CLAUSE_MERGEABLE: + case OMP_CLAUSE_PROC_BIND: + case OMP_CLAUSE_INBRANCH: + case OMP_CLAUSE_NOTINBRANCH: + case OMP_CLAUSE_FOR: + case OMP_CLAUSE_PARALLEL: + case OMP_CLAUSE_SECTIONS: + case OMP_CLAUSE_TASKGROUP: WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); case OMP_CLAUSE_LASTPRIVATE: @@ -11072,7 +11210,11 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); } + case OMP_CLAUSE_ALIGNED: case OMP_CLAUSE_LINEAR: + case OMP_CLAUSE_FROM: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_MAP: WALK_SUBTREE (OMP_CLAUSE_DECL (*tp)); WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); |