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