entry_util.ccGo to the documentation of this file.00001
00002
00003 class Program;
00004 class String;
00005
00006 #include "entry_util.h"
00007 #include "loopMark.h"
00008 #include "../ProgramUnit.h"
00009 #include "../Statement/GotoStmt.h"
00010 #include "../Statement/LabelStmt.h"
00011 #include "../Statement/ReturnStmt.h"
00012 #include "../Program.h"
00013 #include "../ProgramTag.h"
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 void
00026 float_entry_points(ProgramUnit & pgm)
00027 {
00028 Statement *p = pgm.stmts().first_ref();
00029
00030
00031
00032 for (Iterator<Statement> entry_iter = pgm.stmts().iterate_entry_points();
00033 entry_iter.valid();) {
00034
00035 Statement *c = &entry_iter.current();
00036
00037
00038 ++entry_iter;
00039
00040 if (c->stmt_class() != FLOW_ENTRY_STMT) {
00041
00042 Statement *t = c->next_ref();
00043
00044
00045 if (!t)
00046 t = c;
00047
00048 switch (t->stmt_class()) {
00049 case GOTO_STMT:
00050 {
00051
00052
00053 t = t->target_ref();
00054 }
00055 break;
00056
00057 case LABEL_STMT:
00058 break;
00059
00060 default:
00061 {
00062
00063
00064 t = c->prev_ref();
00065
00066 if (!t)
00067 t = c;
00068
00069
00070
00071
00072 if ((t == p) && (!entry_iter.valid())) {
00073 t = c->next_ref();
00074 if (!t)
00075 t = c;
00076 }
00077 else if (t->stmt_class() != LABEL_STMT) {
00078
00079
00080 t = new LabelStmt(pgm.stmts().new_tag(),
00081 pgm.stmts().new_label());
00082 pgm.stmts().ins_after(t, c);
00083 }
00084 }
00085 }
00086
00087
00088 if (p->next_ref() != c)
00089 pgm.stmts().move_after(*c, p);
00090
00091
00092 p = c->next_ref();
00093
00094 if (!p)
00095 p = c;
00096
00097
00098 if (((p != t) || (entry_iter.valid())) &&
00099 ((p->stmt_class() != GOTO_STMT) || (p->target_ref() != t))) {
00100 p = new GotoStmt(pgm.stmts().new_tag(), t);
00101 pgm.stmts().ins_after(p, c);
00102 }
00103 }
00104 }
00105 }
00106
00107
00108
00109
00110
00111
00112 void
00113 sink_return_points(ProgramUnit & pgm)
00114 {
00115
00116
00117 Statement *s = pgm.stmts().last_ref();
00118
00119
00120
00121 if (! s)
00122 return;
00123
00124 p_assert(s->stmt_class() == FLOW_EXIT_STMT,
00125 "Program unit has no FlowExitStmt.");
00126
00127 s = s->prev_ref();
00128
00129
00130
00131 Iterator<Statement> return_iter = pgm.stmts().stmts_of_type(RETURN_STMT);
00132
00133 if (! s || ! return_iter.valid())
00134 return;
00135
00136
00137
00138 if (s->stmt_class() != RETURN_STMT) {
00139 pgm.stmts().ins_after(new ReturnStmt(pgm.stmts().new_tag(), omega()),
00140 s);
00141 s = s->next_ref();
00142 }
00143
00144
00145
00146 LabelStmt *ls = 0;
00147
00148
00149
00150 for ( ; return_iter.valid(); ++return_iter) {
00151
00152 Statement *c = &return_iter.current();
00153
00154
00155 if (c == s)
00156 continue;
00157
00158
00159
00160
00161 if (c->expr_valid())
00162 continue;
00163
00164
00165
00166
00167 if (!ls) {
00168
00169 Statement *p = s->prev_ref();
00170
00171
00172 if (p->stmt_class() == LABEL_STMT)
00173 ls = (LabelStmt *) p;
00174 else {
00175
00176 ls = new LabelStmt(pgm.stmts().new_tag(),
00177 pgm.stmts().new_label());
00178 pgm.stmts().ins_before(ls, s);
00179 }
00180 }
00181
00182
00183 pgm.stmts().ins_before(new GotoStmt(pgm.stmts().new_tag(), ls), c);
00184
00185
00186 pgm.stmts().del(*c);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196 void
00197 split_multiple_entries(ProgramUnit &pgm, Program &new_pgms)
00198 {
00199 float_entry_points(pgm);
00200 String orig_entry_name = pgm.routine_name_ref();
00201 Iterator<Statement> entry_iter = pgm.stmts().stmts_of_type(ENTRY_STMT);
00202
00203 if (entry_iter.valid())
00204 ++entry_iter;
00205
00206 if (entry_iter.valid()) {
00207 for ( ; entry_iter.valid(); ++entry_iter) {
00208 const Statement &entry_stmt = entry_iter.current();
00209 ProgramUnit *pgm_clone = new ProgramUnit(pgm);
00210
00211
00212
00213 String entry_tag(entry_stmt.tag());
00214 Iterator<Statement> c_entry_iter = pgm_clone->stmts().stmts_of_type(ENTRY_STMT);
00215
00216 for ( ; c_entry_iter.valid(); ++c_entry_iter) {
00217 if (entry_tag != c_entry_iter.current().tag()) {
00218 pgm_clone->symtab().del(
00219 c_entry_iter.current().routine_guarded().symbol().name_ref());
00220 pgm_clone->stmts().del(c_entry_iter.current());
00221 }
00222 }
00223
00224
00225
00226 Iterator<Statement> header_iter = pgm_clone->stmts().iterator();
00227
00228 for ( ; header_iter.valid(); ++header_iter) {
00229 Statement &header_stmt = header_iter.current();
00230
00231 if (entry_tag == header_stmt.tag())
00232 break;
00233 else if (header_stmt.stmt_class() != FLOW_ENTRY_STMT)
00234 pgm_clone->stmts().del(header_stmt);
00235 }
00236
00237
00238
00239 ProgramTag clone_tag;
00240 pgm_clone->rename(clone_tag);
00241 String new_entry_name = entry_stmt.routine_guarded().symbol().name_ref();
00242 reset_loop_labels(*pgm_clone, orig_entry_name, new_entry_name);
00243 new_pgms.absorb(pgm_clone);
00244 }
00245
00246
00247
00248
00249 entry_iter.reset();
00250 ++entry_iter;
00251
00252 for ( ; entry_iter.valid(); ++entry_iter) {
00253 pgm.symtab().del(
00254 entry_iter.current().routine_guarded().symbol().name_ref());
00255 pgm.stmts().del(entry_iter.current());
00256 }
00257 }
00258 }
00259
|