VectorQueue neighbour2D(int** matrix,int ignValue, int radius, VectorQueue vctQ,int sizeX, int sizeY) { int xLimitSup,xLimitInf,yLimitSup,yLimitInf; VectorQueue tmpQ; tmpQ.push(vctQ.x.front(),vctQ.y.front(),0); while(!vctQ.isEmpty()) { xLimitSup=vctQ.x.front()+2*radius+1; xLimitInf= vctQ.x.front()-2*radius-1; if(xLimitInf<1)xLimitInf=1; if (xLimitSup>=sizeX-1) xLimitSup=sizeX-1; for(int i=xLimitInf;i<=xLimitSup;i++) { yLimitSup=vctQ.y.front()+2*radius+1; yLimitInf= vctQ.y.front()-2*radius-1; if(yLimitInf<1) yLimitInf=1; yLimitSup=vctQ.y.front()+2*radius; if (yLimitSup>=sizeY-1) yLimitSup=sizeY-1; for(int j=yLimitInf;j<=yLimitSup;j++) { if((matrix[i][j]!=ignValue)&&(matrix[i][j]>0)) { vctQ.push(i,j,0); tmpQ.push(i,j,0); matrix[i][j]-=2*matrix[i][j]; } } } vctQ.pop(); } return tmpQ; }
void SubMatrix::subMatrixCreation2D(int** mtr,int xMin,int yMin,VectorQueue point,int ignValue) { int** sMatrix=new int* [xSize]; for(int i=0;i<xSize;i++) { sMatrix[i]=new int[ySize]; for(int j=0;j<ySize;j++) sMatrix[i][j]=ignValue; } while(!point.isEmpty()) { sMatrix[point.x.front()-xPos+2*radius][point.y.front()-yPos+2*radius]=mtr[point.x.front()][point.y.front()]; point.pop(); } matrix2D=sMatrix; matrixAbs2D(); }
void SubMatrix::subMatrixCreation3D(int*** mtr,int sizeX,int sizeY,int sizeZ,int xMin,int yMin, int zMin,VectorQueue point,int ignValue, int radius) { int*** sMatrix=new int**[sizeX]; for(int i=0;i<sizeX;i++) { sMatrix[i]=new int*[sizeY]; for(int j=0;j<sizeY;j++) { sMatrix[i][j]=new int[sizeZ]; for(int k=0;k<sizeZ;k++) sMatrix[i][j][k]=ignValue; } } while(!point.isEmpty()) { sMatrix[point.x.front()-xMin+radius][point.y.front()-yMin+radius][point.z.front()-zMin+radius]=mtr[point.x.front()][point.y.front()][point.z.front()]; point.pop(); } matrix3D=sMatrix; matrixAbs3D(); }
VectorQueue neighbour3D(int*** matrix,int ignValue, int radius, VectorQueue vctQ) { VectorQueue tmpQ; tmpQ.push(vctQ.x.front(),vctQ.y.front(),vctQ.z.front()); while(!vctQ.isEmpty()) { for(int k=vctQ.z.front()-radius;k<=vctQ.z.front()+radius;k++) { for(int i=vctQ.y.front()-radius;i<=vctQ.y.front()+radius;i++) { for(int j=vctQ.x.front()-radius;j<=vctQ.x.front()+radius;j++) if((matrix[j][i][k]!=ignValue)&&(matrix[j][i][k]>0)) { vctQ.push(j,i,k); tmpQ.push(j,i,k); matrix[j][i][k]-=2*matrix[j][i][k]; } } } vctQ.pop(); } return tmpQ; }
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); } } }