Line data Source code
1 : /* do not edit automatically generated by mc from M2SSA. */
2 : /* M2SSA.mod discover very obvious single assignment temporaries.
3 :
4 : Copyright (C) 2021-2026 Free Software Foundation, Inc.
5 : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 :
7 : This file is part of GNU Modula-2.
8 :
9 : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3, or (at your option)
12 : any later version.
13 :
14 : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with GNU Modula-2; see the file COPYING3. If not see
21 : <http://www.gnu.org/licenses/>. */
22 :
23 : #include "config.h"
24 : #include "system.h"
25 : #include "gcc-consolidation.h"
26 :
27 : #include <stdbool.h>
28 : # if !defined (PROC_D)
29 : # define PROC_D
30 : typedef void (*PROC_t) (void);
31 : typedef struct { PROC_t proc; } PROC;
32 : # endif
33 :
34 : # if !defined (TRUE)
35 : # define TRUE (1==1)
36 : # endif
37 :
38 : # if !defined (FALSE)
39 : # define FALSE (1==0)
40 : # endif
41 :
42 : #define _M2SSA_C
43 :
44 : #include "GM2SSA.h"
45 : # include "GM2Debug.h"
46 : # include "GNameKey.h"
47 : # include "GStrIO.h"
48 : # include "GNumberIO.h"
49 : # include "GM2Error.h"
50 : # include "GM2Batch.h"
51 : # include "GM2Quiet.h"
52 : # include "GM2Scope.h"
53 : # include "GM2StackWord.h"
54 : # include "GM2Options.h"
55 : # include "GLists.h"
56 : # include "GM2Printf.h"
57 : # include "GSymbolTable.h"
58 : # include "GM2Quads.h"
59 :
60 : # define M2SSA_EnableSSA false
61 : static M2StackWord_StackOfWord stack;
62 : static Lists_List visited;
63 :
64 : /*
65 : DiscoverSSA - perform a very simple check to determine whether a
66 : temporary is a single use write.
67 : */
68 :
69 : extern "C" void M2SSA_DiscoverSSA (unsigned int scope);
70 :
71 : /*
72 : writtenOnce - return TRUE if variable is written to once.
73 : */
74 :
75 : static bool writtenOnce (unsigned int variable);
76 :
77 : /*
78 : DetermineSSA - performs a trivial check to see if the temporary is written to
79 : once.
80 : */
81 :
82 : static void DetermineSSA (unsigned int variable);
83 :
84 : /*
85 : DiscoverSSATemporaries -
86 : */
87 :
88 : static void DiscoverSSATemporaries (unsigned int scope);
89 :
90 :
91 : /*
92 : writtenOnce - return TRUE if variable is written to once.
93 : */
94 :
95 0 : static bool writtenOnce (unsigned int variable)
96 : {
97 0 : unsigned int writeStart;
98 0 : unsigned int writeEnd;
99 0 : unsigned int readStart;
100 0 : unsigned int readEnd;
101 :
102 0 : SymbolTable_GetWriteQuads (variable, SymbolTable_GetMode (variable), &writeStart, &writeEnd);
103 0 : SymbolTable_GetReadQuads (variable, SymbolTable_GetMode (variable), &readStart, &readEnd);
104 0 : return (writeStart == writeEnd) && ((readStart > writeStart) || (readStart == 0));
105 : /* static analysis guarentees a RETURN statement will be used before here. */
106 : __builtin_unreachable ();
107 : }
108 :
109 :
110 : /*
111 : DetermineSSA - performs a trivial check to see if the temporary is written to
112 : once.
113 : */
114 :
115 0 : static void DetermineSSA (unsigned int variable)
116 : {
117 0 : NameKey_Name name;
118 :
119 0 : if (M2SSA_EnableSSA && (SymbolTable_IsTemporary (variable)))
120 : {
121 : name = SymbolTable_GetSymName (variable);
122 : if (writtenOnce (variable))
123 : {
124 : /* avoid dangling else. */
125 : SymbolTable_PutVariableSSA (variable, true);
126 : if (M2Options_CompilerDebugging)
127 : {
128 : M2Printf_printf1 ((const char *) " temporary: %a SSA found\\n", 29, (const unsigned char *) &name, (sizeof (name)-1));
129 : }
130 : }
131 : else
132 : {
133 : if (M2Options_CompilerDebugging)
134 : {
135 : M2Printf_printf1 ((const char *) " temporary: %a not SSA\\n", 27, (const unsigned char *) &name, (sizeof (name)-1));
136 : }
137 : }
138 : }
139 0 : }
140 :
141 :
142 : /*
143 : DiscoverSSATemporaries -
144 : */
145 :
146 233429 : static void DiscoverSSATemporaries (unsigned int scope)
147 : {
148 233429 : unsigned int n;
149 233429 : unsigned int variable;
150 :
151 233429 : if (M2Options_CompilerDebugging)
152 : {
153 0 : M2Printf_printf1 ((const char *) "examining scope %d\\n", 20, (const unsigned char *) &scope, (sizeof (scope)-1));
154 : }
155 233429 : n = 1;
156 233429 : variable = SymbolTable_GetNth (scope, n);
157 1630455 : while (variable != SymbolTable_NulSym)
158 : {
159 1163597 : DetermineSSA (variable);
160 1163597 : n += 1;
161 1163597 : variable = SymbolTable_GetNth (scope, n);
162 : }
163 233429 : }
164 :
165 :
166 : /*
167 : DiscoverSSA - perform a very simple check to determine whether a
168 : temporary is a single use write.
169 : */
170 :
171 233429 : extern "C" void M2SSA_DiscoverSSA (unsigned int scope)
172 : {
173 233429 : M2Scope_ScopeBlock sb;
174 :
175 233429 : if (! (Lists_IsItemInList (visited, scope)))
176 : {
177 233429 : Lists_IncludeItemIntoList (visited, scope);
178 233429 : sb = M2Scope_InitScopeBlock (scope);
179 233429 : M2StackWord_PushWord (stack, scope);
180 233429 : if (M2Options_CompilerDebugging)
181 : {
182 0 : M2Printf_printf1 ((const char *) "DiscoverSSA %d\\n", 16, (const unsigned char *) &scope, (sizeof (scope)-1));
183 : }
184 233429 : if (M2Options_CompilerDebugging)
185 : {
186 0 : M2Printf_printf0 ((const char *) "ForeachInnerModuleDo\\n", 22);
187 : }
188 233429 : SymbolTable_ForeachInnerModuleDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
189 233429 : if (M2Options_CompilerDebugging)
190 : {
191 0 : M2Printf_printf0 ((const char *) "ForeachProcedureDo\\n", 20);
192 : }
193 233429 : SymbolTable_ForeachProcedureDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
194 233429 : DiscoverSSATemporaries (scope);
195 233429 : M2Debug_Assert ((M2StackWord_PopWord (stack)) == scope);
196 233429 : M2Scope_KillScopeBlock (&sb);
197 : }
198 233429 : }
199 :
200 14952 : extern "C" void _M2_M2SSA_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
201 : {
202 14952 : stack = M2StackWord_InitStackWord ();
203 14952 : Lists_InitList (&visited);
204 14952 : }
205 :
206 0 : extern "C" void _M2_M2SSA_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
207 : {
208 0 : }
|