
'device_num' and 'ancestor' are now parsed on target device constructs for C, C++, and Fortran (see OpenMP specification 5.0, p. 170). When 'ancestor' is used, then 'sorry, not supported' is output. Moreover, the restrictions for 'ancestor' are implemented (see OpenMP specification 5.0, p. 174f). gcc/c/ChangeLog: * c-parser.c (c_parser_omp_clause_device): Parse device-modifiers 'device_num' and 'ancestor' in 'target device' clauses. gcc/cp/ChangeLog: * parser.c (cp_parser_omp_clause_device): Parse device-modifiers 'device_num' and 'ancestor' in 'target device' clauses. * semantics.c (finish_omp_clauses): Error handling. Constant device ids must evaluate to '1' if 'ancestor' is used. gcc/fortran/ChangeLog: * gfortran.h: Add variable for 'ancestor' in struct gfc_omp_clauses. * openmp.c (gfc_match_omp_clauses): Parse device-modifiers 'device_num' and 'ancestor' in 'target device' clauses. * trans-openmp.c (gfc_trans_omp_clauses): Set OMP_CLAUSE_DEVICE_ANCESTOR. gcc/ChangeLog: * gimplify.c (gimplify_scan_omp_clauses): Error handling. 'ancestor' only allowed on target constructs and only with particular other clauses. * omp-expand.c (expand_omp_target): Output of 'sorry, not supported' if 'ancestor' is used. * omp-low.c (check_omp_nesting_restrictions): Error handling. No nested OpenMP structs when 'ancestor' is used. (scan_omp_1_stmt): No usage of OpenMP runtime routines in a target region when 'ancestor' is used. * tree-pretty-print.c (dump_omp_clause): Append 'ancestor'. * tree.h (OMP_CLAUSE_DEVICE_ANCESTOR): Define macro. gcc/testsuite/ChangeLog: * c-c++-common/gomp/target-device-1.c: New test. * c-c++-common/gomp/target-device-2.c: New test. * c-c++-common/gomp/target-device-ancestor-1.c: New test. * c-c++-common/gomp/target-device-ancestor-2.c: New test. * c-c++-common/gomp/target-device-ancestor-3.c: New test. * c-c++-common/gomp/target-device-ancestor-4.c: New test. * gfortran.dg/gomp/target-device-1.f90: New test. * gfortran.dg/gomp/target-device-2.f90: New test. * gfortran.dg/gomp/target-device-ancestor-1.f90: New test. * gfortran.dg/gomp/target-device-ancestor-2.f90: New test. * gfortran.dg/gomp/target-device-ancestor-3.f90: New test. * gfortran.dg/gomp/target-device-ancestor-4.f90: New test.
4547 lines
118 KiB
C
4547 lines
118 KiB
C
/* Pretty formatting of GENERIC trees in C syntax.
|
|
Copyright (C) 2001-2021 Free Software Foundation, Inc.
|
|
Adapted from c-pretty-print.c by Diego Novillo <dnovillo@redhat.com>
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 3, or (at your option) any later
|
|
version.
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include "config.h"
|
|
#include "system.h"
|
|
#include "coretypes.h"
|
|
#include "backend.h"
|
|
#include "rtl.h"
|
|
#include "tree.h"
|
|
#include "predict.h"
|
|
#include "cgraph.h"
|
|
#include "tree-pretty-print.h"
|
|
#include "stor-layout.h"
|
|
#include "langhooks.h"
|
|
#include "tree-iterator.h"
|
|
#include "dumpfile.h"
|
|
#include "internal-fn.h"
|
|
#include "gomp-constants.h"
|
|
#include "gimple.h"
|
|
#include "fold-const.h"
|
|
|
|
/* Routines in this file get invoked via the default tree printer
|
|
used by diagnostics and thus they are called from pp_printf which
|
|
isn't reentrant. Avoid using pp_printf in this file. */
|
|
#pragma GCC poison pp_printf
|
|
|
|
/* Disable warnings about quoting issues in the pp_xxx calls below
|
|
that (intentionally) don't follow GCC diagnostic conventions. */
|
|
#if __GNUC__ >= 10
|
|
# pragma GCC diagnostic push
|
|
# pragma GCC diagnostic ignored "-Wformat-diag"
|
|
#endif
|
|
|
|
/* Local functions, macros and variables. */
|
|
static const char *op_symbol (const_tree);
|
|
static void newline_and_indent (pretty_printer *, int);
|
|
static void maybe_init_pretty_print (FILE *);
|
|
static void print_struct_decl (pretty_printer *, const_tree, int, dump_flags_t);
|
|
static void do_niy (pretty_printer *, const_tree, dump_flags_t);
|
|
|
|
#define INDENT(SPACE) do { \
|
|
int i; for (i = 0; i<SPACE; i++) pp_space (pp); } while (0)
|
|
|
|
#define NIY do_niy (pp, node, flags)
|
|
|
|
static pretty_printer *tree_pp;
|
|
|
|
/* Try to print something for an unknown tree code. */
|
|
|
|
static void
|
|
do_niy (pretty_printer *pp, const_tree node, dump_flags_t flags)
|
|
{
|
|
int i, len;
|
|
|
|
pp_string (pp, "<<< Unknown tree: ");
|
|
pp_string (pp, get_tree_code_name (TREE_CODE (node)));
|
|
|
|
if (EXPR_P (node))
|
|
{
|
|
len = TREE_OPERAND_LENGTH (node);
|
|
for (i = 0; i < len; ++i)
|
|
{
|
|
newline_and_indent (pp, 2);
|
|
dump_generic_node (pp, TREE_OPERAND (node, i), 2, flags, false);
|
|
}
|
|
}
|
|
|
|
pp_string (pp, " >>>");
|
|
}
|
|
|
|
/* Debugging function to print out a generic expression. */
|
|
|
|
DEBUG_FUNCTION void
|
|
debug_generic_expr (tree t)
|
|
{
|
|
print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS);
|
|
fprintf (stderr, "\n");
|
|
}
|
|
|
|
/* Debugging function to print out a generic statement. */
|
|
|
|
DEBUG_FUNCTION void
|
|
debug_generic_stmt (tree t)
|
|
{
|
|
print_generic_stmt (stderr, t, TDF_VOPS|TDF_MEMSYMS);
|
|
fprintf (stderr, "\n");
|
|
}
|
|
|
|
/* Debugging function to print out a chain of trees . */
|
|
|
|
DEBUG_FUNCTION void
|
|
debug_tree_chain (tree t)
|
|
{
|
|
hash_set<tree> seen;
|
|
|
|
while (t)
|
|
{
|
|
print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
|
|
fprintf (stderr, " ");
|
|
t = TREE_CHAIN (t);
|
|
if (seen.add (t))
|
|
{
|
|
fprintf (stderr, "... [cycled back to ");
|
|
print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
|
|
fprintf (stderr, "]");
|
|
break;
|
|
}
|
|
}
|
|
fprintf (stderr, "\n");
|
|
}
|
|
|
|
/* Prints declaration DECL to the FILE with details specified by FLAGS. */
|
|
void
|
|
print_generic_decl (FILE *file, tree decl, dump_flags_t flags)
|
|
{
|
|
maybe_init_pretty_print (file);
|
|
print_declaration (tree_pp, decl, 2, flags);
|
|
pp_write_text_to_stream (tree_pp);
|
|
}
|
|
|
|
/* Print tree T, and its successors, on file FILE. FLAGS specifies details
|
|
to show in the dump. See TDF_* in dumpfile.h. */
|
|
|
|
void
|
|
print_generic_stmt (FILE *file, tree t, dump_flags_t flags)
|
|
{
|
|
maybe_init_pretty_print (file);
|
|
dump_generic_node (tree_pp, t, 0, flags, true);
|
|
pp_newline_and_flush (tree_pp);
|
|
}
|
|
|
|
/* Print tree T, and its successors, on file FILE. FLAGS specifies details
|
|
to show in the dump. See TDF_* in dumpfile.h. The output is indented by
|
|
INDENT spaces. */
|
|
|
|
void
|
|
print_generic_stmt_indented (FILE *file, tree t, dump_flags_t flags, int indent)
|
|
{
|
|
int i;
|
|
|
|
maybe_init_pretty_print (file);
|
|
|
|
for (i = 0; i < indent; i++)
|
|
pp_space (tree_pp);
|
|
dump_generic_node (tree_pp, t, indent, flags, true);
|
|
pp_newline_and_flush (tree_pp);
|
|
}
|
|
|
|
/* Print a single expression T on file FILE. FLAGS specifies details to show
|
|
in the dump. See TDF_* in dumpfile.h. */
|
|
|
|
void
|
|
print_generic_expr (FILE *file, tree t, dump_flags_t flags)
|
|
{
|
|
maybe_init_pretty_print (file);
|
|
dump_generic_node (tree_pp, t, 0, flags, false);
|
|
pp_flush (tree_pp);
|
|
}
|
|
|
|
/* Print a single expression T to string, and return it. The caller
|
|
must free the returned memory. */
|
|
|
|
char *
|
|
print_generic_expr_to_str (tree t)
|
|
{
|
|
pretty_printer pp;
|
|
dump_generic_node (&pp, t, 0, TDF_VOPS|TDF_MEMSYMS, false);
|
|
return xstrdup (pp_formatted_text (&pp));
|
|
}
|
|
|
|
/* Dump NAME, an IDENTIFIER_POINTER, sanitized so that D<num> sequences
|
|
in it are replaced with Dxxxx, as long as they are at the start or
|
|
preceded by $ and at the end or followed by $. See make_fancy_name
|
|
in tree-sra.c. */
|
|
|
|
static void
|
|
dump_fancy_name (pretty_printer *pp, tree name)
|
|
{
|
|
int cnt = 0;
|
|
int length = IDENTIFIER_LENGTH (name);
|
|
const char *n = IDENTIFIER_POINTER (name);
|
|
do
|
|
{
|
|
n = strchr (n, 'D');
|
|
if (n == NULL)
|
|
break;
|
|
if (ISDIGIT (n[1])
|
|
&& (n == IDENTIFIER_POINTER (name) || n[-1] == '$'))
|
|
{
|
|
int l = 2;
|
|
while (ISDIGIT (n[l]))
|
|
l++;
|
|
if (n[l] == '\0' || n[l] == '$')
|
|
{
|
|
cnt++;
|
|
length += 5 - l;
|
|
}
|
|
n += l;
|
|
}
|
|
else
|
|
n++;
|
|
}
|
|
while (1);
|
|
if (cnt == 0)
|
|
{
|
|
pp_tree_identifier (pp, name);
|
|
return;
|
|
}
|
|
|
|
char *str = XNEWVEC (char, length + 1);
|
|
char *p = str;
|
|
const char *q;
|
|
q = n = IDENTIFIER_POINTER (name);
|
|
do
|
|
{
|
|
q = strchr (q, 'D');
|
|
if (q == NULL)
|
|
break;
|
|
if (ISDIGIT (q[1])
|
|
&& (q == IDENTIFIER_POINTER (name) || q[-1] == '$'))
|
|
{
|
|
int l = 2;
|
|
while (ISDIGIT (q[l]))
|
|
l++;
|
|
if (q[l] == '\0' || q[l] == '$')
|
|
{
|
|
memcpy (p, n, q - n);
|
|
memcpy (p + (q - n), "Dxxxx", 5);
|
|
p += (q - n) + 5;
|
|
n = q + l;
|
|
}
|
|
q += l;
|
|
}
|
|
else
|
|
q++;
|
|
}
|
|
while (1);
|
|
memcpy (p, n, IDENTIFIER_LENGTH (name) - (n - IDENTIFIER_POINTER (name)));
|
|
str[length] = '\0';
|
|
if (pp_translate_identifiers (pp))
|
|
{
|
|
const char *text = identifier_to_locale (str);
|
|
pp_append_text (pp, text, text + strlen (text));
|
|
}
|
|
else
|
|
pp_append_text (pp, str, str + length);
|
|
XDELETEVEC (str);
|
|
}
|
|
|
|
/* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set
|
|
in FLAGS. */
|
|
|
|
static void
|
|
dump_decl_name (pretty_printer *pp, tree node, dump_flags_t flags)
|
|
{
|
|
tree name = DECL_NAME (node);
|
|
if (name)
|
|
{
|
|
if ((flags & TDF_ASMNAME)
|
|
&& HAS_DECL_ASSEMBLER_NAME_P (node)
|
|
&& DECL_ASSEMBLER_NAME_SET_P (node))
|
|
pp_tree_identifier (pp, DECL_ASSEMBLER_NAME_RAW (node));
|
|
/* For -fcompare-debug don't dump DECL_NAMELESS names at all,
|
|
-g might have created more fancy names and their indexes
|
|
could get out of sync. Usually those should be DECL_IGNORED_P
|
|
too, SRA can create even non-DECL_IGNORED_P DECL_NAMELESS fancy
|
|
names, let's hope those never get out of sync after doing the
|
|
dump_fancy_name sanitization. */
|
|
else if ((flags & TDF_COMPARE_DEBUG)
|
|
&& DECL_NAMELESS (node)
|
|
&& DECL_IGNORED_P (node))
|
|
name = NULL_TREE;
|
|
/* For DECL_NAMELESS names look for embedded uids in the
|
|
names and sanitize them for TDF_NOUID. */
|
|
else if ((flags & TDF_NOUID) && DECL_NAMELESS (node))
|
|
dump_fancy_name (pp, name);
|
|
else
|
|
pp_tree_identifier (pp, name);
|
|
}
|
|
char uid_sep = (flags & TDF_GIMPLE) ? '_' : '.';
|
|
if ((flags & TDF_UID) || name == NULL_TREE)
|
|
{
|
|
if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
|
|
{
|
|
pp_character (pp, 'L');
|
|
pp_character (pp, uid_sep);
|
|
pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
|
|
}
|
|
else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
|
|
{
|
|
if (flags & TDF_NOUID)
|
|
pp_string (pp, "D#xxxx");
|
|
else
|
|
{
|
|
pp_string (pp, "D#");
|
|
pp_decimal_int (pp, (int) DEBUG_TEMP_UID (node));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
|
|
pp_character (pp, c);
|
|
pp_character (pp, uid_sep);
|
|
if (flags & TDF_NOUID)
|
|
pp_string (pp, "xxxx");
|
|
else
|
|
pp_scalar (pp, "%u", DECL_UID (node));
|
|
}
|
|
}
|
|
if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node))
|
|
{
|
|
if (flags & TDF_NOUID)
|
|
pp_string (pp, "ptD.xxxx");
|
|
else
|
|
{
|
|
pp_string (pp, "ptD.");
|
|
pp_scalar (pp, "%u", DECL_PT_UID (node));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Like the above, but used for pretty printing function calls. */
|
|
|
|
static void
|
|
dump_function_name (pretty_printer *pp, tree node, dump_flags_t flags)
|
|
{
|
|
if (CONVERT_EXPR_P (node))
|
|
node = TREE_OPERAND (node, 0);
|
|
if (DECL_NAME (node) && (flags & TDF_ASMNAME) == 0)
|
|
pp_string (pp, lang_hooks.decl_printable_name (node, 1));
|
|
else
|
|
dump_decl_name (pp, node, flags);
|
|
}
|
|
|
|
/* Dump a function declaration. NODE is the FUNCTION_TYPE. PP, SPC and
|
|
FLAGS are as in dump_generic_node. */
|
|
|
|
static void
|
|
dump_function_declaration (pretty_printer *pp, tree node,
|
|
int spc, dump_flags_t flags)
|
|
{
|
|
bool wrote_arg = false;
|
|
tree arg;
|
|
|
|
pp_space (pp);
|
|
pp_left_paren (pp);
|
|
|
|
/* Print the argument types. */
|
|
arg = TYPE_ARG_TYPES (node);
|
|
while (arg && arg != void_list_node && arg != error_mark_node)
|
|
{
|
|
if (wrote_arg)
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
wrote_arg = true;
|
|
dump_generic_node (pp, TREE_VALUE (arg), spc, flags, false);
|
|
arg = TREE_CHAIN (arg);
|
|
}
|
|
|
|
/* Drop the trailing void_type_node if we had any previous argument. */
|
|
if (arg == void_list_node && !wrote_arg)
|
|
pp_string (pp, "void");
|
|
/* Properly dump vararg function types. */
|
|
else if (!arg && wrote_arg)
|
|
pp_string (pp, ", ...");
|
|
/* Avoid printing any arg for unprototyped functions. */
|
|
|
|
pp_right_paren (pp);
|
|
}
|
|
|
|
/* Dump the domain associated with an array. */
|
|
|
|
static void
|
|
dump_array_domain (pretty_printer *pp, tree domain, int spc, dump_flags_t flags)
|
|
{
|
|
pp_left_bracket (pp);
|
|
if (domain)
|
|
{
|
|
tree min = TYPE_MIN_VALUE (domain);
|
|
tree max = TYPE_MAX_VALUE (domain);
|
|
|
|
if (min && max
|
|
&& integer_zerop (min)
|
|
&& tree_fits_shwi_p (max))
|
|
pp_wide_integer (pp, tree_to_shwi (max) + 1);
|
|
else
|
|
{
|
|
if (min)
|
|
dump_generic_node (pp, min, spc, flags, false);
|
|
pp_colon (pp);
|
|
if (max)
|
|
dump_generic_node (pp, max, spc, flags, false);
|
|
}
|
|
}
|
|
else
|
|
pp_string (pp, "<unknown>");
|
|
pp_right_bracket (pp);
|
|
}
|
|
|
|
|
|
/* Dump OpenMP iterators ITER. */
|
|
|
|
static void
|
|
dump_omp_iterators (pretty_printer *pp, tree iter, int spc, dump_flags_t flags)
|
|
{
|
|
pp_string (pp, "iterator(");
|
|
for (tree it = iter; it; it = TREE_CHAIN (it))
|
|
{
|
|
if (it != iter)
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_TYPE (TREE_VEC_ELT (it, 0)), spc, flags,
|
|
false);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (it, 0), spc, flags, false);
|
|
pp_equal (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (it, 1), spc, flags, false);
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (it, 2), spc, flags, false);
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (it, 3), spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
}
|
|
|
|
|
|
/* Dump OMP clause CLAUSE, without following OMP_CLAUSE_CHAIN.
|
|
|
|
PP, CLAUSE, SPC and FLAGS are as in dump_generic_node. */
|
|
|
|
static void
|
|
dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
|
|
{
|
|
const char *name;
|
|
const char *modifier = NULL;
|
|
switch (OMP_CLAUSE_CODE (clause))
|
|
{
|
|
case OMP_CLAUSE_PRIVATE:
|
|
name = "private";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_SHARED:
|
|
name = "shared";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_FIRSTPRIVATE:
|
|
name = "firstprivate";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_LASTPRIVATE:
|
|
name = "lastprivate";
|
|
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clause))
|
|
modifier = "conditional:";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_COPYIN:
|
|
name = "copyin";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_COPYPRIVATE:
|
|
name = "copyprivate";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_UNIFORM:
|
|
name = "uniform";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_USE_DEVICE_PTR:
|
|
name = "use_device_ptr";
|
|
if (OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (clause))
|
|
modifier = "if_present:";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_USE_DEVICE_ADDR:
|
|
name = "use_device_addr";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_IS_DEVICE_PTR:
|
|
name = "is_device_ptr";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_INCLUSIVE:
|
|
name = "inclusive";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_EXCLUSIVE:
|
|
name = "exclusive";
|
|
goto print_remap;
|
|
case OMP_CLAUSE__LOOPTEMP_:
|
|
name = "_looptemp_";
|
|
goto print_remap;
|
|
case OMP_CLAUSE__REDUCTEMP_:
|
|
name = "_reductemp_";
|
|
goto print_remap;
|
|
case OMP_CLAUSE__CONDTEMP_:
|
|
name = "_condtemp_";
|
|
goto print_remap;
|
|
case OMP_CLAUSE__SCANTEMP_:
|
|
name = "_scantemp_";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_TO_DECLARE:
|
|
name = "to";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_LINK:
|
|
name = "link";
|
|
goto print_remap;
|
|
case OMP_CLAUSE_NONTEMPORAL:
|
|
name = "nontemporal";
|
|
goto print_remap;
|
|
print_remap:
|
|
pp_string (pp, name);
|
|
pp_left_paren (pp);
|
|
if (modifier)
|
|
pp_string (pp, modifier);
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_TASK_REDUCTION:
|
|
case OMP_CLAUSE_IN_REDUCTION:
|
|
pp_string (pp, OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_IN_REDUCTION
|
|
? "in_" : "task_");
|
|
/* FALLTHRU */
|
|
case OMP_CLAUSE_REDUCTION:
|
|
pp_string (pp, "reduction(");
|
|
if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
|
|
{
|
|
if (OMP_CLAUSE_REDUCTION_TASK (clause))
|
|
pp_string (pp, "task,");
|
|
else if (OMP_CLAUSE_REDUCTION_INSCAN (clause))
|
|
pp_string (pp, "inscan,");
|
|
}
|
|
if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK)
|
|
{
|
|
pp_string (pp,
|
|
op_symbol_code (OMP_CLAUSE_REDUCTION_CODE (clause)));
|
|
pp_colon (pp);
|
|
}
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_IF:
|
|
pp_string (pp, "if(");
|
|
switch (OMP_CLAUSE_IF_MODIFIER (clause))
|
|
{
|
|
case ERROR_MARK: break;
|
|
case VOID_CST: pp_string (pp, "cancel:"); break;
|
|
case OMP_PARALLEL: pp_string (pp, "parallel:"); break;
|
|
case OMP_SIMD: pp_string (pp, "simd:"); break;
|
|
case OMP_TASK: pp_string (pp, "task:"); break;
|
|
case OMP_TASKLOOP: pp_string (pp, "taskloop:"); break;
|
|
case OMP_TARGET_DATA: pp_string (pp, "target data:"); break;
|
|
case OMP_TARGET: pp_string (pp, "target:"); break;
|
|
case OMP_TARGET_UPDATE: pp_string (pp, "target update:"); break;
|
|
case OMP_TARGET_ENTER_DATA:
|
|
pp_string (pp, "target enter data:"); break;
|
|
case OMP_TARGET_EXIT_DATA: pp_string (pp, "target exit data:"); break;
|
|
default: gcc_unreachable ();
|
|
}
|
|
dump_generic_node (pp, OMP_CLAUSE_IF_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_NUM_THREADS:
|
|
pp_string (pp, "num_threads(");
|
|
dump_generic_node (pp, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_NOWAIT:
|
|
pp_string (pp, "nowait");
|
|
break;
|
|
case OMP_CLAUSE_ORDERED:
|
|
pp_string (pp, "ordered");
|
|
if (OMP_CLAUSE_ORDERED_EXPR (clause))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_ORDERED_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
break;
|
|
|
|
case OMP_CLAUSE_DEFAULT:
|
|
pp_string (pp, "default(");
|
|
switch (OMP_CLAUSE_DEFAULT_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
|
|
break;
|
|
case OMP_CLAUSE_DEFAULT_SHARED:
|
|
pp_string (pp, "shared");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULT_NONE:
|
|
pp_string (pp, "none");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULT_PRIVATE:
|
|
pp_string (pp, "private");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE:
|
|
pp_string (pp, "firstprivate");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULT_PRESENT:
|
|
pp_string (pp, "present");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_SCHEDULE:
|
|
pp_string (pp, "schedule(");
|
|
if (OMP_CLAUSE_SCHEDULE_KIND (clause)
|
|
& (OMP_CLAUSE_SCHEDULE_MONOTONIC
|
|
| OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
|
|
{
|
|
if (OMP_CLAUSE_SCHEDULE_KIND (clause)
|
|
& OMP_CLAUSE_SCHEDULE_MONOTONIC)
|
|
pp_string (pp, "monotonic");
|
|
else
|
|
pp_string (pp, "nonmonotonic");
|
|
if (OMP_CLAUSE_SCHEDULE_SIMD (clause))
|
|
pp_comma (pp);
|
|
else
|
|
pp_colon (pp);
|
|
}
|
|
if (OMP_CLAUSE_SCHEDULE_SIMD (clause))
|
|
pp_string (pp, "simd:");
|
|
|
|
switch (OMP_CLAUSE_SCHEDULE_KIND (clause) & OMP_CLAUSE_SCHEDULE_MASK)
|
|
{
|
|
case OMP_CLAUSE_SCHEDULE_STATIC:
|
|
pp_string (pp, "static");
|
|
break;
|
|
case OMP_CLAUSE_SCHEDULE_DYNAMIC:
|
|
pp_string (pp, "dynamic");
|
|
break;
|
|
case OMP_CLAUSE_SCHEDULE_GUIDED:
|
|
pp_string (pp, "guided");
|
|
break;
|
|
case OMP_CLAUSE_SCHEDULE_RUNTIME:
|
|
pp_string (pp, "runtime");
|
|
break;
|
|
case OMP_CLAUSE_SCHEDULE_AUTO:
|
|
pp_string (pp, "auto");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
|
|
{
|
|
pp_comma (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
|
|
spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_UNTIED:
|
|
pp_string (pp, "untied");
|
|
break;
|
|
|
|
case OMP_CLAUSE_COLLAPSE:
|
|
pp_string (pp, "collapse(");
|
|
dump_generic_node (pp, OMP_CLAUSE_COLLAPSE_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_FINAL:
|
|
pp_string (pp, "final(");
|
|
dump_generic_node (pp, OMP_CLAUSE_FINAL_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_MERGEABLE:
|
|
pp_string (pp, "mergeable");
|
|
break;
|
|
|
|
case OMP_CLAUSE_LINEAR:
|
|
pp_string (pp, "linear(");
|
|
switch (OMP_CLAUSE_LINEAR_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_LINEAR_DEFAULT:
|
|
break;
|
|
case OMP_CLAUSE_LINEAR_REF:
|
|
pp_string (pp, "ref(");
|
|
break;
|
|
case OMP_CLAUSE_LINEAR_VAL:
|
|
pp_string (pp, "val(");
|
|
break;
|
|
case OMP_CLAUSE_LINEAR_UVAL:
|
|
pp_string (pp, "uval(");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
if (OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
|
|
pp_right_paren (pp);
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_LINEAR_STEP (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_ALIGNED:
|
|
pp_string (pp, "aligned(");
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
|
|
{
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_ALIGNED_ALIGNMENT (clause),
|
|
spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_ALLOCATE:
|
|
pp_string (pp, "allocate(");
|
|
if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause))
|
|
{
|
|
dump_generic_node (pp, OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause),
|
|
spc, flags, false);
|
|
pp_colon (pp);
|
|
}
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_AFFINITY:
|
|
pp_string (pp, "affinity(");
|
|
{
|
|
tree t = OMP_CLAUSE_DECL (clause);
|
|
if (TREE_CODE (t) == TREE_LIST
|
|
&& TREE_PURPOSE (t)
|
|
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
|
|
{
|
|
dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags);
|
|
pp_colon (pp);
|
|
t = TREE_VALUE (t);
|
|
}
|
|
dump_generic_node (pp, t, spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
case OMP_CLAUSE_DEPEND:
|
|
pp_string (pp, "depend(");
|
|
switch (OMP_CLAUSE_DEPEND_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_DEPEND_DEPOBJ:
|
|
name = "depobj";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_IN:
|
|
name = "in";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_OUT:
|
|
name = "out";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_INOUT:
|
|
name = "inout";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_MUTEXINOUTSET:
|
|
name = "mutexinoutset";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_SOURCE:
|
|
pp_string (pp, "source)");
|
|
return;
|
|
case OMP_CLAUSE_DEPEND_LAST:
|
|
name = "__internal__";
|
|
break;
|
|
case OMP_CLAUSE_DEPEND_SINK:
|
|
pp_string (pp, "sink:");
|
|
for (tree t = OMP_CLAUSE_DECL (clause); t; t = TREE_CHAIN (t))
|
|
if (TREE_CODE (t) == TREE_LIST)
|
|
{
|
|
dump_generic_node (pp, TREE_VALUE (t), spc, flags, false);
|
|
if (TREE_PURPOSE (t) != integer_zero_node)
|
|
{
|
|
if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (t))
|
|
pp_minus (pp);
|
|
else
|
|
pp_plus (pp);
|
|
dump_generic_node (pp, TREE_PURPOSE (t), spc, flags,
|
|
false);
|
|
}
|
|
if (TREE_CHAIN (t))
|
|
pp_comma (pp);
|
|
}
|
|
else
|
|
gcc_unreachable ();
|
|
pp_right_paren (pp);
|
|
return;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
{
|
|
tree t = OMP_CLAUSE_DECL (clause);
|
|
if (TREE_CODE (t) == TREE_LIST
|
|
&& TREE_PURPOSE (t)
|
|
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
|
|
{
|
|
dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags);
|
|
pp_colon (pp);
|
|
t = TREE_VALUE (t);
|
|
}
|
|
if (name[0])
|
|
{
|
|
pp_string (pp, name);
|
|
pp_colon (pp);
|
|
}
|
|
dump_generic_node (pp, t, spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
break;
|
|
|
|
case OMP_CLAUSE_MAP:
|
|
pp_string (pp, "map(");
|
|
switch (OMP_CLAUSE_MAP_KIND (clause))
|
|
{
|
|
case GOMP_MAP_ALLOC:
|
|
case GOMP_MAP_POINTER:
|
|
pp_string (pp, "alloc");
|
|
break;
|
|
case GOMP_MAP_IF_PRESENT:
|
|
pp_string (pp, "no_alloc");
|
|
break;
|
|
case GOMP_MAP_TO:
|
|
case GOMP_MAP_TO_PSET:
|
|
pp_string (pp, "to");
|
|
break;
|
|
case GOMP_MAP_FROM:
|
|
pp_string (pp, "from");
|
|
break;
|
|
case GOMP_MAP_TOFROM:
|
|
pp_string (pp, "tofrom");
|
|
break;
|
|
case GOMP_MAP_FORCE_ALLOC:
|
|
pp_string (pp, "force_alloc");
|
|
break;
|
|
case GOMP_MAP_FORCE_TO:
|
|
pp_string (pp, "force_to");
|
|
break;
|
|
case GOMP_MAP_FORCE_FROM:
|
|
pp_string (pp, "force_from");
|
|
break;
|
|
case GOMP_MAP_FORCE_TOFROM:
|
|
pp_string (pp, "force_tofrom");
|
|
break;
|
|
case GOMP_MAP_FORCE_PRESENT:
|
|
pp_string (pp, "force_present");
|
|
break;
|
|
case GOMP_MAP_DELETE:
|
|
pp_string (pp, "delete");
|
|
break;
|
|
case GOMP_MAP_FORCE_DEVICEPTR:
|
|
pp_string (pp, "force_deviceptr");
|
|
break;
|
|
case GOMP_MAP_ALWAYS_TO:
|
|
pp_string (pp, "always,to");
|
|
break;
|
|
case GOMP_MAP_ALWAYS_FROM:
|
|
pp_string (pp, "always,from");
|
|
break;
|
|
case GOMP_MAP_ALWAYS_TOFROM:
|
|
pp_string (pp, "always,tofrom");
|
|
break;
|
|
case GOMP_MAP_RELEASE:
|
|
pp_string (pp, "release");
|
|
break;
|
|
case GOMP_MAP_FIRSTPRIVATE_POINTER:
|
|
pp_string (pp, "firstprivate");
|
|
break;
|
|
case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
|
|
pp_string (pp, "firstprivate ref");
|
|
break;
|
|
case GOMP_MAP_STRUCT:
|
|
pp_string (pp, "struct");
|
|
break;
|
|
case GOMP_MAP_ALWAYS_POINTER:
|
|
pp_string (pp, "always_pointer");
|
|
break;
|
|
case GOMP_MAP_DEVICE_RESIDENT:
|
|
pp_string (pp, "device_resident");
|
|
break;
|
|
case GOMP_MAP_LINK:
|
|
pp_string (pp, "link");
|
|
break;
|
|
case GOMP_MAP_ATTACH:
|
|
pp_string (pp, "attach");
|
|
break;
|
|
case GOMP_MAP_DETACH:
|
|
pp_string (pp, "detach");
|
|
break;
|
|
case GOMP_MAP_FORCE_DETACH:
|
|
pp_string (pp, "force_detach");
|
|
break;
|
|
case GOMP_MAP_ATTACH_DETACH:
|
|
pp_string (pp, "attach_detach");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
print_clause_size:
|
|
if (OMP_CLAUSE_SIZE (clause))
|
|
{
|
|
switch (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP
|
|
? OMP_CLAUSE_MAP_KIND (clause) : GOMP_MAP_TO)
|
|
{
|
|
case GOMP_MAP_POINTER:
|
|
case GOMP_MAP_FIRSTPRIVATE_POINTER:
|
|
case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
|
|
case GOMP_MAP_ALWAYS_POINTER:
|
|
pp_string (pp, " [pointer assign, bias: ");
|
|
break;
|
|
case GOMP_MAP_TO_PSET:
|
|
pp_string (pp, " [pointer set, len: ");
|
|
break;
|
|
case GOMP_MAP_ATTACH:
|
|
case GOMP_MAP_DETACH:
|
|
case GOMP_MAP_FORCE_DETACH:
|
|
case GOMP_MAP_ATTACH_DETACH:
|
|
pp_string (pp, " [bias: ");
|
|
break;
|
|
default:
|
|
pp_string (pp, " [len: ");
|
|
break;
|
|
}
|
|
dump_generic_node (pp, OMP_CLAUSE_SIZE (clause),
|
|
spc, flags, false);
|
|
pp_right_bracket (pp);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_FROM:
|
|
pp_string (pp, "from(");
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
goto print_clause_size;
|
|
|
|
case OMP_CLAUSE_TO:
|
|
pp_string (pp, "to(");
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
goto print_clause_size;
|
|
|
|
case OMP_CLAUSE__CACHE_:
|
|
pp_string (pp, "(");
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
|
|
spc, flags, false);
|
|
goto print_clause_size;
|
|
|
|
case OMP_CLAUSE_NUM_TEAMS:
|
|
pp_string (pp, "num_teams(");
|
|
dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_THREAD_LIMIT:
|
|
pp_string (pp, "thread_limit(");
|
|
dump_generic_node (pp, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_DEVICE:
|
|
pp_string (pp, "device(");
|
|
if (OMP_CLAUSE_DEVICE_ANCESTOR (clause))
|
|
pp_string (pp, "ancestor:");
|
|
dump_generic_node (pp, OMP_CLAUSE_DEVICE_ID (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_DIST_SCHEDULE:
|
|
pp_string (pp, "dist_schedule(static");
|
|
if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause))
|
|
{
|
|
pp_comma (pp);
|
|
dump_generic_node (pp,
|
|
OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause),
|
|
spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_PROC_BIND:
|
|
pp_string (pp, "proc_bind(");
|
|
switch (OMP_CLAUSE_PROC_BIND_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_PROC_BIND_MASTER:
|
|
/* Same enum value: case OMP_CLAUSE_PROC_BIND_PRIMARY: */
|
|
/* TODO: Change to 'primary' for OpenMP 5.1. */
|
|
pp_string (pp, "master");
|
|
break;
|
|
case OMP_CLAUSE_PROC_BIND_CLOSE:
|
|
pp_string (pp, "close");
|
|
break;
|
|
case OMP_CLAUSE_PROC_BIND_SPREAD:
|
|
pp_string (pp, "spread");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_DEVICE_TYPE:
|
|
pp_string (pp, "device_type(");
|
|
switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_DEVICE_TYPE_HOST:
|
|
pp_string (pp, "host");
|
|
break;
|
|
case OMP_CLAUSE_DEVICE_TYPE_NOHOST:
|
|
pp_string (pp, "nohost");
|
|
break;
|
|
case OMP_CLAUSE_DEVICE_TYPE_ANY:
|
|
pp_string (pp, "any");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_SAFELEN:
|
|
pp_string (pp, "safelen(");
|
|
dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_SIMDLEN:
|
|
pp_string (pp, "simdlen(");
|
|
dump_generic_node (pp, OMP_CLAUSE_SIMDLEN_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_PRIORITY:
|
|
pp_string (pp, "priority(");
|
|
dump_generic_node (pp, OMP_CLAUSE_PRIORITY_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_GRAINSIZE:
|
|
pp_string (pp, "grainsize(");
|
|
if (OMP_CLAUSE_GRAINSIZE_STRICT (clause))
|
|
pp_string (pp, "strict:");
|
|
dump_generic_node (pp, OMP_CLAUSE_GRAINSIZE_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_NUM_TASKS:
|
|
pp_string (pp, "num_tasks(");
|
|
if (OMP_CLAUSE_NUM_TASKS_STRICT (clause))
|
|
pp_string (pp, "strict:");
|
|
dump_generic_node (pp, OMP_CLAUSE_NUM_TASKS_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_HINT:
|
|
pp_string (pp, "hint(");
|
|
dump_generic_node (pp, OMP_CLAUSE_HINT_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_FILTER:
|
|
pp_string (pp, "filter(");
|
|
dump_generic_node (pp, OMP_CLAUSE_FILTER_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_DEFAULTMAP:
|
|
pp_string (pp, "defaultmap(");
|
|
switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (clause))
|
|
{
|
|
case OMP_CLAUSE_DEFAULTMAP_ALLOC:
|
|
pp_string (pp, "alloc");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_TO:
|
|
pp_string (pp, "to");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_FROM:
|
|
pp_string (pp, "from");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_TOFROM:
|
|
pp_string (pp, "tofrom");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE:
|
|
pp_string (pp, "firstprivate");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_NONE:
|
|
pp_string (pp, "none");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_DEFAULT:
|
|
pp_string (pp, "default");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (clause))
|
|
{
|
|
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
|
|
pp_string (pp, ":scalar");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
|
|
pp_string (pp, ":aggregate");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE:
|
|
pp_string (pp, ":allocatable");
|
|
break;
|
|
case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
|
|
pp_string (pp, ":pointer");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_ORDER:
|
|
pp_string (pp, "order(concurrent)");
|
|
break;
|
|
|
|
case OMP_CLAUSE_BIND:
|
|
pp_string (pp, "bind(");
|
|
switch (OMP_CLAUSE_BIND_KIND (clause))
|
|
{
|
|
case OMP_CLAUSE_BIND_TEAMS:
|
|
pp_string (pp, "teams");
|
|
break;
|
|
case OMP_CLAUSE_BIND_PARALLEL:
|
|
pp_string (pp, "parallel");
|
|
break;
|
|
case OMP_CLAUSE_BIND_THREAD:
|
|
pp_string (pp, "thread");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE__SIMDUID_:
|
|
pp_string (pp, "_simduid_(");
|
|
dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE__SIMT_:
|
|
pp_string (pp, "_simt_");
|
|
break;
|
|
|
|
case OMP_CLAUSE_GANG:
|
|
pp_string (pp, "gang");
|
|
if (OMP_CLAUSE_GANG_EXPR (clause) != NULL_TREE)
|
|
{
|
|
pp_string (pp, "(num: ");
|
|
dump_generic_node (pp, OMP_CLAUSE_GANG_EXPR (clause),
|
|
spc, flags, false);
|
|
}
|
|
if (OMP_CLAUSE_GANG_STATIC_EXPR (clause) != NULL_TREE)
|
|
{
|
|
if (OMP_CLAUSE_GANG_EXPR (clause) == NULL_TREE)
|
|
pp_left_paren (pp);
|
|
else
|
|
pp_space (pp);
|
|
pp_string (pp, "static:");
|
|
if (OMP_CLAUSE_GANG_STATIC_EXPR (clause)
|
|
== integer_minus_one_node)
|
|
pp_character (pp, '*');
|
|
else
|
|
dump_generic_node (pp, OMP_CLAUSE_GANG_STATIC_EXPR (clause),
|
|
spc, flags, false);
|
|
}
|
|
if (OMP_CLAUSE_GANG_EXPR (clause) != NULL_TREE
|
|
|| OMP_CLAUSE_GANG_STATIC_EXPR (clause) != NULL_TREE)
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_ASYNC:
|
|
pp_string (pp, "async");
|
|
if (OMP_CLAUSE_ASYNC_EXPR (clause))
|
|
{
|
|
pp_character(pp, '(');
|
|
dump_generic_node (pp, OMP_CLAUSE_ASYNC_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_character(pp, ')');
|
|
}
|
|
break;
|
|
|
|
case OMP_CLAUSE_AUTO:
|
|
case OMP_CLAUSE_SEQ:
|
|
pp_string (pp, omp_clause_code_name[OMP_CLAUSE_CODE (clause)]);
|
|
break;
|
|
|
|
case OMP_CLAUSE_WAIT:
|
|
pp_string (pp, "wait(");
|
|
dump_generic_node (pp, OMP_CLAUSE_WAIT_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_character(pp, ')');
|
|
break;
|
|
|
|
case OMP_CLAUSE_WORKER:
|
|
pp_string (pp, "worker");
|
|
if (OMP_CLAUSE_WORKER_EXPR (clause) != NULL_TREE)
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_WORKER_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
break;
|
|
|
|
case OMP_CLAUSE_VECTOR:
|
|
pp_string (pp, "vector");
|
|
if (OMP_CLAUSE_VECTOR_EXPR (clause) != NULL_TREE)
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, OMP_CLAUSE_VECTOR_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
break;
|
|
|
|
case OMP_CLAUSE_NUM_GANGS:
|
|
pp_string (pp, "num_gangs(");
|
|
dump_generic_node (pp, OMP_CLAUSE_NUM_GANGS_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_character (pp, ')');
|
|
break;
|
|
|
|
case OMP_CLAUSE_NUM_WORKERS:
|
|
pp_string (pp, "num_workers(");
|
|
dump_generic_node (pp, OMP_CLAUSE_NUM_WORKERS_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_character (pp, ')');
|
|
break;
|
|
|
|
case OMP_CLAUSE_VECTOR_LENGTH:
|
|
pp_string (pp, "vector_length(");
|
|
dump_generic_node (pp, OMP_CLAUSE_VECTOR_LENGTH_EXPR (clause),
|
|
spc, flags, false);
|
|
pp_character (pp, ')');
|
|
break;
|
|
|
|
case OMP_CLAUSE_INBRANCH:
|
|
pp_string (pp, "inbranch");
|
|
break;
|
|
case OMP_CLAUSE_NOTINBRANCH:
|
|
pp_string (pp, "notinbranch");
|
|
break;
|
|
case OMP_CLAUSE_FOR:
|
|
pp_string (pp, "for");
|
|
break;
|
|
case OMP_CLAUSE_PARALLEL:
|
|
pp_string (pp, "parallel");
|
|
break;
|
|
case OMP_CLAUSE_SECTIONS:
|
|
pp_string (pp, "sections");
|
|
break;
|
|
case OMP_CLAUSE_TASKGROUP:
|
|
pp_string (pp, "taskgroup");
|
|
break;
|
|
case OMP_CLAUSE_NOGROUP:
|
|
pp_string (pp, "nogroup");
|
|
break;
|
|
case OMP_CLAUSE_THREADS:
|
|
pp_string (pp, "threads");
|
|
break;
|
|
case OMP_CLAUSE_SIMD:
|
|
pp_string (pp, "simd");
|
|
break;
|
|
case OMP_CLAUSE_INDEPENDENT:
|
|
pp_string (pp, "independent");
|
|
break;
|
|
case OMP_CLAUSE_TILE:
|
|
pp_string (pp, "tile(");
|
|
dump_generic_node (pp, OMP_CLAUSE_TILE_LIST (clause),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case OMP_CLAUSE_IF_PRESENT:
|
|
pp_string (pp, "if_present");
|
|
break;
|
|
case OMP_CLAUSE_FINALIZE:
|
|
pp_string (pp, "finalize");
|
|
break;
|
|
case OMP_CLAUSE_NOHOST:
|
|
pp_string (pp, "nohost");
|
|
break;
|
|
case OMP_CLAUSE_DETACH:
|
|
pp_string (pp, "detach(");
|
|
dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags,
|
|
false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
}
|
|
|
|
|
|
/* Dump chain of OMP clauses.
|
|
|
|
PP, SPC and FLAGS are as in dump_generic_node. */
|
|
|
|
void
|
|
dump_omp_clauses (pretty_printer *pp, tree clause, int spc, dump_flags_t flags,
|
|
bool leading_space)
|
|
{
|
|
while (clause)
|
|
{
|
|
if (leading_space)
|
|
pp_space (pp);
|
|
dump_omp_clause (pp, clause, spc, flags);
|
|
leading_space = true;
|
|
|
|
clause = OMP_CLAUSE_CHAIN (clause);
|
|
}
|
|
}
|
|
|
|
|
|
/* Dump location LOC to PP. */
|
|
|
|
void
|
|
dump_location (pretty_printer *pp, location_t loc)
|
|
{
|
|
expanded_location xloc = expand_location (loc);
|
|
|
|
pp_left_bracket (pp);
|
|
if (xloc.file)
|
|
{
|
|
pp_string (pp, xloc.file);
|
|
pp_string (pp, ":");
|
|
}
|
|
pp_decimal_int (pp, xloc.line);
|
|
pp_colon (pp);
|
|
pp_decimal_int (pp, xloc.column);
|
|
pp_string (pp, "] ");
|
|
}
|
|
|
|
|
|
/* Dump lexical block BLOCK. PP, SPC and FLAGS are as in
|
|
dump_generic_node. */
|
|
|
|
static void
|
|
dump_block_node (pretty_printer *pp, tree block, int spc, dump_flags_t flags)
|
|
{
|
|
tree t;
|
|
|
|
pp_string (pp, "BLOCK #");
|
|
pp_decimal_int (pp, BLOCK_NUMBER (block));
|
|
pp_character (pp, ' ');
|
|
|
|
if (flags & TDF_ADDRESS)
|
|
{
|
|
pp_character (pp, '[');
|
|
pp_scalar (pp, "%p", (void *) block);
|
|
pp_string (pp, "] ");
|
|
}
|
|
|
|
if (TREE_ASM_WRITTEN (block))
|
|
pp_string (pp, "[written] ");
|
|
|
|
if (flags & TDF_SLIM)
|
|
return;
|
|
|
|
if (BLOCK_SOURCE_LOCATION (block))
|
|
dump_location (pp, BLOCK_SOURCE_LOCATION (block));
|
|
|
|
newline_and_indent (pp, spc + 2);
|
|
|
|
if (BLOCK_SUPERCONTEXT (block))
|
|
{
|
|
pp_string (pp, "SUPERCONTEXT: ");
|
|
dump_generic_node (pp, BLOCK_SUPERCONTEXT (block), 0,
|
|
flags | TDF_SLIM, false);
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_SUBBLOCKS (block))
|
|
{
|
|
pp_string (pp, "SUBBLOCKS: ");
|
|
for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
|
|
{
|
|
dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
|
|
pp_space (pp);
|
|
}
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_CHAIN (block))
|
|
{
|
|
pp_string (pp, "SIBLINGS: ");
|
|
for (t = BLOCK_CHAIN (block); t; t = BLOCK_CHAIN (t))
|
|
{
|
|
dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
|
|
pp_space (pp);
|
|
}
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_VARS (block))
|
|
{
|
|
pp_string (pp, "VARS: ");
|
|
for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
|
|
{
|
|
dump_generic_node (pp, t, 0, flags, false);
|
|
pp_space (pp);
|
|
}
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (vec_safe_length (BLOCK_NONLOCALIZED_VARS (block)) > 0)
|
|
{
|
|
unsigned i;
|
|
vec<tree, va_gc> *nlv = BLOCK_NONLOCALIZED_VARS (block);
|
|
|
|
pp_string (pp, "NONLOCALIZED_VARS: ");
|
|
FOR_EACH_VEC_ELT (*nlv, i, t)
|
|
{
|
|
dump_generic_node (pp, t, 0, flags, false);
|
|
pp_space (pp);
|
|
}
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_ABSTRACT_ORIGIN (block))
|
|
{
|
|
pp_string (pp, "ABSTRACT_ORIGIN: ");
|
|
dump_generic_node (pp, BLOCK_ABSTRACT_ORIGIN (block), 0,
|
|
flags | TDF_SLIM, false);
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_FRAGMENT_ORIGIN (block))
|
|
{
|
|
pp_string (pp, "FRAGMENT_ORIGIN: ");
|
|
dump_generic_node (pp, BLOCK_FRAGMENT_ORIGIN (block), 0,
|
|
flags | TDF_SLIM, false);
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
|
|
if (BLOCK_FRAGMENT_CHAIN (block))
|
|
{
|
|
pp_string (pp, "FRAGMENT_CHAIN: ");
|
|
for (t = BLOCK_FRAGMENT_CHAIN (block); t; t = BLOCK_FRAGMENT_CHAIN (t))
|
|
{
|
|
dump_generic_node (pp, t, 0, flags | TDF_SLIM, false);
|
|
pp_space (pp);
|
|
}
|
|
newline_and_indent (pp, spc + 2);
|
|
}
|
|
}
|
|
|
|
/* Dump #pragma omp atomic memory order clause. */
|
|
|
|
void
|
|
dump_omp_atomic_memory_order (pretty_printer *pp, enum omp_memory_order mo)
|
|
{
|
|
switch (mo)
|
|
{
|
|
case OMP_MEMORY_ORDER_RELAXED:
|
|
pp_string (pp, " relaxed");
|
|
break;
|
|
case OMP_MEMORY_ORDER_SEQ_CST:
|
|
pp_string (pp, " seq_cst");
|
|
break;
|
|
case OMP_MEMORY_ORDER_ACQ_REL:
|
|
pp_string (pp, " acq_rel");
|
|
break;
|
|
case OMP_MEMORY_ORDER_ACQUIRE:
|
|
pp_string (pp, " acquire");
|
|
break;
|
|
case OMP_MEMORY_ORDER_RELEASE:
|
|
pp_string (pp, " release");
|
|
break;
|
|
case OMP_MEMORY_ORDER_UNSPECIFIED:
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
}
|
|
|
|
/* Helper to dump a MEM_REF node. */
|
|
|
|
static void
|
|
dump_mem_ref (pretty_printer *pp, tree node, int spc, dump_flags_t flags)
|
|
{
|
|
if (TREE_CODE (node) == MEM_REF && (flags & TDF_GIMPLE))
|
|
{
|
|
pp_string (pp, "__MEM <");
|
|
dump_generic_node (pp, TREE_TYPE (node),
|
|
spc, flags | TDF_SLIM, false);
|
|
if (TYPE_ALIGN (TREE_TYPE (node))
|
|
!= TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node))))
|
|
{
|
|
pp_string (pp, ", ");
|
|
pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
|
|
}
|
|
pp_greater (pp);
|
|
pp_string (pp, " (");
|
|
if (TREE_TYPE (TREE_OPERAND (node, 0))
|
|
!= TREE_TYPE (TREE_OPERAND (node, 1)))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_TYPE (TREE_OPERAND (node, 1)),
|
|
spc, flags | TDF_SLIM, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0),
|
|
spc, flags | TDF_SLIM, false);
|
|
if (! integer_zerop (TREE_OPERAND (node, 1)))
|
|
{
|
|
pp_string (pp, " + ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1),
|
|
spc, flags | TDF_SLIM, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
}
|
|
else if (TREE_CODE (node) == MEM_REF
|
|
&& integer_zerop (TREE_OPERAND (node, 1))
|
|
/* Dump the types of INTEGER_CSTs explicitly, for we can't
|
|
infer them and MEM_ATTR caching will share MEM_REFs
|
|
with differently-typed op0s. */
|
|
&& TREE_CODE (TREE_OPERAND (node, 0)) != INTEGER_CST
|
|
/* Released SSA_NAMES have no TREE_TYPE. */
|
|
&& TREE_TYPE (TREE_OPERAND (node, 0)) != NULL_TREE
|
|
/* Same pointer types, but ignoring POINTER_TYPE vs.
|
|
REFERENCE_TYPE. */
|
|
&& (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 0)))
|
|
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))
|
|
&& (TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 0)))
|
|
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 1))))
|
|
&& (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 0)))
|
|
== TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 1))))
|
|
/* Same value types ignoring qualifiers. */
|
|
&& (TYPE_MAIN_VARIANT (TREE_TYPE (node))
|
|
== TYPE_MAIN_VARIANT
|
|
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1)))))
|
|
&& (!(flags & TDF_ALIAS)
|
|
|| MR_DEPENDENCE_CLIQUE (node) == 0))
|
|
{
|
|
if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
|
|
{
|
|
/* Enclose pointers to arrays in parentheses. */
|
|
tree op0 = TREE_OPERAND (node, 0);
|
|
tree op0type = TREE_TYPE (op0);
|
|
if (POINTER_TYPE_P (op0type)
|
|
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
|
|
pp_left_paren (pp);
|
|
pp_star (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
if (POINTER_TYPE_P (op0type)
|
|
&& TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE)
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp,
|
|
TREE_OPERAND (TREE_OPERAND (node, 0), 0),
|
|
spc, flags, false);
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "MEM");
|
|
|
|
tree nodetype = TREE_TYPE (node);
|
|
tree op0 = TREE_OPERAND (node, 0);
|
|
tree op1 = TREE_OPERAND (node, 1);
|
|
tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
|
|
|
|
tree op0size = TYPE_SIZE (nodetype);
|
|
tree op1size = TYPE_SIZE (TREE_TYPE (op1type));
|
|
|
|
if (!op0size || !op1size
|
|
|| !operand_equal_p (op0size, op1size, 0))
|
|
{
|
|
pp_string (pp, " <");
|
|
/* If the size of the type of the operand is not the same
|
|
as the size of the MEM_REF expression include the type
|
|
of the latter similar to the TDF_GIMPLE output to make
|
|
it clear how many bytes of memory are being accessed. */
|
|
dump_generic_node (pp, nodetype, spc, flags | TDF_SLIM, false);
|
|
pp_string (pp, "> ");
|
|
}
|
|
|
|
pp_string (pp, "[(");
|
|
dump_generic_node (pp, op1type, spc, flags | TDF_SLIM, false);
|
|
pp_right_paren (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
if (!integer_zerop (op1))
|
|
{
|
|
pp_string (pp, " + ");
|
|
dump_generic_node (pp, op1, spc, flags, false);
|
|
}
|
|
if (TREE_CODE (node) == TARGET_MEM_REF)
|
|
{
|
|
tree tmp = TMR_INDEX2 (node);
|
|
if (tmp)
|
|
{
|
|
pp_string (pp, " + ");
|
|
dump_generic_node (pp, tmp, spc, flags, false);
|
|
}
|
|
tmp = TMR_INDEX (node);
|
|
if (tmp)
|
|
{
|
|
pp_string (pp, " + ");
|
|
dump_generic_node (pp, tmp, spc, flags, false);
|
|
tmp = TMR_STEP (node);
|
|
pp_string (pp, " * ");
|
|
if (tmp)
|
|
dump_generic_node (pp, tmp, spc, flags, false);
|
|
else
|
|
pp_string (pp, "1");
|
|
}
|
|
}
|
|
if ((flags & TDF_ALIAS)
|
|
&& MR_DEPENDENCE_CLIQUE (node) != 0)
|
|
{
|
|
pp_string (pp, " clique ");
|
|
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_CLIQUE (node));
|
|
pp_string (pp, " base ");
|
|
pp_unsigned_wide_integer (pp, MR_DEPENDENCE_BASE (node));
|
|
}
|
|
pp_right_bracket (pp);
|
|
}
|
|
}
|
|
|
|
/* Helper function for dump_generic_node. Dump INIT or COND expression for
|
|
OpenMP loop non-rectangular iterators. */
|
|
|
|
void
|
|
dump_omp_loop_non_rect_expr (pretty_printer *pp, tree node, int spc,
|
|
dump_flags_t flags)
|
|
{
|
|
gcc_assert (TREE_CODE (node) == TREE_VEC);
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, 0), spc, flags, false);
|
|
pp_string (pp, " * ");
|
|
if (op_prio (TREE_VEC_ELT (node, 1)) <= op_code_prio (MULT_EXPR))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, 1), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, 1), spc, flags, false);
|
|
pp_string (pp, " + ");
|
|
if (op_prio (TREE_VEC_ELT (node, 1)) <= op_code_prio (PLUS_EXPR))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, 2), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, 2), spc, flags, false);
|
|
}
|
|
|
|
/* Dump the node NODE on the pretty_printer PP, SPC spaces of
|
|
indent. FLAGS specifies details to show in the dump (see TDF_* in
|
|
dumpfile.h). If IS_STMT is true, the object printed is considered
|
|
to be a statement and it is terminated by ';' if appropriate. */
|
|
|
|
int
|
|
dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
|
|
bool is_stmt)
|
|
{
|
|
tree type;
|
|
tree op0, op1;
|
|
const char *str;
|
|
bool is_expr;
|
|
enum tree_code code;
|
|
|
|
if (node == NULL_TREE)
|
|
return spc;
|
|
|
|
is_expr = EXPR_P (node);
|
|
|
|
if (is_stmt && (flags & TDF_STMTADDR))
|
|
{
|
|
pp_string (pp, "<&");
|
|
pp_scalar (pp, "%p", (void *)node);
|
|
pp_string (pp, "> ");
|
|
}
|
|
|
|
if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
|
|
dump_location (pp, EXPR_LOCATION (node));
|
|
|
|
code = TREE_CODE (node);
|
|
switch (code)
|
|
{
|
|
case ERROR_MARK:
|
|
pp_string (pp, "<<< error >>>");
|
|
break;
|
|
|
|
case IDENTIFIER_NODE:
|
|
pp_tree_identifier (pp, node);
|
|
break;
|
|
|
|
case TREE_LIST:
|
|
while (node && node != error_mark_node)
|
|
{
|
|
if (TREE_PURPOSE (node))
|
|
{
|
|
dump_generic_node (pp, TREE_PURPOSE (node), spc, flags, false);
|
|
pp_space (pp);
|
|
}
|
|
dump_generic_node (pp, TREE_VALUE (node), spc, flags, false);
|
|
node = TREE_CHAIN (node);
|
|
if (node && TREE_CODE (node) == TREE_LIST)
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TREE_BINFO:
|
|
dump_generic_node (pp, BINFO_TYPE (node), spc, flags, false);
|
|
break;
|
|
|
|
case TREE_VEC:
|
|
{
|
|
size_t i;
|
|
if (TREE_VEC_LENGTH (node) > 0)
|
|
{
|
|
size_t len = TREE_VEC_LENGTH (node);
|
|
for (i = 0; i < len - 1; i++)
|
|
{
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, i), spc, flags,
|
|
false);
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
dump_generic_node (pp, TREE_VEC_ELT (node, len - 1), spc,
|
|
flags, false);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VOID_TYPE:
|
|
case INTEGER_TYPE:
|
|
case REAL_TYPE:
|
|
case FIXED_POINT_TYPE:
|
|
case COMPLEX_TYPE:
|
|
case VECTOR_TYPE:
|
|
case ENUMERAL_TYPE:
|
|
case BOOLEAN_TYPE:
|
|
case OPAQUE_TYPE:
|
|
{
|
|
unsigned int quals = TYPE_QUALS (node);
|
|
enum tree_code_class tclass;
|
|
|
|
if (quals & TYPE_QUAL_ATOMIC)
|
|
pp_string (pp, "atomic ");
|
|
if (quals & TYPE_QUAL_CONST)
|
|
pp_string (pp, "const ");
|
|
if (quals & TYPE_QUAL_VOLATILE)
|
|
pp_string (pp, "volatile ");
|
|
if (quals & TYPE_QUAL_RESTRICT)
|
|
pp_string (pp, "restrict ");
|
|
|
|
if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
|
|
{
|
|
pp_string (pp, "<address-space-");
|
|
pp_decimal_int (pp, TYPE_ADDR_SPACE (node));
|
|
pp_string (pp, "> ");
|
|
}
|
|
|
|
tclass = TREE_CODE_CLASS (TREE_CODE (node));
|
|
|
|
if (tclass == tcc_declaration)
|
|
{
|
|
if (DECL_NAME (node))
|
|
dump_decl_name (pp, node, flags);
|
|
else
|
|
pp_string (pp, "<unnamed type decl>");
|
|
}
|
|
else if (tclass == tcc_type)
|
|
{
|
|
if (TYPE_NAME (node))
|
|
{
|
|
if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
|
|
pp_tree_identifier (pp, TYPE_NAME (node));
|
|
else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
|
|
&& DECL_NAME (TYPE_NAME (node)))
|
|
dump_decl_name (pp, TYPE_NAME (node), flags);
|
|
else
|
|
pp_string (pp, "<unnamed type>");
|
|
}
|
|
else if (TREE_CODE (node) == VECTOR_TYPE)
|
|
{
|
|
pp_string (pp, "vector");
|
|
pp_left_paren (pp);
|
|
pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (node));
|
|
pp_string (pp, ") ");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
}
|
|
else if (TREE_CODE (node) == INTEGER_TYPE)
|
|
{
|
|
if (TYPE_PRECISION (node) == CHAR_TYPE_SIZE)
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "unsigned char"
|
|
: "signed char"));
|
|
else if (TYPE_PRECISION (node) == SHORT_TYPE_SIZE)
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "unsigned short"
|
|
: "signed short"));
|
|
else if (TYPE_PRECISION (node) == INT_TYPE_SIZE)
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "unsigned int"
|
|
: "signed int"));
|
|
else if (TYPE_PRECISION (node) == LONG_TYPE_SIZE)
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "unsigned long"
|
|
: "signed long"));
|
|
else if (TYPE_PRECISION (node) == LONG_LONG_TYPE_SIZE)
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "unsigned long long"
|
|
: "signed long long"));
|
|
else if (TYPE_PRECISION (node) >= CHAR_TYPE_SIZE
|
|
&& pow2p_hwi (TYPE_PRECISION (node)))
|
|
{
|
|
pp_string (pp, (TYPE_UNSIGNED (node) ? "uint" : "int"));
|
|
pp_decimal_int (pp, TYPE_PRECISION (node));
|
|
pp_string (pp, "_t");
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "<unnamed-unsigned:"
|
|
: "<unnamed-signed:"));
|
|
pp_decimal_int (pp, TYPE_PRECISION (node));
|
|
pp_greater (pp);
|
|
}
|
|
}
|
|
else if (TREE_CODE (node) == COMPLEX_TYPE)
|
|
{
|
|
pp_string (pp, "__complex__ ");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
}
|
|
else if (TREE_CODE (node) == REAL_TYPE)
|
|
{
|
|
pp_string (pp, "<float:");
|
|
pp_decimal_int (pp, TYPE_PRECISION (node));
|
|
pp_greater (pp);
|
|
}
|
|
else if (TREE_CODE (node) == FIXED_POINT_TYPE)
|
|
{
|
|
pp_string (pp, "<fixed-point-");
|
|
pp_string (pp, TYPE_SATURATING (node) ? "sat:" : "nonsat:");
|
|
pp_decimal_int (pp, TYPE_PRECISION (node));
|
|
pp_greater (pp);
|
|
}
|
|
else if (TREE_CODE (node) == BOOLEAN_TYPE)
|
|
{
|
|
pp_string (pp, (TYPE_UNSIGNED (node)
|
|
? "<unsigned-boolean:"
|
|
: "<signed-boolean:"));
|
|
pp_decimal_int (pp, TYPE_PRECISION (node));
|
|
pp_greater (pp);
|
|
}
|
|
else if (TREE_CODE (node) == VOID_TYPE)
|
|
pp_string (pp, "void");
|
|
else
|
|
pp_string (pp, "<unnamed type>");
|
|
}
|
|
break;
|
|
}
|
|
|
|
case POINTER_TYPE:
|
|
case REFERENCE_TYPE:
|
|
str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&");
|
|
|
|
if (TREE_TYPE (node) == NULL)
|
|
{
|
|
pp_string (pp, str);
|
|
pp_string (pp, "<null type>");
|
|
}
|
|
else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
|
|
{
|
|
tree fnode = TREE_TYPE (node);
|
|
|
|
dump_generic_node (pp, TREE_TYPE (fnode), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_left_paren (pp);
|
|
pp_string (pp, str);
|
|
if (TYPE_IDENTIFIER (node))
|
|
dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
|
|
else if (flags & TDF_NOUID)
|
|
pp_string (pp, "<Txxxx>");
|
|
else
|
|
{
|
|
pp_string (pp, "<T");
|
|
pp_scalar (pp, "%x", TYPE_UID (node));
|
|
pp_character (pp, '>');
|
|
}
|
|
|
|
pp_right_paren (pp);
|
|
dump_function_declaration (pp, fnode, spc, flags);
|
|
}
|
|
else
|
|
{
|
|
unsigned int quals = TYPE_QUALS (node);
|
|
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_string (pp, str);
|
|
|
|
if (quals & TYPE_QUAL_CONST)
|
|
pp_string (pp, " const");
|
|
if (quals & TYPE_QUAL_VOLATILE)
|
|
pp_string (pp, " volatile");
|
|
if (quals & TYPE_QUAL_RESTRICT)
|
|
pp_string (pp, " restrict");
|
|
|
|
if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
|
|
{
|
|
pp_string (pp, " <address-space-");
|
|
pp_decimal_int (pp, TYPE_ADDR_SPACE (node));
|
|
pp_greater (pp);
|
|
}
|
|
|
|
if (TYPE_REF_CAN_ALIAS_ALL (node))
|
|
pp_string (pp, " {ref-all}");
|
|
}
|
|
break;
|
|
|
|
case OFFSET_TYPE:
|
|
NIY;
|
|
break;
|
|
|
|
case MEM_REF:
|
|
case TARGET_MEM_REF:
|
|
dump_mem_ref (pp, node, spc, flags);
|
|
break;
|
|
|
|
case ARRAY_TYPE:
|
|
{
|
|
unsigned int quals = TYPE_QUALS (node);
|
|
tree tmp;
|
|
|
|
if (quals & TYPE_QUAL_ATOMIC)
|
|
pp_string (pp, "atomic ");
|
|
if (quals & TYPE_QUAL_CONST)
|
|
pp_string (pp, "const ");
|
|
if (quals & TYPE_QUAL_VOLATILE)
|
|
pp_string (pp, "volatile ");
|
|
|
|
/* Print the innermost component type. */
|
|
for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
|
|
tmp = TREE_TYPE (tmp))
|
|
;
|
|
dump_generic_node (pp, tmp, spc, flags, false);
|
|
|
|
/* Print the dimensions. */
|
|
for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE; tmp = TREE_TYPE (tmp))
|
|
dump_array_domain (pp, TYPE_DOMAIN (tmp), spc, flags);
|
|
break;
|
|
}
|
|
|
|
case RECORD_TYPE:
|
|
case UNION_TYPE:
|
|
case QUAL_UNION_TYPE:
|
|
{
|
|
unsigned int quals = TYPE_QUALS (node);
|
|
|
|
if (quals & TYPE_QUAL_ATOMIC)
|
|
pp_string (pp, "atomic ");
|
|
if (quals & TYPE_QUAL_CONST)
|
|
pp_string (pp, "const ");
|
|
if (quals & TYPE_QUAL_VOLATILE)
|
|
pp_string (pp, "volatile ");
|
|
|
|
if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node)))
|
|
{
|
|
pp_string (pp, "<address-space-");
|
|
pp_decimal_int (pp, TYPE_ADDR_SPACE (node));
|
|
pp_string (pp, "> ");
|
|
}
|
|
|
|
/* Print the name of the structure. */
|
|
if (TREE_CODE (node) == RECORD_TYPE)
|
|
pp_string (pp, "struct ");
|
|
else if (TREE_CODE (node) == UNION_TYPE)
|
|
pp_string (pp, "union ");
|
|
|
|
if (TYPE_NAME (node))
|
|
dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
|
|
else if (!(flags & TDF_SLIM))
|
|
/* FIXME: If we eliminate the 'else' above and attempt
|
|
to show the fields for named types, we may get stuck
|
|
following a cycle of pointers to structs. The alleged
|
|
self-reference check in print_struct_decl will not detect
|
|
cycles involving more than one pointer or struct type. */
|
|
print_struct_decl (pp, node, spc, flags);
|
|
break;
|
|
}
|
|
|
|
case LANG_TYPE:
|
|
NIY;
|
|
break;
|
|
|
|
case INTEGER_CST:
|
|
if (flags & TDF_GIMPLE
|
|
&& (POINTER_TYPE_P (TREE_TYPE (node))
|
|
|| (TYPE_PRECISION (TREE_TYPE (node))
|
|
< TYPE_PRECISION (integer_type_node))
|
|
|| exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1
|
|
|| tree_int_cst_sgn (node) < 0))
|
|
{
|
|
pp_string (pp, "_Literal (");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_string (pp, ") ");
|
|
}
|
|
if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
|
|
&& ! (flags & TDF_GIMPLE))
|
|
{
|
|
/* In the case of a pointer, one may want to divide by the
|
|
size of the pointed-to type. Unfortunately, this not
|
|
straightforward. The C front-end maps expressions
|
|
|
|
(int *) 5
|
|
int *p; (p + 5)
|
|
|
|
in such a way that the two INTEGER_CST nodes for "5" have
|
|
different values but identical types. In the latter
|
|
case, the 5 is multiplied by sizeof (int) in c-common.c
|
|
(pointer_int_sum) to convert it to a byte address, and
|
|
yet the type of the node is left unchanged. Argh. What
|
|
is consistent though is that the number value corresponds
|
|
to bytes (UNITS) offset.
|
|
|
|
NB: Neither of the following divisors can be trivially
|
|
used to recover the original literal:
|
|
|
|
TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
|
|
TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node))) */
|
|
pp_wide_integer (pp, TREE_INT_CST_LOW (node));
|
|
pp_string (pp, "B"); /* pseudo-unit */
|
|
}
|
|
else if (tree_fits_shwi_p (node))
|
|
pp_wide_integer (pp, tree_to_shwi (node));
|
|
else if (tree_fits_uhwi_p (node))
|
|
pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
|
|
else
|
|
{
|
|
wide_int val = wi::to_wide (node);
|
|
|
|
if (wi::neg_p (val, TYPE_SIGN (TREE_TYPE (node))))
|
|
{
|
|
pp_minus (pp);
|
|
val = -val;
|
|
}
|
|
print_hex (val, pp_buffer (pp)->digit_buffer);
|
|
pp_string (pp, pp_buffer (pp)->digit_buffer);
|
|
}
|
|
if ((flags & TDF_GIMPLE)
|
|
&& ! (POINTER_TYPE_P (TREE_TYPE (node))
|
|
|| (TYPE_PRECISION (TREE_TYPE (node))
|
|
< TYPE_PRECISION (integer_type_node))
|
|
|| exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
|
|
{
|
|
if (TYPE_UNSIGNED (TREE_TYPE (node)))
|
|
pp_character (pp, 'u');
|
|
if (TYPE_PRECISION (TREE_TYPE (node))
|
|
== TYPE_PRECISION (unsigned_type_node))
|
|
;
|
|
else if (TYPE_PRECISION (TREE_TYPE (node))
|
|
== TYPE_PRECISION (long_unsigned_type_node))
|
|
pp_character (pp, 'l');
|
|
else if (TYPE_PRECISION (TREE_TYPE (node))
|
|
== TYPE_PRECISION (long_long_unsigned_type_node))
|
|
pp_string (pp, "ll");
|
|
}
|
|
if (TREE_OVERFLOW (node))
|
|
pp_string (pp, "(OVF)");
|
|
break;
|
|
|
|
case POLY_INT_CST:
|
|
pp_string (pp, "POLY_INT_CST [");
|
|
dump_generic_node (pp, POLY_INT_CST_COEFF (node, 0), spc, flags, false);
|
|
for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
|
|
{
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, POLY_INT_CST_COEFF (node, i),
|
|
spc, flags, false);
|
|
}
|
|
pp_string (pp, "]");
|
|
break;
|
|
|
|
case REAL_CST:
|
|
/* Code copied from print_node. */
|
|
{
|
|
REAL_VALUE_TYPE d;
|
|
if (TREE_OVERFLOW (node))
|
|
pp_string (pp, " overflow");
|
|
|
|
d = TREE_REAL_CST (node);
|
|
if (REAL_VALUE_ISINF (d))
|
|
pp_string (pp, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf");
|
|
else if (REAL_VALUE_ISNAN (d))
|
|
pp_string (pp, " Nan");
|
|
else
|
|
{
|
|
char string[100];
|
|
real_to_decimal (string, &d, sizeof (string), 0, 1);
|
|
pp_string (pp, string);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case FIXED_CST:
|
|
{
|
|
char string[100];
|
|
fixed_to_decimal (string, TREE_FIXED_CST_PTR (node), sizeof (string));
|
|
pp_string (pp, string);
|
|
break;
|
|
}
|
|
|
|
case COMPLEX_CST:
|
|
pp_string (pp, "__complex__ (");
|
|
dump_generic_node (pp, TREE_REALPART (node), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_IMAGPART (node), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case STRING_CST:
|
|
{
|
|
pp_string (pp, "\"");
|
|
if (unsigned nbytes = TREE_STRING_LENGTH (node))
|
|
pretty_print_string (pp, TREE_STRING_POINTER (node), nbytes);
|
|
pp_string (pp, "\"");
|
|
break;
|
|
}
|
|
|
|
case VECTOR_CST:
|
|
{
|
|
unsigned i;
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_string (pp, "_Literal (");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_string (pp, ") ");
|
|
}
|
|
pp_string (pp, "{ ");
|
|
unsigned HOST_WIDE_INT nunits;
|
|
if (!VECTOR_CST_NELTS (node).is_constant (&nunits))
|
|
nunits = vector_cst_encoded_nelts (node);
|
|
for (i = 0; i < nunits; ++i)
|
|
{
|
|
if (i != 0)
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, VECTOR_CST_ELT (node, i),
|
|
spc, flags, false);
|
|
}
|
|
if (!VECTOR_CST_NELTS (node).is_constant ())
|
|
pp_string (pp, ", ...");
|
|
pp_string (pp, " }");
|
|
}
|
|
break;
|
|
|
|
case FUNCTION_TYPE:
|
|
case METHOD_TYPE:
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_space (pp);
|
|
if (TREE_CODE (node) == METHOD_TYPE)
|
|
{
|
|
if (TYPE_METHOD_BASETYPE (node))
|
|
dump_generic_node (pp, TYPE_NAME (TYPE_METHOD_BASETYPE (node)),
|
|
spc, flags, false);
|
|
else
|
|
pp_string (pp, "<null method basetype>");
|
|
pp_colon_colon (pp);
|
|
}
|
|
if (TYPE_IDENTIFIER (node))
|
|
dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
|
|
else if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
|
|
dump_decl_name (pp, TYPE_NAME (node), flags);
|
|
else if (flags & TDF_NOUID)
|
|
pp_string (pp, "<Txxxx>");
|
|
else
|
|
{
|
|
pp_string (pp, "<T");
|
|
pp_scalar (pp, "%x", TYPE_UID (node));
|
|
pp_character (pp, '>');
|
|
}
|
|
dump_function_declaration (pp, node, spc, flags);
|
|
break;
|
|
|
|
case FUNCTION_DECL:
|
|
case CONST_DECL:
|
|
dump_decl_name (pp, node, flags);
|
|
break;
|
|
|
|
case LABEL_DECL:
|
|
if (DECL_NAME (node))
|
|
dump_decl_name (pp, node, flags);
|
|
else if (LABEL_DECL_UID (node) != -1)
|
|
{
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_character (pp, 'L');
|
|
pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "<L");
|
|
pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
|
|
pp_character (pp, '>');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (flags & TDF_NOUID)
|
|
pp_string (pp, "<D.xxxx>");
|
|
else
|
|
{
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_character (pp, 'D');
|
|
pp_scalar (pp, "%u", DECL_UID (node));
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "<D.");
|
|
pp_scalar (pp, "%u", DECL_UID (node));
|
|
pp_character (pp, '>');
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TYPE_DECL:
|
|
if (DECL_IS_UNDECLARED_BUILTIN (node))
|
|
{
|
|
/* Don't print the declaration of built-in types. */
|
|
break;
|
|
}
|
|
if (DECL_NAME (node))
|
|
dump_decl_name (pp, node, flags);
|
|
else if (TYPE_NAME (TREE_TYPE (node)) != node)
|
|
{
|
|
pp_string (pp, (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
|
|
? "union" : "struct "));
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
}
|
|
else
|
|
pp_string (pp, "<anon>");
|
|
break;
|
|
|
|
case VAR_DECL:
|
|
case PARM_DECL:
|
|
case FIELD_DECL:
|
|
case DEBUG_EXPR_DECL:
|
|
case NAMESPACE_DECL:
|
|
case NAMELIST_DECL:
|
|
dump_decl_name (pp, node, flags);
|
|
break;
|
|
|
|
case RESULT_DECL:
|
|
pp_string (pp, "<retval>");
|
|
break;
|
|
|
|
case COMPONENT_REF:
|
|
op0 = TREE_OPERAND (node, 0);
|
|
str = ".";
|
|
if (op0
|
|
&& (TREE_CODE (op0) == INDIRECT_REF
|
|
|| (TREE_CODE (op0) == MEM_REF
|
|
&& TREE_CODE (TREE_OPERAND (op0, 0)) != ADDR_EXPR
|
|
&& integer_zerop (TREE_OPERAND (op0, 1))
|
|
/* Dump the types of INTEGER_CSTs explicitly, for we
|
|
can't infer them and MEM_ATTR caching will share
|
|
MEM_REFs with differently-typed op0s. */
|
|
&& TREE_CODE (TREE_OPERAND (op0, 0)) != INTEGER_CST
|
|
/* Released SSA_NAMES have no TREE_TYPE. */
|
|
&& TREE_TYPE (TREE_OPERAND (op0, 0)) != NULL_TREE
|
|
/* Same pointer types, but ignoring POINTER_TYPE vs.
|
|
REFERENCE_TYPE. */
|
|
&& (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0)))
|
|
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1))))
|
|
&& (TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)))
|
|
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 1))))
|
|
&& (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 0)))
|
|
== TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 1))))
|
|
/* Same value types ignoring qualifiers. */
|
|
&& (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
|
|
== TYPE_MAIN_VARIANT
|
|
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1)))))
|
|
&& MR_DEPENDENCE_CLIQUE (op0) == 0)))
|
|
{
|
|
op0 = TREE_OPERAND (op0, 0);
|
|
str = "->";
|
|
}
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_right_paren (pp);
|
|
pp_string (pp, str);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
op0 = component_ref_field_offset (node);
|
|
if (op0 && TREE_CODE (op0) != INTEGER_CST)
|
|
{
|
|
pp_string (pp, "{off: ");
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
pp_right_brace (pp);
|
|
}
|
|
break;
|
|
|
|
case BIT_FIELD_REF:
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_string (pp, "__BIT_FIELD_REF <");
|
|
dump_generic_node (pp, TREE_TYPE (node),
|
|
spc, flags | TDF_SLIM, false);
|
|
if (TYPE_ALIGN (TREE_TYPE (node))
|
|
!= TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node))))
|
|
{
|
|
pp_string (pp, ", ");
|
|
pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
|
|
}
|
|
pp_greater (pp);
|
|
pp_string (pp, " (");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc,
|
|
flags | TDF_SLIM, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc,
|
|
flags | TDF_SLIM, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc,
|
|
flags | TDF_SLIM, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "BIT_FIELD_REF <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_greater (pp);
|
|
}
|
|
break;
|
|
|
|
case BIT_INSERT_EXPR:
|
|
pp_string (pp, "BIT_INSERT_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " (");
|
|
if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 1))))
|
|
pp_decimal_int (pp,
|
|
TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (node, 1))));
|
|
else
|
|
dump_generic_node (pp, TYPE_SIZE (TREE_TYPE (TREE_OPERAND (node, 1))),
|
|
spc, flags, false);
|
|
pp_string (pp, " bits)>");
|
|
break;
|
|
|
|
case ARRAY_REF:
|
|
case ARRAY_RANGE_REF:
|
|
op0 = TREE_OPERAND (node, 0);
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_right_paren (pp);
|
|
pp_left_bracket (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
if (TREE_CODE (node) == ARRAY_RANGE_REF)
|
|
pp_string (pp, " ...");
|
|
pp_right_bracket (pp);
|
|
|
|
op0 = array_ref_low_bound (node);
|
|
op1 = array_ref_element_size (node);
|
|
|
|
if (!integer_zerop (op0)
|
|
|| TREE_OPERAND (node, 2)
|
|
|| TREE_OPERAND (node, 3))
|
|
{
|
|
pp_string (pp, "{lb: ");
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
pp_string (pp, " sz: ");
|
|
dump_generic_node (pp, op1, spc, flags, false);
|
|
pp_right_brace (pp);
|
|
}
|
|
break;
|
|
|
|
case CONSTRUCTOR:
|
|
{
|
|
unsigned HOST_WIDE_INT ix;
|
|
tree field, val;
|
|
bool is_struct_init = false;
|
|
bool is_array_init = false;
|
|
widest_int curidx;
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_string (pp, "_Literal (");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_string (pp, ") ");
|
|
}
|
|
pp_left_brace (pp);
|
|
if (TREE_CLOBBER_P (node))
|
|
pp_string (pp, "CLOBBER");
|
|
else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
|
|
|| TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
|
|
is_struct_init = true;
|
|
else if (TREE_CODE (TREE_TYPE (node)) == ARRAY_TYPE
|
|
&& TYPE_DOMAIN (TREE_TYPE (node))
|
|
&& TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)))
|
|
&& TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node))))
|
|
== INTEGER_CST)
|
|
{
|
|
tree minv = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)));
|
|
is_array_init = true;
|
|
curidx = wi::to_widest (minv);
|
|
}
|
|
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val)
|
|
{
|
|
if (field)
|
|
{
|
|
if (is_struct_init)
|
|
{
|
|
pp_dot (pp);
|
|
dump_generic_node (pp, field, spc, flags, false);
|
|
pp_equal (pp);
|
|
}
|
|
else if (is_array_init
|
|
&& (TREE_CODE (field) != INTEGER_CST
|
|
|| curidx != wi::to_widest (field)))
|
|
{
|
|
pp_left_bracket (pp);
|
|
if (TREE_CODE (field) == RANGE_EXPR)
|
|
{
|
|
dump_generic_node (pp, TREE_OPERAND (field, 0), spc,
|
|
flags, false);
|
|
pp_string (pp, " ... ");
|
|
dump_generic_node (pp, TREE_OPERAND (field, 1), spc,
|
|
flags, false);
|
|
if (TREE_CODE (TREE_OPERAND (field, 1)) == INTEGER_CST)
|
|
curidx = wi::to_widest (TREE_OPERAND (field, 1));
|
|
}
|
|
else
|
|
dump_generic_node (pp, field, spc, flags, false);
|
|
if (TREE_CODE (field) == INTEGER_CST)
|
|
curidx = wi::to_widest (field);
|
|
pp_string (pp, "]=");
|
|
}
|
|
}
|
|
if (is_array_init)
|
|
curidx += 1;
|
|
if (val && TREE_CODE (val) == ADDR_EXPR)
|
|
if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL)
|
|
val = TREE_OPERAND (val, 0);
|
|
if (val && TREE_CODE (val) == FUNCTION_DECL)
|
|
dump_decl_name (pp, val, flags);
|
|
else
|
|
dump_generic_node (pp, val, spc, flags, false);
|
|
if (ix != CONSTRUCTOR_NELTS (node) - 1)
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
}
|
|
pp_right_brace (pp);
|
|
}
|
|
break;
|
|
|
|
case COMPOUND_EXPR:
|
|
{
|
|
tree *tp;
|
|
if (flags & TDF_SLIM)
|
|
{
|
|
pp_string (pp, "<COMPOUND_EXPR>");
|
|
break;
|
|
}
|
|
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0),
|
|
spc, flags, !(flags & TDF_SLIM));
|
|
if (flags & TDF_SLIM)
|
|
newline_and_indent (pp, spc);
|
|
else
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
|
|
for (tp = &TREE_OPERAND (node, 1);
|
|
TREE_CODE (*tp) == COMPOUND_EXPR;
|
|
tp = &TREE_OPERAND (*tp, 1))
|
|
{
|
|
dump_generic_node (pp, TREE_OPERAND (*tp, 0),
|
|
spc, flags, !(flags & TDF_SLIM));
|
|
if (flags & TDF_SLIM)
|
|
newline_and_indent (pp, spc);
|
|
else
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
}
|
|
|
|
dump_generic_node (pp, *tp, spc, flags, !(flags & TDF_SLIM));
|
|
}
|
|
break;
|
|
|
|
case STATEMENT_LIST:
|
|
{
|
|
tree_stmt_iterator si;
|
|
bool first = true;
|
|
|
|
if (flags & TDF_SLIM)
|
|
{
|
|
pp_string (pp, "<STATEMENT_LIST>");
|
|
break;
|
|
}
|
|
|
|
for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
|
|
{
|
|
if (!first)
|
|
newline_and_indent (pp, spc);
|
|
else
|
|
first = false;
|
|
dump_generic_node (pp, tsi_stmt (si), spc, flags, true);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MODIFY_EXPR:
|
|
case INIT_EXPR:
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags,
|
|
false);
|
|
pp_space (pp);
|
|
pp_equal (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags,
|
|
false);
|
|
break;
|
|
|
|
case TARGET_EXPR:
|
|
pp_string (pp, "TARGET_EXPR <");
|
|
dump_generic_node (pp, TARGET_EXPR_SLOT (node), spc, flags, false);
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TARGET_EXPR_INITIAL (node), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case DECL_EXPR:
|
|
print_declaration (pp, DECL_EXPR_DECL (node), spc, flags);
|
|
is_stmt = false;
|
|
break;
|
|
|
|
case COND_EXPR:
|
|
if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
|
|
{
|
|
pp_string (pp, "if (");
|
|
dump_generic_node (pp, COND_EXPR_COND (node), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
/* The lowered cond_exprs should always be printed in full. */
|
|
if (COND_EXPR_THEN (node)
|
|
&& (IS_EMPTY_STMT (COND_EXPR_THEN (node))
|
|
|| TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR)
|
|
&& COND_EXPR_ELSE (node)
|
|
&& (IS_EMPTY_STMT (COND_EXPR_ELSE (node))
|
|
|| TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR))
|
|
{
|
|
pp_space (pp);
|
|
dump_generic_node (pp, COND_EXPR_THEN (node),
|
|
0, flags, true);
|
|
if (!IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
|
|
{
|
|
pp_string (pp, " else ");
|
|
dump_generic_node (pp, COND_EXPR_ELSE (node),
|
|
0, flags, true);
|
|
}
|
|
}
|
|
else if (!(flags & TDF_SLIM))
|
|
{
|
|
/* Output COND_EXPR_THEN. */
|
|
if (COND_EXPR_THEN (node))
|
|
{
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, COND_EXPR_THEN (node), spc+4,
|
|
flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
}
|
|
|
|
/* Output COND_EXPR_ELSE. */
|
|
if (COND_EXPR_ELSE (node)
|
|
&& !IS_EMPTY_STMT (COND_EXPR_ELSE (node)))
|
|
{
|
|
newline_and_indent (pp, spc);
|
|
pp_string (pp, "else");
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, COND_EXPR_ELSE (node), spc+4,
|
|
flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
}
|
|
}
|
|
is_expr = false;
|
|
}
|
|
else
|
|
{
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_question (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_colon (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
}
|
|
break;
|
|
|
|
case BIND_EXPR:
|
|
pp_left_brace (pp);
|
|
if (!(flags & TDF_SLIM))
|
|
{
|
|
if (BIND_EXPR_VARS (node))
|
|
{
|
|
pp_newline (pp);
|
|
|
|
for (op0 = BIND_EXPR_VARS (node); op0; op0 = DECL_CHAIN (op0))
|
|
{
|
|
print_declaration (pp, op0, spc+2, flags);
|
|
pp_newline (pp);
|
|
}
|
|
}
|
|
|
|
newline_and_indent (pp, spc+2);
|
|
dump_generic_node (pp, BIND_EXPR_BODY (node), spc+2, flags, true);
|
|
newline_and_indent (pp, spc);
|
|
pp_right_brace (pp);
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case CALL_EXPR:
|
|
if (CALL_EXPR_FN (node) != NULL_TREE)
|
|
print_call_name (pp, CALL_EXPR_FN (node), flags);
|
|
else
|
|
{
|
|
pp_dot (pp);
|
|
pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));
|
|
}
|
|
|
|
/* Print parameters. */
|
|
pp_space (pp);
|
|
pp_left_paren (pp);
|
|
{
|
|
tree arg;
|
|
call_expr_arg_iterator iter;
|
|
FOR_EACH_CALL_EXPR_ARG (arg, iter, node)
|
|
{
|
|
dump_generic_node (pp, arg, spc, flags, false);
|
|
if (more_call_expr_args_p (&iter))
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
}
|
|
}
|
|
if (CALL_EXPR_VA_ARG_PACK (node))
|
|
{
|
|
if (call_expr_nargs (node) > 0)
|
|
{
|
|
pp_comma (pp);
|
|
pp_space (pp);
|
|
}
|
|
pp_string (pp, "__builtin_va_arg_pack ()");
|
|
}
|
|
pp_right_paren (pp);
|
|
|
|
op1 = CALL_EXPR_STATIC_CHAIN (node);
|
|
if (op1)
|
|
{
|
|
pp_string (pp, " [static-chain: ");
|
|
dump_generic_node (pp, op1, spc, flags, false);
|
|
pp_right_bracket (pp);
|
|
}
|
|
|
|
if (CALL_EXPR_RETURN_SLOT_OPT (node))
|
|
pp_string (pp, " [return slot optimization]");
|
|
if (CALL_EXPR_TAILCALL (node))
|
|
pp_string (pp, " [tail call]");
|
|
break;
|
|
|
|
case WITH_CLEANUP_EXPR:
|
|
NIY;
|
|
break;
|
|
|
|
case CLEANUP_POINT_EXPR:
|
|
pp_string (pp, "<<cleanup_point ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ">>");
|
|
break;
|
|
|
|
case PLACEHOLDER_EXPR:
|
|
pp_string (pp, "<PLACEHOLDER_EXPR ");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
/* Binary arithmetic and logic expressions. */
|
|
case WIDEN_PLUS_EXPR:
|
|
case WIDEN_MINUS_EXPR:
|
|
case WIDEN_SUM_EXPR:
|
|
case WIDEN_MULT_EXPR:
|
|
case MULT_EXPR:
|
|
case MULT_HIGHPART_EXPR:
|
|
case PLUS_EXPR:
|
|
case POINTER_PLUS_EXPR:
|
|
case POINTER_DIFF_EXPR:
|
|
case MINUS_EXPR:
|
|
case TRUNC_DIV_EXPR:
|
|
case CEIL_DIV_EXPR:
|
|
case FLOOR_DIV_EXPR:
|
|
case ROUND_DIV_EXPR:
|
|
case TRUNC_MOD_EXPR:
|
|
case CEIL_MOD_EXPR:
|
|
case FLOOR_MOD_EXPR:
|
|
case ROUND_MOD_EXPR:
|
|
case RDIV_EXPR:
|
|
case EXACT_DIV_EXPR:
|
|
case LSHIFT_EXPR:
|
|
case RSHIFT_EXPR:
|
|
case LROTATE_EXPR:
|
|
case RROTATE_EXPR:
|
|
case WIDEN_LSHIFT_EXPR:
|
|
case BIT_IOR_EXPR:
|
|
case BIT_XOR_EXPR:
|
|
case BIT_AND_EXPR:
|
|
case TRUTH_ANDIF_EXPR:
|
|
case TRUTH_ORIF_EXPR:
|
|
case TRUTH_AND_EXPR:
|
|
case TRUTH_OR_EXPR:
|
|
case TRUTH_XOR_EXPR:
|
|
case LT_EXPR:
|
|
case LE_EXPR:
|
|
case GT_EXPR:
|
|
case GE_EXPR:
|
|
case EQ_EXPR:
|
|
case NE_EXPR:
|
|
case UNLT_EXPR:
|
|
case UNLE_EXPR:
|
|
case UNGT_EXPR:
|
|
case UNGE_EXPR:
|
|
case UNEQ_EXPR:
|
|
case LTGT_EXPR:
|
|
case ORDERED_EXPR:
|
|
case UNORDERED_EXPR:
|
|
{
|
|
const char *op = op_symbol (node);
|
|
op0 = TREE_OPERAND (node, 0);
|
|
op1 = TREE_OPERAND (node, 1);
|
|
|
|
/* When the operands are expressions with less priority,
|
|
keep semantics of the tree representation. */
|
|
if (op_prio (op0) <= op_prio (node))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
|
|
pp_space (pp);
|
|
pp_string (pp, op);
|
|
pp_space (pp);
|
|
|
|
/* When the operands are expressions with less priority,
|
|
keep semantics of the tree representation. */
|
|
if (op_prio (op1) <= op_prio (node))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, op1, spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, op1, spc, flags, false);
|
|
}
|
|
break;
|
|
|
|
/* Unary arithmetic and logic expressions. */
|
|
case NEGATE_EXPR:
|
|
case BIT_NOT_EXPR:
|
|
case TRUTH_NOT_EXPR:
|
|
case ADDR_EXPR:
|
|
case PREDECREMENT_EXPR:
|
|
case PREINCREMENT_EXPR:
|
|
case INDIRECT_REF:
|
|
if (TREE_CODE (node) == ADDR_EXPR
|
|
&& (TREE_CODE (TREE_OPERAND (node, 0)) == STRING_CST
|
|
|| TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL))
|
|
; /* Do not output '&' for strings and function pointers. */
|
|
else
|
|
pp_string (pp, op_symbol (node));
|
|
|
|
if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
break;
|
|
|
|
case POSTDECREMENT_EXPR:
|
|
case POSTINCREMENT_EXPR:
|
|
if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
else
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, op_symbol (node));
|
|
break;
|
|
|
|
case MIN_EXPR:
|
|
pp_string (pp, "MIN_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case MAX_EXPR:
|
|
pp_string (pp, "MAX_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case ABS_EXPR:
|
|
pp_string (pp, "ABS_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case ABSU_EXPR:
|
|
pp_string (pp, "ABSU_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case RANGE_EXPR:
|
|
NIY;
|
|
break;
|
|
|
|
case ADDR_SPACE_CONVERT_EXPR:
|
|
case FIXED_CONVERT_EXPR:
|
|
case FIX_TRUNC_EXPR:
|
|
case FLOAT_EXPR:
|
|
CASE_CONVERT:
|
|
type = TREE_TYPE (node);
|
|
op0 = TREE_OPERAND (node, 0);
|
|
if (type != TREE_TYPE (op0))
|
|
{
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, type, spc, flags, false);
|
|
pp_string (pp, ") ");
|
|
}
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
if (op_prio (op0) < op_prio (node))
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case VIEW_CONVERT_EXPR:
|
|
if (flags & TDF_GIMPLE)
|
|
pp_string (pp, "__VIEW_CONVERT <");
|
|
else
|
|
pp_string (pp, "VIEW_CONVERT_EXPR<");
|
|
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
|
|
pp_string (pp, ">(");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case PAREN_EXPR:
|
|
pp_string (pp, "((");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, "))");
|
|
break;
|
|
|
|
case NON_LVALUE_EXPR:
|
|
pp_string (pp, "NON_LVALUE_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case SAVE_EXPR:
|
|
pp_string (pp, "SAVE_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case COMPLEX_EXPR:
|
|
pp_string (pp, "COMPLEX_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case CONJ_EXPR:
|
|
pp_string (pp, "CONJ_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case REALPART_EXPR:
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_string (pp, "__real ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "REALPART_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
}
|
|
break;
|
|
|
|
case IMAGPART_EXPR:
|
|
if (flags & TDF_GIMPLE)
|
|
{
|
|
pp_string (pp, "__imag ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
}
|
|
else
|
|
{
|
|
pp_string (pp, "IMAGPART_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
}
|
|
break;
|
|
|
|
case VA_ARG_EXPR:
|
|
pp_string (pp, "VA_ARG_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case TRY_FINALLY_EXPR:
|
|
case TRY_CATCH_EXPR:
|
|
pp_string (pp, "try");
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4, flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
newline_and_indent (pp, spc);
|
|
if (TREE_CODE (node) == TRY_CATCH_EXPR)
|
|
{
|
|
node = TREE_OPERAND (node, 1);
|
|
pp_string (pp, "catch");
|
|
}
|
|
else
|
|
{
|
|
gcc_assert (TREE_CODE (node) == TRY_FINALLY_EXPR);
|
|
node = TREE_OPERAND (node, 1);
|
|
pp_string (pp, "finally");
|
|
if (TREE_CODE (node) == EH_ELSE_EXPR)
|
|
{
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4,
|
|
flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
newline_and_indent (pp, spc);
|
|
node = TREE_OPERAND (node, 1);
|
|
pp_string (pp, "else");
|
|
}
|
|
}
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, node, spc+4, flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case CATCH_EXPR:
|
|
pp_string (pp, "catch (");
|
|
dump_generic_node (pp, CATCH_TYPES (node), spc+2, flags, false);
|
|
pp_right_paren (pp);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, CATCH_BODY (node), spc+4, flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case EH_FILTER_EXPR:
|
|
pp_string (pp, "<<<eh_filter (");
|
|
dump_generic_node (pp, EH_FILTER_TYPES (node), spc+2, flags, false);
|
|
pp_string (pp, ")>>>");
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, EH_FILTER_FAILURE (node), spc+4, flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case LABEL_EXPR:
|
|
op0 = TREE_OPERAND (node, 0);
|
|
/* If this is for break or continue, don't bother printing it. */
|
|
if (DECL_NAME (op0))
|
|
{
|
|
const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
|
|
if (strcmp (name, "break") == 0
|
|
|| strcmp (name, "continue") == 0)
|
|
break;
|
|
}
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
pp_colon (pp);
|
|
if (DECL_NONLOCAL (op0))
|
|
pp_string (pp, " [non-local]");
|
|
break;
|
|
|
|
case LOOP_EXPR:
|
|
pp_string (pp, "while (1)");
|
|
if (!(flags & TDF_SLIM))
|
|
{
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, LOOP_EXPR_BODY (node), spc+4, flags, true);
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case PREDICT_EXPR:
|
|
pp_string (pp, "// predicted ");
|
|
if (PREDICT_EXPR_OUTCOME (node))
|
|
pp_string (pp, "likely by ");
|
|
else
|
|
pp_string (pp, "unlikely by ");
|
|
pp_string (pp, predictor_name (PREDICT_EXPR_PREDICTOR (node)));
|
|
pp_string (pp, " predictor.");
|
|
break;
|
|
|
|
case ANNOTATE_EXPR:
|
|
pp_string (pp, "ANNOTATE_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (node, 1)))
|
|
{
|
|
case annot_expr_ivdep_kind:
|
|
pp_string (pp, ", ivdep");
|
|
break;
|
|
case annot_expr_unroll_kind:
|
|
{
|
|
pp_string (pp, ", unroll ");
|
|
pp_decimal_int (pp,
|
|
(int) TREE_INT_CST_LOW (TREE_OPERAND (node, 2)));
|
|
break;
|
|
}
|
|
case annot_expr_no_vector_kind:
|
|
pp_string (pp, ", no-vector");
|
|
break;
|
|
case annot_expr_vector_kind:
|
|
pp_string (pp, ", vector");
|
|
break;
|
|
case annot_expr_parallel_kind:
|
|
pp_string (pp, ", parallel");
|
|
break;
|
|
default:
|
|
gcc_unreachable ();
|
|
}
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case RETURN_EXPR:
|
|
pp_string (pp, "return");
|
|
op0 = TREE_OPERAND (node, 0);
|
|
if (op0)
|
|
{
|
|
pp_space (pp);
|
|
if (TREE_CODE (op0) == MODIFY_EXPR)
|
|
dump_generic_node (pp, TREE_OPERAND (op0, 1),
|
|
spc, flags, false);
|
|
else
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
}
|
|
break;
|
|
|
|
case EXIT_EXPR:
|
|
pp_string (pp, "if (");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ") break");
|
|
break;
|
|
|
|
case SWITCH_EXPR:
|
|
pp_string (pp, "switch (");
|
|
dump_generic_node (pp, SWITCH_COND (node), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
if (!(flags & TDF_SLIM))
|
|
{
|
|
newline_and_indent (pp, spc+2);
|
|
pp_left_brace (pp);
|
|
if (SWITCH_BODY (node))
|
|
{
|
|
newline_and_indent (pp, spc+4);
|
|
dump_generic_node (pp, SWITCH_BODY (node), spc+4, flags,
|
|
true);
|
|
}
|
|
newline_and_indent (pp, spc+2);
|
|
pp_right_brace (pp);
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case GOTO_EXPR:
|
|
op0 = GOTO_DESTINATION (node);
|
|
if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0))
|
|
{
|
|
const char *name = IDENTIFIER_POINTER (DECL_NAME (op0));
|
|
if (strcmp (name, "break") == 0
|
|
|| strcmp (name, "continue") == 0)
|
|
{
|
|
pp_string (pp, name);
|
|
break;
|
|
}
|
|
}
|
|
pp_string (pp, "goto ");
|
|
dump_generic_node (pp, op0, spc, flags, false);
|
|
break;
|
|
|
|
case ASM_EXPR:
|
|
pp_string (pp, "__asm__");
|
|
if (ASM_VOLATILE_P (node))
|
|
pp_string (pp, " __volatile__");
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, ASM_STRING (node), spc, flags, false);
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, ASM_OUTPUTS (node), spc, flags, false);
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, ASM_INPUTS (node), spc, flags, false);
|
|
if (ASM_CLOBBERS (node))
|
|
{
|
|
pp_colon (pp);
|
|
dump_generic_node (pp, ASM_CLOBBERS (node), spc, flags, false);
|
|
}
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case CASE_LABEL_EXPR:
|
|
if (CASE_LOW (node) && CASE_HIGH (node))
|
|
{
|
|
pp_string (pp, "case ");
|
|
dump_generic_node (pp, CASE_LOW (node), spc, flags, false);
|
|
pp_string (pp, " ... ");
|
|
dump_generic_node (pp, CASE_HIGH (node), spc, flags, false);
|
|
}
|
|
else if (CASE_LOW (node))
|
|
{
|
|
pp_string (pp, "case ");
|
|
dump_generic_node (pp, CASE_LOW (node), spc, flags, false);
|
|
}
|
|
else
|
|
pp_string (pp, "default");
|
|
pp_colon (pp);
|
|
break;
|
|
|
|
case OBJ_TYPE_REF:
|
|
pp_string (pp, "OBJ_TYPE_REF(");
|
|
dump_generic_node (pp, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
|
|
pp_semicolon (pp);
|
|
/* We omit the class type for -fcompare-debug because we may
|
|
drop TYPE_BINFO early depending on debug info, and then
|
|
virtual_method_call_p would return false, whereas when
|
|
TYPE_BINFO is preserved it may still return true and then
|
|
we'd print the class type. Compare tree and rtl dumps for
|
|
libstdc++-prettyprinters/shared_ptr.cc with and without -g,
|
|
for example, at occurrences of OBJ_TYPE_REF. */
|
|
if (!(flags & (TDF_SLIM | TDF_COMPARE_DEBUG))
|
|
&& virtual_method_call_p (node, true))
|
|
{
|
|
pp_string (pp, "(");
|
|
dump_generic_node (pp, obj_type_ref_class (node, true),
|
|
spc, flags, false);
|
|
pp_string (pp, ")");
|
|
}
|
|
dump_generic_node (pp, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
|
|
pp_arrow (pp);
|
|
dump_generic_node (pp, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
break;
|
|
|
|
case SSA_NAME:
|
|
if (SSA_NAME_IDENTIFIER (node))
|
|
{
|
|
if ((flags & TDF_NOUID)
|
|
&& SSA_NAME_VAR (node)
|
|
&& DECL_NAMELESS (SSA_NAME_VAR (node)))
|
|
dump_fancy_name (pp, SSA_NAME_IDENTIFIER (node));
|
|
else if (! (flags & TDF_GIMPLE)
|
|
|| SSA_NAME_VAR (node))
|
|
dump_generic_node (pp, SSA_NAME_IDENTIFIER (node),
|
|
spc, flags, false);
|
|
}
|
|
pp_underscore (pp);
|
|
pp_decimal_int (pp, SSA_NAME_VERSION (node));
|
|
if (SSA_NAME_IS_DEFAULT_DEF (node))
|
|
pp_string (pp, "(D)");
|
|
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
|
|
pp_string (pp, "(ab)");
|
|
break;
|
|
|
|
case WITH_SIZE_EXPR:
|
|
pp_string (pp, "WITH_SIZE_EXPR <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case ASSERT_EXPR:
|
|
pp_string (pp, "ASSERT_EXPR <");
|
|
dump_generic_node (pp, ASSERT_EXPR_VAR (node), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, ASSERT_EXPR_COND (node), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case SCEV_KNOWN:
|
|
pp_string (pp, "scev_known");
|
|
break;
|
|
|
|
case SCEV_NOT_KNOWN:
|
|
pp_string (pp, "scev_not_known");
|
|
break;
|
|
|
|
case POLYNOMIAL_CHREC:
|
|
pp_left_brace (pp);
|
|
dump_generic_node (pp, CHREC_LEFT (node), spc, flags, false);
|
|
pp_string (pp, ", +, ");
|
|
dump_generic_node (pp, CHREC_RIGHT (node), spc, flags, false);
|
|
pp_string (pp, "}_");
|
|
pp_scalar (pp, "%u", CHREC_VARIABLE (node));
|
|
is_stmt = false;
|
|
break;
|
|
|
|
case REALIGN_LOAD_EXPR:
|
|
pp_string (pp, "REALIGN_LOAD <");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_greater (pp);
|
|
break;
|
|
|
|
case VEC_COND_EXPR:
|
|
pp_string (pp, " VEC_COND_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " , ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " , ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_PERM_EXPR:
|
|
pp_string (pp, " VEC_PERM_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " , ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " , ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case DOT_PROD_EXPR:
|
|
pp_string (pp, " DOT_PROD_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case WIDEN_MULT_PLUS_EXPR:
|
|
pp_string (pp, " WIDEN_MULT_PLUS_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case WIDEN_MULT_MINUS_EXPR:
|
|
pp_string (pp, " WIDEN_MULT_MINUS_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case OACC_PARALLEL:
|
|
pp_string (pp, "#pragma acc parallel");
|
|
goto dump_omp_clauses_body;
|
|
|
|
case OACC_KERNELS:
|
|
pp_string (pp, "#pragma acc kernels");
|
|
goto dump_omp_clauses_body;
|
|
|
|
case OACC_SERIAL:
|
|
pp_string (pp, "#pragma acc serial");
|
|
goto dump_omp_clauses_body;
|
|
|
|
case OACC_DATA:
|
|
pp_string (pp, "#pragma acc data");
|
|
dump_omp_clauses (pp, OACC_DATA_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OACC_HOST_DATA:
|
|
pp_string (pp, "#pragma acc host_data");
|
|
dump_omp_clauses (pp, OACC_HOST_DATA_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OACC_DECLARE:
|
|
pp_string (pp, "#pragma acc declare");
|
|
dump_omp_clauses (pp, OACC_DECLARE_CLAUSES (node), spc, flags);
|
|
break;
|
|
|
|
case OACC_UPDATE:
|
|
pp_string (pp, "#pragma acc update");
|
|
dump_omp_clauses (pp, OACC_UPDATE_CLAUSES (node), spc, flags);
|
|
break;
|
|
|
|
case OACC_ENTER_DATA:
|
|
pp_string (pp, "#pragma acc enter data");
|
|
dump_omp_clauses (pp, OACC_ENTER_DATA_CLAUSES (node), spc, flags);
|
|
break;
|
|
|
|
case OACC_EXIT_DATA:
|
|
pp_string (pp, "#pragma acc exit data");
|
|
dump_omp_clauses (pp, OACC_EXIT_DATA_CLAUSES (node), spc, flags);
|
|
break;
|
|
|
|
case OACC_CACHE:
|
|
pp_string (pp, "#pragma acc cache");
|
|
dump_omp_clauses (pp, OACC_CACHE_CLAUSES (node), spc, flags);
|
|
break;
|
|
|
|
case OMP_PARALLEL:
|
|
pp_string (pp, "#pragma omp parallel");
|
|
dump_omp_clauses (pp, OMP_PARALLEL_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
dump_omp_clauses_body:
|
|
dump_omp_clauses (pp, OMP_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
dump_omp_body:
|
|
if (!(flags & TDF_SLIM) && OMP_BODY (node))
|
|
{
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc + 4);
|
|
dump_generic_node (pp, OMP_BODY (node), spc + 4, flags, false);
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_right_brace (pp);
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case OMP_TASK:
|
|
pp_string (pp, OMP_TASK_BODY (node) ? "#pragma omp task"
|
|
: "#pragma omp taskwait");
|
|
dump_omp_clauses (pp, OMP_TASK_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_FOR:
|
|
pp_string (pp, "#pragma omp for");
|
|
goto dump_omp_loop;
|
|
|
|
case OMP_SIMD:
|
|
pp_string (pp, "#pragma omp simd");
|
|
goto dump_omp_loop;
|
|
|
|
case OMP_DISTRIBUTE:
|
|
pp_string (pp, "#pragma omp distribute");
|
|
goto dump_omp_loop;
|
|
|
|
case OMP_TASKLOOP:
|
|
pp_string (pp, "#pragma omp taskloop");
|
|
goto dump_omp_loop;
|
|
|
|
case OMP_LOOP:
|
|
pp_string (pp, "#pragma omp loop");
|
|
goto dump_omp_loop;
|
|
|
|
case OACC_LOOP:
|
|
pp_string (pp, "#pragma acc loop");
|
|
goto dump_omp_loop;
|
|
|
|
case OMP_TEAMS:
|
|
pp_string (pp, "#pragma omp teams");
|
|
dump_omp_clauses (pp, OMP_TEAMS_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_TARGET_DATA:
|
|
pp_string (pp, "#pragma omp target data");
|
|
dump_omp_clauses (pp, OMP_TARGET_DATA_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_TARGET_ENTER_DATA:
|
|
pp_string (pp, "#pragma omp target enter data");
|
|
dump_omp_clauses (pp, OMP_TARGET_ENTER_DATA_CLAUSES (node), spc, flags);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case OMP_TARGET_EXIT_DATA:
|
|
pp_string (pp, "#pragma omp target exit data");
|
|
dump_omp_clauses (pp, OMP_TARGET_EXIT_DATA_CLAUSES (node), spc, flags);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case OMP_TARGET:
|
|
pp_string (pp, "#pragma omp target");
|
|
dump_omp_clauses (pp, OMP_TARGET_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_TARGET_UPDATE:
|
|
pp_string (pp, "#pragma omp target update");
|
|
dump_omp_clauses (pp, OMP_TARGET_UPDATE_CLAUSES (node), spc, flags);
|
|
is_expr = false;
|
|
break;
|
|
|
|
dump_omp_loop:
|
|
dump_omp_clauses (pp, OMP_FOR_CLAUSES (node), spc, flags);
|
|
if (!(flags & TDF_SLIM))
|
|
{
|
|
int i;
|
|
|
|
if (OMP_FOR_PRE_BODY (node))
|
|
{
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_left_brace (pp);
|
|
spc += 4;
|
|
newline_and_indent (pp, spc);
|
|
dump_generic_node (pp, OMP_FOR_PRE_BODY (node),
|
|
spc, flags, false);
|
|
}
|
|
if (OMP_FOR_INIT (node))
|
|
{
|
|
spc -= 2;
|
|
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (node)); i++)
|
|
{
|
|
spc += 2;
|
|
newline_and_indent (pp, spc);
|
|
pp_string (pp, "for (");
|
|
tree init = TREE_VEC_ELT (OMP_FOR_INIT (node), i);
|
|
if (TREE_CODE (init) != MODIFY_EXPR
|
|
|| TREE_CODE (TREE_OPERAND (init, 1)) != TREE_VEC)
|
|
dump_generic_node (pp, init, spc, flags, false);
|
|
else
|
|
{
|
|
dump_generic_node (pp, TREE_OPERAND (init, 0),
|
|
spc, flags, false);
|
|
pp_string (pp, " = ");
|
|
dump_omp_loop_non_rect_expr (pp, TREE_OPERAND (init, 1),
|
|
spc, flags);
|
|
}
|
|
pp_string (pp, "; ");
|
|
tree cond = TREE_VEC_ELT (OMP_FOR_COND (node), i);
|
|
if (!COMPARISON_CLASS_P (cond)
|
|
|| TREE_CODE (TREE_OPERAND (cond, 1)) != TREE_VEC)
|
|
dump_generic_node (pp, cond, spc, flags, false);
|
|
else
|
|
{
|
|
dump_generic_node (pp, TREE_OPERAND (cond, 0),
|
|
spc, flags, false);
|
|
const char *op = op_symbol (cond);
|
|
pp_space (pp);
|
|
pp_string (pp, op);
|
|
pp_space (pp);
|
|
dump_omp_loop_non_rect_expr (pp, TREE_OPERAND (cond, 1),
|
|
spc, flags);
|
|
}
|
|
pp_string (pp, "; ");
|
|
dump_generic_node (pp,
|
|
TREE_VEC_ELT (OMP_FOR_INCR (node), i),
|
|
spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
}
|
|
if (OMP_FOR_BODY (node))
|
|
{
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc + 4);
|
|
dump_generic_node (pp, OMP_FOR_BODY (node), spc + 4, flags,
|
|
false);
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_right_brace (pp);
|
|
}
|
|
if (OMP_FOR_INIT (node))
|
|
spc -= 2 * TREE_VEC_LENGTH (OMP_FOR_INIT (node)) - 2;
|
|
if (OMP_FOR_PRE_BODY (node))
|
|
{
|
|
spc -= 4;
|
|
newline_and_indent (pp, spc + 2);
|
|
pp_right_brace (pp);
|
|
}
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case OMP_SECTIONS:
|
|
pp_string (pp, "#pragma omp sections");
|
|
dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_SECTION:
|
|
pp_string (pp, "#pragma omp section");
|
|
goto dump_omp_body;
|
|
|
|
case OMP_SCAN:
|
|
if (OMP_SCAN_CLAUSES (node))
|
|
{
|
|
pp_string (pp, "#pragma omp scan");
|
|
dump_omp_clauses (pp, OMP_SCAN_CLAUSES (node), spc, flags);
|
|
}
|
|
goto dump_omp_body;
|
|
|
|
case OMP_MASTER:
|
|
pp_string (pp, "#pragma omp master");
|
|
goto dump_omp_body;
|
|
|
|
case OMP_MASKED:
|
|
pp_string (pp, "#pragma omp masked");
|
|
dump_omp_clauses (pp, OMP_MASKED_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_TASKGROUP:
|
|
pp_string (pp, "#pragma omp taskgroup");
|
|
dump_omp_clauses (pp, OMP_TASKGROUP_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_ORDERED:
|
|
pp_string (pp, "#pragma omp ordered");
|
|
dump_omp_clauses (pp, OMP_ORDERED_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_CRITICAL:
|
|
pp_string (pp, "#pragma omp critical");
|
|
if (OMP_CRITICAL_NAME (node))
|
|
{
|
|
pp_space (pp);
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, OMP_CRITICAL_NAME (node), spc,
|
|
flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
dump_omp_clauses (pp, OMP_CRITICAL_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_ATOMIC:
|
|
pp_string (pp, "#pragma omp atomic");
|
|
dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node));
|
|
newline_and_indent (pp, spc + 2);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_equal (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
break;
|
|
|
|
case OMP_ATOMIC_READ:
|
|
pp_string (pp, "#pragma omp atomic read");
|
|
dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node));
|
|
newline_and_indent (pp, spc + 2);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_space (pp);
|
|
break;
|
|
|
|
case OMP_ATOMIC_CAPTURE_OLD:
|
|
case OMP_ATOMIC_CAPTURE_NEW:
|
|
pp_string (pp, "#pragma omp atomic capture");
|
|
dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node));
|
|
newline_and_indent (pp, spc + 2);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_space (pp);
|
|
pp_equal (pp);
|
|
pp_space (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
break;
|
|
|
|
case OMP_SINGLE:
|
|
pp_string (pp, "#pragma omp single");
|
|
dump_omp_clauses (pp, OMP_SINGLE_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_SCOPE:
|
|
pp_string (pp, "#pragma omp scope");
|
|
dump_omp_clauses (pp, OMP_SCOPE_CLAUSES (node), spc, flags);
|
|
goto dump_omp_body;
|
|
|
|
case OMP_CLAUSE:
|
|
/* If we come here, we're dumping something that's not an OMP construct,
|
|
for example, OMP clauses attached to a function's '__attribute__'.
|
|
Dump the whole OMP clause chain. */
|
|
dump_omp_clauses (pp, node, spc, flags, false);
|
|
is_expr = false;
|
|
break;
|
|
|
|
case TRANSACTION_EXPR:
|
|
if (TRANSACTION_EXPR_OUTER (node))
|
|
pp_string (pp, "__transaction_atomic [[outer]]");
|
|
else if (TRANSACTION_EXPR_RELAXED (node))
|
|
pp_string (pp, "__transaction_relaxed");
|
|
else
|
|
pp_string (pp, "__transaction_atomic");
|
|
if (!(flags & TDF_SLIM) && TRANSACTION_EXPR_BODY (node))
|
|
{
|
|
newline_and_indent (pp, spc);
|
|
pp_left_brace (pp);
|
|
newline_and_indent (pp, spc + 2);
|
|
dump_generic_node (pp, TRANSACTION_EXPR_BODY (node),
|
|
spc + 2, flags, false);
|
|
newline_and_indent (pp, spc);
|
|
pp_right_brace (pp);
|
|
}
|
|
is_expr = false;
|
|
break;
|
|
|
|
case VEC_SERIES_EXPR:
|
|
case VEC_WIDEN_MULT_HI_EXPR:
|
|
case VEC_WIDEN_MULT_LO_EXPR:
|
|
case VEC_WIDEN_PLUS_HI_EXPR:
|
|
case VEC_WIDEN_PLUS_LO_EXPR:
|
|
case VEC_WIDEN_MINUS_HI_EXPR:
|
|
case VEC_WIDEN_MINUS_LO_EXPR:
|
|
case VEC_WIDEN_MULT_EVEN_EXPR:
|
|
case VEC_WIDEN_MULT_ODD_EXPR:
|
|
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
|
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
|
pp_space (pp);
|
|
for (str = get_tree_code_name (code); *str; str++)
|
|
pp_character (pp, TOUPPER (*str));
|
|
pp_string (pp, " < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_DUPLICATE_EXPR:
|
|
pp_space (pp);
|
|
for (str = get_tree_code_name (code); *str; str++)
|
|
pp_character (pp, TOUPPER (*str));
|
|
pp_string (pp, " < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_HI_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_HI_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_LO_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_LO_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_FLOAT_HI_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_FLOAT_HI_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_FLOAT_LO_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_FLOAT_LO_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_FIX_TRUNC_HI_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
|
|
pp_string (pp, " VEC_UNPACK_FIX_TRUNC_LO_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_PACK_TRUNC_EXPR:
|
|
pp_string (pp, " VEC_PACK_TRUNC_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_PACK_SAT_EXPR:
|
|
pp_string (pp, " VEC_PACK_SAT_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_PACK_FIX_TRUNC_EXPR:
|
|
pp_string (pp, " VEC_PACK_FIX_TRUNC_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case VEC_PACK_FLOAT_EXPR:
|
|
pp_string (pp, " VEC_PACK_FLOAT_EXPR < ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
|
|
pp_string (pp, ", ");
|
|
dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
|
|
pp_string (pp, " > ");
|
|
break;
|
|
|
|
case BLOCK:
|
|
dump_block_node (pp, node, spc, flags);
|
|
break;
|
|
|
|
case DEBUG_BEGIN_STMT:
|
|
pp_string (pp, "# DEBUG BEGIN STMT");
|
|
break;
|
|
|
|
default:
|
|
NIY;
|
|
}
|
|
|
|
if (is_stmt && is_expr)
|
|
pp_semicolon (pp);
|
|
|
|
return spc;
|
|
}
|
|
|
|
/* Print the declaration of a variable. */
|
|
|
|
void
|
|
print_declaration (pretty_printer *pp, tree t, int spc, dump_flags_t flags)
|
|
{
|
|
INDENT (spc);
|
|
|
|
if (TREE_CODE(t) == NAMELIST_DECL)
|
|
{
|
|
pp_string(pp, "namelist ");
|
|
dump_decl_name (pp, t, flags);
|
|
pp_semicolon (pp);
|
|
return;
|
|
}
|
|
|
|
if (TREE_CODE (t) == TYPE_DECL)
|
|
pp_string (pp, "typedef ");
|
|
|
|
if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t))
|
|
pp_string (pp, "register ");
|
|
|
|
if (TREE_PUBLIC (t) && DECL_EXTERNAL (t))
|
|
pp_string (pp, "extern ");
|
|
else if (TREE_STATIC (t))
|
|
pp_string (pp, "static ");
|
|
|
|
/* Print the type and name. */
|
|
if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
|
|
{
|
|
tree tmp;
|
|
|
|
/* Print array's type. */
|
|
tmp = TREE_TYPE (t);
|
|
while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
|
|
tmp = TREE_TYPE (tmp);
|
|
dump_generic_node (pp, TREE_TYPE (tmp), spc, flags, false);
|
|
|
|
/* Print variable's name. */
|
|
pp_space (pp);
|
|
dump_generic_node (pp, t, spc, flags, false);
|
|
|
|
/* Print the dimensions. */
|
|
tmp = TREE_TYPE (t);
|
|
while (TREE_CODE (tmp) == ARRAY_TYPE)
|
|
{
|
|
dump_array_domain (pp, TYPE_DOMAIN (tmp), spc, flags);
|
|
tmp = TREE_TYPE (tmp);
|
|
}
|
|
}
|
|
else if (TREE_CODE (t) == FUNCTION_DECL)
|
|
{
|
|
dump_generic_node (pp, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
|
|
pp_space (pp);
|
|
dump_decl_name (pp, t, flags);
|
|
dump_function_declaration (pp, TREE_TYPE (t), spc, flags);
|
|
}
|
|
else
|
|
{
|
|
/* Print type declaration. */
|
|
dump_generic_node (pp, TREE_TYPE (t), spc, flags, false);
|
|
|
|
/* Print variable's name. */
|
|
pp_space (pp);
|
|
dump_generic_node (pp, t, spc, flags, false);
|
|
}
|
|
|
|
if (VAR_P (t) && DECL_HARD_REGISTER (t))
|
|
{
|
|
pp_string (pp, " __asm__ ");
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, DECL_ASSEMBLER_NAME (t), spc, flags, false);
|
|
pp_right_paren (pp);
|
|
}
|
|
|
|
/* The initial value of a function serves to determine whether the function
|
|
is declared or defined. So the following does not apply to function
|
|
nodes. */
|
|
if (TREE_CODE (t) != FUNCTION_DECL)
|
|
{
|
|
/* Print the initial value. */
|
|
if (DECL_INITIAL (t))
|
|
{
|
|
pp_space (pp);
|
|
pp_equal (pp);
|
|
pp_space (pp);
|
|
if (!(flags & TDF_SLIM))
|
|
dump_generic_node (pp, DECL_INITIAL (t), spc, flags, false);
|
|
else
|
|
pp_string (pp, "<<< omitted >>>");
|
|
}
|
|
}
|
|
|
|
if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
|
|
{
|
|
pp_string (pp, " [value-expr: ");
|
|
dump_generic_node (pp, DECL_VALUE_EXPR (t), spc, flags, false);
|
|
pp_right_bracket (pp);
|
|
}
|
|
|
|
pp_semicolon (pp);
|
|
}
|
|
|
|
|
|
/* Prints a structure: name, fields, and methods.
|
|
FIXME: Still incomplete. */
|
|
|
|
static void
|
|
print_struct_decl (pretty_printer *pp, const_tree node, int spc,
|
|
dump_flags_t flags)
|
|
{
|
|
/* Print the name of the structure. */
|
|
if (TYPE_NAME (node))
|
|
{
|
|
INDENT (spc);
|
|
if (TREE_CODE (node) == RECORD_TYPE)
|
|
pp_string (pp, "struct ");
|
|
else if ((TREE_CODE (node) == UNION_TYPE
|
|
|| TREE_CODE (node) == QUAL_UNION_TYPE))
|
|
pp_string (pp, "union ");
|
|
|
|
dump_generic_node (pp, TYPE_NAME (node), spc, TDF_NONE, false);
|
|
}
|
|
|
|
/* Print the contents of the structure. */
|
|
pp_newline (pp);
|
|
INDENT (spc);
|
|
pp_left_brace (pp);
|
|
pp_newline (pp);
|
|
|
|
/* Print the fields of the structure. */
|
|
{
|
|
tree tmp;
|
|
tmp = TYPE_FIELDS (node);
|
|
while (tmp)
|
|
{
|
|
/* Avoid to print recursively the structure. */
|
|
/* FIXME : Not implemented correctly...,
|
|
what about the case when we have a cycle in the contain graph? ...
|
|
Maybe this could be solved by looking at the scope in which the
|
|
structure was declared. */
|
|
if (TREE_TYPE (tmp) != node
|
|
&& (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
|
|
|| TREE_TYPE (TREE_TYPE (tmp)) != node))
|
|
{
|
|
print_declaration (pp, tmp, spc+2, flags);
|
|
pp_newline (pp);
|
|
}
|
|
tmp = DECL_CHAIN (tmp);
|
|
}
|
|
}
|
|
INDENT (spc);
|
|
pp_right_brace (pp);
|
|
}
|
|
|
|
/* Return the priority of the operator CODE.
|
|
|
|
From lowest to highest precedence with either left-to-right (L-R)
|
|
or right-to-left (R-L) associativity]:
|
|
|
|
1 [L-R] ,
|
|
2 [R-L] = += -= *= /= %= &= ^= |= <<= >>=
|
|
3 [R-L] ?:
|
|
4 [L-R] ||
|
|
5 [L-R] &&
|
|
6 [L-R] |
|
|
7 [L-R] ^
|
|
8 [L-R] &
|
|
9 [L-R] == !=
|
|
10 [L-R] < <= > >=
|
|
11 [L-R] << >>
|
|
12 [L-R] + -
|
|
13 [L-R] * / %
|
|
14 [R-L] ! ~ ++ -- + - * & (type) sizeof
|
|
15 [L-R] fn() [] -> .
|
|
|
|
unary +, - and * have higher precedence than the corresponding binary
|
|
operators. */
|
|
|
|
int
|
|
op_code_prio (enum tree_code code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case TREE_LIST:
|
|
case COMPOUND_EXPR:
|
|
case BIND_EXPR:
|
|
return 1;
|
|
|
|
case MODIFY_EXPR:
|
|
case INIT_EXPR:
|
|
return 2;
|
|
|
|
case COND_EXPR:
|
|
return 3;
|
|
|
|
case TRUTH_OR_EXPR:
|
|
case TRUTH_ORIF_EXPR:
|
|
return 4;
|
|
|
|
case TRUTH_AND_EXPR:
|
|
case TRUTH_ANDIF_EXPR:
|
|
return 5;
|
|
|
|
case BIT_IOR_EXPR:
|
|
return 6;
|
|
|
|
case BIT_XOR_EXPR:
|
|
case TRUTH_XOR_EXPR:
|
|
return 7;
|
|
|
|
case BIT_AND_EXPR:
|
|
return 8;
|
|
|
|
case EQ_EXPR:
|
|
case NE_EXPR:
|
|
return 9;
|
|
|
|
case UNLT_EXPR:
|
|
case UNLE_EXPR:
|
|
case UNGT_EXPR:
|
|
case UNGE_EXPR:
|
|
case UNEQ_EXPR:
|
|
case LTGT_EXPR:
|
|
case ORDERED_EXPR:
|
|
case UNORDERED_EXPR:
|
|
case LT_EXPR:
|
|
case LE_EXPR:
|
|
case GT_EXPR:
|
|
case GE_EXPR:
|
|
return 10;
|
|
|
|
case LSHIFT_EXPR:
|
|
case RSHIFT_EXPR:
|
|
case LROTATE_EXPR:
|
|
case RROTATE_EXPR:
|
|
case VEC_WIDEN_LSHIFT_HI_EXPR:
|
|
case VEC_WIDEN_LSHIFT_LO_EXPR:
|
|
case WIDEN_LSHIFT_EXPR:
|
|
return 11;
|
|
|
|
case WIDEN_SUM_EXPR:
|
|
case PLUS_EXPR:
|
|
case POINTER_PLUS_EXPR:
|
|
case POINTER_DIFF_EXPR:
|
|
case MINUS_EXPR:
|
|
return 12;
|
|
|
|
case VEC_WIDEN_MULT_HI_EXPR:
|
|
case VEC_WIDEN_MULT_LO_EXPR:
|
|
case WIDEN_MULT_EXPR:
|
|
case DOT_PROD_EXPR:
|
|
case WIDEN_MULT_PLUS_EXPR:
|
|
case WIDEN_MULT_MINUS_EXPR:
|
|
case MULT_EXPR:
|
|
case MULT_HIGHPART_EXPR:
|
|
case TRUNC_DIV_EXPR:
|
|
case CEIL_DIV_EXPR:
|
|
case FLOOR_DIV_EXPR:
|
|
case ROUND_DIV_EXPR:
|
|
case RDIV_EXPR:
|
|
case EXACT_DIV_EXPR:
|
|
case TRUNC_MOD_EXPR:
|
|
case CEIL_MOD_EXPR:
|
|
case FLOOR_MOD_EXPR:
|
|
case ROUND_MOD_EXPR:
|
|
return 13;
|
|
|
|
case TRUTH_NOT_EXPR:
|
|
case BIT_NOT_EXPR:
|
|
case POSTINCREMENT_EXPR:
|
|
case POSTDECREMENT_EXPR:
|
|
case PREINCREMENT_EXPR:
|
|
case PREDECREMENT_EXPR:
|
|
case NEGATE_EXPR:
|
|
case INDIRECT_REF:
|
|
case ADDR_EXPR:
|
|
case FLOAT_EXPR:
|
|
CASE_CONVERT:
|
|
case FIX_TRUNC_EXPR:
|
|
case TARGET_EXPR:
|
|
return 14;
|
|
|
|
case CALL_EXPR:
|
|
case ARRAY_REF:
|
|
case ARRAY_RANGE_REF:
|
|
case COMPONENT_REF:
|
|
return 15;
|
|
|
|
/* Special expressions. */
|
|
case MIN_EXPR:
|
|
case MAX_EXPR:
|
|
case ABS_EXPR:
|
|
case REALPART_EXPR:
|
|
case IMAGPART_EXPR:
|
|
case VEC_UNPACK_HI_EXPR:
|
|
case VEC_UNPACK_LO_EXPR:
|
|
case VEC_UNPACK_FLOAT_HI_EXPR:
|
|
case VEC_UNPACK_FLOAT_LO_EXPR:
|
|
case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
|
|
case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
|
|
case VEC_PACK_TRUNC_EXPR:
|
|
case VEC_PACK_SAT_EXPR:
|
|
return 16;
|
|
|
|
default:
|
|
/* Return an arbitrarily high precedence to avoid surrounding single
|
|
VAR_DECLs in ()s. */
|
|
return 9999;
|
|
}
|
|
}
|
|
|
|
/* Return the priority of the operator OP. */
|
|
|
|
int
|
|
op_prio (const_tree op)
|
|
{
|
|
enum tree_code code;
|
|
|
|
if (op == NULL)
|
|
return 9999;
|
|
|
|
code = TREE_CODE (op);
|
|
if (code == SAVE_EXPR || code == NON_LVALUE_EXPR)
|
|
return op_prio (TREE_OPERAND (op, 0));
|
|
|
|
return op_code_prio (code);
|
|
}
|
|
|
|
/* Return the symbol associated with operator CODE. */
|
|
|
|
const char *
|
|
op_symbol_code (enum tree_code code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case MODIFY_EXPR:
|
|
return "=";
|
|
|
|
case TRUTH_OR_EXPR:
|
|
case TRUTH_ORIF_EXPR:
|
|
return "||";
|
|
|
|
case TRUTH_AND_EXPR:
|
|
case TRUTH_ANDIF_EXPR:
|
|
return "&&";
|
|
|
|
case BIT_IOR_EXPR:
|
|
return "|";
|
|
|
|
case TRUTH_XOR_EXPR:
|
|
case BIT_XOR_EXPR:
|
|
return "^";
|
|
|
|
case ADDR_EXPR:
|
|
case BIT_AND_EXPR:
|
|
return "&";
|
|
|
|
case ORDERED_EXPR:
|
|
return "ord";
|
|
case UNORDERED_EXPR:
|
|
return "unord";
|
|
|
|
case EQ_EXPR:
|
|
return "==";
|
|
case UNEQ_EXPR:
|
|
return "u==";
|
|
|
|
case NE_EXPR:
|
|
return "!=";
|
|
|
|
case LT_EXPR:
|
|
return "<";
|
|
case UNLT_EXPR:
|
|
return "u<";
|
|
|
|
case LE_EXPR:
|
|
return "<=";
|
|
case UNLE_EXPR:
|
|
return "u<=";
|
|
|
|
case GT_EXPR:
|
|
return ">";
|
|
case UNGT_EXPR:
|
|
return "u>";
|
|
|
|
case GE_EXPR:
|
|
return ">=";
|
|
case UNGE_EXPR:
|
|
return "u>=";
|
|
|
|
case LTGT_EXPR:
|
|
return "<>";
|
|
|
|
case LSHIFT_EXPR:
|
|
return "<<";
|
|
|
|
case RSHIFT_EXPR:
|
|
return ">>";
|
|
|
|
case LROTATE_EXPR:
|
|
return "r<<";
|
|
|
|
case RROTATE_EXPR:
|
|
return "r>>";
|
|
|
|
case WIDEN_LSHIFT_EXPR:
|
|
return "w<<";
|
|
|
|
case WIDEN_PLUS_EXPR:
|
|
return "w+";
|
|
|
|
case WIDEN_MINUS_EXPR:
|
|
return "w-";
|
|
|
|
case POINTER_PLUS_EXPR:
|
|
return "+";
|
|
|
|
case PLUS_EXPR:
|
|
return "+";
|
|
|
|
case WIDEN_SUM_EXPR:
|
|
return "w+";
|
|
|
|
case WIDEN_MULT_EXPR:
|
|
return "w*";
|
|
|
|
case MULT_HIGHPART_EXPR:
|
|
return "h*";
|
|
|
|
case NEGATE_EXPR:
|
|
case MINUS_EXPR:
|
|
case POINTER_DIFF_EXPR:
|
|
return "-";
|
|
|
|
case BIT_NOT_EXPR:
|
|
return "~";
|
|
|
|
case TRUTH_NOT_EXPR:
|
|
return "!";
|
|
|
|
case MULT_EXPR:
|
|
case INDIRECT_REF:
|
|
return "*";
|
|
|
|
case TRUNC_DIV_EXPR:
|
|
case RDIV_EXPR:
|
|
return "/";
|
|
|
|
case CEIL_DIV_EXPR:
|
|
return "/[cl]";
|
|
|
|
case FLOOR_DIV_EXPR:
|
|
return "/[fl]";
|
|
|
|
case ROUND_DIV_EXPR:
|
|
return "/[rd]";
|
|
|
|
case EXACT_DIV_EXPR:
|
|
return "/[ex]";
|
|
|
|
case TRUNC_MOD_EXPR:
|
|
return "%";
|
|
|
|
case CEIL_MOD_EXPR:
|
|
return "%[cl]";
|
|
|
|
case FLOOR_MOD_EXPR:
|
|
return "%[fl]";
|
|
|
|
case ROUND_MOD_EXPR:
|
|
return "%[rd]";
|
|
|
|
case PREDECREMENT_EXPR:
|
|
return " --";
|
|
|
|
case PREINCREMENT_EXPR:
|
|
return " ++";
|
|
|
|
case POSTDECREMENT_EXPR:
|
|
return "-- ";
|
|
|
|
case POSTINCREMENT_EXPR:
|
|
return "++ ";
|
|
|
|
case MAX_EXPR:
|
|
return "max";
|
|
|
|
case MIN_EXPR:
|
|
return "min";
|
|
|
|
default:
|
|
return "<<< ??? >>>";
|
|
}
|
|
}
|
|
|
|
/* Return the symbol associated with operator OP. */
|
|
|
|
static const char *
|
|
op_symbol (const_tree op)
|
|
{
|
|
return op_symbol_code (TREE_CODE (op));
|
|
}
|
|
|
|
/* Prints the name of a call. NODE is the CALL_EXPR_FN of a CALL_EXPR or
|
|
the gimple_call_fn of a GIMPLE_CALL. */
|
|
|
|
void
|
|
print_call_name (pretty_printer *pp, tree node, dump_flags_t flags)
|
|
{
|
|
tree op0 = node;
|
|
|
|
if (TREE_CODE (op0) == NON_LVALUE_EXPR)
|
|
op0 = TREE_OPERAND (op0, 0);
|
|
|
|
again:
|
|
switch (TREE_CODE (op0))
|
|
{
|
|
case VAR_DECL:
|
|
case PARM_DECL:
|
|
case FUNCTION_DECL:
|
|
dump_function_name (pp, op0, flags);
|
|
break;
|
|
|
|
case ADDR_EXPR:
|
|
case INDIRECT_REF:
|
|
CASE_CONVERT:
|
|
op0 = TREE_OPERAND (op0, 0);
|
|
goto again;
|
|
|
|
case COND_EXPR:
|
|
pp_left_paren (pp);
|
|
dump_generic_node (pp, TREE_OPERAND (op0, 0), 0, flags, false);
|
|
pp_string (pp, ") ? ");
|
|
dump_generic_node (pp, TREE_OPERAND (op0, 1), 0, flags, false);
|
|
pp_string (pp, " : ");
|
|
dump_generic_node (pp, TREE_OPERAND (op0, 2), 0, flags, false);
|
|
break;
|
|
|
|
case ARRAY_REF:
|
|
if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
|
|
dump_function_name (pp, TREE_OPERAND (op0, 0), flags);
|
|
else
|
|
dump_generic_node (pp, op0, 0, flags, false);
|
|
break;
|
|
|
|
case MEM_REF:
|
|
if (integer_zerop (TREE_OPERAND (op0, 1)))
|
|
{
|
|
op0 = TREE_OPERAND (op0, 0);
|
|
goto again;
|
|
}
|
|
/* Fallthru. */
|
|
case COMPONENT_REF:
|
|
case SSA_NAME:
|
|
case OBJ_TYPE_REF:
|
|
dump_generic_node (pp, op0, 0, flags, false);
|
|
break;
|
|
|
|
default:
|
|
NIY;
|
|
}
|
|
}
|
|
|
|
/* Print the first N characters in the array STR, replacing non-printable
|
|
characters (including embedded nuls) with unambiguous escape sequences. */
|
|
|
|
void
|
|
pretty_print_string (pretty_printer *pp, const char *str, size_t n)
|
|
{
|
|
if (str == NULL)
|
|
return;
|
|
|
|
for ( ; n; --n, ++str)
|
|
{
|
|
switch (str[0])
|
|
{
|
|
case '\b':
|
|
pp_string (pp, "\\b");
|
|
break;
|
|
|
|
case '\f':
|
|
pp_string (pp, "\\f");
|
|
break;
|
|
|
|
case '\n':
|
|
pp_string (pp, "\\n");
|
|
break;
|
|
|
|
case '\r':
|
|
pp_string (pp, "\\r");
|
|
break;
|
|
|
|
case '\t':
|
|
pp_string (pp, "\\t");
|
|
break;
|
|
|
|
case '\v':
|
|
pp_string (pp, "\\v");
|
|
break;
|
|
|
|
case '\\':
|
|
pp_string (pp, "\\\\");
|
|
break;
|
|
|
|
case '\"':
|
|
pp_string (pp, "\\\"");
|
|
break;
|
|
|
|
case '\'':
|
|
pp_string (pp, "\\'");
|
|
break;
|
|
|
|
default:
|
|
if (str[0] || n > 1)
|
|
{
|
|
if (!ISPRINT (str[0]))
|
|
{
|
|
char buf[5];
|
|
sprintf (buf, "\\x%02x", (unsigned char)str[0]);
|
|
pp_string (pp, buf);
|
|
}
|
|
else
|
|
pp_character (pp, str[0]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
maybe_init_pretty_print (FILE *file)
|
|
{
|
|
if (!tree_pp)
|
|
{
|
|
tree_pp = new pretty_printer ();
|
|
pp_needs_newline (tree_pp) = true;
|
|
pp_translate_identifiers (tree_pp) = false;
|
|
}
|
|
|
|
tree_pp->buffer->stream = file;
|
|
}
|
|
|
|
static void
|
|
newline_and_indent (pretty_printer *pp, int spc)
|
|
{
|
|
pp_newline (pp);
|
|
INDENT (spc);
|
|
}
|
|
|
|
/* Print the identifier ID to PRETTY-PRINTER. */
|
|
|
|
void
|
|
pp_tree_identifier (pretty_printer *pp, tree id)
|
|
{
|
|
if (pp_translate_identifiers (pp))
|
|
{
|
|
const char *text = identifier_to_locale (IDENTIFIER_POINTER (id));
|
|
pp_append_text (pp, text, text + strlen (text));
|
|
}
|
|
else
|
|
pp_append_text (pp, IDENTIFIER_POINTER (id),
|
|
IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id));
|
|
}
|
|
|
|
/* A helper function that is used to dump function information before the
|
|
function dump. */
|
|
|
|
void
|
|
dump_function_header (FILE *dump_file, tree fdecl, dump_flags_t flags)
|
|
{
|
|
const char *dname, *aname;
|
|
struct cgraph_node *node = cgraph_node::get (fdecl);
|
|
struct function *fun = DECL_STRUCT_FUNCTION (fdecl);
|
|
|
|
dname = lang_hooks.decl_printable_name (fdecl, 1);
|
|
|
|
if (DECL_ASSEMBLER_NAME_SET_P (fdecl))
|
|
aname = (IDENTIFIER_POINTER
|
|
(DECL_ASSEMBLER_NAME (fdecl)));
|
|
else
|
|
aname = "<unset-asm-name>";
|
|
|
|
fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d",
|
|
dname, aname, fun->funcdef_no);
|
|
if (!(flags & TDF_NOUID))
|
|
fprintf (dump_file, ", decl_uid=%d", DECL_UID (fdecl));
|
|
if (node)
|
|
{
|
|
fprintf (dump_file, ", cgraph_uid=%d", node->get_uid ());
|
|
fprintf (dump_file, ", symbol_order=%d)%s\n\n", node->order,
|
|
node->frequency == NODE_FREQUENCY_HOT
|
|
? " (hot)"
|
|
: node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
|
|
? " (unlikely executed)"
|
|
: node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
|
|
? " (executed once)"
|
|
: "");
|
|
}
|
|
else
|
|
fprintf (dump_file, ")\n\n");
|
|
}
|
|
|
|
/* Dump double_int D to pretty_printer PP. UNS is true
|
|
if D is unsigned and false otherwise. */
|
|
void
|
|
pp_double_int (pretty_printer *pp, double_int d, bool uns)
|
|
{
|
|
if (d.fits_shwi ())
|
|
pp_wide_integer (pp, d.low);
|
|
else if (d.fits_uhwi ())
|
|
pp_unsigned_wide_integer (pp, d.low);
|
|
else
|
|
{
|
|
unsigned HOST_WIDE_INT low = d.low;
|
|
HOST_WIDE_INT high = d.high;
|
|
if (!uns && d.is_negative ())
|
|
{
|
|
pp_minus (pp);
|
|
high = ~high + !low;
|
|
low = -low;
|
|
}
|
|
/* Would "%x%0*x" or "%x%*0x" get zero-padding on all
|
|
systems? */
|
|
sprintf (pp_buffer (pp)->digit_buffer,
|
|
HOST_WIDE_INT_PRINT_DOUBLE_HEX,
|
|
(unsigned HOST_WIDE_INT) high, low);
|
|
pp_string (pp, pp_buffer (pp)->digit_buffer);
|
|
}
|
|
}
|
|
|
|
#if __GNUC__ >= 10
|
|
# pragma GCC diagnostic pop
|
|
#endif
|