LCOV - code coverage report
Current view: top level - gcc - omp-general.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.8 % 32 30
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* General types and functions that are uselful for processing of OpenMP,
       2              :    OpenACC and similar directivers at various stages of compilation.
       3              : 
       4              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #ifndef GCC_OMP_GENERAL_H
      23              : #define GCC_OMP_GENERAL_H
      24              : 
      25              : #include "gomp-constants.h"
      26              : #include "omp-api.h"
      27              : #include "omp-selectors.h"
      28              : 
      29              : /*  Flags for an OpenACC loop.  */
      30              : 
      31              : enum oacc_loop_flags {
      32              :   OLF_SEQ       = 1u << 0,  /* Explicitly sequential  */
      33              :   OLF_AUTO      = 1u << 1,        /* Compiler chooses axes.  */
      34              :   OLF_INDEPENDENT = 1u << 2,      /* Iterations are known independent.  */
      35              :   OLF_GANG_STATIC = 1u << 3,      /* Gang partitioning is static (has op). */
      36              :   OLF_TILE      = 1u << 4,        /* Tiled loop. */
      37              :   OLF_REDUCTION = 1u << 5,        /* Reduction loop.  */
      38              : 
      39              :   /* Explicitly specified loop axes.  */
      40              :   OLF_DIM_BASE = 6,
      41              :   OLF_DIM_GANG   = 1u << (OLF_DIM_BASE + GOMP_DIM_GANG),
      42              :   OLF_DIM_WORKER = 1u << (OLF_DIM_BASE + GOMP_DIM_WORKER),
      43              :   OLF_DIM_VECTOR = 1u << (OLF_DIM_BASE + GOMP_DIM_VECTOR),
      44              : 
      45              :   OLF_MAX = OLF_DIM_BASE + GOMP_DIM_MAX
      46              : };
      47              : 
      48              : /* A structure holding the elements of:
      49              :    for (V = N1; V cond N2; V += STEP) [...]
      50              :    or for non-rectangular loops:
      51              :    for (V = M1 * W + N1; V cond M2 * W + N2; V += STEP;
      52              :    where W is V of the OUTER-th loop (e.g. for OUTER 1 it is the
      53              :    the index of the immediately surrounding loop).
      54              :    NON_RECT_REFERENCED is true for loops referenced by loops
      55              :    with non-NULL M1 or M2.  */
      56              : 
      57              : struct omp_for_data_loop
      58              : {
      59              :   tree v, n1, n2, step, m1, m2;
      60              :   enum tree_code cond_code;
      61              :   int outer;
      62              :   bool non_rect_referenced;
      63              : };
      64              : 
      65              : /* A structure describing the main elements of a parallel loop.  */
      66              : 
      67              : struct omp_for_data
      68              : {
      69              :   struct omp_for_data_loop loop;
      70              :   tree chunk_size;
      71              :   gomp_for *for_stmt;
      72              :   tree pre, iter_type;
      73              :   tree tiling;  /* Tiling values (if non null).  */
      74              :   int collapse;  /* Collapsed loops, 1 for a non-collapsed loop.  */
      75              :   int ordered;
      76              :   int first_nonrect, last_nonrect;
      77              :   bool have_nowait, have_ordered, simd_schedule, have_reductemp;
      78              :   bool have_pointer_condtemp, have_scantemp, have_nonctrl_scantemp;
      79              :   bool non_rect;
      80              :   int lastprivate_conditional;
      81              :   unsigned char sched_modifiers;
      82              :   enum omp_clause_schedule_kind sched_kind;
      83              :   struct omp_for_data_loop *loops;
      84              :   /* The following are relevant only for non-rectangular loops
      85              :      where only a single loop depends on an outer loop iterator.  */
      86              :   tree first_inner_iterations; /* Number of iterations of the inner
      87              :                                   loop with the first outer iterator
      88              :                                   (or adjn1, if that is non-NULL).  */
      89              :   tree factor; /* (m2 - m1) * outer_step / inner_step.  */
      90              :   /* Adjusted n1 of the outer loop in such loop nests (if needed).  */
      91              :   tree adjn1;
      92              : };
      93              : 
      94              : /* Needs to be a GC-friendly widest_int variant, but precision is
      95              :    desirable to be the same on all targets.  */
      96              : typedef generic_wide_int <fixed_wide_int_storage <1024> > score_wide_int;
      97              : 
      98              : /* A structure describing a variant alternative in a metadirective or
      99              :    variant function, used for matching and scoring during resolution.  */
     100         9503 : struct GTY(()) omp_variant
     101              : {
     102              :   /* Context selector.  This is NULL_TREE for the default.  */
     103              :   tree selector;
     104              :   /* For early resolution of "metadirective", contains the nested directive.
     105              :      For early resolution of "declare variant", contains the function decl
     106              :      for this alternative.  For late resolution of both, contains the label
     107              :      that is the branch target for this alternative.  */
     108              :   tree alternative;
     109              :   /* Common body, used for metadirective, null otherwise.  */
     110              :   tree body;
     111              :   /* The score, or the best guess if scorable is false.  */
     112              :   score_wide_int score;
     113              :   /* True if the selector is dynamic.  Filled in during resolution.  */
     114              :   bool dynamic_selector;
     115              :   /* Whether the selector is known to definitely match.  */
     116              :   bool matchable;
     117              :   /* Whether the score for the selector is definitely known.  */
     118              :   bool scorable;
     119              : };
     120              : 
     121              : #define OACC_FN_ATTRIB "oacc function"
     122              : 
     123              : /* Accessors for OMP context selectors, used by variant directives.
     124              :    These are represented internally by a multilevel TREE_LIST structure, but
     125              :    these accessors should be used to avoid confusion.  The grammar is:
     126              : 
     127              :    context-set-selector-specification:
     128              :      trait-set-selector [, trait-set-selector [, ...]]
     129              :    trait-set-selector:
     130              :      trait-set-selector-name = { trait-selector [, trait-selector [, ... ]] }
     131              :    trait-selector:
     132              :      trait-selector-name [ ( [trait-score: ]
     133              :                              trait-property [, trait-property  [, ...]] ) ]
     134              : 
     135              :    trait-properties can variously be identifiers, strings, clauses, or
     136              :    expressions.
     137              : 
     138              :    All the lists are chained via TREE_CHAIN.  If a score is present, it is
     139              :    internally tacked on to the properties with a TREE_PURPOSE of
     140              :    OMP_TS_SCORE_NODE.  */
     141              : 
     142              : #define OMP_TS_SCORE_NODE integer_minus_one_node
     143              : #define OMP_TP_NAMELIST_NODE integer_one_node
     144              : 
     145              : #define OMP_TSS_ID(NODE) \
     146              :   TREE_PURPOSE (NODE)
     147              : #define OMP_TSS_TRAIT_SELECTORS(NODE) \
     148              :   TREE_VALUE (NODE)
     149              : #define OMP_TS_ID(NODE) \
     150              :   TREE_PURPOSE (NODE)
     151              : #define OMP_TS_SCORE(NODE) \
     152              :   ((TREE_VALUE (NODE)                                         \
     153              :     && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST             \
     154              :     && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
     155              :    ? TREE_VALUE (TREE_VALUE (NODE)) : NULL_TREE)
     156              : #define OMP_TS_PROPERTIES(NODE) \
     157              :   ((TREE_VALUE (NODE)                                         \
     158              :     && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST             \
     159              :     && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
     160              :    ? TREE_CHAIN (TREE_VALUE (NODE)) : TREE_VALUE (NODE))
     161              : #define OMP_TP_NAME(NODE) \
     162              :   TREE_PURPOSE (NODE)
     163              : #define OMP_TP_VALUE(NODE) \
     164              :   TREE_VALUE (NODE)
     165              : 
     166              : #define OMP_TSS_CODE(t)                                         \
     167              :   ((enum omp_tss_code) TREE_INT_CST_LOW (OMP_TSS_ID (t)))
     168              : #define OMP_TSS_NAME(t)                 \
     169              :   (omp_tss_map[OMP_TSS_CODE (t)])
     170              : 
     171              : #define OMP_TS_CODE(t)                                          \
     172              :   ((enum omp_ts_code) TREE_INT_CST_LOW (OMP_TS_ID (t)))
     173              : #define OMP_TS_NAME(t)                  \
     174              :   (omp_ts_map[OMP_TS_CODE (t)].name)
     175              : 
     176              : extern tree make_trait_set_selector (enum omp_tss_code, tree, tree);
     177              : extern tree make_trait_selector (enum omp_ts_code, tree, tree, tree);
     178              : extern tree make_trait_property (tree, tree, tree);
     179              : 
     180              : extern tree make_omp_metadirective_variant (tree, tree, tree);
     181              : 
     182              : extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
     183              : extern bool omp_is_allocatable_or_ptr (tree decl);
     184              : extern tree omp_check_optional_argument (tree decl, bool for_present_check);
     185              : extern bool omp_mappable_type (tree type);
     186              : extern bool omp_privatize_by_reference (tree decl);
     187              : extern void omp_adjust_for_condition (location_t loc, enum tree_code *cond_code,
     188              :                                       tree *n2, tree v, tree step);
     189              : extern tree omp_get_for_step_from_incr (location_t loc, tree incr);
     190              : extern void omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
     191              :                                   struct omp_for_data_loop *loops);
     192              : extern gimple *omp_build_barrier (tree lhs);
     193              : extern tree find_combined_omp_for (tree *, int *, void *);
     194              : extern poly_uint64 omp_max_vf (bool);
     195              : extern int omp_max_simt_vf (void);
     196              : extern const char *omp_context_name_list_prop (tree);
     197              : enum omp_ctx_directive
     198              :   { OMP_CTX_DECLARE_VARIANT,
     199              :     OMP_CTX_BEGIN_DECLARE_VARIANT,
     200              :     OMP_CTX_METADIRECTIVE };
     201              : extern tree omp_check_context_selector (location_t loc, tree ctx,
     202              :                                         enum omp_ctx_directive directive);
     203              : extern tree omp_mangle_variant_name (tree base_id, tree ctx, const char *sep);
     204              : extern bool omp_check_for_duplicate_variant (location_t loc,
     205              :                                              tree base_decl, tree ctx);
     206              : extern void omp_mark_declare_variant (location_t loc, tree variant,
     207              :                                       tree construct);
     208              : extern int omp_context_selector_matches (tree, tree, bool, bool = false);
     209              : extern tree omp_merge_context_selectors (location_t, tree, tree,
     210              :                                          enum omp_ctx_directive);
     211              : extern tree resolve_omp_target_device_matches (tree node);
     212              : extern tree omp_get_context_selector (tree, enum omp_tss_code,
     213              :                                       enum omp_ts_code);
     214              : extern tree omp_get_context_selector_list (tree, enum omp_tss_code);
     215              : extern vec<struct omp_variant> omp_declare_variant_candidates (tree, tree);
     216              : extern vec<struct omp_variant> omp_metadirective_candidates (tree, tree);
     217              : extern vec<struct omp_variant>
     218              : omp_get_dynamic_candidates (vec<struct omp_variant>&, tree);
     219              : extern vec<struct omp_variant> omp_early_resolve_metadirective (tree);
     220              : extern vec<struct omp_variant> omp_resolve_variant_construct (tree, tree);
     221              : extern tree omp_dynamic_cond (tree, tree);
     222              : extern tree oacc_launch_pack (unsigned code, tree device, unsigned op);
     223              : extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims);
     224              : extern void oacc_replace_fn_attrib (tree fn, tree dims);
     225              : extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args);
     226              : extern int oacc_verify_routine_clauses (tree, tree *, location_t,
     227              :                                         const char *);
     228              : extern tree oacc_build_routine_dims (tree clauses);
     229              : extern tree oacc_get_fn_attrib (tree fn);
     230              : extern bool offloading_function_p (tree fn);
     231              : extern int oacc_get_fn_dim_size (tree fn, int axis);
     232              : extern int oacc_get_ifn_dim_arg (const gimple *stmt);
     233              : 
     234              : enum omp_requires {
     235              :   OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER = 0xf,
     236              :   OMP_REQUIRES_UNIFIED_ADDRESS = GOMP_REQUIRES_UNIFIED_ADDRESS,
     237              :   OMP_REQUIRES_UNIFIED_SHARED_MEMORY = GOMP_REQUIRES_UNIFIED_SHARED_MEMORY,
     238              :   OMP_REQUIRES_DYNAMIC_ALLOCATORS = 0x40,
     239              :   OMP_REQUIRES_REVERSE_OFFLOAD = GOMP_REQUIRES_REVERSE_OFFLOAD,
     240              :   OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED = 0x100,
     241              :   OMP_REQUIRES_TARGET_USED = GOMP_REQUIRES_TARGET_USED,
     242              :   OMP_REQUIRES_SELF_MAPS = GOMP_REQUIRES_SELF_MAPS
     243              : };
     244              : 
     245              : extern GTY(()) enum omp_requires omp_requires_mask;
     246              : 
     247              : inline dump_flags_t
     248        41270 : get_openacc_privatization_dump_flags ()
     249              : {
     250        41270 :   dump_flags_t l_dump_flags = MSG_NOTE;
     251              : 
     252              :   /* For '--param=openacc-privatization=quiet', diagnostics only go to dump
     253              :      files.  */
     254        41270 :   if (param_openacc_privatization == OPENACC_PRIVATIZATION_QUIET)
     255        22751 :     l_dump_flags |= MSG_PRIORITY_INTERNALS;
     256              : 
     257        41270 :   return l_dump_flags;
     258              : }
     259              : 
     260              : extern tree omp_build_component_ref (tree obj, tree field);
     261              : 
     262              : template <typename T>
     263              : struct omp_name_type
     264              : {
     265              :   tree name;
     266              :   T type;
     267              : };
     268              : 
     269              : template <>
     270              : struct default_hash_traits <omp_name_type<tree> >
     271              :   : typed_noop_remove <omp_name_type<tree> >
     272              : {
     273              :   GTY((skip)) typedef omp_name_type<tree> value_type;
     274              :   GTY((skip)) typedef omp_name_type<tree> compare_type;
     275              : 
     276              :   static hashval_t
     277         6558 :   hash (omp_name_type<tree> p)
     278              :   {
     279         6558 :     return p.name ? iterative_hash_expr (p.name, TYPE_UID (p.type))
     280         5878 :                   : TYPE_UID (p.type);
     281              :   }
     282              : 
     283              :   static const bool empty_zero_p = true;
     284              : 
     285              :   static bool
     286      1996807 :   is_empty (omp_name_type<tree> p)
     287              :   {
     288      1996257 :     return p.type == NULL;
     289              :   }
     290              : 
     291              :   static bool
     292              :   is_deleted (omp_name_type<tree>)
     293              :   {
     294              :     return false;
     295              :   }
     296              : 
     297              :   static bool
     298          701 :   equal (const omp_name_type<tree> &a, const omp_name_type<tree> &b)
     299              :   {
     300          701 :     if (a.name == NULL_TREE && b.name == NULL_TREE)
     301          381 :       return a.type == b.type;
     302          320 :     else if (a.name == NULL_TREE || b.name == NULL_TREE)
     303              :       return false;
     304              :     else
     305          465 :       return a.name == b.name && a.type == b.type;
     306              :   }
     307              : 
     308              :   static void
     309            0 :   mark_empty (omp_name_type<tree> &e)
     310              :   {
     311            0 :     e.type = NULL;
     312              :   }
     313              : };
     314              : 
     315              : template <typename T>
     316              : struct omp_mapper_list
     317              : {
     318              :   hash_set<omp_name_type<T>> *seen_types;
     319              :   vec<tree> *mappers;
     320              : 
     321         8970 :   omp_mapper_list (hash_set<omp_name_type<T>> *s, vec<tree> *m)
     322         8970 :     : seen_types (s), mappers (m) { }
     323              : 
     324          237 :   void add_mapper (tree name, T type, tree mapperfn)
     325              :   {
     326              :     /* We can't hash a NULL_TREE...  */
     327          237 :     if (!name)
     328          237 :       name = void_node;
     329              : 
     330          237 :     omp_name_type<T> n_t = { name, type };
     331              : 
     332          237 :     if (seen_types->contains (n_t))
     333          112 :       return;
     334              : 
     335          125 :     seen_types->add (n_t);
     336          125 :     mappers->safe_push (mapperfn);
     337              :   }
     338              : 
     339           68 :   bool contains (tree name, T type)
     340              :   {
     341           68 :     if (!name)
     342           68 :       name = void_node;
     343              : 
     344           68 :     return seen_types->contains ({ name, type });
     345              :   }
     346              : };
     347              : 
     348              : namespace omp_addr_tokenizer {
     349              : 
     350              : /* These are the ways of accessing a variable that have special-case handling
     351              :    in the middle end (gimplify, omp-lower, etc.).  */
     352              : 
     353              : /* These are the kinds of access that an ACCESS_METHOD token can represent.  */
     354              : 
     355              : enum access_method_kinds
     356              : {
     357              :   ACCESS_DIRECT,
     358              :   ACCESS_REF,
     359              :   ACCESS_POINTER,
     360              :   ACCESS_REF_TO_POINTER,
     361              :   ACCESS_POINTER_OFFSET,
     362              :   ACCESS_REF_TO_POINTER_OFFSET,
     363              :   ACCESS_INDEXED_ARRAY,
     364              :   ACCESS_INDEXED_REF_TO_ARRAY
     365              : };
     366              : 
     367              : /* These are the kinds that a STRUCTURE_BASE or ARRAY_BASE (except
     368              :    BASE_COMPONENT_EXPR) can represent.  */
     369              : 
     370              : enum structure_base_kinds
     371              : {
     372              :   BASE_DECL,
     373              :   BASE_COMPONENT_EXPR,
     374              :   BASE_ARBITRARY_EXPR
     375              : };
     376              : 
     377              : /* The coarse type for an address token.  These can have subtypes for
     378              :    ARRAY_BASE or STRUCTURE_BASE (structure_base_kinds) or ACCESS_METHOD
     379              :    (access_method_kinds).  */
     380              : 
     381              : enum token_type
     382              : {
     383              :   ARRAY_BASE,
     384              :   STRUCTURE_BASE,
     385              :   COMPONENT_SELECTOR,
     386              :   ACCESS_METHOD
     387              : };
     388              : 
     389              : /* The struct that forms a single token of an address expression as parsed by
     390              :    omp_parse_expr.  These are typically held in a vec after parsing.  */
     391              : 
     392              : struct omp_addr_token
     393              : {
     394              :   enum token_type type;
     395              :   tree expr;
     396              : 
     397              :   union
     398              :   {
     399              :     access_method_kinds access_kind;
     400              :     structure_base_kinds structure_base_kind;
     401              :   } u;
     402              : 
     403              :   omp_addr_token (token_type, tree);
     404              :   omp_addr_token (access_method_kinds, tree);
     405              :   omp_addr_token (token_type, structure_base_kinds, tree);
     406              : };
     407              : 
     408              : extern bool omp_access_chain_p (vec<omp_addr_token *> &, unsigned);
     409              : extern tree omp_accessed_addr (vec<omp_addr_token *> &, unsigned, tree);
     410              : 
     411              : }
     412              : 
     413              : typedef omp_addr_tokenizer::omp_addr_token omp_addr_token;
     414              : 
     415              : extern bool omp_parse_expr (vec<omp_addr_token *> &, tree);
     416              : 
     417              : extern tree omp_loop_number_of_iterations (tree, int, tree * = NULL);
     418              : extern void omp_maybe_apply_loop_xforms (tree *, tree);
     419              : 
     420              : #endif /* GCC_OMP_GENERAL_H */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.