/* void splitNode() * Splits a node by creating a new child. */ Node* splitNode(Node* par, Node* gp, int ch, int size) { Node* n = (Node*) memalloc(sizeof(Node)); //ncount++; gp->child[ch] = n; n->child[0] = par; n->child[1] = NULL; n->head = NULL; /*printf("splitNode\n"); for (int i = par->st; i < par->end; i++) printf("%c", par->seq[i]); printf("\n");*/ // parent gets new seq if (size > (par->end - par->st) / 2.0) { /*printf("splitNode\n"); for (int i = par->st; i < par->end; i++) printf("%c", par->seq[i]); printf("\n"); printf("parent gets new\n");*/ n->seq = par->seq; n->st = par->st; n->end = par->st + size; par->st = 0; par->end = par->end - par->st - size; par->seq = copySeq(par->seq, par->st + size, par->end); /*printf("results in:\nchild "); for (int i = n->st; i < n->end; i++) printf("%c", n->seq[i]); printf("\nparent "); for (int i = par->st; i < par->end; i++) printf("%c", par->seq[i]); printf("\n"); while (!getchar()) ;*/ } else { //printf("child gets new\n"); // child gets new seq n->st = 0; n->end = size; n->seq = copySeq(par->seq, par->st, size); par->st = par->st + size; } /*printf("results in:\nchild "); for (int i = n->st; i < n->end; i++) printf("%c", n->seq[i]); printf("\nparent "); for (int i = par->st; i < par->end; i++) printf("%c", par->seq[i]); printf("\n"); while (!getchar()) ;*/ return n; }
void gbFaWriteFromFa(struct gbFa *fa, struct gbFa *inFa, char *newHdr) /* Write a fasta sequence that is buffered gbFa object. If newHdr is not * null, then it is a replacement header, not including the '>' or '\n'. If * null, the header in the inGbFa is used as-is. */ { fa->recOff = fa->off; copyHeader(fa, inFa, newHdr); copySeq(fa, inFa); if (ferror(fa->fh)) errnoAbort("write failed: %s", fa->fileName); }
// Node* makeNode() Node* makeNode(Node* par, int ch, int pos, int size) { /*int i; for (i = 0; i < CHILD; i++) if (par->child[i] == NULL) break;*/ Node* n = (Node*) memalloc(sizeof(Node)); n->head = NULL; par->child[ch] = n; if (++ch < CHILD) par->child[ch] = NULL; n->child[0] = NULL; n->seq = copySeq(line, pos, size); n->st = 0; n->end = size; //ncount++; return n; }
void allpathUpdateEdge (unsigned int e1, unsigned int e2, int indicate) { int tightLen; char *tightSeq = NULL; if (edge_array[e1].cvg == 0) { edge_array[e1].cvg = edge_array[e2].cvg; } if (edge_array[e2].cvg == 0) { edge_array[e2].cvg = edge_array[e1].cvg; } /* if(edge_array[e1].length&&edge_array[e2].length){ fprintf(stderr,">e1\n"); printEdgeSeq(stderr,edge_array[e1].seq,edge_array[e1].length); fprintf(stderr,">e2\n"); printEdgeSeq(stderr,edge_array[e2].seq,edge_array[e2].length); } */ unsigned int cvgsum = edge_array[e1].cvg * edge_array[e1].length + edge_array[e2].cvg * edge_array[e2].length; tightLen = edge_array[e1].length + edge_array[e2].length; if (tightLen) { tightSeq = (char *) ckalloc ((tightLen / 4 + 1) * sizeof (char)); } tightLen = 0; if (edge_array[e1].length) { copySeq (tightSeq, edge_array[e1].seq, 0, edge_array[e1].length); tightLen = edge_array[e1].length; if (edge_array[e1].seq) { free ((void *) edge_array[e1].seq); edge_array[e1].seq = NULL; } else { printf ("allpathUpdateEdge: edge %d with length %d, but without seq\n", e1, edge_array[e1].length); } } if (edge_array[e2].length) { copySeq (tightSeq, edge_array[e2].seq, tightLen, edge_array[e2].length); tightLen += edge_array[e2].length; if (edge_array[e2].seq) { free ((void *) edge_array[e2].seq); edge_array[e2].seq = NULL; } else { printf ("allpathUpdateEdge: edge %d with length %d, but without seq\n", e2, edge_array[e2].length); } } /* if(edge_array[e1].length&&edge_array[e2].length){ fprintf(stderr,">e1+e2\n"); printEdgeSeq(stderr,tightSeq,tightLen); } */ //edge_array[e2].extend_len = tightLen-edge_array[e2].length; //the sequence of e1 is to be updated if (!indicate) { edge_array[e2].length = 0; //e1 is removed from the graph edge_array[e1].to_vt = edge_array[e2].to_vt; //e2 is part of e1 now edge_array[e1].length = tightLen; edge_array[e1].seq = tightSeq; if (tightLen) { edge_array[e1].cvg = cvgsum / tightLen; } edge_array[e1].cvg = edge_array[e1].cvg > 0 ? edge_array[e1].cvg : 1; } else { edge_array[e1].length = 0; //e1 is removed from the graph edge_array[e2].from_vt = edge_array[e1].from_vt; //e1 is part of e2 now edge_array[e2].length = tightLen; edge_array[e2].seq = tightSeq; if (tightLen) { edge_array[e2].cvg = cvgsum / tightLen; } edge_array[e2].cvg = edge_array[e2].cvg > 0 ? edge_array[e2].cvg : 1; } }
/* * Traverse CFG in reverse topological order (already given in bblist) * to collect cost, eliminating infeasible paths. */ int traverse( int pid, block **bblist, int num_bb, int *in_degree, uint *cost ) { DSTART( "traverse" ); int i, j, k, id, pt; char direction, extend; path *pu, *pv; block *bu, *bv; branch *bru; for( i = 0; i < num_bb; i++ ) { bu = bblist[i]; bru = branchlist[pid][bu->bbid]; // printf( "Node %d cost %d: \n", bu->bbid, cost[bu->bbid] ); fflush( stdout ); // printBlock( bu ); if( !bu->num_outgoing ) { // bu is a sink // cost(bu) = { sum(bu) | sum(bu) is the sum of costs of each instruction in bu }; MALLOC( pu, path*, sizeof(path), "path" ); pu->cost = cost[bu->bbid]; pu->bb_len = 1; MALLOC( pu->bb_seq, int*, sizeof(int), "path bb_seq" ); pu->bb_seq[0] = bu->bbid; pu->branch_len = 0; pu->branch_eff = NULL; pu->branch_dir = NULL; num_paths[bu->bbid]++; REALLOC( pathlist[bu->bbid], path**, num_paths[bu->bbid] * sizeof(path*), "pathlist elm" ); pathlist[bu->bbid][ num_paths[bu->bbid]-1 ] = pu; continue; } // Step 1: Compute the WCET paths of each branch for( j = 0; j < bu->num_outgoing; j++ ) { id = getblock( bu->outgoing[j], bblist, 0, i-1 ); if( id == -1 ) prerr( "Block %d-%d not found.\n", pid, bu->outgoing[j] ); bv = bblist[id]; // printf( "out: " ); printBlock( bv ); for( pt = 0; pt < num_paths[bv->bbid]; pt++ ) { pv = pathlist[bv->bbid][pt]; // branches with potential conflict if( bru != NULL ) { direction = detectDirection( bru, bv ); // printf( "%d:%d->%d: dirn = %d\n", pid, bu->bbid, bv->bbid, direction ); /* * temporary disable conflict detection * // test BB conflicts if( BBconflictInPath( bru, direction, bv, pv, bblist, num_bb )) continue; */ } /* * temporary disable conflict detection * // test BA conflicts if( BAconflictInPath( bu, bv, pv, bblist, num_bb )) continue; */ // else, include this path for bu MALLOC( pu, path*, sizeof(path), "path" ); pu->bb_len = pv->bb_len + 1; pu->cost = pv->cost + cost[bu->bbid]; // extra cost if bu-->bv is a region transition //int rid; //if( regionmode ) { // if( bu->callpid != -1 ) // rid = procs[bu->callpid]->bblist[ procs[bu->callpid]->num_bb - 1 ]->regid; // if( bu->callpid == -1 || rid == -1 ) { // if( bu->regid != -1 && bv->regid != -1 && bu->regid != bv->regid ) { // printf( "region transition %d-%d(%d) --> %d-%d(%d) cost: %u\n", // bu->pid, bu->bbid, bu->regid, bv->pid, bv->bbid, bv->regid, regioncost[bv->regid] ); // fflush( stdout ); // pu->cost += regioncost[bv->regid]; // } // } // // region transition due to procedure call at end of bu // else { // if( rid != -1 && bv->regid != -1 && rid != bv->regid ) { // printf( "region transition %d-%d(%d) procedure return %d(%d) --> %d-%d(%d) cost: %u\n", // bu->pid, bu->bbid, bu->regid, bu->callpid, rid, // bv->pid, bv->bbid, bv->regid, regioncost[bv->regid] ); fflush( stdout ); // pu->cost += regioncost[bv->regid]; // } // } //} // end if( regionmode ) extend = 0; if( bru != NULL && hasIncomingConflict( bru, direction, bblist, i+1, num_bb )) extend = 1; pu->branch_len = pv->branch_len; if( extend ) pu->branch_len++; MALLOC( pu->bb_seq, int*, pu->bb_len * sizeof(int), "path bb_seq" ); MALLOC( pu->branch_eff, branch**, pu->branch_len * sizeof(branch*), "path branch_eff" ); MALLOC( pu->branch_dir, char*, pu->branch_len * sizeof(char), "path branch_dir" ); copySeq( pu, pv ); pu->bb_seq[ pu->bb_len - 1 ] = bu->bbid; if( extend ) sortedInsertBranch( pu, bru, direction ); num_paths[bu->bbid]++; REALLOC( pathlist[bu->bbid], path**, num_paths[bu->bbid] * sizeof(path*), "pathlist elm" ); pathlist[bu->bbid][ num_paths[bu->bbid]-1 ] = pu; } // end for paths of bv } // end for bu's children if( num_paths[bu->bbid] <= 0 ) prerr( "\nNo feasible path at %d-%d!\n\n", pid, bu->bbid ); // Step 2: Consolidate // if( edges e1, ..., en in subgraph(bu) are not conflicting with some predecessors ) // combine the two paths in cost(bu) if they only differ in term ei // Note that for each node bu, we keep a list of nodes conflicting with bu and can reach bu. // Step 2.1 Update incoming conflicts list: clear bu since it is already visited for( j = 0; j < procs[pid]->num_bb; j++ ) { bru = branchlist[pid][j]; if( bru != NULL && bru->in_conflict[bu->bbid] ) bru->num_active_incfs--; } // Step 2.2 Merge paths for( pt = 0; pt < num_paths[bu->bbid]; pt++ ) { pu = pathlist[bu->bbid][pt]; // check each branch in this path for expired conflicts k = 0; while( k < pu->branch_len ) { // remove if no more incoming conflict, or cancelled by assignment in bu if( !pu->branch_eff[k]->num_active_incfs || assignsTo( bu, pu->branch_eff[k]->deri_tree )) removeBranch( pu, k ); else k++; } } // end for paths // printf( "Consolidation: Decision cancelled over\n" ); fflush( stdout ); if( num_paths[bu->bbid] > 1 ) { // sort by increasing cost, then decreasing number of branches sortPath( pathlist[bu->bbid], num_paths[bu->bbid] ); for( pt = 0; pt < num_paths[bu->bbid] - 1; pt++ ) { pu = pathlist[bu->bbid][pt]; for( k = pt + 1; k < num_paths[bu->bbid]; k++ ) { pv = pathlist[bu->bbid][k]; // remove pu if its conflict list is a superset of pv's // (i.e. pu has less cost yet more conflicts than pv, thus cannot be wcet path) if( subsetConflict( pv, pu )) { pu->bb_len = -1; break; } } } // remove the marked paths (id: the index to overwrite) id = -1; for( pt = 0; pt < num_paths[bu->bbid]; pt++ ) { pu = pathlist[bu->bbid][pt]; if( pu->bb_len == -1 ) { freePath( bu->bbid, pt ); if( id == -1 ) id = pt; } else { if( id > -1 ) pathlist[bu->bbid][id++] = pu; } } if( id > -1 ) num_paths[bu->bbid] = id; } // stats if( num_paths[bu->bbid] > max_paths ) max_paths = num_paths[bu->bbid]; // free paths in nodes which are dead (i.e. already processed) for( j = 0; j < bu->num_outgoing; j++ ) in_degree[ bu->outgoing[j] ]--; // note that the node in top topo order is excluded for( j = 0; j < num_bb - 1; j++ ) { id = bblist[j]->bbid; if( in_degree[id] == 0 && pathFreed[id] == 0 ) { freePathsInNode( id ); pathFreed[id] = 1; } } DOUT( "Paths at %d-%d: %d\n", pid, bu->bbid, num_paths[bu->bbid] ); DACTION( for( pt = 0; pt < num_paths[bu->bbid]; pt++ ) printPath( pathlist[bu->bbid][pt] ); );