bool PatmosSPMark::runOnMachineModule(const Module &M) { DEBUG( dbgs() << "[Single-Path] Mark functions reachable from single-path roots\n"); MMI = &getAnalysis<MachineModuleInfo>(); assert(MMI); Worklist W; // initialize the worklist with machine functions that have either // sp-root or sp-reachable function attribute for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) { if (F->hasFnAttribute("sp-root") || F->hasFnAttribute("sp-reachable")) { // get the machine-level function MachineFunction *MF = MMI->getMachineFunction(F); assert( MF ); PatmosMachineFunctionInfo *PMFI = MF->getInfo<PatmosMachineFunctionInfo>(); PMFI->setSinglePath(); NumSPTotal++; // bump STATISTIC W.push_back(MF); } } // process worklist while (!W.empty()) { MachineFunction *MF = W.front(); W.pop_front(); scanAndRewriteCalls(MF, W); } removeUncalledSPFunctions(M); // We either have rewritten calls or removed superfluous functions. return true; }
// // Computes path_summary_iterative_original // void WFA::path_summary_iterative_original(Worklist<State>& wl, sem_elem_t wt) { // BEGIN DEBUGGING //int numPops = 0; // END DEBUGGING IncomingTransMap_t preds; setupFixpoint(wl, &preds, NULL, wt); while (!wl.empty()) { State* q = wl.get(); sem_elem_t the_delta = q->delta(); q->delta() = the_delta->zero(); { // BEGIN DEBUGGING //numPops++; //q->print(*waliErr << " Popped: ") << std::endl; } // END DEBUGGING // Get a handle on ZERO b/c we use it alot sem_elem_t ZERO = q->weight()->zero(); // Find predecessor set IncomingTransMap_t::iterator incomingTransIt = preds.find(q->name()); // Some states may have no predecessors, like // the initial state if (incomingTransIt == preds.end()) { continue; } // Tell predecessors we have changed std::vector<ITrans*> & incoming = incomingTransIt->second; std::vector<ITrans*>::iterator transit = incoming.begin(); for ( ; transit != incoming.end() ; ++transit) { ITrans* t = *transit; // We are looking at a transition (q', _, q) State* qprime = state_map[t->from()]; sem_elem_t newW = qprime->weight()->zero(); { // BEGIN DEBUGGING //t->print(*waliErr << "\t++ Popped ") << std::endl; } // END DEBUGGING assert(t->to() == q->name()); sem_elem_t extended; if (query == INORDER) { extended = t->weight()->extend(the_delta); } else { extended = the_delta->extend(t->weight()); } newW = newW->combine(extended); // delta => (w+se,w-se) // Use extended->delta b/c we want the diff b/w the new // weight (extended) and what was there before std::pair<sem_elem_t,sem_elem_t> p = newW->delta(qprime->weight()); { // BEGIN DEBUGGING //qprime->weight()->print(*waliErr << " oldW " << key2str(qprime->name())) << std::endl; //newW->print(*waliErr << " newW " << key2str(qprime->name())) << std::endl; //p.first->print(*waliErr << "\t++ p.first ") << std::endl; //p.second->print(*waliErr << "\t++ p.second ") << std::endl; } // END DEBUGGING // Sets qprime's new weight // p.first == (l(t) X the_delta) + W(qprime) qprime->weight() = p.first; // on the worklist? if (qprime->marked()) { qprime->delta() = qprime->delta()->combine(p.second); } else { // not on the worklist means its delta is zero qprime->delta() = p.second; // add to worklist if not zero if (!qprime->delta()->equal(ZERO)) { wl.put(qprime); } } } if (progress.is_valid()) { progress->tick(); } } { // BEGIN DEBUGGING //*waliErr << "\n --- WFA::path_summary_iterative_original needed " << numPops << " pops\n"; //*waliErr << "WFA state labels:\n"; //FOR_EACH_STATE(st) { // *waliErr << "\t" << key2str(st->name()) << ": "; // st->weight()->print(*waliErr) << std::endl; //} } // END DEBUGGING }
bool PatmosSPMark::runOnMachineModule(const Module &M) { DEBUG( dbgs() << "[Single-Path] Mark functions reachable from single-path roots\n"); MMI = &getAnalysis<MachineModuleInfo>(); assert(MMI); Worklist W; // initialize the worklist with machine functions that have either // sp-root or sp-reachable function attribute for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) { if (F->hasFnAttribute("sp-root") || F->hasFnAttribute("sp-reachable")) { // get the machine-level function MachineFunction *MF = MMI->getMachineFunction(F); assert( MF ); PatmosMachineFunctionInfo *PMFI = MF->getInfo<PatmosMachineFunctionInfo>(); PMFI->setSinglePath(); NumSPTotal++; // bump STATISTIC W.push_back(MF); } } // process worklist while (!W.empty()) { MachineFunction *MF = W.front(); W.pop_front(); scanAndRewriteCalls(MF, W); } // clear all cloned machine functions that are not marked as single-path // by now for(Module::const_iterator F(M.begin()), FE(M.end()); F != FE; ++F) { if (F->hasFnAttribute("sp-maybe")) { // get the machine-level function MachineFunction *MF = MMI->getMachineFunction(F); assert( MF ); PatmosMachineFunctionInfo *PMFI = MF->getInfo<PatmosMachineFunctionInfo>(); if (!PMFI->isSinglePath()) { // delete all MBBs while (MF->begin() != MF->end()) { MF->begin()->eraseFromParent(); } // insert a new single MBB with a single return instruction MachineBasicBlock *EmptyMBB = MF->CreateMachineBasicBlock(); MF->push_back(EmptyMBB); DebugLoc DL; AddDefaultPred(BuildMI(*EmptyMBB, EmptyMBB->end(), DL, TM.getInstrInfo()->get(Patmos::RET))); NumSPCleared++; // bump STATISTIC }; } } return true; }