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 : : #define INCLUDE_MEMORY
24 : : #include "config.h"
25 : : #include "system.h"
26 : : #include "gcc-consolidation.h"
27 : :
28 : : #include <stdbool.h>
29 : : # if !defined (PROC_D)
30 : : # define PROC_D
31 : : typedef void (*PROC_t) (void);
32 : : typedef struct { PROC_t proc; } PROC;
33 : : # endif
34 : :
35 : : # if !defined (TRUE)
36 : : # define TRUE (1==1)
37 : : # endif
38 : :
39 : : # if !defined (FALSE)
40 : : # define FALSE (1==0)
41 : : # endif
42 : :
43 : : #define _M2SSA_C
44 : :
45 : : #include "GM2SSA.h"
46 : : # include "GM2Debug.h"
47 : : # include "GNameKey.h"
48 : : # include "GStrIO.h"
49 : : # include "GNumberIO.h"
50 : : # include "GM2Error.h"
51 : : # include "GM2Batch.h"
52 : : # include "GM2Quiet.h"
53 : : # include "GM2Scope.h"
54 : : # include "GM2StackWord.h"
55 : : # include "GM2Options.h"
56 : : # include "GLists.h"
57 : : # include "GM2Printf.h"
58 : : # include "GSymbolTable.h"
59 : : # include "GM2Quads.h"
60 : :
61 : : # define M2SSA_EnableSSA false
62 : : static M2StackWord_StackOfWord stack;
63 : : static Lists_List visited;
64 : :
65 : : /*
66 : : DiscoverSSA - perform a very simple check to determine whether a
67 : : temporary is a single use write.
68 : : */
69 : :
70 : : extern "C" void M2SSA_DiscoverSSA (unsigned int scope);
71 : :
72 : : /*
73 : : writtenOnce - return TRUE if variable is written to once.
74 : : */
75 : :
76 : : static bool writtenOnce (unsigned int variable);
77 : :
78 : : /*
79 : : DetermineSSA - performs a trivial check to see if the temporary is written to
80 : : once.
81 : : */
82 : :
83 : : static void DetermineSSA (unsigned int variable);
84 : :
85 : : /*
86 : : DiscoverSSATemporaries -
87 : : */
88 : :
89 : : static void DiscoverSSATemporaries (unsigned int scope);
90 : :
91 : :
92 : : /*
93 : : writtenOnce - return TRUE if variable is written to once.
94 : : */
95 : :
96 : 0 : static bool writtenOnce (unsigned int variable)
97 : : {
98 : 0 : unsigned int writeStart;
99 : 0 : unsigned int writeEnd;
100 : 0 : unsigned int readStart;
101 : 0 : unsigned int readEnd;
102 : :
103 : 0 : SymbolTable_GetWriteQuads (variable, SymbolTable_GetMode (variable), &writeStart, &writeEnd);
104 : 0 : SymbolTable_GetReadQuads (variable, SymbolTable_GetMode (variable), &readStart, &readEnd);
105 : 0 : return (writeStart == writeEnd) && ((readStart > writeStart) || (readStart == 0));
106 : : /* static analysis guarentees a RETURN statement will be used before here. */
107 : : __builtin_unreachable ();
108 : : }
109 : :
110 : :
111 : : /*
112 : : DetermineSSA - performs a trivial check to see if the temporary is written to
113 : : once.
114 : : */
115 : :
116 : 0 : static void DetermineSSA (unsigned int variable)
117 : : {
118 : 0 : NameKey_Name name;
119 : :
120 : 0 : if (M2SSA_EnableSSA && (SymbolTable_IsTemporary (variable)))
121 : : {
122 : : name = SymbolTable_GetSymName (variable);
123 : : if (writtenOnce (variable))
124 : : {
125 : : /* avoid dangling else. */
126 : : SymbolTable_PutVariableSSA (variable, true);
127 : : if (M2Options_CompilerDebugging)
128 : : {
129 : : M2Printf_printf1 ((const char *) " temporary: %a SSA found\\n", 29, (const unsigned char *) &name, (sizeof (name)-1));
130 : : }
131 : : }
132 : : else
133 : : {
134 : : if (M2Options_CompilerDebugging)
135 : : {
136 : : M2Printf_printf1 ((const char *) " temporary: %a not SSA\\n", 27, (const unsigned char *) &name, (sizeof (name)-1));
137 : : }
138 : : }
139 : : }
140 : 0 : }
141 : :
142 : :
143 : : /*
144 : : DiscoverSSATemporaries -
145 : : */
146 : :
147 : 180131 : static void DiscoverSSATemporaries (unsigned int scope)
148 : : {
149 : 180131 : unsigned int n;
150 : 180131 : unsigned int variable;
151 : :
152 : 180131 : if (M2Options_CompilerDebugging)
153 : : {
154 : 0 : M2Printf_printf1 ((const char *) "examining scope %d\\n", 20, (const unsigned char *) &scope, (sizeof (scope)-1));
155 : : }
156 : 180131 : n = 1;
157 : 180131 : variable = SymbolTable_GetNth (scope, n);
158 : 1295784 : while (variable != SymbolTable_NulSym)
159 : : {
160 : 935522 : DetermineSSA (variable);
161 : 935522 : n += 1;
162 : 935522 : variable = SymbolTable_GetNth (scope, n);
163 : : }
164 : 180131 : }
165 : :
166 : :
167 : : /*
168 : : DiscoverSSA - perform a very simple check to determine whether a
169 : : temporary is a single use write.
170 : : */
171 : :
172 : 180131 : extern "C" void M2SSA_DiscoverSSA (unsigned int scope)
173 : : {
174 : 180131 : M2Scope_ScopeBlock sb;
175 : :
176 : 180131 : if (! (Lists_IsItemInList (visited, scope)))
177 : : {
178 : 180131 : Lists_IncludeItemIntoList (visited, scope);
179 : 180131 : sb = M2Scope_InitScopeBlock (scope);
180 : 180131 : M2StackWord_PushWord (stack, scope);
181 : 180131 : if (M2Options_CompilerDebugging)
182 : : {
183 : 0 : M2Printf_printf1 ((const char *) "DiscoverSSA %d\\n", 16, (const unsigned char *) &scope, (sizeof (scope)-1));
184 : : }
185 : 180131 : if (M2Options_CompilerDebugging)
186 : : {
187 : 0 : M2Printf_printf0 ((const char *) "ForeachInnerModuleDo\\n", 22);
188 : : }
189 : 180131 : SymbolTable_ForeachInnerModuleDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
190 : 180131 : if (M2Options_CompilerDebugging)
191 : : {
192 : 0 : M2Printf_printf0 ((const char *) "ForeachProcedureDo\\n", 20);
193 : : }
194 : 180131 : SymbolTable_ForeachProcedureDo (scope, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) M2SSA_DiscoverSSA});
195 : 180131 : DiscoverSSATemporaries (scope);
196 : 180131 : M2Debug_Assert ((M2StackWord_PopWord (stack)) == scope);
197 : 180131 : M2Scope_KillScopeBlock (&sb);
198 : : }
199 : 180131 : }
200 : :
201 : 13568 : extern "C" void _M2_M2SSA_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
202 : : {
203 : 13568 : stack = M2StackWord_InitStackWord ();
204 : 13568 : Lists_InitList (&visited);
205 : 13568 : }
206 : :
207 : 0 : extern "C" void _M2_M2SSA_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
208 : : {
209 : 0 : }
|