示例#1
0
/**
 * candl_loops_are_permutable: output 1 if the 2 loops are permutable.
 * Assume loop1 and loop2 are nested.
 *
 */
int
candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
			   int loop_id1, int loop_id2)
{
  CandlDDV* l1 = candl_ddv_extract_in_loop (program, deps, loop_id1);
  CandlDDV* l2 = candl_ddv_extract_in_loop (program, deps, loop_id2);

  // One of the loop do not carry any dependence.
  if (l1 == NULL || l2 == NULL)
    return 1;

  CandlDDV* dv;
  if (l1->length > l2->length)
    dv = l1;
  else
    dv = l2;

  int loop_dim_1 = -1;
  int loop_dim_2 = -1;
  int i, j;
  CandlStatement* stm;
  for (j = 0; j < program->nb_statements; ++j)
    {
      stm = program->statement[j];
      for (i = 0; i < stm->depth; ++i)
	if (stm->index[i] == loop_id1)
	  loop_dim_1 = i;
	else if (stm->index[i] == loop_id2)
	  loop_dim_2 = i;
      if (loop_dim_1 != -1 && loop_dim_2 != -1)
	break;
    }

  int is_pos_1 = 0;
  int is_neg_1 = 0;
  int is_pos_2 = 0;
  int is_neg_2 = 0;
  int is_star = 0;
  for (; dv; dv = dv->next)
    {
      switch (dv->data[loop_dim_1].type)
	{
	case candl_dv_plus:
	  is_pos_1 = 1;
	  break;
	case candl_dv_minus:
	  is_neg_1 = 1;
	  break;
	case candl_dv_scalar:
	  if (dv->data[loop_dim_1].value > 0)
	    is_pos_1 = 1;
	  else if (dv->data[loop_dim_1].value < 0)
	    is_neg_1 = 1;
	  break;
	case candl_dv_star:
	  is_star = 1;
	  break;
	default:
	  break;
	}
      switch (dv->data[loop_dim_2].type)
	{
	case candl_dv_plus:
	  is_pos_2 = 1;
	  break;
	case candl_dv_minus:
	  is_neg_2 = 1;
	  break;
	case candl_dv_scalar:
	  if (dv->data[loop_dim_2].value > 0)
	    is_pos_2 = 1;
	  else if (dv->data[loop_dim_2].value < 0)
	    is_neg_2 = 1;
	  break;
	case candl_dv_star:
	  is_star = 1;
	  break;
	default:
	  break;
	}
      if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star)
	{
	  candl_ddv_free (l1);
	  candl_ddv_free (l2);
	  return 0;
	}
    }
  
  candl_ddv_free (l1);
  candl_ddv_free (l2);
  
  
  return ! ((is_pos_1 && is_neg_2) || (is_neg_1 && is_pos_2));
}
示例#2
0
文件: ddv.c 项目: Ced/candl
/**
 * candl_loops_are_permutable: output 1 if the 2 loops are permutable.
 * Assume loop1 and loop2 are nested.
 *
 */
int
candl_loops_are_permutable(osl_scop_p scop, osl_dependence_p deps,
                           int loop_id1, int loop_id2) {
  CandlDDV* l1 = candl_ddv_extract_in_loop(scop, deps, loop_id1);
  CandlDDV* l2 = candl_ddv_extract_in_loop(scop, deps, loop_id2);

  // One of the loop do not carry any dependence.
  if (l1 == NULL || l2 == NULL)
    return 1;

  CandlDDV* dv;
  if (l1->length > l2->length)
    dv = l1;
  else
    dv = l2;

  int loop_dim_1 = -1;
  int loop_dim_2 = -1;
  int i;
  candl_statement_usr_p usr;
  osl_statement_p stm = scop->statement;
  for (; stm != NULL; stm = stm->next) {
    usr = stm->usr;
    for (i = 0; i < usr->depth; ++i)
      if (usr->index[i] == loop_id1)
        loop_dim_1 = i;
      else if (usr->index[i] == loop_id2)
        loop_dim_2 = i;
    if (loop_dim_1 != -1 && loop_dim_2 != -1)
      break;
  }

  int is_pos_1 = 0;
  int is_neg_1 = 0;
  int is_pos_2 = 0;
  int is_neg_2 = 0;
  int is_star = 0;
  for (; dv; dv = dv->next) {
    switch (dv->data[loop_dim_1].type) {
      case candl_dv_plus:
        is_pos_1 = 1;
        break;
      case candl_dv_minus:
        is_neg_1 = 1;
        break;
      case candl_dv_scalar:
        if (dv->data[loop_dim_1].value > 0)
          is_pos_1 = 1;
        else if (dv->data[loop_dim_1].value < 0)
          is_neg_1 = 1;
        break;
      case candl_dv_star:
        is_star = 1;
        break;
      default:
        break;
    }
    switch (dv->data[loop_dim_2].type) {
      case candl_dv_plus:
        is_pos_2 = 1;
        break;
      case candl_dv_minus:
        is_neg_2 = 1;
        break;
      case candl_dv_scalar:
        if (dv->data[loop_dim_2].value > 0)
          is_pos_2 = 1;
        else if (dv->data[loop_dim_2].value < 0)
          is_neg_2 = 1;
        break;
      case candl_dv_star:
        is_star = 1;
        break;
      default:
        break;
    }
    if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star) {
      candl_ddv_free(l1);
      candl_ddv_free(l2);
      return 0;
    }
  }

  candl_ddv_free(l1);
  candl_ddv_free(l2);


  return ! ((is_pos_1 && is_neg_2) || (is_neg_1 && is_pos_2));
}