Loop* FlowGraph::getOuterMostLoopForLoop(uint32_t idx){
    Loop* input = loops[idx];
    while (input->getIndex() != getOuterLoop(input->getIndex())->getIndex()){
        input = getOuterLoop(input->getIndex());
    }
    return input;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/**
 * 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);
    }
}
Exemplo n.º 4
0
//===----------------------------------------------------------------------===//
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);
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 7
0
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;
    }
  }
}
Exemplo n.º 8
0
/// 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;
}
Exemplo n.º 11
0
// 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;
}
Exemplo n.º 12
0
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";
    }
  }
}
Exemplo n.º 13
0
// 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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
0
	// 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;
	}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
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;
}
Exemplo n.º 25
0
// 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;
}
Exemplo n.º 26
0
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)) {}
Exemplo n.º 27
0
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;
}
Exemplo n.º 28
0
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;
}
Exemplo n.º 29
0
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();
}
Exemplo n.º 30
0
/// 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;
      }
    }
  }
}