void CRePair::unroll(uint s, uint i) { if(s>max_value) { unroll(symbols_pair[2*(s-max_value-1)],i); unroll(symbols_pair[1+2*(s-max_value-1)],i); return; } pos++; }
int unroll(boxedint x ) { void *tmp ; int tmp___0 ; int __a_local ; int __retres ; void *__cil_tmp6 ; int __cil_tmp7 ; { tmp = (void *)0; if ((unsigned int )(& __a_local) <= ___stack_threshhold) { ___stack_overflow(); } { if (x & 1) { __retres = x; goto return_label; } __cil_tmp6 = (unsigned int )((void *)x); tmp = (void *)__cil_tmp6; CHECK_NULL((void *)((int *)tmp)); __cil_tmp7 = unroll(*((int *)tmp)); tmp___0 = __cil_tmp7; __retres = tmp___0; goto return_label; } return_label: /* CIL Label */ ; return (__retres); } }
/** * Unroll the entire algorithm history. * * This is method will unroll the entire history for every algorithm by calling *unroll * on each element in the list. Every child algorithm with be visible after *calling this method. */ void HistoryView::unrollAll() { auto it = m_historyItems.begin(); while (it != m_historyItems.end()) { // iterator passed by reference to prevent iterator invalidation. // iterator incremented within function. unroll(it); } }
/** * Unroll an algorithm history to export its child algorithms. * * This places each of the child algorithm histories into the * HistoryView object. The parent is retained as a marker so we can * "roll" the history back up if we want. This method does nothing if * the history object has no children * * @param index :: index of the history object to unroll * @throws std::out_of_range if the index is larger than the number of history *items. */ void HistoryView::unroll(size_t index) { if (index >= m_historyItems.size()) { throw std::out_of_range("HistoryView::unroll() - Index out of range"); } // advance to the item at the index auto it = m_historyItems.begin(); std::advance(it, index); unroll(it); }
static void unroll(struct Allocator_pvt* context, int includeAllocations, struct Unroller* unroller) { writeUnroller(unroller); const char* ident = (context->pub.fileName) ? context->pub.fileName : "UNKNOWN"; fprintf(stderr, "%s:%d [%lu] bytes%s\n", ident, context->pub.lineNum, context->allocatedHere, (context->pub.isFreeing) ? " (freeing)" : ""); struct Unroller childUnroller = { .content = ((context->nextSibling) ? "| " : " "), .last = unroller }; if (context->firstChild) { unroll(context->firstChild, includeAllocations, &childUnroller); } struct Allocator_Allocation_pvt* allocation = context->allocations; while (allocation && includeAllocations) { writeUnroller(&childUnroller); fprintf(stderr, "%s:%d [%lu] bytes at [0x%lx]\n", allocation->pub.fileName, allocation->pub.lineNum, allocation->pub.size, (long)(uintptr_t)allocation); allocation = allocation->next; } if (context->nextSibling) { unroll(context->nextSibling, includeAllocations, unroller); } } static inline uint64_t bytesAllocated(struct Allocator_pvt* ctx) { uint64_t bytes = ctx->allocatedHere; for (struct Allocator_pvt* child = ctx->firstChild; child; child = child->nextSibling) { bytes += bytesAllocated(child); } return bytes; }
void CRePair::fillBR() { uint bits_BR_len = (uint)(n+2); uint *bits_BR = new uint[((bits_BR_len+W-1)/W)]; for(uint i=0; i<(W-1+bits_BR_len)/W;i++) bits_BR[i]=0; pos = 0; for(uint i=0;i<m;i++) { bitset(bits_BR,pos); unroll(symbols[i],i); } bitset(bits_BR,pos); delete [] bits_BR; }
void LoopUnroller::processWorkSpace(otawa::WorkSpace *fw) { int cfgidx = 0; const CFGCollection *orig_coll = INVOLVED_CFGS(fw); // Create the new VCFG collection first, so that it will be available when we do the loop unrolling for (CFGCollection::Iterator cfg(*orig_coll); cfg; cfg++, cfgidx++) { VirtualCFG *vcfg = new VirtualCFG(false); coll->add(vcfg); INDEX(vcfg) = cfgidx; vcfg->addBB(vcfg->entry()); } cfgidx = 0; for (CFGCollection::Iterator vcfg(*coll), cfg(*orig_coll); vcfg; vcfg++, cfg++) { ASSERT(INDEX(vcfg) == INDEX(cfg)); LABEL(vcfg) = cfg->label(); INDEX(vcfg->entry()) = 0; idx = 1; // if (isVerbose()) { cout << "Processing CFG: " << cfg->label() << "\n"; //} /* !!GRUIK!! Ca serait bien d'avoir une classe VCFGCollection */ VirtualCFG *casted_vcfg = static_cast<otawa::VirtualCFG*>((otawa::CFG*)vcfg); unroll((otawa::CFG*) cfg, 0, casted_vcfg); if (ENTRY_CFG(fw) == cfg) ENTRY_CFG(fw) = vcfg; casted_vcfg->addBB(vcfg->exit()); INDEX(vcfg->exit()) = idx; } }
void Allocator_snapshot(struct Allocator* allocator, int includeAllocations) { // get the root allocator. struct Allocator_pvt* alloc = Identity_check((struct Allocator_pvt*)allocator); struct Allocator_FirstCtx* rootAlloc = Identity_check(alloc->rootAlloc); alloc = Identity_check((struct Allocator_pvt*)rootAlloc); fprintf(stderr, "----- %scjdns memory snapshot -----\n", ""); uint64_t totalAllocated = rootAlloc->maxSpace - rootAlloc->spaceAvailable; uint64_t realAllocated = bytesAllocated(alloc); unroll(alloc, includeAllocations, NULL); if (totalAllocated != realAllocated) { fprintf(stderr, "!!!!!! INTERNAL ERROR totalAllocated = [%lu] realAllocated = [%lu] !!!!!", (unsigned long)totalAllocated, (unsigned long)realAllocated); } fprintf(stderr, "totalBytes [%ld] remaining [%ld]\n", (long)rootAlloc->maxSpace, (long)rootAlloc->spaceAvailable); fprintf(stderr, "----- %scjdns memory snapshot -----\n", "end "); }
RVal operator|(A&& a) const { using Sequence = typename GenSequence<sizeof...(P)>::type; return unroll(std::forward<A>(a), Sequence{}); }
void LoopUnroller::unroll(otawa::CFG *cfg, BasicBlock *header, VirtualCFG *vcfg) { VectorQueue<BasicBlock*> workList; VectorQueue<BasicBlock*> loopList; VectorQueue<BasicBlock*> virtualCallList; genstruct::Vector<BasicBlock*> doneList; typedef genstruct::Vector<Pair<VirtualBasicBlock*, Edge::kind_t> > BackEdgePairVector; BackEdgePairVector backEdges; bool dont_unroll = false; BasicBlock *unrolled_from; int start; /* Avoid unrolling loops with LOOP_COUNT of 0, since it would create a LOOP_COUNT of -1 for the non-unrolled part of the loop*/ /* if (header && (ipet::LOOP_COUNT(header) == 0)) { dont_unroll = true; } */ //if (header) dont_unroll = true; start = dont_unroll ? 1 : 0; for (int i = start; ((i < 2) && header) || (i < 1); i++) { doneList.clear(); ASSERT(workList.isEmpty()); ASSERT(loopList.isEmpty()); ASSERT(doneList.isEmpty()); workList.put(header ? header : cfg->entry()); doneList.add(header ? header : cfg->entry()); genstruct::Vector<BasicBlock*> bbs; while (!workList.isEmpty()) { BasicBlock *current = workList.get(); if (LOOP_HEADER(current) && (current != header)) { /* we enter another loop */ loopList.put(current); /* add exit edges destinations to the worklist */ for (genstruct::Vector<Edge*>::Iterator exitedge(**EXIT_LIST(current)); exitedge; exitedge++) { if (!doneList.contains(exitedge->target())) { workList.put(exitedge->target()); doneList.add(exitedge->target()); } } } else { VirtualBasicBlock *new_bb = 0; if ((!current->isEntry()) && (!current->isExit())) { /* Duplicate the current basic block */ new_bb = new VirtualBasicBlock(current); new_bb->removeAllProp(&ENCLOSING_LOOP_HEADER); new_bb->removeAllProp(&EXIT_LIST); new_bb->removeAllProp(&REVERSE_DOM); new_bb->removeAllProp(&LOOP_EXIT_EDGE); new_bb->removeAllProp(&LOOP_HEADER); new_bb->removeAllProp(&ENTRY); /* Remember the call block so we can correct its destination when we have processed it */ if (VIRTUAL_RETURN_BLOCK(new_bb)) virtualCallList.put(new_bb); if ((current == header) && (!dont_unroll)) { if (i == 0) { unrolled_from = new_bb; } else { UNROLLED_FROM(new_bb) = unrolled_from; } } /* if (ipet::LOOP_COUNT(new_bb) != -1) { if (i == 0) { new_bb->removeAllProp(&ipet::LOOP_COUNT); } else { int old_count = ipet::LOOP_COUNT(new_bb); new_bb->removeAllProp(&ipet::LOOP_COUNT); ipet::LOOP_COUNT(new_bb) = old_count - (1 - start); ASSERT(ipet::LOOP_COUNT(new_bb) >= 0); } } */ INDEX(new_bb) = idx; idx++; vcfg->addBB(new_bb); bbs.add(current); map.put(current, new_bb); } /* add successors which are in loop (including possible sub-loop headers) */ for (BasicBlock::OutIterator outedge(current); outedge; outedge++) { if (outedge->target() == cfg->exit()) continue; if (outedge->kind() == Edge::CALL) continue; if (ENCLOSING_LOOP_HEADER(outedge->target()) == header) { // cout << "Test for add: " << outedge->target()->number() << "\n"; if (!doneList.contains(outedge->target())) { workList.put(outedge->target()); doneList.add(outedge->target()); } } if (LOOP_EXIT_EDGE(outedge)) { ASSERT(new_bb); /* Connect exit edge */ VirtualBasicBlock *vdst = map.get(outedge->target()); new Edge(new_bb, vdst, outedge->kind()); } } } } while (!virtualCallList.isEmpty()) { BasicBlock *vcall = virtualCallList.get(); BasicBlock *vreturn = map.get(VIRTUAL_RETURN_BLOCK(vcall), 0); ASSERT(vreturn != 0); VIRTUAL_RETURN_BLOCK(vcall) = vreturn; } while (!loopList.isEmpty()) { BasicBlock *loop = loopList.get(); unroll(cfg, loop, vcfg); } /* Connect the internal edges for the current loop */ for (genstruct::Vector<BasicBlock*>::Iterator bb(bbs); bb; bb++) { for (BasicBlock::OutIterator outedge(bb); outedge; outedge++) { if (LOOP_EXIT_EDGE(outedge)) continue; if (LOOP_HEADER(outedge->target()) && (outedge->target() != header)) continue; if (outedge->target() == cfg->exit()) continue; VirtualBasicBlock *vsrc = map.get(*bb, 0); VirtualBasicBlock *vdst = map.get(outedge->target(), 0); if (outedge->kind() == Edge::CALL) { CFG *called_cfg = outedge->calledCFG(); int called_idx = INDEX(called_cfg); CFG *called_vcfg = coll->get(called_idx); Edge *vedge = new Edge(vsrc, called_vcfg->entry(), Edge::CALL); CALLED_BY(called_vcfg).add(vedge); ENTRY(called_vcfg->entry()) = called_vcfg; CALLED_CFG(outedge) = called_vcfg; /* XXX: ??!? */ } else if ((outedge->target() != header) || ((i == 1) /* XXX && !dont_unroll XXX*/ )) { new Edge(vsrc, vdst, outedge->kind()); } else { backEdges.add(pair(vsrc, outedge->kind())); } } } if (i == start) { /* Connect virtual entry edges */ if (header) { for (BasicBlock::InIterator inedge(header); inedge; inedge++) { if (Dominance::dominates(header, inedge->source())) continue; /* skip back edges */ if (inedge->source() == cfg->entry()) continue; VirtualBasicBlock *vsrc = map.get(inedge->source()); VirtualBasicBlock *vdst = map.get(header); new Edge(vsrc, vdst, inedge->kind()); } } } else { /* Connect virtual backedges from the first to the other iterations */ for (BackEdgePairVector::Iterator iter(backEdges); iter; iter++) { VirtualBasicBlock *vdst = map.get(header); new Edge((*iter).fst, vdst, (*iter).snd); } } } if (!header) { /* add main entry edges */ for (BasicBlock::OutIterator outedge(cfg->entry()); outedge; outedge++) { VirtualBasicBlock *vdst = map.get(outedge->target()); new Edge(vcfg->entry(), vdst, Edge::VIRTUAL_CALL); } /* add main exit edges */ for (BasicBlock::InIterator inedge(cfg->exit()); inedge; inedge++) { VirtualBasicBlock *vsrc = map.get(inedge->source()); new Edge(vsrc, vcfg->exit(), Edge::VIRTUAL_RETURN); } } }
static VALUE rb_sumbur(VALUE self, VALUE hashed_int, VALUE capacity) { unsigned int h = NUM2UINT(hashed_int); unsigned int capa = NUM2UINT(capacity); unsigned int part, n, i, c; if (capa == 0) { rb_raise(rb_eArgError, "Sumbur is not applicable to empty cluster"); } part = L / capa; if (L - h < part) return INT2FIX(0); n = 1; do { if (h >= L / 2) h -= L / 2; else { n = 2; if (L / 2 - h < part) return INT2FIX(1); } if (capa == 2) return INT2FIX(1); #define curslice(i) (L / (i * (i - 1))) #define unroll(i) \ if (curslice(i) <= h) h -= curslice(i); \ else { \ h += curslice(i) * (i - n - 1); \ n = i; \ if (L / i - h < part) return INT2FIX(n-1); \ } \ if (capa == i) return INT2FIX(n-1) unroll(3); unroll(4); unroll(5); unroll(6); unroll(7); unroll(8); unroll(9); unroll(10); unroll(11); unroll(12); unroll(13); unroll(14); unroll(15); unroll(16); unroll(17); unroll(18); unroll(19); unroll(20); unroll(21); unroll(22); unroll(23); unroll(24); unroll(25); unroll(26); for (i = 27; i <= capa && i <= 62; i++) { c = LL27_38[i-27]; if (c <= h) { h -= c; } else { h += c * (i - n - 1); n = i; if (L27_38[i-27] - h < part) return INT2FIX(n-1); } } for(i = 63; i <= capa; i++) { c = L / (i * (i - 1)); if (c <= h) { h -= c; } else { h += c * (i - n - 1); n = i; if (L / i - h < part) return INT2FIX(n - 1); } } } while(0); return INT2FIX(n - 1); }
static void unroll(struct Allocator_pvt* context, int includeAllocations, struct Unroller* unroller) { writeUnroller(unroller); const char* ident = (context->pub.fileName) ? context->pub.fileName : "UNKNOWN"; fprintf(stderr, "%s:%d [%lu] bytes%s\n", ident, context->pub.lineNum, context->allocatedHere, (context->pub.isFreeing) ? " (freeing)" : ""); struct Unroller childUnroller = { .content = ((context->nextSibling) ? "| " : " "), .last = unroller }; if (context->firstChild) { unroll(context->firstChild, includeAllocations, &childUnroller); } struct Allocator_Allocation_pvt* allocation = context->allocations; while (allocation && includeAllocations) { writeUnroller(&childUnroller); fprintf(stderr, "%s:%d [%lu] bytes at [0x%lx]\n", allocation->pub.fileName, allocation->pub.lineNum, allocation->pub.size, (long)(uintptr_t)allocation); allocation = allocation->next; } if (context->nextSibling) { unroll(context->nextSibling, includeAllocations, unroller); } } void Allocator_snapshot(struct Allocator* alloc, int includeAllocations) { // get the root allocator. struct Allocator_pvt* rootAlloc = Identity_check((struct Allocator_pvt*)alloc); while (rootAlloc->parent && rootAlloc->parent != rootAlloc) { rootAlloc = rootAlloc->parent; } fprintf(stderr, "----- %scjdns memory snapshot -----\n", ""); unroll(rootAlloc, includeAllocations, NULL); fprintf(stderr, "totalBytes [%ld] remaining [%ld]\n", (long)rootAlloc->rootAlloc->maxSpace, (long)rootAlloc->rootAlloc->spaceAvailable); fprintf(stderr, "----- %scjdns memory snapshot -----\n", "end "); } Gcc_NORETURN static void failure(struct Allocator_pvt* context, const char* message, const char* fileName, int lineNum) { Allocator_snapshot(&context->pub, 1); Assert_failure("%s:%d Fatal error: [%s]", fileName, lineNum, message); }