range_dict_util.ccGo to the documentation of this file.00001
00002
00003
00004
00005 #include <map>
00006
00007 #include "ProgramUnit.h"
00008 #include "../Collection/Iterator.h"
00009 #include "../Symbol/FunctionSymbol.h"
00010 #include "../Statement/Statement.h"
00011 #include "../Directive/AssertMayMod.h"
00012 #include "../Symtab.h"
00013
00014 #include "range_dict_util.h"
00015
00016
00017
00018
00019
00020 void
00021 sort_sym_list(RefList<Symbol> &sym_list)
00022 {
00023 RefList<Symbol> sym_queue = sym_list;
00024 sym_list.clear();
00025
00026 while (sym_queue.entries()) {
00027 Symbol &sym = sym_queue.grab(0);
00028 const char *sym_name = sym.name_ref();
00029 Symbol *prev = 0;
00030 Iterator<Symbol> sorted_iter = sym_list;
00031
00032 for ( ; sorted_iter.valid(); ++sorted_iter) {
00033 int name_cmp = strcmp(sym_name, sorted_iter.current().name_ref());
00034
00035 if (name_cmp < 0)
00036 break;
00037 else
00038 prev = &sorted_iter.current();
00039 }
00040
00041 sym_list.ins_after(sym, *prev);
00042 }
00043 }
00044
00045
00046
00047
00048
00049
00050 static void
00051 _fix_intr_var_conflicts(Symtab &symtab, Symbol &var)
00052 {
00053 if (var.sym_class() != FUNCTION_CLASS || ! var.intrinsic()) {
00054 Symbol *var_ptr = symtab.grab(var.name_ref());
00055
00056 Symbol *intr = new FunctionSymbol(var.name_ref(),
00057 make_type(INTEGER_TYPE),
00058 NOT_EXTERNAL, IS_INTRINSIC,
00059 NOT_FORMAL);
00060 symtab.ins(intr);
00061 symtab.rename_and_ins(var_ptr);
00062 }
00063 }
00064
00065 void
00066 remove_min_max_var_conflicts(Symtab &symtab)
00067 {
00068 Symbol *min_sym = symtab.find_ref("MIN");
00069
00070 if (min_sym)
00071 _fix_intr_var_conflicts(symtab, *min_sym);
00072
00073 Symbol *max_sym = symtab.find_ref("MAX");
00074
00075 if (max_sym)
00076 _fix_intr_var_conflicts(symtab, *max_sym);
00077 }
00078
00079
00080
00081
00082
00083
00084 RefSet<Symbol> *
00085 stmt_maymods(const Statement &stmt)
00086 {
00087 RefSet<Symbol> *maymods = 0;
00088 Iterator<Assertion> asrt_iter = stmt.assertions();
00089
00090 for ( ; asrt_iter.valid(); ++asrt_iter) {
00091 Assertion &asrt = asrt_iter.current();
00092
00093 if (asrt.type() == AS_MAYMOD) {
00094 if (! maymods)
00095 maymods = new RefSet<Symbol>;
00096
00097 if (asrt.arg_list_valid()) {
00098 Iterator<Expression> aexpr_iter = asrt.arg_list_guarded();
00099
00100 for ( ; aexpr_iter.valid(); ++aexpr_iter) {
00101 Symbol *var_ref = aexpr_iter.current().base_variable_ref();
00102
00103 if (var_ref)
00104 maymods->ins(*var_ref);
00105 }
00106 }
00107 }
00108 }
00109
00110 return maymods;
00111 }
00112
00113
00114 static void get_array_refs(Expression& expr, RefList<Expression>& array_refs){
00115 if (expr.op()==ARRAY_REF_OP){
00116 array_refs.ins_last(expr);
00117 }
00118 for(Iterator<Expression> expit=expr.arg_list(); expit.valid(); ++expit){
00119 get_array_refs(expit.current(), array_refs);
00120 }
00121 }
00122
00123
00124 static Statement* skip_blocks(Statement* ref){
00125 Statement* toret=ref;
00126 Statement* next=toret;
00127 while(next){
00128 switch(next->stmt_class()){
00129 case ENDDO_STMT:
00130 case ENDIF_STMT:
00131 case FLOW_EXIT_STMT:
00132
00133 return toret;
00134 case DO_STMT:
00135 case WHILE_STMT:
00136
00137 toret=next->follow_ref();
00138 break;
00139 case IF_STMT:
00140
00141 toret=next->matching_endif_ref();
00142 break;
00143 default:
00144 toret=next->next_ref();
00145 }
00146 next=toret;
00147 }
00148 return toret;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 void enforce_standard_within_bounds(ProgramUnit& pgm,
00168 RefList<Statement>& new_ifs){
00169
00170 return;
00171
00172
00173 Iterator<Statement> loopit=pgm.stmts().stmts_of_type(DO_STMT);
00174 for( ; loopit.valid(); ++loopit){
00175
00176
00177
00178 RefList<Expression> base;
00179 if (loopit.current().init().op()==ID_OP){
00180 base.ins_last(loopit.current().init());
00181 }
00182 if (loopit.current().limit().op()==ID_OP){
00183 base.ins_last(loopit.current().limit());
00184 }
00185 if (base.entries()==0){
00186
00187 continue;
00188 }
00189 map<Symbol*, pair<Expression*, Expression*> > solutions;
00190 for(Statement* stit=loopit.current().next_ref();
00191 stit!=loopit.current().follow_ref(); stit=stit->next_ref()){
00192
00193
00194 for(Iterator<Expression> expit=stit->iterate_expressions();
00195 expit.valid(); ++expit){
00196 RefList<Expression> array_refs;
00197 get_array_refs(expit.current(), array_refs);
00198 for(Iterator<Expression> arit=array_refs; arit.valid(); ++arit){
00199
00200 Expression& ar=arit.current();
00201
00202 Symbol& sym=ar.array().symbol();
00203
00204 ArrayDims& dims=sym.dim();
00205 List<Expression>& subs=ar.subscript().arg_list();
00206 for (int i=0; i<dims.entries()-1; ++i){
00207 Expression& expr=subs[i];
00208 if (expr.op()!=ID_OP){
00209 continue;
00210 }
00211 if (expr!=loopit.current().index()){
00212 continue;
00213 }
00214
00215 ArrayBounds& ab=dims[i];
00216 Expression* lower=0;
00217 Expression* upper=0;
00218 if (ab.lower_exists()){
00219 lower=ab.lower_guarded().clone();
00220 } else {
00221 lower=constant(1);
00222 }
00223 if (ab.upper_exists()){
00224 upper=ab.upper_guarded().clone();
00225 } else {
00226 upper=constant(1);
00227 p_abort("Upper bound not declared in array inner dimension.");
00228 }
00229
00230 for(Iterator<Expression> bit=base; bit.valid(); ++bit){
00231
00232 map<Symbol*, pair<Expression*, Expression*> >::iterator found=
00233 solutions.find(&bit.current().symbol());
00234 if (found==solutions.end()){
00235
00236
00237 solutions.insert(make_pair(&bit.current().symbol(),
00238 make_pair(lower->clone(),
00239 upper->clone())));
00240 }
00241 }
00242 delete lower;
00243 delete upper;
00244 }
00245 }
00246 }
00247 }
00248
00249
00250
00251 for(map<Symbol*, pair<Expression*, Expression*> >::iterator
00252 sit=solutions.begin(); sit!=solutions.end(); ++sit){
00253 Expression* guard=simplify(and(le((*sit).second.first,
00254 id(*(*sit).first)),
00255 le(id(*(*sit).first),
00256 (*sit).second.second)));
00257 Statement* if_after=pgm.stmts().first_ref()->next_ref();
00258 Statement* endif_after=pgm.stmts().last_ref()->prev_ref();
00259 VariableSymbol& vsym=(VariableSymbol&)*(*sit).first;
00260 if (vsym.is_gsa_symbol()){
00261 continue;
00262 }
00263 pgm.stmts().ins_IF_after(guard,
00264 if_after,
00265 endif_after);
00266 new_ifs.ins_last(*pgm.stmts().first_ref()->next_ref()->next_ref());
00267 }
00268 }
00269 }
00270
00271
00272
00273 void clean_after_standard_enforcement(ProgramUnit& pgm,
00274 RefList<Statement>& new_ifs){
00275 for(Iterator<Statement> stit=new_ifs; stit.valid(); ++stit){
00276 Statement& ifstmt=stit.current();
00277 Statement& endif=*ifstmt.matching_endif_ref();
00278 Statement& after_if=*ifstmt.next_ref();
00279 Statement& before_implicit_goto=
00280 *ifstmt.matching_endif_ref()->prev_ref()->prev_ref();
00281 pgm.stmts().move_block_before(after_if,
00282 before_implicit_goto,
00283 &ifstmt);
00284 pgm.stmts().del(ifstmt, endif);
00285 }
00286 }
|