00001 #include "OpenAnalysis/CSFIActivity/ManagerDUGStandard.hpp"
00002 #include "OpenAnalysis/ReachDefs/ReachDefsStandard.hpp"
00003
00004 #include "Open64IRInterface/Open64IRInterface.hpp"
00005 #include "OpenAnalysis/ICFG/ManagerICFG.hpp"
00006
00007 #include "OAMaps.h"
00008 #include "WhirlParentize.h"
00009 #include "XAIFStrings.h"
00010
00011 namespace fortTkSupport {
00012
00013 OA::OA_ptr<OA::CFG::CFGInterface>
00014 CreateCFG(PU_Info* pu,
00015 OA::OA_ptr<OA::CFG::EachCFGInterface> cfgeach,
00016 OA::OA_ptr<Open64IRInterface> irIF);
00017
00018 static void
00019 MassageOACallGraphIntoXAIFCallGraph(OA::OA_ptr<OA::CallGraph::CallGraph> cg);
00020
00021 static void
00022 AddControlFlowEndTags(PU_Info* pu,
00023 WhirlParentMap* wnParentMap,
00024 OA::OA_ptr<Open64IRInterface> irIF);
00025
00026
00027 static void
00028 MassageOACFGIntoXAIFCFG(OA::OA_ptr<OA::CFG::CFG> cfg,
00029 OA::OA_ptr<Open64IRInterface> irIF);
00030
00031
00032 std::set<ST*> IntraOAInfo::ourActiveGlobalSTPSet;
00033 bool IntraOAInfo::ourDoNotFilterFlag=false;
00034
00035 IntraOAInfo::IntraOAInfo(PU_Info* pu, InterOAInfoMap* inter) {
00036 OA::ProcHandle proc((OA::irhandle_t)pu);
00037 OA::OA_ptr<Open64IRInterface> irIF = inter->getIRInterface();
00038 OA::OA_ptr<OA::CFG::CFGInterface> cfg = inter->getCFGEach()->getCFGResults(proc);
00039 OA::OA_ptr<OA::SideEffect::InterSideEffectStandard> interSideEffect = inter->getInterSideEffect();
00040 FORTTK_MSG(2, "progress: retrieve intra alias from inter alias information");
00041 OA::OA_ptr<OA::Alias::Interface> intraAlias;
00042 intraAlias=inter->getInterAlias()->getAliasResults(proc);
00043 setAlias(intraAlias);
00044 FORTTK_MSG(2, "progress: reach defs: performAnalysis");
00045 OA::OA_ptr<OA::ReachDefsOverwrite::ManagerReachDefsOverwriteStandard> rdoman;
00046 rdoman = new OA::ReachDefsOverwrite::ManagerReachDefsOverwriteStandard(irIF);
00047 OA::OA_ptr<OA::ReachDefsOverwrite::ReachDefsOverwriteStandard> rdos
00048 = rdoman->performAnalysis(proc, cfg, intraAlias, interSideEffect,OA::DataFlow::ITERATIVE);
00049 setReachDefsOverwrite(rdos);
00050 OA::OA_ptr<OA::ReachDefs::ReachDefsStandard> rds=rdos.convert<OA::ReachDefs::ReachDefsStandard>();
00051 FORTTK_MSG(2, "progress: uddu: performAnalysis");
00052 OA::OA_ptr<OA::UDDUChains::ManagerUDDUChainsStandard> udman;
00053 udman = new OA::UDDUChains::ManagerUDDUChainsStandard(irIF);
00054 OA::OA_ptr<OA::UDDUChains::UDDUChainsStandard> udduchains
00055 = udman->performAnalysis(proc, intraAlias, rds, interSideEffect);
00056
00057 setUDDUChains(udduchains);
00058 FORTTK_MSG(2, "progress: alias to xaif: performAnalysis");
00059 OA::OA_ptr<OA::XAIF::ManagerAliasMapXAIF> aliasmanXAIF;
00060 aliasmanXAIF = new OA::XAIF::ManagerAliasMapXAIF(irIF);
00061 OA::OA_ptr<OA::XAIF::AliasMapXAIF> aliasXAIF =
00062 aliasmanXAIF->performAnalysis(proc, intraAlias);
00063 setAliasXAIF(aliasXAIF);
00064 FORTTK_MSG(2, "progress: ud to xaif : performAnalysis");
00065 OA::OA_ptr<OA::XAIF::ManagerUDDUChainsXAIF> udmanXAIF;
00066 udmanXAIF = new OA::XAIF::ManagerUDDUChainsXAIF(irIF);
00067 OA::OA_ptr<OA::XAIF::UDDUChainsXAIF> udduchainsXAIF
00068 = udmanXAIF->performAnalysis(cfg, udduchains,IntraOAInfo::getDoNotFilterFlag());
00069
00070 setUDDUChainsXAIF(udduchainsXAIF);
00071 FORTTK_MSG(2, "progress: overwrite to xaif : performAnalysis");
00072 OA::OA_ptr<OA::XAIF::ManagerReachDefsOverwriteXAIF> rdomanXAIF;
00073 rdomanXAIF = new OA::XAIF::ManagerReachDefsOverwriteXAIF(irIF);
00074 OA::OA_ptr<OA::XAIF::ReachDefsOverwriteXAIF> rdoXAIF
00075 = rdomanXAIF->performAnalysis(cfg, getReachDefsOverwrite());
00076
00077 setReachDefsOverwriteXAIF(rdoXAIF);
00078 };
00079
00080 void IntraOAInfo::setDoNotFilterFlag() {
00081 ourDoNotFilterFlag=true;
00082 }
00083
00084 bool IntraOAInfo::getDoNotFilterFlag() {
00085 return ourDoNotFilterFlag;
00086 }
00087
00088 void
00089 InterOAInfoMap::init(PU_Info* pu_forest, OA::OA_ptr<Open64IRInterface> irIF,
00090 bool activeWithVariedOnly) {
00091 assert(pu_forest);
00092 setIRInterface(irIF);
00093 OA::OA_ptr<Open64IRProcIterator> procIt;
00094 procIt = new Open64IRProcIterator(pu_forest);
00095
00096
00097 OA::OA_ptr<OA::CFG::ManagerCFGStandard> cfgman;
00098 cfgman = new OA::CFG::ManagerCFGStandard(getIRInterface());
00099 OA::OA_ptr<OA::CFG::EachCFGInterface> cfgeach;
00100 cfgeach = new OA::CFG::EachCFGStandard(cfgman);
00101 FORTTK_MSG(1, "progress: CreateCFG");
00102 for ( ; procIt->isValid(); ++(*procIt)) {
00103 PU_Info* pu = (PU_Info*)procIt->current().hval();
00104 OA::OA_ptr<OA::CFG::CFGInterface> cfg = CreateCFG(pu, cfgeach, getIRInterface());
00105 }
00106 setCFGEach(cfgeach);
00107
00108 procIt->reset();
00109 FORTTK_MSG(1, "progress: inter alias: performAnalysis");
00110 OA::OA_ptr<OA::Alias::ManagerFIAliasAliasMap> interaliasmapman;
00111 interaliasmapman = new OA::Alias::ManagerFIAliasAliasMap(getIRInterface());
00112 OA::OA_ptr<OA::Alias::InterAliasMap> interAlias;
00113 interAlias = interaliasmapman->performAnalysis(procIt);
00114 setInterAlias(interAlias);
00115
00116 FORTTK_MSG(1, "progress: call graph: performAnalysis");
00117
00118 procIt->reset();
00119 OA::OA_ptr<OA::CallGraph::ManagerCallGraphStandard> cgraphman;
00120 cgraphman = new OA::CallGraph::ManagerCallGraphStandard(getIRInterface());
00121 OA::OA_ptr<OA::CallGraph::CallGraph> cgraph =
00122 cgraphman->performAnalysis(procIt,interAlias);
00123 if (0) { cgraph->dump(std::cout, getIRInterface()); }
00124 setCallGraph(cgraph);
00125
00126
00127
00128 FORTTK_MSG(1, "progress: parameter bindings: performAnalysis");
00129
00130 OA::OA_ptr<OA::DataFlow::ManagerParamBindings> parambindman;
00131 parambindman = new OA::DataFlow::ManagerParamBindings(getIRInterface());
00132 OA::OA_ptr<OA::DataFlow::ParamBindings> parambind
00133 = parambindman->performAnalysis(cgraph);
00134 setParamBind(parambind);
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 FORTTK_MSG(1, "progress: side effect: performAnalysis");
00159 OA::OA_ptr<OA::SideEffect::ManagerSideEffectStandard> sideeffectman;
00160 sideeffectman = new OA::SideEffect::ManagerSideEffectStandard(getIRInterface());
00161
00162 FORTTK_MSG(1, "progress: inter side effect: performAnalysis");
00163 OA::OA_ptr<OA::SideEffect::ManagerInterSideEffectStandard> interSEman;
00164 interSEman = new OA::SideEffect::ManagerInterSideEffectStandard(getIRInterface());
00165 OA::OA_ptr<OA::SideEffect::InterSideEffectStandard> interSE;
00166 interSE = interSEman->performAnalysis(cgraph, parambind, interAlias, sideeffectman, OA::DataFlow::ITERATIVE);
00167 setInterSideEffect(interSE);
00168
00169 FORTTK_MSG(1, "progress: icfg standard: performAnalysis");
00170 OA::OA_ptr<OA::ICFG::ManagerICFGStandard> icfgman;
00171 icfgman = new OA::ICFG::ManagerICFGStandard(getIRInterface());
00172 OA::OA_ptr<OA::ICFG::ICFG> icfg
00173 = icfgman->performAnalysis(procIt,cfgeach,cgraph);
00174
00175 FORTTK_MSG(1, "progress: DUG standard: building Def-Use graph");
00176 OA::OA_ptr<OA::DUG::ManagerDUGStandard> dugman;
00177 dugman = new OA::DUG::ManagerDUGStandard(getIRInterface(), getIRInterface());
00178 OA::OA_ptr<OA::DUG::DUGStandard> dug
00179 = dugman->performAnalysis(procIt, parambind, cgraph);
00180 dugman->transitiveClosureDepMatrix(cgraph);
00181
00182 #ifdef DEBUG_DUAA_LAST
00183 dug->dumpdot(cout, getIRInterface());
00184 #endif
00185
00186 FORTTK_MSG(1, "progress: Def-Use activity: performAnalysis");
00187 OA::OA_ptr<OA::Activity::ManagerDUActive> duactiveman;
00188 duactiveman = new OA::Activity::ManagerDUActive(getIRInterface(), dug);
00189 OA::OA_ptr<OA::Activity::InterActiveFortran> duactive;
00190 duactive = duactiveman->performAnalysis(parambind, activeWithVariedOnly);
00191 #ifdef DEBUG_DUAA
00192 duactive->dump(cout, getIRInterface());
00193 #endif
00194 setInterActiveFortran(duactive);
00195
00196
00197
00198
00199
00200
00201
00202
00203 FORTTK_MSG(1, "progress: intraprocedural analysis");
00204 procIt->reset();
00205 for ( ; procIt->isValid(); ++(*procIt)) {
00206 PU_Info* pu = (PU_Info*)procIt->current().hval();
00207 ST* st = ST_ptr(PU_Info_proc_sym(pu));
00208 const char* nm = ST_name(st);
00209 FORTTK_MSG(1, "progress: analyzing compile unit " << nm );
00210 IntraOAInfo* info = new IntraOAInfo(pu, this);
00211 Insert(pu, info);
00212 }
00213
00214
00215
00216
00217 FORTTK_MSG(1, "progress: call graph: massage for XAIF");
00218 MassageOACallGraphIntoXAIFCallGraph(cgraph);
00219
00220 procIt->reset();
00221 for ( ; procIt->isValid(); ++(*procIt)) {
00222 PU_Info* pu = (PU_Info*)procIt->current().hval();
00223 OA::ProcHandle proc((OA::irhandle_t)pu);
00224 OA::OA_ptr<OA::CFG::CFGInterface> cfgIF = cfgeach->getCFGResults(proc);
00225 OA::OA_ptr<OA::CFG::CFG> cfg = cfgIF.convert<OA::CFG::CFG>();
00226 MassageOACFGIntoXAIFCFG(cfg,getIRInterface());
00227 }
00228 }
00229
00230
00231 OA::OA_ptr<OA::CFG::CFGInterface>
00232 CreateCFG(PU_Info* pu, OA::OA_ptr<OA::CFG::EachCFGInterface> cfgeach,
00233 OA::OA_ptr<Open64IRInterface> irIF)
00234 {
00235 OA::ProcHandle proc((OA::irhandle_t)pu);
00236
00237
00238 WN *wn_pu = PU_Info_tree_ptr(pu);
00239 WhirlParentMap wnParentMap(wn_pu);
00240
00241
00242
00243
00244 AddControlFlowEndTags(pu, &wnParentMap, irIF);
00245
00246 OA::OA_ptr<OA::CFG::CFGInterface> cfgIF = cfgeach->getCFGResults(proc);
00247 OA::OA_ptr<OA::CFG::CFG> cfg = cfgIF.convert<OA::CFG::CFG>();
00248 if (0) { cfg->dump(std::cout, irIF); }
00249
00250 return cfg;
00251 }
00252
00253
00254
00255
00256
00257
00258 static void
00259 MassageOACallGraphIntoXAIFCallGraph(OA::OA_ptr<OA::CallGraph::CallGraph> cg) {
00260 using namespace OA::CallGraph;
00261 DGraphNodeList toRemove;
00262 OA::OA_ptr<OA::DGraph::NodesIteratorInterface> it = cg->getNodesIterator();
00263 for( ; it->isValid(); ++(*it)) {
00264 OA::OA_ptr<OA::DGraph::NodeInterface> dn = it->current();
00265 OA::OA_ptr<Node> n = dn.convert<Node>();
00266 if (n->getProc().hval() == 0) {
00267 FORTTK_DIAGIF_DEV(2) {
00268 ST* st = (ST*)n->getProcSym().hval();
00269 std::cout << "* Removing '" << ST_name(st) << "' from CallGraph\n";
00270 }
00271 toRemove.push_back(n);
00272 }
00273 }
00274 for (DGraphNodeList::iterator it = toRemove.begin(); it != toRemove.end(); ++it) {
00275 OA::OA_ptr<OA::DGraph::NodeInterface> n = (*it);
00276 cg->removeNode(n);
00277 }
00278 toRemove.clear();
00279 }
00280
00281
00282
00283
00284
00285
00286 static void
00287 AddControlFlowEndTags(PU_Info* pu, WhirlParentMap* wnParentMap,
00288 OA::OA_ptr<Open64IRInterface> irIF) {
00289
00290
00291 WN* wn = PU_Info_tree_ptr(pu);
00292 WN_TREE_CONTAINER<PRE_ORDER> wtree(wn);
00293 WN_TREE_CONTAINER<PRE_ORDER>::iterator it;
00294 for (it = wtree.begin(); it != wtree.end(); ++it) {
00295 WN* curWN = it.Wn();
00296 OPERATOR opr = WN_operator(curWN);
00297 const char* vty = GetCFGControlFlowVertexType(curWN);
00298 if (!vty) { continue; }
00299
00300
00301 if (vty == XAIFStrings.elem_BBForLoop() ||
00302 vty == XAIFStrings.elem_BBPostLoop() ||
00303 vty == XAIFStrings.elem_BBPreLoop()) {
00304
00305
00306
00307
00308 WN* loopBodyWN = NULL;
00309 if (opr == OPR_DO_LOOP) {
00310 loopBodyWN = WN_do_body(curWN);
00311 } else {
00312 loopBodyWN = WN_while_body(curWN);
00313 }
00314 WN* newWN = WN_CreateComment((char*)XAIFStrings.elem_BBEndLoop());
00315 WN_INSERT_BlockLast(loopBodyWN, newWN);
00316
00317 irIF->setContext((OA::irhandle_t)newWN, (OA::irhandle_t)pu);
00318 }
00319 else if (vty == XAIFStrings.elem_BBBranch()) {
00320 WN* ipWN = NULL;
00321 if (opr == OPR_SWITCH) {
00322
00323
00324
00325
00326
00327
00328
00329 INT32 lbl = WN_last_label(curWN);
00330 for (WN* x = WN_next(curWN); x; x = WN_next(x)) {
00331 if (WN_operator(x) == OPR_LABEL && WN_label_number(x) == lbl) {
00332 ipWN = x;
00333 break;
00334 }
00335 }
00336 }
00337 else {
00338
00339
00340
00341
00342 ipWN = curWN;
00343 }
00344 if (ipWN) {
00345 WN* blkWN = wnParentMap->FindBlock(ipWN);
00346 WN* newWN = WN_CreateComment((char*)XAIFStrings.elem_BBEndBranch());
00347
00348
00349 WN_INSERT_BlockAfter(blkWN, ipWN, newWN);
00350
00351 irIF->setContext((OA::irhandle_t)newWN, (OA::irhandle_t)pu);
00352 }
00353 }
00354 }
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 static void
00427 MassageOACFGIntoXAIFCFG(OA::OA_ptr<OA::CFG::CFG> cfg,
00428 OA::OA_ptr<Open64IRInterface> irIF) {
00429 typedef std::list< pair<CFGNodeList::iterator, WN*> > MySplitList;
00430
00431 CFGNodeList workList;
00432 MySplitList toSplit;
00433 OA::OA_ptr<OA::DGraph::NodesIteratorInterface> nodeItTmp;
00434
00435
00436
00437
00438 nodeItTmp = cfg->getNodesIterator();
00439 for ( ; nodeItTmp->isValid(); ++(*nodeItTmp)) {
00440 OA::OA_ptr<OA::DGraph::NodeInterface> dn = nodeItTmp->current();
00441 OA::OA_ptr<OA::CFG::NodeInterface> n = dn.convert<OA::CFG::NodeInterface>();
00442 if ( (n->size() > 1) ) {
00443 workList.push_back(n);
00444 }
00445 }
00446
00447
00448
00449 for (CFGNodeList::iterator wnodeIt = workList.begin();
00450 wnodeIt != workList.end(); ++wnodeIt) {
00451 OA::OA_ptr<OA::CFG::NodeInterface> n = (*wnodeIt);
00452 OA::OA_ptr<OA::CFG::NodeStatementsIteratorInterface> stmtItPtr
00453 = n->getNodeStatementsIterator();
00454 for (; stmtItPtr->isValid(); ++(*stmtItPtr)) {
00455 OA::StmtHandle stmt = stmtItPtr->current();
00456 OA::CFG::IRStmtType ty = irIF->getCFGStmtType(stmt);
00457 if (ty == OA::CFG::STRUCT_TWOWAY_CONDITIONAL
00458 || ty == OA::CFG::USTRUCT_TWOWAY_CONDITIONAL_T
00459 || ty == OA::CFG::USTRUCT_TWOWAY_CONDITIONAL_F
00460 || ty == OA::CFG::STRUCT_MULTIWAY_CONDITIONAL
00461 || ty == OA::CFG::USTRUCT_MULTIWAY_CONDITIONAL) {
00462 toSplit.push_back(make_pair(wnodeIt, (WN*)stmt.hval()));
00463 break;
00464 }
00465 }
00466 }
00467
00468 for (MySplitList::iterator it = toSplit.begin(); it != toSplit.end(); ++it) {
00469 CFGNodeList::iterator wnodeIt = (*it).first;
00470 OA::OA_ptr<OA::CFG::NodeInterface> ntmp = *wnodeIt;
00471 OA::OA_ptr<OA::CFG::Node> n = ntmp.convert<OA::CFG::Node>();
00472 WN* startWN = (*it).second;
00473 OA::StmtHandle stmt((OA::irhandle_t)startWN);
00474 OA::OA_ptr<OA::CFG::Node> newblock = cfg->splitBlock(n, stmt);
00475 cfg->connect(n, newblock, OA::CFG::FALLTHROUGH_EDGE);
00476 }
00477 toSplit.clear();
00478
00479 workList.clear();
00480
00481
00482
00483
00484 CFGNodeList toRemove;
00485 nodeItTmp = cfg->getNodesIterator();
00486 for ( ; nodeItTmp->isValid(); ++(*nodeItTmp)) {
00487 OA::OA_ptr<OA::DGraph::NodeInterface> dn = nodeItTmp->current();
00488 OA::OA_ptr<OA::CFG::Node> n = dn.convert<OA::CFG::Node>();
00489
00490
00491
00492
00493
00494
00495 if (GetCFGVertexType(cfg, n) == XAIFStrings.elem_BBForLoop()) {
00496 assert(n->size() == 1);
00497 OA::OA_ptr<OA::CFG::NodeStatementsIteratorInterface> stmtItPtr = n->getNodeStatementsIterator();
00498 OA::StmtHandle loopStmt = stmtItPtr->current();
00499 WN* loopWN = (WN *)loopStmt.hval();
00500 WN* initWN = WN_start(loopWN);
00501 WN* updateWN = WN_step(loopWN);
00502
00503
00504
00505 OA::OA_ptr<OA::DGraph::NodesIteratorInterface> nodeIt1Ptr = cfg->getNodesIterator();
00506 for (; nodeIt1Ptr->isValid(); ++(*nodeIt1Ptr)) {
00507 OA::OA_ptr<OA::DGraph::NodeInterface> dn1 = nodeIt1Ptr->current();
00508 OA::OA_ptr<OA::CFG::Node> n1 = dn1.convert<OA::CFG::Node>();
00509 OA::OA_ptr<OA::CFG::NodeStatementsIteratorInterface> stmtIt1Ptr = n1->getNodeStatementsIterator();
00510 for (; stmtIt1Ptr->isValid(); ++(*stmtIt1Ptr)) {
00511 OA::StmtHandle st = stmtIt1Ptr->current();
00512 WN* wn = (WN*)st.hval();
00513 if ((wn == initWN) || (wn == updateWN)) {
00514 n1->erase(OA::StmtHandle((OA::irhandle_t)wn));
00515 if (n1->size() == 0 && wn == updateWN) {
00516 toRemove.push_back(n1);
00517 }
00518 break;
00519 }
00520 }
00521 }
00522 }
00523 }
00524
00525 for (CFGNodeList::iterator it = toRemove.begin();
00526 it != toRemove.end(); ++it) {
00527 OA::OA_ptr<OA::CFG::NodeInterface> n = *it;
00528
00529 if (n->num_incoming() > 1) {
00530 continue;
00531 }
00532 OA::OA_ptr<OA::DGraph::NodeInterface> predI = n->getSourceNodesIterator()->current();
00533 OA::OA_ptr<OA::CFG::Node> pred = predI.convert<OA::CFG::Node>();
00534
00535 OA::OA_ptr<OA::DGraph::EdgesIteratorInterface> outEdgeItPtr = n->getOutgoingEdgesIterator();
00536 for ( ; outEdgeItPtr->isValid(); ++(*outEdgeItPtr)) {
00537 OA::OA_ptr<OA::DGraph::EdgeInterface> de = outEdgeItPtr->current();
00538 OA::OA_ptr<OA::CFG::Edge> e = de.convert<OA::CFG::Edge>();
00539 OA::OA_ptr<OA::DGraph::NodeInterface> dsnk = e->getSink();
00540 OA::OA_ptr<OA::CFG::Node> snk = dsnk.convert<OA::CFG::Node>();
00541 cfg->connect(pred, snk, e->getType());
00542 }
00543 cfg->removeNode(n);
00544 }
00545 toRemove.clear();
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 std::list<CFGNodeList::iterator> toRem;
00560
00561 nodeItTmp = cfg->getNodesIterator();
00562 for ( ; nodeItTmp->isValid(); ++(*nodeItTmp)) {
00563 OA::OA_ptr<OA::DGraph::NodeInterface> dn = nodeItTmp->current();
00564 OA::OA_ptr<OA::CFG::Node> n = dn.convert<OA::CFG::Node>();
00565 if ( (n->size() > 1) ) {
00566 workList.push_back(n);
00567 }
00568 }
00569
00570
00571 while (!workList.empty()) {
00572 for (CFGNodeList::iterator wnodeIt = workList.begin();
00573 wnodeIt != workList.end(); ++wnodeIt) {
00574 OA::OA_ptr<OA::CFG::NodeInterface> ntmp = *wnodeIt;
00575 OA::OA_ptr<OA::CFG::Node> n = ntmp.convert<OA::CFG::Node>();
00576
00577
00578 restart_loop:
00579 WN* bbSplitPointWN = NULL;
00580 unsigned int stmtcount = 1;
00581 OA::OA_ptr<OA::CFG::NodeStatementsIteratorInterface> stmtIt = n->getNodeStatementsIterator();
00582 for (; stmtIt->isValid(); ++(*stmtIt), ++stmtcount) {
00583 OA::StmtHandle st = stmtIt->current();
00584 WN* wn = (WN*)st.hval();
00585 const char* vty = GetCFGControlFlowVertexType(wn);
00586 if (vty == XAIFStrings.elem_BBEndBranch()) {
00587
00588
00589 if (stmtcount > 1) {
00590 n->erase(OA::StmtHandle((OA::irhandle_t)wn));
00591 n->add_front(OA::StmtHandle((OA::irhandle_t)wn));
00592 goto restart_loop;
00593 }
00594 ++(*stmtIt);
00595 assert(stmtIt->isValid());
00596 bbSplitPointWN = (WN*)stmtIt->current().hval();
00597 break;
00598 }
00599 else if (vty == XAIFStrings.elem_BBEndLoop()) {
00600 bbSplitPointWN = wn;
00601 break;
00602 }
00603 }
00604 if (bbSplitPointWN) {
00605 toSplit.push_back(make_pair(wnodeIt, bbSplitPointWN));
00606 } else {
00607 toRem.push_back(wnodeIt);
00608 }
00609 }
00610
00611 for (MySplitList::iterator it = toSplit.begin();
00612 it != toSplit.end(); ++it) {
00613 CFGNodeList::iterator wnodeIt = (*it).first;
00614 OA::OA_ptr<OA::CFG::NodeInterface> ntmp = *wnodeIt;
00615 OA::OA_ptr<OA::CFG::Node> n =
00616 ntmp.convert<OA::CFG::Node>();
00617 WN* startWN = (*it).second;
00618 OA::StmtHandle stmt((OA::irhandle_t)startWN);
00619 OA::OA_ptr<OA::CFG::Node> newblock = cfg->splitBlock(n, stmt);
00620 cfg->connect(n, newblock, OA::CFG::FALLTHROUGH_EDGE);
00621
00622 if (newblock->size() > 1) {
00623 workList.push_back(newblock);
00624 }
00625 if ( !(n->size() > 1) ) {
00626 toRem.push_back(wnodeIt);
00627 }
00628 }
00629 toSplit.clear();
00630
00631 for (std::list<CFGNodeList::iterator>::iterator it = toRem.begin();
00632 it != toRem.end(); ++it) {
00633 workList.erase(*it);
00634 }
00635 toRem.clear();
00636 }
00637 }
00638
00639
00640
00641 class CollectModVars_ST_TAB {
00642 public:
00643 CollectModVars_ST_TAB(std::map<std::string, ST*>* modSymNmMap_,
00644 std::set<ST*>* modSymDup_)
00645 : modSymNmMap(modSymNmMap_), modSymDup(modSymDup_)
00646 { }
00647
00648
00649 void operator()(UINT32 idx, ST* st) const
00650 {
00651
00652 if (ST_is_in_module(st)) {
00653
00654 if (!ST_is_external(st)) {
00655 modSymNmMap->insert(make_pair(std::string(ST_name(st)), st));
00656 }
00657 else {
00658 modSymDup->insert(st);
00659 }
00660 }
00661 }
00662
00663 private:
00664 std::map<std::string, ST*>* modSymNmMap;
00665 std::set<ST*>* modSymDup;
00666 };
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 const char*
00683 GetCFGVertexType(OA::OA_ptr<OA::CFG::CFGInterface> cfg,
00684 OA::OA_ptr<OA::CFG::NodeInterface> n)
00685 {
00686 using namespace OA::CFG;
00687
00688
00689 OA::OA_ptr<NodeInterface> entry = cfg->getEntry();
00690 OA::OA_ptr<NodeInterface> exit = cfg->getExit();
00691
00692 if (n == entry) {
00693 return XAIFStrings.elem_BBEntry();
00694 } else if (n == exit) {
00695 return XAIFStrings.elem_BBExit();
00696 }
00697
00698
00699
00700 OA::OA_ptr<OA::CFG::NodeStatementsIteratorInterface> stmtIt
00701 = n->getNodeStatementsIterator();
00702 for (; stmtIt->isValid(); ++(*stmtIt)) {
00703 OA::StmtHandle st = stmtIt->current();
00704 WN* wstmt = (WN*)st.hval();
00705 const char* vty = GetCFGControlFlowVertexType(wstmt);
00706 if (vty) {
00707 return vty;
00708 }
00709 }
00710
00711 return XAIFStrings.elem_BB();
00712 }
00713
00714
00715
00716
00717
00718 const char*
00719 GetCFGControlFlowVertexType(WN* wstmt)
00720 {
00721 OPERATOR opr = WN_operator(wstmt);
00722 switch (opr) {
00723
00724
00725
00726
00727 case OPR_DO_LOOP:
00728 return XAIFStrings.elem_BBForLoop();
00729 case OPR_DO_WHILE:
00730 return XAIFStrings.elem_BBPostLoop();
00731 case OPR_WHILE_DO:
00732 return XAIFStrings.elem_BBPreLoop();
00733
00734
00735 case OPR_IF:
00736 case OPR_TRUEBR:
00737 case OPR_FALSEBR:
00738 return XAIFStrings.elem_BBBranch();
00739 case OPR_SWITCH:
00740 case OPR_COMPGOTO:
00741 return XAIFStrings.elem_BBBranch();
00742
00743
00744 case OPR_COMMENT:
00745 {
00746 static const char* endbr = XAIFStrings.elem_BBEndBranch();
00747 static const char* endlp = XAIFStrings.elem_BBEndLoop();
00748 const char* com = Index_To_Str(WN_GetComment(wstmt));
00749 if (strcmp(com, endbr) == 0) {
00750 return endbr;
00751 } else if (strcmp(com, endlp) == 0) {
00752 return endlp;
00753 }
00754
00755 }
00756
00757 default:
00758 break;
00759 }
00760
00761 return NULL;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820 bool
00821 IntraOAInfo::isGlobalSymbolActive(ST* anST_p) {
00822 return (ourActiveGlobalSTPSet.find(anST_p)!=ourActiveGlobalSTPSet.end());
00823 }
00824
00825 }