Polaris: IPCPConstants.cc Source File

IPCPConstants.cc

Go to the documentation of this file.
00001 ///
00002 ///
00003 /// \file IPCPConstants.cc
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 /// Template Instantiations:
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 ///  CallSite methods
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     /// ...  Nothing to do.
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 ///  Constructors
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     /// ...  Make sure no constant expression uses a variable belonging to another
00085     /// ...  constant.
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 ///  Destructor
00103 
00104 IPCPConstants::~IPCPConstants()
00105 {
00106     delete _constants;
00107     delete _alias_sets;
00108 }
00109 
00110 
00111 ///  operator ==
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 /// add_invocation_path
00135 
00136 void
00137 IPCPConstants::add_invocation_site(CallSite *invocation_site)
00138 {
00139     _invocation_sites.ins(invocation_site);
00140 }
00141 
00142 
00143 /// merge_invocation_paths
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 ///  contains_var_not_in_set
00158 ///    Return true if the expression contains a variable not in
00159 ///    the given set.
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 ///  filter_out_local_vars
00182 ///    Filter out all local symbols from the given map.
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 ///  listable_clone
00205 
00206 Listable *
00207 IPCPConstants::listable_clone() const
00208 {
00209     return new IPCPConstants(*this);
00210 }
00211 
00212 
00213 ///  print_constants
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 ///  print
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 ///  structures_OK
00250 
00251 int
00252 IPCPConstants::structures_OK() const
00253 {
00254     return _constants->structures_OK();
00255 }
00256 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:56 2005