예제 #1
0
파일: cov_function.C 프로젝트: ggcov/ggcov
cov::status_t
cov_function_t::calc_stats(cov_stats_t *stats) const
{
    unsigned int bidx;
    cov_stats_t mine;
    cov::status_t st;

    assert(file_->finalised_);

    if (suppression_)
	st = cov::SUPPRESSED;
    else
    {
	/* skip the psuedo-blocks which don't correspond to code */
	assert(num_blocks() >= 2);
	for (bidx = first_real_block() ; bidx <= last_real_block() ; bidx++)
	{
	    cov_block_t *b = nth_block(bidx);
	    if (!b->locations().head())
		continue;
	    b->calc_stats(&mine);
	}
	stats->accumulate(&mine);
	st = mine.status_by_lines();
    }

    stats->add_function(st);

    return st;
}
예제 #2
0
파일: cov_function.C 프로젝트: ggcov/ggcov
gboolean
cov_function_t::reconcile_calls()
{
    unsigned int bidx;
    gboolean ret = TRUE;

    if (suppression_)
	return TRUE;    /* ignored */

    /*
     * Last two blocks in a function appear to be the function
     * epilogue with one fake arc out representing returns *from*
     * the function, and a block inserted as the target of all
     * function call arcs, with one fake arc back to block 0
     * representing returns *to* the function.  So don't attempt
     * to reconcile those.
     */
    if (num_blocks() <= 2)
	return TRUE;

    for (bidx = first_real_block() ; bidx <= last_real_block() ; bidx++)
    {
	cov_block_t *b = nth_block(bidx);

	if (b->out_ncalls_ != (b->call_ == 0 ? 0U : 1U))
	{
	    /* TODO */
	    if (b->locations().head() != 0)
	    {
		/*
		 * Don't complain about not being to reconcile weird
		 * calls inserted by g++, like _Unwind_Resume() or
		 * __cxa_throw(), or any other call with no direct
		 * relationship to the source code.
		 */
		cgraph_log.debug("Failed to reconcile calls for block %s, %d call arcs, %d recorded calls\n",
				 b->describe(), b->out_ncalls_, (b->call_ == 0 ? 0 : 1));
	    }
	    b->call_ = (const char *)0;   /* free and null out */
	    ret = FALSE;
	    continue;
	}

	for (list_iterator_t<cov_arc_t> aiter = b->first_arc() ; *aiter ; ++aiter)
	{
	    cov_arc_t *a = *aiter;
	    char *name;

	    if (a->is_call() && (name = b->pop_call()))
	    {
		cgraph_log.debug2("    block %s calls %s\n", b->describe(), name);
		a->take_name(name);
	    }
	}
	cgraph_log.debug("Reconciled %d calls for block %s\n", b->out_ncalls_, b->describe());
    }
    return ret;
}
예제 #3
0
inline void copy_decs(nb_decompositions *dst, nb_decompositions *src)
{
  unsigned long int i;
  for (i=0; i<NBLOCKS; i++) nth_block(dst, i) = nth_block(src, i);
}
예제 #4
0
{
  unsigned long int start_block, decal;
  epi8 block;

  assert(src->decs[gen] == 1);

  dst->conductor = gen + 1;
  dst->genus = src->genus + 1;
  dst->min = gen == src->min ? dst->conductor : src->min;

  copy_decs(&dst->decs, &src->decs);

  start_block = gen >> 4;
  decal = gen & 0xF;
  // Shift block by decal uchar
  block = (epi8) _mm_shuffle_epi8((__m128i) nth_block(src->decs, 0),
				  (__m128i) shift16[decal]);
  nth_block(dst->decs, start_block) -= ((block != zero) & block1);

#if NBLOCKS >= 5
#warning "Using unrolled loop version"

#define CASE_UNROLL(i_loop)			\
  case i_loop : \
      nth_block(dst->decs, i_loop+1) -= ((load_epi8(srcblock) != zero) & block1); \
      srcblock += 16

  {
    unsigned char *srcblock = src->decs + 16 - decal;
  switch(start_block)
    {