IPCPConstants.ccGo to the documentation of this file.00001
00002
00003
00004
00005 #include "../Collection/KeyIterator.h"
00006 #include "../Collection/Mutator.h"
00007
00008 #include "IPCPConstants.h"
00009 #include "IPCPProcData.h"
00010 #include "AliasSets.h"
00011 #include "JumpFunction.h"
00012
00013
00014
00015 template class TypedCollection<CallSite>;
00016 template class Set<CallSite>;
00017 template ostream & operator << (ostream &, const Set<CallSite> &);
00018 template class Assign<CallSite>;
00019 template class Iterator<CallSite>;
00020 template class Mutator<CallSite>;
00021
00022
00023
00024
00025 CallSite::CallSite(const IPCPConstants *caller_consts_ref,
00026 const char *call_tag)
00027 : _call_tag(call_tag)
00028 {
00029 _caller_consts_ref = caller_consts_ref;
00030 }
00031
00032 CallSite::CallSite(const CallSite &other)
00033 : _call_tag(other.call_tag())
00034 {
00035 _caller_consts_ref = other._caller_consts_ref;
00036 }
00037
00038 CallSite::~CallSite()
00039 {
00040
00041 }
00042
00043 Listable *
00044 CallSite::listable_clone() const
00045 {
00046 return new CallSite(*this);
00047 }
00048
00049 void
00050 CallSite::print(ostream &o) const
00051 {
00052 if (_caller_consts_ref)
00053 o << _caller_consts_ref->invocation_sites() << "->"
00054 << _caller_consts_ref->proc_data_ref->entry().routine_guarded();
00055 else
00056 o << "<MAIN>";
00057
00058 o << ":" << call_tag();
00059 }
00060
00061 int
00062 CallSite::structures_OK() const
00063 {
00064 return (call_tag().structures_OK());
00065 }
00066
00067
00068
00069
00070 IPCPConstants::IPCPConstants()
00071 {
00072 _constants = new Map<Symbol,Expression>;
00073 _alias_sets = new AliasSets;
00074 }
00075
00076 IPCPConstants::IPCPConstants(Map<Symbol,Expression> *constants,
00077 AliasSets *alias_sets)
00078 {
00079 p_assert(constants, "A NULL constants field was given to the IPCPConstants constructor.");
00080 p_assert(alias_sets, "A NULL alias_sets field was given to the IPCPConstants constructor.");
00081
00082 _constants = constants;
00083
00084
00085
00086
00087 subst_vars_in_map(*constants, *constants);
00088
00089 _alias_sets = alias_sets;
00090 proc_data_ref = 0;
00091 }
00092
00093 IPCPConstants::IPCPConstants(const IPCPConstants &other)
00094 {
00095 _constants = new Map<Symbol,Expression>(*other._constants);
00096 _alias_sets = new AliasSets(*other._alias_sets);
00097 _invocation_sites = other._invocation_sites;
00098 proc_data_ref = other.proc_data_ref;
00099 }
00100
00101
00102
00103
00104 IPCPConstants::~IPCPConstants()
00105 {
00106 delete _constants;
00107 delete _alias_sets;
00108 }
00109
00110
00111
00112
00113 int
00114 IPCPConstants::operator == (const IPCPConstants &other) const
00115 {
00116 if (_constants->entries() != other._constants->entries())
00117 return 0;
00118 else {
00119 KeyIterator<Symbol, Expression> iter = *_constants;
00120
00121 for ( ; iter.valid(); ++iter) {
00122 Expression *other_const
00123 = other._constants->find_ref(iter.current_key());
00124
00125 if (! other_const || iter.current_data() != *other_const)
00126 return 0;
00127 }
00128 }
00129
00130 return 1;
00131 }
00132
00133
00134
00135
00136 void
00137 IPCPConstants::add_invocation_site(CallSite *invocation_site)
00138 {
00139 _invocation_sites.ins(invocation_site);
00140 }
00141
00142
00143
00144
00145 void
00146 IPCPConstants::merge_invocation_sites(IPCPConstants *other)
00147 {
00148 Mutator<CallSite> iter = other->_invocation_sites;
00149
00150 for ( ; iter.valid(); ++iter)
00151 add_invocation_site(iter.grab());
00152
00153 delete other;
00154 }
00155
00156
00157
00158
00159
00160
00161 static Boolean
00162 _contains_vars_not_in_set(const Expression &expr,
00163 const RefSet<Symbol> &keepable_vars)
00164 {
00165 if (expr.op() == ID_OP) {
00166 return (expr.symbol().sym_class() == VARIABLE_CLASS
00167 && ! keepable_vars.member(expr.symbol()));
00168 }
00169 else {
00170 Iterator<Expression> arg_iter = expr.arg_list();
00171
00172 for ( ; arg_iter.valid(); ++arg_iter)
00173 if (_contains_vars_not_in_set(arg_iter.current(), keepable_vars))
00174 return True;
00175 }
00176
00177 return False;
00178 }
00179
00180
00181
00182
00183
00184 void
00185 IPCPConstants::filter_out_vars_not_in_set(const RefSet<Symbol> &keepable_lhs_vars,
00186 const RefSet<Symbol> &keepable_rhs_vars)
00187 {
00188 RefSet<Symbol> *mod_vars = modified_vars(*_constants);
00189 Iterator<Symbol> mod_var_iter = *mod_vars;
00190
00191 for ( ; mod_var_iter.valid(); ++mod_var_iter) {
00192 Symbol &var = mod_var_iter.current();
00193
00194 if (! keepable_lhs_vars.member(var)
00195 || _contains_vars_not_in_set((*_constants)[var], keepable_rhs_vars))
00196
00197 _constants->del(var);
00198 }
00199
00200 delete mod_vars;
00201 }
00202
00203
00204
00205
00206 Listable *
00207 IPCPConstants::listable_clone() const
00208 {
00209 return new IPCPConstants(*this);
00210 }
00211
00212
00213
00214
00215 void
00216 IPCPConstants::print_constants(ostream &o) const
00217 {
00218 o << "{";
00219 KeyIterator<Symbol, Expression> iter = *_constants;
00220
00221 if (iter.valid()) {
00222 o << iter.current_key().name_ref() << "=" << iter.current_data();
00223 ++iter;
00224
00225 for ( ; iter.valid(); ++iter)
00226 o << ", " << iter.current_key().name_ref() << "="
00227 << iter.current_data();
00228 }
00229
00230 o << "}";
00231 }
00232
00233
00234
00235
00236 void
00237 IPCPConstants::print(ostream &o) const
00238 {
00239 o << "[";
00240 o << "constants=";
00241 print_constants(o);
00242 o << ", invoke_sites=" << _invocation_sites;
00243 o << ", alias_sets=";
00244 _alias_sets->print(o);
00245 o << "]";
00246 }
00247
00248
00249
00250
00251 int
00252 IPCPConstants::structures_OK() const
00253 {
00254 return _constants->structures_OK();
00255 }
00256
|