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; }
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; }