OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ManagerICFGActive.cpp
Go to the documentation of this file.
1 
15 #include <iostream>
16 #include "ManagerICFGActive.hpp"
17 #include <Utils/Util.hpp>
18 
19 
20 
21 namespace OA {
22  namespace Activity {
23 
24 static bool debug = false;
25 
28 {
29  OA_DEBUG_CTRL_MACRO("DEBUG_ManagerICFGActive:ALL", debug);
31 }
32 
45  DataFlow::DFPImplement algorithm)
46 {
47  OA_ptr<InterActive> retval;
48  retval = new InterActive;
49 
50  // create a Manager that generates dep information for each statement in
51  // ICFG
53  depman = new ManagerICFGDep(mIR);
54  OA_ptr<ICFGDep> icfgDep = depman->performAnalysis(icfg, paramBind,
55  interAlias,
56  algorithm);
57 
58  if (debug) { icfgDep->output(*mIR); }
59 
60 
61  if (debug) {
62  std::cout << "Calling usefulman->performAnalysis() ...\n";
63  std::cout.flush();
64  }
65 
66  OA_ptr<ManagerICFGUseful> usefulman;
67  usefulman = new ManagerICFGUseful(mIR);
69  interUseful = usefulman->performAnalysis(icfg, paramBind, interAlias,
70  interSE, icfgDep,
71  algorithm);
72 
73  retval->setNumIterUseful(interUseful->getNumIter());
74  if (debug) { interUseful->output(*mIR); }
75 
76  // ManagerICFGVaryActive does vary analysis and determines which
77  // locations are active coming Into a stmt and Outof a stmt
78  if (debug) {
79  std::cout << "Calling varyman->performAnalysis() ...\n";
80  std::cout.flush();
81  }
82 
84  varyman = new ManagerICFGVaryActive(mIR);
85  OA_ptr<ActivePerStmt> active = varyman->performAnalysis(icfg, paramBind,
86  interAlias, icfgDep, interUseful,algorithm);
87 
88  retval->setNumIterVary(active->getNumIter());
89  if (debug) { active->output(*mIR); }
90 
91 
92  //-------------------------------------------------------------
93  // Do backward dataflow analysis to determine which def memrefs
94  // and stmts are active
95 
96  // store results that will be needed in callbacks
97  mICFG = icfg;
98  mParamBind = paramBind;
99  mICFGDep = icfgDep;
100  mInterAlias = interAlias;
101  mActive = active;
102 
103  // call iterative data-flow solver for ICFG
104  mSolver->solve(icfg,algorithm);
105 
106  // then iterate over each statement to find active use memrefs
107 
185  // For each ICFG node:
187  icfg->getICFGNodesIterator();
188  for ( ; nodeIter->isValid(); (*nodeIter)++) {
189 
190  OA_ptr<ICFG::NodeInterface> icfgNode = nodeIter->currentICFGNode();
191 
192  // get alias and active results for current procedure
193  ProcHandle proc = icfgNode->getProc();
194  OA_ptr<Alias::Interface> alias = interAlias->getAliasResults(proc);
195  OA_ptr<ActiveStandard> active = mActiveMap[proc];
196 
197  // For each stmt in the ICFG node:
199  icfgNode->getNodeStatementsIterator();
200  for ( ; stmtIter->isValid(); (*stmtIter)++) {
201  StmtHandle stmt = stmtIter->current();
202 
203  // if this is an active statement, mark all inVaryMemRefs as active
204  if (active->isActive(stmt)) {
205 
207  for (; useIter->isValid(); (*useIter)++ ) {
208  MemRefHandle use = useIter->current();
209  if (debug) {
210  std::cout << "\tuse = ";
211  mIR->dump(use,std::cout);
212  }
213 
214  // iterate over locations that are active anywhere
215  // in procedure, flow-insensitive active locations
216  OA_ptr<LocIterator> procActiveLocIter
217  = active->getActiveLocsIterator();
218  for ( ; procActiveLocIter->isValid(); (*procActiveLocIter)++ ) {
219  OA_ptr<Location> activeLoc = procActiveLocIter->current();
220  if (debug) {
221  std::cout << "\t activeLoc = ";
222  activeLoc->dump(std::cout,mIR);
223  }
224 
225  // iterate over may locs for use
226  OA_ptr<LocIterator> mayLocIter = alias->getMayLocs(use);
227  for ( ; mayLocIter->isValid(); (*mayLocIter)++ ) {
228  OA_ptr<Location> useLoc = mayLocIter->current();
229  if (debug) {
230  std::cout << "\t\t may loc for use, useLoc = ";
231  useLoc->dump(std::cout,mIR);
232  }
233  if (activeLoc->mayOverlap(*useLoc)) {
234  active->insertMemRef(use);
235  if (debug) {
236  std::cout << "\t\tinserting active memref use = ";
237  mIR->dump(use,std::cout);
238  std::cout << std::endl;
239  }
240 
241  } // if active loc mayOverlap the mayloc of the use memref
242  // then use memref is set active
243 
244  } // for each mayloc of the use memref
245 
246  } // for each active locations anywhere in the procedure
247 
248  } // iterate over use memrefs
249 
250  } // if active stmt
251 
252  } // for each stmt in the icfg node
253 
254  } // for each icfg node
255 
256 
257 
258 
259 
260 
261  // assign activity results for each procedure into InterActive
262  std::map<ProcHandle,OA_ptr<ActiveStandard> >::iterator mapIter;
263  for (mapIter=mActiveMap.begin(); mapIter!=mActiveMap.end(); mapIter++) {
264  retval->mapProcToActive(mapIter->first,mapIter->second);
265  }
266 
267  // how many iterations did this take?
268  if (debug)
269  {
270  std::cout << "ICFGActive took " << mSolver->getNumIter()
271  << " iterations.\n";
272  }
273 
274  retval->setNumIterActive(mSolver->getNumIter());
275 
276  return retval;
277 }
278 
279 //========================================================
280 // implementation of ICFGDFProblem interface
281 //========================================================
282 //--------------------------------------------------------
283 // initialization callbacks
284 //--------------------------------------------------------
285 
291 {
293  retval = new DataFlow::LocDFSet;
294  return retval;
295 }
296 
299 {
301  retval = new DataFlow::LocDFSet;
302  return retval;
303 }
304 
307 {
309  retval = new DataFlow::LocDFSet;
310  return retval;
311 }
312 
313 
314 //--------------------------------------------------------
315 // solver callbacks
316 //--------------------------------------------------------
317 
323 {
324  // just return in set
325  return set1;
326 }
327 
333 {
334 
335  // ignoring data flow, using outActiveSet from previous analysis
336  OA_ptr<DataFlow::LocDFSet> outRecast = mActive->getOutActiveSet(stmt);
337 
338  if (debug) {
339  std::cout << "In transfer, stmt(hval=" << stmt.hval() << ")= ";
340  mIR->dump(stmt,std::cout);
341  std::cout << "\toutRecast = ";
342  outRecast->dump(std::cout,mIR);
343  }
344 
345  // will be storing activity results for stmt and memrefs in
346  // ActiveStandard for current procedure
347  if (mActiveMap[proc].ptrEqual(0)) {
348  mActiveMap[proc] = new ActiveStandard(proc);
349  }
350 
351  // get alias and active results for current procedure
353  OA_ptr<ActiveStandard> active = mActiveMap[proc];
354 
355  // iterate over def mem refs and if any of them access a location
356  // that is in the out active set then the mem ref is active and so
357  // is the stmt
358  bool activeStmt = false;
360  for (; defIter->isValid(); (*defIter)++ ) {
361  MemRefHandle def = defIter->current();
362  if (debug) {
363  std::cout << "\tdef = ";
364  mIR->dump(def,std::cout);
365  }
366 
367  bool activeMemRef = false;
368  // loop over may locs for the memref
369  OA_ptr<LocIterator> locIter = alias->getMayLocs(def);
370  for ( ; locIter->isValid()&&!activeMemRef; (*locIter)++ ) {
371  OA_ptr<Location> loc = locIter->current();
372  if (debug) {
373  std::cout << "\t\t mayloc for def = ";
374  loc->dump(std::cout,mIR);
375  }
376 
377  // if at least one may loc of this def overlaps with
378  // something in the active set ... then we know
379  // that this def is active, and we know
380  // that this stmt is active as well.
381  if (outRecast->hasOverlapLoc(loc)) {
382  active->insertMemRef(def);
383 
384  // don't need to look at any more mayLocs, since we
385  // already know that this def is active ... set flag
386  activeMemRef = true;
387 
388  if (!activeStmt) {
389  // now we know it is, insert and set flag
390  active->insertStmt(stmt);
391  activeStmt = true;
392  }
393  }
394  }
395  }
396 
397  // since we are ignoring in/out data flow sets, only one iteration
398  // iterate through all of the active locations that come into this
399  // statement and insert those locations as active within the
400  // procedure
401  OA_ptr<DataFlow::LocDFSet> inActiveSet = mActive->getInActiveSet(stmt);
402  OA_ptr<LocIterator> locIter = inActiveSet->getLocIterator();
403  for ( ; locIter->isValid(); (*locIter)++ ) {
404  active->insertLoc(locIter->current());
405  }
406 
407  // If we are ignoring the incoming set (see comments at top of transfer)
408  // upshot: cuts the iterations by one. (no impact on correct output)
409  return out;
410 }
411 
418 {
419  return in;
420 }
421 
426 {
427  return out;
428 }
429 
430 
435 {
436  // no data flow for this analysis ... returning in set
437  return dfset;
438 }
439 
444 {
445  // no data flow for this analysis ... returning in set
446  return dfset;
447 }
448 
453 {
454  // no data flow for this analysis ... returning in set
455  return dfset;
456 }
457 
458  } // end of namespace Activity
459 } // end of namespace OA