Branch data 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-2024 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 : 186237 : static void DiscoverSSATemporaries (unsigned int scope)
147 : : {
148 : 186237 : unsigned int n;
149 : 186237 : unsigned int variable;
150 : :
151 : 186237 : if (M2Options_CompilerDebugging)
152 : : {
153 : 0 : M2Printf_printf1 ((const char *) "examining scope %d\\n", 20, (const unsigned char *) &scope, (sizeof (scope)-1));
154 : : }
155 : 186237 : n = 1;
156 : 186237 : variable = SymbolTable_GetNth (scope, n);
157 : 1336412 : while (variable != SymbolTable_NulSym)
158 : : {
159 : 963938 : DetermineSSA (variable);
160 : 963938 : n += 1;
161 : 963938 : variable = SymbolTable_GetNth (scope, n);
162 : : }
163 : 186237 : }
164 : :
165 : :
166 : : /*
167 : : DiscoverSSA - perform a very simple check to determine whether a
168 : : temporary is a single use write.
169 : : */
170 : :
171 : 186237 : extern "C" void M2SSA_DiscoverSSA (unsigned int scope)
172 : : {
173 : 186237 : M2Scope_ScopeBlock sb;
174 : :
175 : 186237 : if (! (Lists_IsItemInList (visited, scope)))
176 : : {
177 : 186237 : Lists_IncludeItemIntoList (visited, scope);
178 : 186237 : sb = M2Scope_InitScopeBlock (scope);
179 : 186237 : M2StackWord_PushWord (stack, scope);
180 : 186237 : if (M2Options_CompilerDebugging)
181 : : {
182 : 0 : M2Printf_printf1 ((const char *) "DiscoverSSA %d\\n", 16, (const unsigned char *) &scope, (sizeof (scope)-1));
183 : : }
184 : 186237 : if (M2Options_CompilerDebugging)
185 : : {
186 : 0 : M2Printf_printf0 ((const char *) "ForeachInnerModuleDo\\n", 22);
187 : : }
188 : 186237 : SymbolTable_ForeachInnerModuleDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
189 : 186237 : if (M2Options_CompilerDebugging)
190 : : {
191 : 0 : M2Printf_printf0 ((const char *) "ForeachProcedureDo\\n", 20);
192 : : }
193 : 186237 : SymbolTable_ForeachProcedureDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
194 : 186237 : DiscoverSSATemporaries (scope);
195 : 186237 : M2Debug_Assert ((M2StackWord_PopWord (stack)) == scope);
196 : 186237 : M2Scope_KillScopeBlock (&sb);
197 : : }
198 : 186237 : }
199 : :
200 : 14232 : extern "C" void _M2_M2SSA_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
201 : : {
202 : 14232 : stack = M2StackWord_InitStackWord ();
203 : 14232 : Lists_InitList (&visited);
204 : 14232 : }
205 : :
206 : 0 : extern "C" void _M2_M2SSA_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
207 : : {
208 : 0 : }
|