Beispiel #1
0
/* 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);
}
Beispiel #3
0
// 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;
	}
}
Beispiel #5
0
/*
 * 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] );
    );