00001
00002 #ifdef POLARIS_GNU_PRAGMAS
00003 #pragma implementation
00004 #endif
00005
00006 #include "Collection/Assign.h"
00007 #include "Collection/Iterator.h"
00008 #include "Collection/List.h"
00009 #include "Collection/Mutator.h"
00010 #include "Expression/expr_funcs.h"
00011
00012 #include "GSAPathExpr.h"
00013
00014 template class Iterator<GSAPathExpr>;
00015 template class Mutator<GSAPathExpr>;
00016 template class Assign<GSAPathExpr>;
00017 template class List<GSAPathExpr>;
00018 template class TypedCollection<GSAPathExpr>;
00019 template ostream & operator << (ostream &, const List<GSAPathExpr> &);
00020
00021 ostream &
00022 operator << (ostream & o,
00023 const GSAPathExpr & e)
00024 {
00025 e.print(o);
00026 return o;
00027 }
00028
00029 Expression * build_expr(const GSAPathExpr &a, const Statement &cur,
00030 const Statement &pred)
00031 {
00032 if (&cur==a.tail) {
00033 int i = cur.pred()._member((Statement &) pred);
00034 p_assert(i>=0, "Not a predecessor!");
00035 return constant(i);
00036 }
00037
00038 if (cur.stmt_class() == IF_STMT ||
00039 cur.stmt_class() == ARITHMETIC_IF_STMT ||
00040 cur.stmt_class() == COMPUTED_GOTO_STMT ||
00041 cur.stmt_class() == ASSIGNED_GOTO_STMT ||
00042 cur.stmt_class() == ELSEIF_STMT) {
00043
00044 const GSAPathMap *p = a.find_ref(cur);
00045 if (p->children.entries()==1)
00046 return (p->children[0]) ?
00047 build_expr(a,*p->children[0],cur) : omega();
00048
00049 List<Expression> *t_parameter = new List<Expression>;
00050 Expression * gate_expr = cur.expr().clone();
00051
00052 for (int i=0; i<p->children.entries(); ++i){
00053 if (p->children[i]==NULL)
00054 t_parameter->ins_last(omega());
00055 else
00056 t_parameter->ins_last(build_expr(a,*p->children[i],cur));
00057 }
00058
00059 return gamma(gate_expr, comma(t_parameter));
00060
00061 }else if (cur.stmt_class() == READ_STMT ||
00062 cur.stmt_class() == WRITE_STMT ||
00063 cur.stmt_class() == PRINT_STMT ||
00064 cur.stmt_class() == OPEN_STMT ||
00065 cur.stmt_class() == CLOSE_STMT ||
00066 cur.stmt_class() == REWIND_STMT ||
00067 cur.stmt_class() == BACKSPACE_STMT ||
00068 cur.stmt_class() == ENDFILE_STMT ||
00069 cur.stmt_class() == INQUIRE_STMT ||
00070 cur.stmt_class() == FLOW_ENTRY_STMT) {
00071 const GSAPathMap *p = a.find_ref(cur);
00072 if (p->children.entries()==1)
00073 return (p->children[0]) ?
00074 build_expr(a,*p->children[0],cur) : omega();
00075
00076 List<Expression> *t_parameter = new List<Expression>;
00077
00078 for (int i=0; i<p->children.entries(); ++i){
00079 if (p->children[i]==NULL)
00080 t_parameter->ins_last(omega());
00081 else
00082 t_parameter->ins_last(build_expr(a,*p->children[i],cur));
00083 }
00084
00085 return gamma(omega(), comma(t_parameter));
00086
00087
00088 }else if (cur.stmt_class() == DO_STMT) {
00089
00090 const GSAPathMap *p = a.find_ref(cur);
00091 if (p->children.entries()==1)
00092 return (p->children[0]) ?
00093 build_expr(a,*p->children[0],cur) : omega();
00094
00095
00096 if (p->children[0] != cur.follow_ref())
00097 return (p->children[1]) ? build_expr(a,*p->children[1],cur) : omega();
00098 else
00099 return (p->children[0]) ? build_expr(a,*p->children[0],cur) : omega();
00100
00101 } else if (cur.succ().entries()==1) {
00102
00103 const GSAPathMap *p = a.find_ref(cur);
00104 return (p->children[0]) ? build_expr(a,*p->children[0],cur) : omega();
00105
00106 } else {
00107
00108 cerr << cur << endl;
00109 cerr << cur.stmt_class() << endl;
00110 p_abort("Unknown branch statement class");
00111
00112 }
00113 return NULL;
00114 }
00115
00116 Expression * build_mu(const GSAPathExpr &a, const Statement &cur,
00117 const Statement & NOTUSED(pred), Expression *ex)
00118 {
00119 const GSAPathMap *p = a.find_ref(cur);
00120 List<Expression> *t = new List<Expression>;
00121 if (ex) {
00122 t->ins_last(ex);
00123 for (int i = 0; i<p->children.entries(); ++i)
00124 if (p->children[i]!=NULL)
00125 t->ins_last(build_expr(a,*p->children[i],cur));
00126 } else {
00127 t->ins_last(constant(0));
00128 t->ins_last(constant(1));
00129 }
00130
00131 return mu(comma(t));
00132 }
00133
00134 int
00135 GSAPathExpr::structures_OK() const
00136 {
00137 return 1;
00138 }
00139
00140 void
00141 GSAPathExpr::print(ostream & o) const
00142 {
00143 if (expr) o << *expr << endl;
00144 }
00145
00146 void
00147 GSAPathExpr::fill_expr()
00148 {
00149 if ((expr==NULL) && (head!=NULL))
00150 expr = build_expr(*this,*head,*head);
00151 }
00152
00153 void
00154 GSAPathExpr::fill_expr(Expression *ex)
00155 {
00156 if ((expr==NULL) && (head!=NULL))
00157 expr = build_mu(*this,*head,*head,ex);
00158 }
00159
00160 void
00161 GSAPathExpr::add_edge(Statement &h, Statement &t, int b)
00162 {
00163
00164 if (head == 0){
00165
00166 head = &h;
00167 tail = &t;
00168 GSAPathMap *p = new GSAPathMap(h.succ().entries());
00169 p->children[b] = &t;
00170 ins(h, p);
00171 ins(t, new GSAPathMap(h.succ().entries()));
00172
00173 } else {
00174
00175 GSAPathMap *p = find_ref(h);
00176 GSAPathMap *q = find_ref(t);
00177 if (!q) ins(t, new GSAPathMap(t.succ().entries()));
00178 if (p)
00179 p->children[b] = &t;
00180 else {
00181 GSAPathMap *p = new GSAPathMap(h.succ().entries());
00182 p->children[b] = &t;
00183 }
00184 }
00185 }
00186
00187
00188
00189 GSAPathExpr &
00190 GSAPathExpr::operator |= (const GSAPathExpr &a)
00191 {
00192 p_assert(head == a.head,"Different header !");
00193 p_assert(tail == a.tail,"Different tail !");
00194
00195 for (KeyIterator<Statement,GSAPathMap> iter = a; iter.valid(); ++iter){
00196 Statement & s = iter.current_key();
00197 GSAPathMap & t = iter.current_data();
00198 GSAPathMap *p = find_ref(s);
00199
00200 if (p){
00201 if (p->children.entries()==1 && p->children[0])
00202 ;
00203 else if (t.children.entries()==1 && t.children[0]) {
00204 p->children.resize(1);
00205 p->children[0] = t.children[0];
00206 } else
00207 for (int i=0; i<t.children.entries(); ++i)
00208 if (t.children[i]) p->children[i] = t.children[i];
00209 } else
00210 ins(s, t.clone());
00211 }
00212
00213 return *this;
00214 }
00215
00216
00217 GSAPathExpr &
00218 GSAPathExpr::operator *= (const GSAPathExpr &a)
00219 {
00220 p_assert(tail == a.head,"Different head and tail!");
00221
00222 tail = a.tail;
00223
00224 for (KeyIterator<Statement,GSAPathMap> iter = a; iter.valid(); ++iter){
00225 Statement & s = iter.current_key();
00226 GSAPathMap & t = iter.current_data();
00227 GSAPathMap *p = find_ref(s);
00228
00229 if (p){
00230 if (p->children.entries()==1 && p->children[0])
00231 ;
00232 else if (t.children.entries()==1 && t.children[0]) {
00233 p->children.resize(1);
00234 p->children[0] = t.children[0];
00235 } else
00236 for (int i=0; i<p->children.entries(); ++i)
00237 if (t.children[i]) p->children[i] = t.children[i];
00238 } else
00239 ins(s, t.clone());
00240 }
00241
00242 return *this;
00243 }
00244
00245
00246 GSAPathExpr &
00247 GSAPathExpr::operator /= (const GSAPathExpr &a)
00248 {
00249 p_assert(head == a.tail,"Different head and tail!");
00250
00251 head = a.head;
00252 for (KeyIterator<Statement,GSAPathMap> iter = a; iter.valid(); ++iter){
00253 Statement & s = iter.current_key();
00254 GSAPathMap & t = iter.current_data();
00255 GSAPathMap *p = find_ref(s);
00256
00257 if (p){
00258 if (p->children.entries()==1 && p->children[0])
00259 ;
00260 else if (t.children.entries()==1 && t.children[0]) {
00261 p->children.resize(1);
00262 p->children[0] = t.children[0];
00263 } else
00264 for (int i=0; i<p->children.entries(); ++i)
00265 if (t.children[i]) p->children[i] = t.children[i];
00266 } else
00267 ins(s, t.clone());
00268 }
00269
00270 return *this;
00271 }
00272
00273 GSAPathExpr *
00274 GSAPathExpr::clone() const
00275 {
00276 GSAPathExpr *res = new GSAPathExpr();
00277
00278 for (KeyIterator<Statement,GSAPathMap> iter = *this; iter.valid(); ++iter)
00279 res->ins(iter.current_key(), iter.current_data().clone());
00280
00281 res->head = head;
00282 res->tail = tail;
00283
00284 return res;
00285 }
00286
00287 Listable *
00288 GSAPathExpr::listable_clone() const
00289 {
00290 return (Listable *) clone();
00291 }