/* * Build the CFG, then the dominator tree, then use it to validate SSA. * 1. Each src must be defined by some other instruction, and each dst must * be defined by the current instruction. * 2. Each src must be defined earlier in the same block or in a dominator. * 3. Each dst must not be previously defined. * 4. Treat tmps defined by DefConst as always defined. * 5. Each predecessor of a reachable block must be reachable (deleted * blocks must not have out-edges to reachable blocks). */ bool checkCfg(IRTrace* trace, const IRFactory& factory) { forEachTraceBlock(trace, checkBlock); // Check valid successor/predecessor edges. auto const blocks = rpoSortCfg(trace, factory); std::unordered_set<const Edge*> edges; for (Block* b : blocks) { auto checkEdge = [&] (const Edge* e) { assert(e->from() == b); edges.insert(e); for (auto& p : e->to()->preds()) if (&p == e) return; assert(false); // did not find edge. }; if (auto *e = nextEdge(b)) checkEdge(e); if (auto *e = takenEdge(b)) checkEdge(e); } for (Block* b : blocks) { for (DEBUG_ONLY auto const &e : b->preds()) { assert(&e == takenEdge(e.from()) || &e == nextEdge(e.from())); assert(e.to() == b); } } checkCatchTraces(trace, factory); // visit dom tree in preorder, checking all tmps auto const children = findDomChildren(blocks); StateVector<SSATmp, bool> defined0(&factory, false); forPreorderDoms(blocks.front(), children, defined0, [] (Block* block, StateVector<SSATmp, bool>& defined) { for (IRInstruction& inst : *block) { for (DEBUG_ONLY SSATmp* src : inst.srcs()) { assert(src->inst() != &inst); assert_log(src->inst()->op() == DefConst || defined[src], [&]{ return folly::format( "src '{}' in '{}' came from '{}', which is not a " "DefConst and is not defined at this use site", src->toString(), inst.toString(), src->inst()->toString()).str(); }); } for (SSATmp& dst : inst.dsts()) { assert(dst.inst() == &inst && inst.op() != DefConst); assert(!defined[dst]); defined[dst] = true; } } }); return true; }
void KisPixelSelection::nextOutlineEdge(EdgeType *edge, qint32 *row, qint32 *col, quint8* buffer, qint32 width, qint32 height) { int original_row = *row; int original_col = *col; switch (*edge) { case RightEdge: TRY_PIXEL(-1, 0, RightEdge); TRY_PIXEL(-1, 1, BottomEdge); break; case TopEdge: TRY_PIXEL(0, -1, TopEdge); TRY_PIXEL(-1, -1, RightEdge); break; case LeftEdge: TRY_PIXEL(1, 0, LeftEdge); TRY_PIXEL(1, -1, TopEdge); break; case BottomEdge: TRY_PIXEL(0, 1, BottomEdge); TRY_PIXEL(1, 1, LeftEdge); break; default: break; } if (*row == original_row && *col == original_col) *edge = nextEdge(*edge); }
void justine::robocar::SmartCar::step() { if (m_type == CarType::POLICE) { if (m_guided) nextGuidedEdge(); else nextEdge(); } else if (m_type == CarType::GOTIN) { return; } else if (m_type == CarType::CAUGHT) { return; } else if (m_type == CarType::GANGSTER) { return; } else Car::step(); }
void KisOutlineGenerator::nextOutlineEdge(StorageStrategy &storage, EdgeType *edge, qint32 *row, qint32 *col, qint32 width, qint32 height) { int original_row = *row; int original_col = *col; switch (*edge) { case RightEdge: TRY_PIXEL(-1, 0, RightEdge); TRY_PIXEL(-1, 1, BottomEdge); break; case TopEdge: TRY_PIXEL(0, -1, TopEdge); TRY_PIXEL(-1, -1, RightEdge); break; case LeftEdge: TRY_PIXEL(1, 0, LeftEdge); TRY_PIXEL(1, -1, TopEdge); break; case BottomEdge: TRY_PIXEL(0, 1, BottomEdge); TRY_PIXEL(1, 1, LeftEdge); break; default: break; } if (*row == original_row && *col == original_col) *edge = nextEdge(*edge); }
Boolean FGLstepper::firstEdge(const GLref& entryPacketRef){ packetRef=entryPacketRef; edgeIndex=0; edgeSign=-1; count=-1; // place the edge ref sizeof(GLref) bytes BEFORE the first // slot, so that the call to nextEdge advances to the first slot edgeRef.index=packetRef.index; edgeRef.offset=packetRef.offset+edgeRefOffset-(long)sizeof(GLref); return(nextEdge()); }
static void randomRange(Addr *baseReturn, Addr *limitReturn, FBMState state) { Index base; /* the start of our range */ Index end; /* an edge (i.e. different from its predecessor) */ /* after base */ Index limit; /* a randomly chosen value in (base, limit]. */ base = fbmRnd(ArraySize); do { end = nextEdge(state->allocTable, ArraySize, base); } while(end < ArraySize && fbmRnd(2) == 0); /* p=0.5 exponential */ Insist(end > base); limit = base + 1 + fbmRnd(end - base); *baseReturn = addrOfIndex(state, base); *limitReturn = addrOfIndex(state, limit); }
void dfs(Graph &g, int v) { std::vector<EdgeNodePtr> nextEdge(g.vc+1); std::vector<VStatus> vs(g.vc+1); std::stack<int> s; s.push(v); vs[v] = DIS; process_vertex_early(v); nextEdge[v] = g.eNs[v]; while (!s.empty()) { int x = s.top(); EdgeNodePtr yp = nextEdge[x]; if (yp) { int y = yp->y; nextEdge[x] = yp->next; bool newEdge = false; if(vs[y] == UND) { nextEdge[y] = g.eNs[y]; s.push(y); vs[y] = DIS; process_vertex_early(y); } if (vs[y] != PRO || g.directed) { process_edge(x, y); } } else { s.pop(); process_vertex_late(x); vs[x] = PRO; } } }
static void deallocate(FBMState state, Addr base, Addr limit) { Res res; Index ib, il; Bool isAllocated; Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ RangeStruct range, freeRange; /* interval returned by the manager */ ib = indexOfAddr(state, base); il = indexOfAddr(state, limit); isAllocated = BTIsSetRange(state->allocTable, ib, il); NDeallocateTried++; if (isAllocated) { Size left, right, total; /* Sizes of block and two fragments */ /* Find the free blocks adjacent to the allocated block */ if (ib > 0 && !BTGet(state->allocTable, ib - 1)) { outerBase = addrOfIndex(state, lastEdge(state->allocTable, ArraySize, ib - 1)); } else { outerBase = base; } if (il < ArraySize && !BTGet(state->allocTable, il)) { outerLimit = addrOfIndex(state, nextEdge(state->allocTable, ArraySize, il)); } else { outerLimit = limit; } left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* TODO: check these values */ UNUSED(left); UNUSED(right); UNUSED(total); } RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: res = CBSInsert(&freeRange, state->the.cbs, &range); break; case FBMTypeFreelist: res = FreelistInsert(&freeRange, state->the.fl, &range); break; default: fail(); return; } if (verbose) { printf("deallocate: [%p,%p) -- %s\n", (void *)base, (void *)limit, isAllocated ? "succeed" : "fail"); describe(state); } if (!isAllocated) { die_expect((mps_res_t)res, MPS_RES_FAIL, "succeeded in inserting non-allocated block"); } else { /* isAllocated */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to insert allocated block"); NDeallocateSucceeded++; BTResRange(state->allocTable, ib, il); Insist(RangeBase(&freeRange) == outerBase); Insist(RangeLimit(&freeRange) == outerLimit); } }
static void allocate(FBMState state, Addr base, Addr limit) { Res res; Index ib, il; /* Indexed for base and limit */ Bool isFree; RangeStruct range, oldRange; Addr outerBase, outerLimit; /* interval containing [ib, il) */ ib = indexOfAddr(state, base); il = indexOfAddr(state, limit); isFree = BTIsResRange(state->allocTable, ib, il); NAllocateTried++; if (isFree) { Size left, right, total; /* Sizes of block and two fragments */ outerBase = addrOfIndex(state, lastEdge(state->allocTable, ArraySize, ib)); outerLimit = addrOfIndex(state, nextEdge(state->allocTable, ArraySize, il - 1)); left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* TODO: check these values */ UNUSED(left); UNUSED(right); UNUSED(total); } else { outerBase = outerLimit = NULL; } RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: res = CBSDelete(&oldRange, state->the.cbs, &range); break; case FBMTypeFreelist: res = FreelistDelete(&oldRange, state->the.fl, &range); break; default: fail(); return; } if (verbose) { printf("allocate: [%p,%p) -- %s\n", (void *)base, (void *)limit, isFree ? "succeed" : "fail"); describe(state); } if (!isFree) { die_expect((mps_res_t)res, MPS_RES_FAIL, "Succeeded in deleting allocated block"); } else { /* isFree */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to delete free block"); Insist(RangeBase(&oldRange) == outerBase); Insist(RangeLimit(&oldRange) == outerLimit); NAllocateSucceeded++; BTSetRange(state->allocTable, ib, il); } }
MetricOffset Edge::getEndMetricOffset() const { Edge* nextEdge(getNext()); return nextEdge ? nextEdge->getMetricOffset() : getMetricOffset(); }
QVector<QPolygon> KisOutlineGenerator::outlineImpl(typename StorageStrategy::StorageType buffer, qint32 xOffset, qint32 yOffset, qint32 width, qint32 height) { QVector<QPolygon> paths; try { StorageStrategy storage(buffer, width, height, m_cs->pixelSize()); for (qint32 y = 0; y < height; y++) { for (qint32 x = 0; x < width; x++) { if (m_cs->opacityU8(storage.pickPixel(x, y)) == m_defaultOpacity) continue; EdgeType startEdge = TopEdge; EdgeType edge = startEdge; while (edge != NoEdge && (*storage.pickMark(x, y) & (1 << edge) || !isOutlineEdge(storage, edge, x, y, width, height))) { edge = nextEdge(edge); if (edge == startEdge) edge = NoEdge; } if (edge != NoEdge) { QPolygon path; path << QPoint(x + xOffset, y + yOffset); bool clockwise = edge == BottomEdge; qint32 row = y, col = x; EdgeType currentEdge = edge; EdgeType lastEdge = currentEdge; forever { //While following a straight line no points need to be added if (lastEdge != currentEdge) { appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge); lastEdge = currentEdge; } *storage.pickMark(col, row) |= 1 << currentEdge; nextOutlineEdge(storage, ¤tEdge, &row, &col, width, height); if (row == y && col == x && currentEdge == edge) { // add last point of the polygon appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge); break; } } if(!m_simple || !clockwise) paths.push_back(path); } } } } catch(std::bad_alloc) { warnKrita << "KisOutlineGenerator::outline ran out of memory allocating " << width << "*" << height << "marks"; } return paths; }
QVector<QPolygon> KisPixelSelection::outline() { quint8 defaultPixel = *(m_datamanager->defaultPixel()); QRect selectionExtent = exactBounds(); qint32 xOffset = selectionExtent.x(); qint32 yOffset = selectionExtent.y(); qint32 width = selectionExtent.width(); qint32 height = selectionExtent.height(); quint8* buffer = new quint8[width*height]; quint8* marks = new quint8[width*height]; for (int i = 0; i < width*height; i++) { marks[i] = 0; } QVector<QPolygon> paths; readBytes(buffer, xOffset, yOffset, width, height); int nodes = 0; for (qint32 y = 0; y < height; y++) { for (qint32 x = 0; x < width; x++) { if (buffer[y*width+x] == defaultPixel) continue; EdgeType startEdge = TopEdge; EdgeType edge = startEdge; while (edge != NoEdge && (marks[y*width+x] & (1 << edge) || !isOutlineEdge(edge, x, y, buffer, width, height))) { edge = nextEdge(edge); if (edge == startEdge) edge = NoEdge; } if (edge != NoEdge) { QPolygon path; path << QPoint(x + xOffset, y + yOffset); // XXX: Unused? (BSAR) // bool clockwise = edge == BottomEdge; qint32 row = y, col = x; EdgeType currentEdge = edge; EdgeType lastEdge = currentEdge; do { //While following a strait line no points nead to be added if (lastEdge != currentEdge) { appendCoordinate(&path, col + xOffset, row + yOffset, currentEdge); nodes++; lastEdge = currentEdge; } marks[row*width+col] |= 1 << currentEdge; nextOutlineEdge(¤tEdge, &row, &col, buffer, width, height); } while (row != y || col != x || currentEdge != edge); paths.push_back(path); } } } delete[] buffer; delete[] marks; return paths; }
static void deallocate(CBS cbs, Addr block, BT allocTable, Addr base, Addr limit) { Res res; Index ib, il; Bool isAllocated; Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ Addr freeBase, freeLimit; /* interval returned by CBS */ ib = indexOfAddr(block, base); il = indexOfAddr(block, limit); isAllocated = BTIsSetRange(allocTable, ib, il); /* printf("deallocate: [%p, %p) -- %s\n", base, limit, isAllocated ? "succeed" : "fail"); */ NDeallocateTried++; if (isAllocated) { Size left, right, total; /* Sizes of block and two fragments */ /* Find the free blocks adjacent to the allocated block */ if (ib > 0 && !BTGet(allocTable, ib - 1)) { outerBase = addrOfIndex(block, lastEdge(allocTable, ArraySize, ib - 1)); } else { outerBase = base; } if (il < ArraySize && !BTGet(allocTable, il)) { outerLimit = addrOfIndex(block, nextEdge(allocTable, ArraySize, il)); } else { outerLimit = limit; } left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* based on detailed knowledge of CBS behaviour */ checkExpectations(); if (total >= MinSize && left < MinSize && right < MinSize) { if (left >= right) expectCallback(&CallbackNew, left, outerBase, outerLimit); else expectCallback(&CallbackNew, right, outerBase, outerLimit); } else if (left >= MinSize && right >= MinSize) { if (left >= right) { expectCallback(&CallbackDelete, right, (Addr)0, (Addr)0); expectCallback(&CallbackGrow, left, outerBase, outerLimit); } else { expectCallback(&CallbackDelete, left, (Addr)0, (Addr)0); expectCallback(&CallbackGrow, right, outerBase, outerLimit); } } else if (total >= MinSize) { if (left >= right) { Insist(left >= MinSize); Insist(right < MinSize); expectCallback(&CallbackGrow, left, outerBase, outerLimit); } else { Insist(left < MinSize); Insist(right >= MinSize); expectCallback(&CallbackGrow, right, outerBase, outerLimit); } } } res = CBSInsertReturningRange(&freeBase, &freeLimit, cbs, base, limit); if (!isAllocated) { die_expect((mps_res_t)res, MPS_RES_FAIL, "succeeded in inserting non-allocated block"); } else { /* isAllocated */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to insert allocated block"); NDeallocateSucceeded++; BTResRange(allocTable, ib, il); checkExpectations(); Insist(freeBase == outerBase); Insist(freeLimit == outerLimit); } }
static void allocate(CBS cbs, Addr block, BT allocTable, Addr base, Addr limit) { Res res; Index ib, il; /* Indexed for base and limit */ Bool isFree; ib = indexOfAddr(block, base); il = indexOfAddr(block, limit); isFree = BTIsResRange(allocTable, ib, il); /* printf("allocate: [%p, %p) -- %s\n", base, limit, isFree ? "succeed" : "fail"); */ NAllocateTried++; if (isFree) { Addr outerBase, outerLimit; /* interval containing [ib, il) */ Size left, right, total; /* Sizes of block and two fragments */ outerBase = addrOfIndex(block, lastEdge(allocTable, ArraySize, ib)); outerLimit = addrOfIndex(block, nextEdge(allocTable, ArraySize, il - 1)); left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* based on detailed knowledge of CBS behaviour */ checkExpectations(); if (total >= MinSize && left < MinSize && right < MinSize) { if (left == (Size)0 && right == (Size)0) { expectCallback(&CallbackDelete, total, (Addr)0, (Addr)0); } else if (left >= right) { expectCallback(&CallbackDelete, total, outerBase, base); } else { expectCallback(&CallbackDelete, total, limit, outerLimit); } } else if (left >= MinSize && right >= MinSize) { if (left >= right) { expectCallback(&CallbackShrink, total, outerBase, base); expectCallback(&CallbackNew, (Size)0, limit, outerLimit); } else { expectCallback(&CallbackNew, (Size)0, outerBase, base); expectCallback(&CallbackShrink, total, limit, outerLimit); } } else if (total >= MinSize) { if (left >= right) { Insist(left >= MinSize); Insist(right < MinSize); expectCallback(&CallbackShrink, total, outerBase, base); } else { Insist(left < MinSize); Insist(right >= MinSize); expectCallback(&CallbackShrink, total, limit, outerLimit); } } } res = CBSDelete(cbs, base, limit); if (!isFree) { die_expect((mps_res_t)res, MPS_RES_FAIL, "Succeeded in deleting allocated block"); } else { /* isFree */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to delete free block"); NAllocateSucceeded++; BTSetRange(allocTable, ib, il); checkExpectations(); } }