Loop* FlowGraph::getOuterMostLoopForLoop(uint32_t idx){ Loop* input = loops[idx]; while (input->getIndex() != getOuterLoop(input->getIndex())->getIndex()){ input = getOuterLoop(input->getIndex()); } return input; }
void TempScopInfo::buildLoopBounds(TempScop &Scop) { Region &R = Scop.getMaxRegion(); unsigned MaxLoopDepth = 0; for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E; ++I) { Loop *L = LI->getLoopFor(I->getNodeAs<BasicBlock>()); if (!L || !R.contains(L)) continue; if (LoopBounds.find(L) != LoopBounds.end()) continue; LoopBounds[L] = SCEVAffFunc(SCEVAffFunc::Eq); const SCEV *LoopCount = SE->getBackedgeTakenCount(L); buildAffineFunction(LoopCount, LoopBounds[L], Scop.getMaxRegion(), Scop.getParamSet()); Loop *OL = R.outermostLoopInRegion(L); unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1; if (LoopDepth > MaxLoopDepth) MaxLoopDepth = LoopDepth; } Scop.MaxLoopDepth = MaxLoopDepth; }
/** * Compile a signal * @param sig the signal expression to compile. * @return the C code translation of sig as a string */ string VectorCompiler::generateLoopCode (Tree sig) { int i; Tree x; Loop* l; l = fClass->topLoop(); assert(l); //cerr << "VectorCompiler::OLDgenerateCode " << ppsig(sig) << endl; if (needSeparateLoop(sig)) { // we need a separate loop unless it's an old recursion if (isProj(sig, &i, x)) { // projection of a recursive group x if (l->hasRecDependencyIn(singleton(x))) { // x is already in the loop stack return ScalarCompiler::generateCode(sig); } else { // x must be defined fClass->openLoop(x, "count"); string c = ScalarCompiler::generateCode(sig); fClass->closeLoop(sig); return c; } } else { fClass->openLoop("count"); string c = ScalarCompiler::generateCode(sig); fClass->closeLoop(sig); return c; } } else { return ScalarCompiler::generateCode(sig); } }
//===----------------------------------------------------------------------===// int VPreRegAllocSched::analyzeLoopDep(MachineMemOperand *SrcAddr, MachineMemOperand *DstAddr, Loop &L, bool SrcBeforeDest) { uint64_t SrcSize = SrcAddr->getSize(); uint64_t DstSize = DstAddr->getSize(); Value *SrcAddrVal = const_cast<Value*>(SrcAddr->getValue()), *DstAddrVal = const_cast<Value*>(DstAddr->getValue()); DEBUG(dbgs() << '\n' << *SrcAddr->getValue() << "+" << SrcAddr->getOffset() << " and " << *DstAddr->getValue() << "+" << DstAddr->getOffset() << ": "); if (!isMachineMemOperandAlias(SrcAddr, DstAddr, AA, SE)) return -1; if (L.isLoopInvariant(SrcAddrVal) && L.isLoopInvariant(DstAddrVal)) { DEBUG(dbgs() << " Invariant"); // FIXME: What about nested loops? // Loop Invariant, let AA decide. return getLoopDepDist(SrcBeforeDest); } // We can only handle two access have the same element size. if (SrcSize == DstSize) { const SCEV *SSAddr = SE->getSCEVAtScope(getMachineMemOperandSCEV(SrcAddr, SE), &L); const SCEV *SDAddr = SE->getSCEVAtScope(getMachineMemOperandSCEV(DstAddr, SE), &L); return getLoopDepDist(SSAddr, SDAddr, SrcBeforeDest, SrcSize, SE); } // Cannot handle, simply assume dependence occur. return getLoopDepDist(SrcBeforeDest); }
void workloop(void *t) { Loop* me = (Loop*)t; log_info("%s starting.", me->name); LoopData loop; loop.count = 0; loop.period = start_period / n_worker; loop.deadline = abs_start + loop.period*me->id; // entering primary mode rt_task_set_mode(0, T_WARNSW, NULL);/* Ask Xenomai to warn us upon switches to secondary mode. */ RTIME now = rt_timer_read(); while(loop.deadline < now) loop.deadline += loop.period; while(bTesting) { rt_task_sleep_until(loop.deadline);//blocks ///////////////////// if(!bTesting) break; now = rt_timer_read(); loop.jitter = now - loop.deadline;//measure jitter /* Begin "work" ****************************************/ me->work(); //rt_task_sleep(100000000); //for debugging /* End "work" ******************************************/ RTIME t0 = now;//use an easy to remember var now = rt_timer_read(); // Post work book keeping /////////////////////////////// //to report how much the work took loop.t_work = now - t0; if(me->loopdata_q.push(loop)) { } else { /* Have to throw away data; need to alarm! */ log_alert("Loop data full"); } if(!me->late_q.isEmpty()// Manage the late q && me->late_q[0].count < (loop.count - 100)) { me->late_q.pop(); // if sufficiently old, forget about it } loop.deadline += loop.period; if(now > loop.deadline) { // Did I miss the deadline? // How badly did I miss the deadline? // Definition of "badness": just a simple count over the past N loop if(me->late_q.isFull()) { //FATAL log_fatal("Missed too many deadlines"); break; } } /* decrement the period by a fraction */ loop.period -= dec_ppm ? loop.period / (1000000 / dec_ppm) : 0; if(loop.period < 1000000) break; /* Limit at 1 ms for now */ ++loop.count; } rt_task_set_mode(T_WARNSW, 0, NULL);// popping out of primary mode log_info("%s exiting.", me->name); }
bool LoopControllersDepGraph::runOnFunction(Function& F){ //Step 1: Get the complete dependence graph functionDepGraph& DepGraph = getAnalysis<functionDepGraph> (); depGraph = DepGraph.depGraph; //Step 2: Get the list of values that control the loop exit LoopInfoEx& li = getAnalysis<LoopInfoEx>(); std::set<Value*> loopExitPredicates; for (LoopInfoEx::iterator lit = li.begin(), lend = li.end(); lit != lend; lit++) { Loop* l = *lit; SmallVector<BasicBlock*, 4> loopExitingBlocks; l->getExitingBlocks(loopExitingBlocks); for(SmallVectorImpl<BasicBlock*>::iterator BB = loopExitingBlocks.begin(); BB != loopExitingBlocks.end(); BB++){ if (BranchInst* BI = dyn_cast<BranchInst>((*BB)->getTerminator())) { loopExitPredicates.insert(BI->getCondition()); } else if (SwitchInst* SI = dyn_cast<SwitchInst>((*BB)->getTerminator())) { loopExitPredicates.insert(SI->getCondition()); } else if (IndirectBrInst* IBI = dyn_cast<IndirectBrInst>((*BB)->getTerminator())) { loopExitPredicates.insert(IBI->getAddress()); } else if (InvokeInst* II = dyn_cast<InvokeInst>((*BB)->getTerminator())) { loopExitPredicates.insert(II); } } } //Step 3: Make a list of graph nodes that represent the dependencies of the loop controllers std::set<GraphNode*> visitedNodes; for(std::set<Value*>::iterator v = loopExitPredicates.begin(); v != loopExitPredicates.end(); v++){ if (GraphNode* valueNode = depGraph->findNode(*v)) depGraph->dfsVisitBack(valueNode, visitedNodes); else errs() << "Function : " << F.getName() << " - Value not found in the graph : " << **v << "\n"; } //Step 4: Remove from the graph all the nodes that are not in the list of dependencies std::set<GraphNode*> nodesToRemove; for(DepGraph::iterator node = depGraph->begin(); node != depGraph->end(); node++ ){ if (!visitedNodes.count(*node)) nodesToRemove.insert(*node); } for(std::set<GraphNode*>::iterator node = nodesToRemove.begin(); node != nodesToRemove.end(); node++ ){ depGraph->removeNode(*node); } //Step 5: ta-da! The graph is ready to use :) fullGraph = depGraph; return false; }
void LoopInfo::markAsRemoved(Loop *Unloop) { assert(!Unloop->isInvalid() && "Loop has already been removed"); Unloop->invalidate(); RemovedLoops.push_back(Unloop); // First handle the special case of no parent loop to simplify the algorithm. if (!Unloop->getParentLoop()) { // Since BBLoop had no parent, Unloop blocks are no longer in a loop. for (Loop::block_iterator I = Unloop->block_begin(), E = Unloop->block_end(); I != E; ++I) { // Don't reparent blocks in subloops. if (getLoopFor(*I) != Unloop) continue; // Blocks no longer have a parent but are still referenced by Unloop until // the Unloop object is deleted. changeLoopFor(*I, nullptr); } // Remove the loop from the top-level LoopInfo object. for (iterator I = begin();; ++I) { assert(I != end() && "Couldn't find loop"); if (*I == Unloop) { removeLoop(I); break; } } // Move all of the subloops to the top-level. while (!Unloop->empty()) addTopLevelLoop(Unloop->removeChildLoop(std::prev(Unloop->end()))); return; } // Update the parent loop for all blocks within the loop. Blocks within // subloops will not change parents. UnloopUpdater Updater(Unloop, this); Updater.updateBlockParents(); // Remove blocks from former ancestor loops. Updater.removeBlocksFromAncestors(); // Add direct subloops as children in their new parent loop. Updater.updateSubloopParents(); // Remove unloop from its parent loop. Loop *ParentLoop = Unloop->getParentLoop(); for (Loop::iterator I = ParentLoop->begin();; ++I) { assert(I != ParentLoop->end() && "Couldn't find loop"); if (*I == Unloop) { ParentLoop->removeChildLoop(I); break; } } }
/// Sinks instructions from loop's preheader to the loop body if the /// sum frequency of inserted copy is smaller than preheader's frequency. static bool sinkLoopInvariantInstructions(Loop &L, AAResults &AA, LoopInfo &LI, DominatorTree &DT, BlockFrequencyInfo &BFI, ScalarEvolution *SE) { BasicBlock *Preheader = L.getLoopPreheader(); if (!Preheader) return false; // Enable LoopSink only when runtime profile is available. // With static profile, the sinking decision may be sub-optimal. if (!Preheader->getParent()->getEntryCount()) return false; const BlockFrequency PreheaderFreq = BFI.getBlockFreq(Preheader); // If there are no basic blocks with lower frequency than the preheader then // we can avoid the detailed analysis as we will never find profitable sinking // opportunities. if (all_of(L.blocks(), [&](const BasicBlock *BB) { return BFI.getBlockFreq(BB) > PreheaderFreq; })) return false; bool Changed = false; AliasSetTracker CurAST(AA); // Compute alias set. for (BasicBlock *BB : L.blocks()) CurAST.add(*BB); // Sort loop's basic blocks by frequency SmallVector<BasicBlock *, 10> ColdLoopBBs; SmallDenseMap<BasicBlock *, int, 16> LoopBlockNumber; int i = 0; for (BasicBlock *B : L.blocks()) if (BFI.getBlockFreq(B) < BFI.getBlockFreq(L.getLoopPreheader())) { ColdLoopBBs.push_back(B); LoopBlockNumber[B] = ++i; } std::stable_sort(ColdLoopBBs.begin(), ColdLoopBBs.end(), [&](BasicBlock *A, BasicBlock *B) { return BFI.getBlockFreq(A) < BFI.getBlockFreq(B); }); // Traverse preheader's instructions in reverse order becaue if A depends // on B (A appears after B), A needs to be sinked first before B can be // sinked. for (auto II = Preheader->rbegin(), E = Preheader->rend(); II != E;) { Instruction *I = &*II++; if (!canSinkOrHoistInst(*I, &AA, &DT, &L, &CurAST, nullptr)) continue; if (sinkInstruction(L, *I, ColdLoopBBs, LoopBlockNumber, LI, DT, BFI)) Changed = true; } if (Changed && SE) SE->forgetLoopDispositions(&L); return Changed; }
// Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges // as taken, exiting edges as not-taken. bool BranchProbabilityInfo::calcLoopBranchHeuristics(BasicBlock *BB, const LoopInfo &LI) { Loop *L = LI.getLoopFor(BB); if (!L) return false; SmallVector<unsigned, 8> BackEdges; SmallVector<unsigned, 8> ExitingEdges; SmallVector<unsigned, 8> InEdges; // Edges from header to the loop. for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { if (!L->contains(*I)) ExitingEdges.push_back(I.getSuccessorIndex()); else if (L->getHeader() == *I) BackEdges.push_back(I.getSuccessorIndex()); else InEdges.push_back(I.getSuccessorIndex()); } if (BackEdges.empty() && ExitingEdges.empty()) return false; if (uint32_t numBackEdges = BackEdges.size()) { uint32_t backWeight = LBH_TAKEN_WEIGHT / numBackEdges; if (backWeight < NORMAL_WEIGHT) backWeight = NORMAL_WEIGHT; for (SmallVectorImpl<unsigned>::iterator EI = BackEdges.begin(), EE = BackEdges.end(); EI != EE; ++EI) { setEdgeWeight(BB, *EI, backWeight); } } if (uint32_t numInEdges = InEdges.size()) { uint32_t inWeight = LBH_TAKEN_WEIGHT / numInEdges; if (inWeight < NORMAL_WEIGHT) inWeight = NORMAL_WEIGHT; for (SmallVectorImpl<unsigned>::iterator EI = InEdges.begin(), EE = InEdges.end(); EI != EE; ++EI) { setEdgeWeight(BB, *EI, inWeight); } } if (uint32_t numExitingEdges = ExitingEdges.size()) { uint32_t exitWeight = LBH_NONTAKEN_WEIGHT / numExitingEdges; if (exitWeight < MIN_WEIGHT) exitWeight = MIN_WEIGHT; for (SmallVectorImpl<unsigned>::iterator EI = ExitingEdges.begin(), EE = ExitingEdges.end(); EI != EE; ++EI) { setEdgeWeight(BB, *EI, exitWeight); } } return true; }
Loop* FlowGraph::getOuterLoop(uint32_t idx){ Loop* input = loops[idx]; for (uint32_t i = 0; i < loops.size(); i++){ if (input->isInnerLoopOf(loops[i])){ return loops[i]; } } return input; }
// Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges // as taken, exiting edges as not-taken. bool BranchProbabilityInfo::calcLoopBranchHeuristics(const BasicBlock *BB, const LoopInfo &LI) { Loop *L = LI.getLoopFor(BB); if (!L) return false; SmallVector<unsigned, 8> BackEdges; SmallVector<unsigned, 8> ExitingEdges; SmallVector<unsigned, 8> InEdges; // Edges from header to the loop. for (succ_const_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { if (!L->contains(*I)) ExitingEdges.push_back(I.getSuccessorIndex()); else if (L->getHeader() == *I) BackEdges.push_back(I.getSuccessorIndex()); else InEdges.push_back(I.getSuccessorIndex()); } if (BackEdges.empty() && ExitingEdges.empty()) return false; // Collect the sum of probabilities of back-edges/in-edges/exiting-edges, and // normalize them so that they sum up to one. BranchProbability Probs[] = {BranchProbability::getZero(), BranchProbability::getZero(), BranchProbability::getZero()}; unsigned Denom = (BackEdges.empty() ? 0 : LBH_TAKEN_WEIGHT) + (InEdges.empty() ? 0 : LBH_TAKEN_WEIGHT) + (ExitingEdges.empty() ? 0 : LBH_NONTAKEN_WEIGHT); if (!BackEdges.empty()) Probs[0] = BranchProbability(LBH_TAKEN_WEIGHT, Denom); if (!InEdges.empty()) Probs[1] = BranchProbability(LBH_TAKEN_WEIGHT, Denom); if (!ExitingEdges.empty()) Probs[2] = BranchProbability(LBH_NONTAKEN_WEIGHT, Denom); if (uint32_t numBackEdges = BackEdges.size()) { auto Prob = Probs[0] / numBackEdges; for (unsigned SuccIdx : BackEdges) setEdgeProbability(BB, SuccIdx, Prob); } if (uint32_t numInEdges = InEdges.size()) { auto Prob = Probs[1] / numInEdges; for (unsigned SuccIdx : InEdges) setEdgeProbability(BB, SuccIdx, Prob); } if (uint32_t numExitingEdges = ExitingEdges.size()) { auto Prob = Probs[2] / numExitingEdges; for (unsigned SuccIdx : ExitingEdges) setEdgeProbability(BB, SuccIdx, Prob); } return true; }
void Delinearization::print(raw_ostream &O, const Module *) const { O << "Delinearization on function " << F->getName() << ":\n"; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { Instruction *Inst = &(*I); // Only analyze loads and stores. if (!isa<StoreInst>(Inst) && !isa<LoadInst>(Inst) && !isa<GetElementPtrInst>(Inst)) continue; const BasicBlock *BB = Inst->getParent(); // Delinearize the memory access as analyzed in all the surrounding loops. // Do not analyze memory accesses outside loops. for (Loop *L = LI->getLoopFor(BB); L != nullptr; L = L->getParentLoop()) { const SCEV *AccessFn = SE->getSCEVAtScope(getPointerOperand(*Inst), L); const SCEVUnknown *BasePointer = dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFn)); // Do not delinearize if we cannot find the base pointer. if (!BasePointer) break; AccessFn = SE->getMinusSCEV(AccessFn, BasePointer); const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(AccessFn); // Do not try to delinearize memory accesses that are not AddRecs. if (!AR) break; O << "\n"; O << "Inst:" << *Inst << "\n"; O << "In Loop with Header: " << L->getHeader()->getName() << "\n"; O << "AddRec: " << *AR << "\n"; SmallVector<const SCEV *, 3> Subscripts, Sizes; SE->delinearize(AR, Subscripts, Sizes, SE->getElementSize(Inst)); if (Subscripts.size() == 0 || Sizes.size() == 0 || Subscripts.size() != Sizes.size()) { O << "failed to delinearize\n"; continue; } O << "Base offset: " << *BasePointer << "\n"; O << "ArrayDecl[UnknownSize]"; int Size = Subscripts.size(); for (int i = 0; i < Size - 1; i++) O << "[" << *Sizes[i] << "]"; O << " with elements of " << *Sizes[Size - 1] << " bytes.\n"; O << "ArrayRef"; for (int i = 0; i < Size; i++) O << "[" << *Subscripts[i] << "]"; O << "\n"; } } }
// Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges // as taken, exiting edges as not-taken. bool BranchProbabilityInfo::calcLoopBranchHeuristics(BasicBlock *BB) { Loop *L = LI->getLoopFor(BB); if (!L) return false; SmallPtrSet<BasicBlock *, 8> BackEdges; SmallPtrSet<BasicBlock *, 8> ExitingEdges; SmallPtrSet<BasicBlock *, 8> InEdges; // Edges from header to the loop. for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { if (!L->contains(*I)) ExitingEdges.insert(*I); else if (L->getHeader() == *I) BackEdges.insert(*I); else InEdges.insert(*I); } if (uint32_t numBackEdges = BackEdges.size()) { uint32_t backWeight = LBH_TAKEN_WEIGHT / numBackEdges; if (backWeight < NORMAL_WEIGHT) backWeight = NORMAL_WEIGHT; for (SmallPtrSet<BasicBlock *, 8>::iterator EI = BackEdges.begin(), EE = BackEdges.end(); EI != EE; ++EI) { BasicBlock *Back = *EI; setEdgeWeight(BB, Back, backWeight); } } if (uint32_t numInEdges = InEdges.size()) { uint32_t inWeight = LBH_TAKEN_WEIGHT / numInEdges; if (inWeight < NORMAL_WEIGHT) inWeight = NORMAL_WEIGHT; for (SmallPtrSet<BasicBlock *, 8>::iterator EI = InEdges.begin(), EE = InEdges.end(); EI != EE; ++EI) { BasicBlock *Back = *EI; setEdgeWeight(BB, Back, inWeight); } } if (uint32_t numExitingEdges = ExitingEdges.size()) { uint32_t exitWeight = LBH_NONTAKEN_WEIGHT / numExitingEdges; if (exitWeight < MIN_WEIGHT) exitWeight = MIN_WEIGHT; for (SmallPtrSet<BasicBlock *, 8>::iterator EI = ExitingEdges.begin(), EE = ExitingEdges.end(); EI != EE; ++EI) { BasicBlock *Exiting = *EI; setEdgeWeight(BB, Exiting, exitWeight); } } return true; }
std::shared_ptr<Timer> Timer::Create(Loop& loop) { auto h = std::make_shared<Timer>(private_init{}); int err = uv_timer_init(loop.GetRaw(), h->GetRaw()); if (err < 0) { loop.ReportError(err); return nullptr; } h->Keep(); return h; }
std::shared_ptr<Tty> Tty::Create(Loop& loop, uv_file fd, bool readable) { auto h = std::make_shared<Tty>(private_init{}); int err = uv_tty_init(loop.GetRaw(), h->GetRaw(), fd, readable ? 1 : 0); if (err < 0) { loop.ReportError(err); return nullptr; } h->Keep(); return h; }
Loop* FlowGraph::getParentLoop(uint32_t idx){ Loop* input = loops[idx]; for (uint32_t i = 0; i < loops.size(); i++){ if (input->isInnerLoopOf(loops[i])){ if (getLoopDepth(loops[idx]->getHead()->getIndex()) == getLoopDepth(loops[i]->getHead()->getIndex()) + 1){ return loops[i]; } } } return input; }
Loop* JoinEnumLoop::dropFirstLoop() { Loop* toReturn = tInnerLoop; for (int i = 0; i < tInnerLoops.size(); ++i) { Loop* currentLoop = tInnerLoops[i]; if (currentLoop != NULL){ currentLoop->dropLoop(tInnerLoop); } } tInnerLoop = NULL; return toReturn; }
int main() { int n; freopen("node3.txt", "r", stdin); os.open("result.txt"); while(EOF != scanf("%d",&n) ) { l.Init(n); l.Input(); l.solve(); } os.close(); return 0; }
/* * This pass groups all the incoming blocks that a loop header have into * one single basic block. We call this basic block the "Entry Block" of * a loop. * The entry block is a basic block that is executed only once before the first * iteration of the loop. * * Moreover, we normalize the exits of the loop such that when the loop stop, * the control goes to a block that does not belong to the loop but is * dominated by the entry block. We call blocks like that as "Post Exit Blocks". * A loop may have more than one post exit block, if it has more than one exit point * (e.g. when the loop has a break instruction). */ bool llvm::LoopNormalizer::runOnFunction(Function& F) { LoopInfoEx& li = getAnalysis<LoopInfoEx>(); //Normalize headers for (LoopInfoEx::iterator it = li.begin(); it!= li.end(); it++){ Loop* loop = *it; BasicBlock* header = loop->getHeader(); std::set<BasicBlock*> OutsidePreHeaders; for(pred_iterator pred = pred_begin(header); pred != pred_end(header); pred++){ BasicBlock* predecessor = *pred; if (li.getLoopFor(predecessor) != li.getLoopFor(header)){ OutsidePreHeaders.insert(predecessor); } } normalizePreHeaders(OutsidePreHeaders, header); NumNormalizedLoops++; } // //Normalize exits // std::set<BasicBlock*> loopExits = nla.getLoopExitBlocks(); // for (std::set<BasicBlock*>::iterator it = loopExits.begin(); it!= loopExits.end(); it++){ // // BasicBlock* exitBlock = *it; // // for(succ_iterator succ = succ_begin(exitBlock); succ != succ_end(exitBlock); succ++){ // // BasicBlock* successor = *succ; // // if (li.getLoopDepth(successor) < li.getLoopDepth(exitBlock)){ // // //Successor is outside the block // normalizePostExit(exitBlock, successor); // // } // // } // // } return true; }
// delete a pair of halfedges and make a inner loop // the isolated vertex will be identified by its he which is null // for consistency, we assume that he2 is next to he1 and they are a pair Loop* Solid::kemr(HalfEdge *he1) { Loop *lp = he1->l; // DelHalfEdge delete he1 and its partner halfedge // and return the isolated vertex // the isolated vertex is already in the solid's vertex list lp->delHalfEdgePair(he1); // modified at 2011-11-4 8:47:51, add a ring to the face Loop *newl = new Loop(); lp->f->addLoop(newl); return newl; }
int main(void) { std::string target = "(hoge)"; boost::regex pattern("hoge"); Loop loop; std::cout << loop.calc_loop(add) << std::endl; std::cout << loop.calc_loop(sub) << std::endl; std::cout << loop.regex_loop(target, pattern, regex) << std::endl; return 0; }
bool WorklessInstrument::runOnModule(Module& M) { Function * pFunction = SearchFunctionByName(M, strFileName, strFuncName, uSrcLine); if(pFunction == NULL) { errs() << "Cannot find the input function\n"; return false; } LoopInfo *pLoopInfo = &(getAnalysis<LoopInfo>(*pFunction)); Loop * pLoop = SearchLoopByLineNo(pFunction, pLoopInfo, uSrcLine); if(pLoop == NULL) { errs() << "Cannot find the input loop\n"; return false; } SetupTypes(&M); SetupConstants(&M); SetupHooks(&M); SetupGlobals(&M); BasicBlock * pHeader = pLoop->getHeader(); LoopSimplify(pLoop, this); pLoop = pLoopInfo->getLoopFor(pHeader); if(uType == 0) { } else if(uType == 1) { InstrumentWorkless0Star1(&M, pLoop); } else if(uType == 2) { set<string> setWorkingBlocks; ParseWorkingBlocks(setWorkingBlocks); InstrumentWorkless0Or1Star(&M, pLoop, setWorkingBlocks); } else { errs() << "Wrong Workless Instrument Type\n"; } return true; }
void JoinEnumLoop::addInnerLoop(Loop* innerLoop) { if (tInnerLoop == NULL) { tInnerLoop = innerLoop; for (int i = 0; i < tInnerLoops.size(); ++i) { Loop* currentLoop = tInnerLoops[i]; if (currentLoop != NULL){ currentLoop->addInnerLoop(tInnerLoop); } } } else { tInnerLoop->addInnerLoop(innerLoop); } }
Loop* FlowGraph::getInnermostLoopForBlock(uint32_t idx){ Loop* loop = NULL; for (uint32_t i = 0; i < loops.size(); i++){ if (loops[i]->isBlockIn(idx)){ if (loop){ if (loops[i]->getNumberOfBlocks() < loop->getNumberOfBlocks()){ loop = loops[i]; } } else { loop = loops[i]; } } } return loop; }
// Check that 'BB' doesn't have any uses outside of the 'L' static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB, DominatorTree &DT) { for (const Instruction &I : BB) { // Tokens can't be used in PHI nodes and live-out tokens prevent loop // optimizations, so for the purposes of considered LCSSA form, we // can ignore them. if (I.getType()->isTokenTy()) continue; for (const Use &U : I.uses()) { const Instruction *UI = cast<Instruction>(U.getUser()); const BasicBlock *UserBB = UI->getParent(); if (const PHINode *P = dyn_cast<PHINode>(UI)) UserBB = P->getIncomingBlock(U); // Check the current block, as a fast-path, before checking whether // the use is anywhere in the loop. Most values are used in the same // block they are defined in. Also, blocks not reachable from the // entry are special; uses in them don't need to go through PHIs. if (UserBB != &BB && !L.contains(UserBB) && DT.isReachableFromEntry(UserBB)) return false; } } return true; }
CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs, BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI) : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI), BPI(BPI), AllowVarArgs(false), Blocks(buildExtractionBlockSet(L.getBlocks(), &DT, /* AllowVarArgs */ false)) {}
static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU) { bool Changed = false; DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager); // Copy blocks into a temporary array to avoid iterator invalidation issues // as we remove them. SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); for (auto &Block : Blocks) { // Attempt to merge blocks in the trivial case. Don't modify blocks which // belong to other loops. BasicBlock *Succ = cast_or_null<BasicBlock>(Block); if (!Succ) continue; BasicBlock *Pred = Succ->getSinglePredecessor(); if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) continue; // Merge Succ into Pred and delete it. MergeBlockIntoPredecessor(Succ, &DTU, &LI, MSSAU); Changed = true; } return Changed; }
static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE) { bool Changed = false; // Copy blocks into a temporary array to avoid iterator invalidation issues // as we remove them. SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); for (auto &Block : Blocks) { // Attempt to merge blocks in the trivial case. Don't modify blocks which // belong to other loops. BasicBlock *Succ = cast_or_null<BasicBlock>(Block); if (!Succ) continue; BasicBlock *Pred = Succ->getSinglePredecessor(); if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L) continue; // Merge Succ into Pred and delete it. MergeBlockIntoPredecessor(Succ, &DT, &LI); SE.forgetLoop(&L); Changed = true; } return Changed; }
PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &Updater) { DEBUG(dbgs() << "Analyzing Loop for deletion: "); DEBUG(L.dump()); std::string LoopName = L.getName(); auto Result = deleteLoopIfDead(&L, AR.DT, AR.SE, AR.LI); if (Result == LoopDeletionResult::Unmodified) return PreservedAnalyses::all(); if (Result == LoopDeletionResult::Deleted) Updater.markLoopAsDeleted(L, LoopName); return getLoopPassPreservedAnalyses(); }
/// updateBlockParents - Update the parent loop for all blocks that are directly /// contained within the original "unloop". void UnloopUpdater::updateBlockParents() { if (Unloop->getNumBlocks()) { // Perform a post order CFG traversal of all blocks within this loop, // propagating the nearest loop from sucessors to predecessors. LoopBlocksTraversal Traversal(DFS, LI); for (LoopBlocksTraversal::POTIterator POI = Traversal.begin(), POE = Traversal.end(); POI != POE; ++POI) { Loop *L = LI->getLoopFor(*POI); Loop *NL = getNearestLoop(*POI, L); if (NL != L) { // For reducible loops, NL is now an ancestor of Unloop. assert((NL != Unloop && (!NL || NL->contains(Unloop))) && "uninitialized successor"); LI->changeLoopFor(*POI, NL); } else { // Or the current block is part of a subloop, in which case its parent // is unchanged. assert((FoundIB || Unloop->contains(L)) && "uninitialized successor"); } } } // Each irreducible loop within the unloop induces a round of iteration using // the DFS result cached by Traversal. bool Changed = FoundIB; for (unsigned NIters = 0; Changed; ++NIters) { assert(NIters < Unloop->getNumBlocks() && "runaway iterative algorithm"); // Iterate over the postorder list of blocks, propagating the nearest loop // from successors to predecessors as before. Changed = false; for (LoopBlocksDFS::POIterator POI = DFS.beginPostorder(), POE = DFS.endPostorder(); POI != POE; ++POI) { Loop *L = LI->getLoopFor(*POI); Loop *NL = getNearestLoop(*POI, L); if (NL != L) { assert(NL != Unloop && (!NL || NL->contains(Unloop)) && "uninitialized successor"); LI->changeLoopFor(*POI, NL); Changed = true; } } } }