⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trans-array.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 5 页
字号:
gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag,			 stmtblock_t * pblock){  tree index;  tree stride;  gfc_ss_info *info;  gfc_ss *ss;  gfc_se se;  int i;  /* This code will be executed before entering the scalarization loop     for this dimension.  */  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)    {      if ((ss->useflags & flag) == 0)	continue;      if (ss->type != GFC_SS_SECTION	  && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR	  && ss->type != GFC_SS_COMPONENT)	continue;      info = &ss->data.info;      if (dim >= info->dimen)	continue;      if (dim == info->dimen - 1)	{	  /* For the outermost loop calculate the offset due to any	     elemental dimensions.  It will have been initialized with the	     base offset of the array.  */	  if (info->ref)	    {	      for (i = 0; i < info->ref->u.ar.dimen; i++)		{		  if (info->ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)		    continue;		  gfc_init_se (&se, NULL);		  se.loop = loop;		  se.expr = info->descriptor;		  stride = gfc_conv_array_stride (info->descriptor, i);		  index = gfc_conv_array_index_offset (&se, info, i, -1,						       &info->ref->u.ar,						       stride);		  gfc_add_block_to_block (pblock, &se.pre);		  info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,					      info->offset, index);		  info->offset = gfc_evaluate_now (info->offset, pblock);		}	      i = loop->order[0];	      stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);	    }	  else	    stride = gfc_conv_array_stride (info->descriptor, 0);	  /* Calculate the stride of the innermost loop.  Hopefully this will             allow the backend optimizers to do their stuff more effectively.           */	  info->stride0 = gfc_evaluate_now (stride, pblock);	}      else	{	  /* Add the offset for the previous loop dimension.  */	  gfc_array_ref *ar;	  if (info->ref)	    {	      ar = &info->ref->u.ar;	      i = loop->order[dim + 1];	    }	  else	    {	      ar = NULL;	      i = dim + 1;	    }	  gfc_init_se (&se, NULL);	  se.loop = loop;	  se.expr = info->descriptor;	  stride = gfc_conv_array_stride (info->descriptor, info->dim[i]);	  index = gfc_conv_array_index_offset (&se, info, info->dim[i], i,					       ar, stride);	  gfc_add_block_to_block (pblock, &se.pre);	  info->offset = fold_build2 (PLUS_EXPR, gfc_array_index_type,				      info->offset, index);	  info->offset = gfc_evaluate_now (info->offset, pblock);	}      /* Remember this offset for the second loop.  */      if (dim == loop->temp_dim - 1)        info->saved_offset = info->offset;    }}/* Start a scalarized expression.  Creates a scope and declares loop   variables.  */voidgfc_start_scalarized_body (gfc_loopinfo * loop, stmtblock_t * pbody){  int dim;  int n;  int flags;  gcc_assert (!loop->array_parameter);  for (dim = loop->dimen - 1; dim >= 0; dim--)    {      n = loop->order[dim];      gfc_start_block (&loop->code[n]);      /* Create the loop variable.  */      loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "S");      if (dim < loop->temp_dim)	flags = 3;      else	flags = 1;      /* Calculate values that will be constant within this loop.  */      gfc_trans_preloop_setup (loop, dim, flags, &loop->code[n]);    }  gfc_start_block (pbody);}/* Generates the actual loop code for a scalarization loop.  */static voidgfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,			       stmtblock_t * pbody){  stmtblock_t block;  tree cond;  tree tmp;  tree loopbody;  tree exit_label;  loopbody = gfc_finish_block (pbody);  /* Initialize the loopvar.  */  gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);  exit_label = gfc_build_label_decl (NULL_TREE);  /* Generate the loop body.  */  gfc_init_block (&block);  /* The exit condition.  */  cond = build2 (GT_EXPR, boolean_type_node, loop->loopvar[n], loop->to[n]);  tmp = build1_v (GOTO_EXPR, exit_label);  TREE_USED (exit_label) = 1;  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());  gfc_add_expr_to_block (&block, tmp);  /* The main body.  */  gfc_add_expr_to_block (&block, loopbody);  /* Increment the loopvar.  */  tmp = build2 (PLUS_EXPR, gfc_array_index_type,		loop->loopvar[n], gfc_index_one_node);  gfc_add_modify_expr (&block, loop->loopvar[n], tmp);  /* Build the loop.  */  tmp = gfc_finish_block (&block);  tmp = build1_v (LOOP_EXPR, tmp);  gfc_add_expr_to_block (&loop->code[n], tmp);  /* Add the exit label.  */  tmp = build1_v (LABEL_EXPR, exit_label);  gfc_add_expr_to_block (&loop->code[n], tmp);}/* Finishes and generates the loops for a scalarized expression.  */voidgfc_trans_scalarizing_loops (gfc_loopinfo * loop, stmtblock_t * body){  int dim;  int n;  gfc_ss *ss;  stmtblock_t *pblock;  tree tmp;  pblock = body;  /* Generate the loops.  */  for (dim = 0; dim < loop->dimen; dim++)    {      n = loop->order[dim];      gfc_trans_scalarized_loop_end (loop, n, pblock);      loop->loopvar[n] = NULL_TREE;      pblock = &loop->code[n];    }  tmp = gfc_finish_block (pblock);  gfc_add_expr_to_block (&loop->pre, tmp);  /* Clear all the used flags.  */  for (ss = loop->ss; ss; ss = ss->loop_chain)    ss->useflags = 0;}/* Finish the main body of a scalarized expression, and start the secondary   copying body.  */voidgfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body){  int dim;  int n;  stmtblock_t *pblock;  gfc_ss *ss;  pblock = body;  /* We finish as many loops as are used by the temporary.  */  for (dim = 0; dim < loop->temp_dim - 1; dim++)    {      n = loop->order[dim];      gfc_trans_scalarized_loop_end (loop, n, pblock);      loop->loopvar[n] = NULL_TREE;      pblock = &loop->code[n];    }  /* We don't want to finish the outermost loop entirely.  */  n = loop->order[loop->temp_dim - 1];  gfc_trans_scalarized_loop_end (loop, n, pblock);  /* Restore the initial offsets.  */  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)    {      if ((ss->useflags & 2) == 0)	continue;      if (ss->type != GFC_SS_SECTION	  && ss->type != GFC_SS_FUNCTION && ss->type != GFC_SS_CONSTRUCTOR	  && ss->type != GFC_SS_COMPONENT)	continue;      ss->data.info.offset = ss->data.info.saved_offset;    }  /* Restart all the inner loops we just finished.  */  for (dim = loop->temp_dim - 2; dim >= 0; dim--)    {      n = loop->order[dim];      gfc_start_block (&loop->code[n]);      loop->loopvar[n] = gfc_create_var (gfc_array_index_type, "Q");      gfc_trans_preloop_setup (loop, dim, 2, &loop->code[n]);    }  /* Start a block for the secondary copying code.  */  gfc_start_block (body);}/* Calculate the upper bound of an array section.  */static treegfc_conv_section_upper_bound (gfc_ss * ss, int n, stmtblock_t * pblock){  int dim;  gfc_expr *end;  tree desc;  tree bound;  gfc_se se;  gfc_ss_info *info;  gcc_assert (ss->type == GFC_SS_SECTION);  info = &ss->data.info;  dim = info->dim[n];  if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)    /* We'll calculate the upper bound once we have access to the       vector's descriptor.  */    return NULL;  gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);  desc = info->descriptor;  end = info->ref->u.ar.end[dim];  if (end)    {      /* The upper bound was specified.  */      gfc_init_se (&se, NULL);      gfc_conv_expr_type (&se, end, gfc_array_index_type);      gfc_add_block_to_block (pblock, &se.pre);      bound = se.expr;    }  else    {      /* No upper bound was specified, so use the bound of the array.  */      bound = gfc_conv_array_ubound (desc, dim);    }  return bound;}/* Calculate the lower bound of an array section.  */static voidgfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int n){  gfc_expr *start;  gfc_expr *stride;  tree desc;  gfc_se se;  gfc_ss_info *info;  int dim;  gcc_assert (ss->type == GFC_SS_SECTION);  info = &ss->data.info;  dim = info->dim[n];  if (info->ref->u.ar.dimen_type[dim] == DIMEN_VECTOR)    {      /* We use a zero-based index to access the vector.  */      info->start[n] = gfc_index_zero_node;      info->stride[n] = gfc_index_one_node;      return;    }  gcc_assert (info->ref->u.ar.dimen_type[dim] == DIMEN_RANGE);  desc = info->descriptor;  start = info->ref->u.ar.start[dim];  stride = info->ref->u.ar.stride[dim];  /* Calculate the start of the range.  For vector subscripts this will     be the range of the vector.  */  if (start)    {      /* Specified section start.  */      gfc_init_se (&se, NULL);      gfc_conv_expr_type (&se, start, gfc_array_index_type);      gfc_add_block_to_block (&loop->pre, &se.pre);      info->start[n] = se.expr;    }  else    {      /* No lower bound specified so use the bound of the array.  */      info->start[n] = gfc_conv_array_lbound (desc, dim);    }  info->start[n] = gfc_evaluate_now (info->start[n], &loop->pre);  /* Calculate the stride.  */  if (stride == NULL)    info->stride[n] = gfc_index_one_node;  else    {      gfc_init_se (&se, NULL);      gfc_conv_expr_type (&se, stride, gfc_array_index_type);      gfc_add_block_to_block (&loop->pre, &se.pre);      info->stride[n] = gfc_evaluate_now (se.expr, &loop->pre);    }}/* Calculates the range start and stride for a SS chain.  Also gets the   descriptor and data pointer.  The range of vector subscripts is the size   of the vector.  Array bounds are also checked.  */voidgfc_conv_ss_startstride (gfc_loopinfo * loop){  int n;  tree tmp;  gfc_ss *ss;  tree desc;  loop->dimen = 0;  /* Determine the rank of the loop.  */  for (ss = loop->ss;       ss != gfc_ss_terminator && loop->dimen == 0; ss = ss->loop_chain)    {      switch (ss->type)	{	case GFC_SS_SECTION:	case GFC_SS_CONSTRUCTOR:	case GFC_SS_FUNCTION:	case GFC_SS_COMPONENT:	  loop->dimen = ss->data.info.dimen;	  break;	default:	  break;	}    }  if (loop->dimen == 0)    gfc_todo_error ("Unable to determine rank of expression");  /* Loop over all the SS in the chain.  */  for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)    {      if (ss->expr && ss->expr->shape && !ss->shape)	ss->shape = ss->expr->shape;      switch (ss->type)	{	case GFC_SS_SECTION:	  /* Get the descriptor for the array.  */	  gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);	  for (n = 0; n < ss->data.info.dimen; n++)	    gfc_conv_section_startstride (loop, ss, n);	  break;	case GFC_SS_CONSTRUCTOR:	case GFC_SS_FUNCTION:	  for (n = 0; n < ss->data.info.dimen; n++)	    {	      ss->data.info.start[n] = gfc_index_zero_node;	      ss->data.info.stride[n] = gfc_index_one_node;	    }	  break;	default:	  break;	}    }  /* The rest is just runtime bound checking.  */  if (flag_bounds_check)    {      stmtblock_t block;      tree fault;      tree bound;      tree end;      tree size[GFC_MAX_DIMENSIONS];      gfc_ss_info *info;      int dim;      gfc_start_block (&block);      fault = integer_zero_node;      for (n = 0; n < loop->dimen; n++)	size[n] = NULL_TREE;      for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)	{	  if (ss->type != GFC_SS_SECTION)	    continue;	  /* TODO: range checking for mapped dimensions.  */	  info = &ss->data.info;	  /* This code only checks ranges.  Elemental and vector	     dimensions are checked later.  */	  for (n = 0; n < loop->dimen; n++)	    {	      dim = info->dim[n];	      if (info->ref->u.ar.dimen_type[dim] != DIMEN_RANGE)		continue;	      desc = ss->data.info.descriptor;	      /* Check lower bound.  */	      bound = gfc_conv_array_lbound (desc, dim);	      tmp = info->start[n];	      tmp = fold_build2 (LT_EXPR, boolean_type_node, tmp, bound);	    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -