aboutsummaryrefslogtreecommitdiff
path: root/gcc/algol68/a68-parser-serial-dsa.cc
blob: b48c13da3bf6d20c59522971359d234336a62890 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* Check dynamic stack usage in serial clauses.
   Copyright (C) 2025 Jose E. Marchesi.

   Written by Jose E. Marchesi.

   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/>.  */

/* This file implements a phase that determines what serial clauses contain
   phrases whose elaboration may involve dynamic stack allocation.  It
   annotates the SERIAL_CLAUSE parse nodes by setting the DYNAMIC_STACK_ALLOCS
   flag.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "options.h"

#include "a68.h"

/* Uncomment the following line for debugging traces.  */
/* #define SERIAL_DSA_DEBUG */

static void
serial_dsa_check_serial_clause (NODE_T *p, bool *dsa)
{
  for (; p != NO_NODE; FORWARD (p))
    {
      if (IS (p, GENERATOR))
	{
	  /* LOC generators always result in dyamic stack allocation regardless
	     of the mode of the allocated value.  */
	  if (IS (SUB (p), LOC_SYMBOL))
	    {
#ifdef SERIAL_DSA_DEBUG
	      fprintf (stderr, "serial_dsa: %s:%d: loc generator implies DSA\n",
		       FILENAME (LINE (INFO (p))),
		       LINE_NUMBER (p));
#endif
	      *dsa = true;
	      return;
	    }
	}
      else if (IS (p, DEFINING_IDENTIFIER))
	{
	  /* Variable declarations of values with sample loc generators will
	     result in dynamic stack allocation.

	     Note that label declarations do no have a mode, so we have to
	     check for MOID (p).  */

	  if (MOID (p) != NO_MOID && IS_REF (MOID (p)))
	    {
	      bool heap = HEAP (TAX (p)) == HEAP_SYMBOL;
	      if (HAS_ROWS (SUB (MOID (p))) && !heap)
		{
#ifdef SERIAL_DSA_DEBUG		  
		  fprintf (stderr,
			   "serial_dsa: %s:%d: defining identifier %s implies DSA\n",
			   FILENAME (LINE (INFO (p))),
			   LINE_NUMBER (p),
			   NSYMBOL (p));
#endif
		  *dsa = true;
		  return;
		}
	    }
	}
      else
	{
	  /* Inner serial clauses will take care of their own.  Code in routine
	     texts will not impact the stack of the containing serial
	     clause.  */
	  if (!IS (p, SERIAL_CLAUSE) && !IS (p, ROUTINE_TEXT))
	    serial_dsa_check_serial_clause (SUB (p), dsa);
	}
    }
}

void
a68_serial_dsa (NODE_T *p)
{
  for (; p != NO_NODE; FORWARD (p))
    {
      a68_serial_dsa (SUB (p));
      if (IS (p, SERIAL_CLAUSE))
	{
	  bool dsa = false;
	  serial_dsa_check_serial_clause (SUB (p), &dsa);
	  DYNAMIC_STACK_ALLOCS (p) = dsa;
#ifdef SERIAL_DSA_DEBUG
	  if (dsa)
	    {
	      fprintf (stderr, "serial_dsa: %s:%d: marking serial clause %p as DSA\n",
		       FILENAME (LINE (INFO (p))),
		       LINE_NUMBER (p),
		       (void *) p);
	    }
	  
#endif
	}
    }
}