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

📄 c-iterate.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  expand_start_loop_continue_elsewhere (1);  ITERATOR_BOUND_P (idecl) = 1;  if (end_note)    *end_note = emit_note (0, NOTE_INSN_DELETED);}/* Similar to the previous function, but for the end of the loop.   DECL_RTL is zeroed unless we are inside "({...})". The reason for that is   described below.   When we create two (or more) loops based on the same IDECL, and   both inside the same "({...})"  construct, we must be prepared to   delete both of the loops and create a single one on the level   above, i.e.  enclosing the "({...})". The new loop has to use the   same counter rtl because the references to the iterator decl   (IDECL) have already been expanded as references to the counter   rtl.   It is incorrect to use the same counter reg in different functions,   and it is desirable to use different counters in disjoint loops   when we know there's no need to combine them (because then they can   get allocated separately).  */static voiditerator_loop_epilogue (idecl, start_note, end_note)     tree idecl;     rtx *start_note, *end_note;{  tree test, incr;  if (start_note)    *start_note = emit_note (0, NOTE_INSN_DELETED);  expand_loop_continue_here ();  incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);  incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr);  TREE_SIDE_EFFECTS (incr) = 1;  expand_expr (incr, const0_rtx, VOIDmode, 0);  test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);  expand_exit_loop_if_false (0, test);  expand_end_loop ();  ITERATOR_BOUND_P (idecl) = 0;  /* we can reset rtl since there is not chance that this expansion */  /* would be superseded by a higher level one */  /* but don't do this if the decl is static, since we need to share */  /* the same decl in that case.  */  if (top_level_ixpansion_p () && ! TREE_STATIC (idecl))    DECL_RTL (idecl) = 0;  if (end_note)    *end_note = emit_note (0, NOTE_INSN_DELETED);}/* Return true if we are not currently inside a "({...})" construct.  */static inttop_level_ixpansion_p (){  return iter_stack == 0;}/* Given two chains of iter_stack_nodes,   append the nodes in X into Y.  */static voidisn_append (x, y)     struct iter_stack_node *x, *y;{  if (x->first == 0)     return;  if (y->first == 0)    {      y->first = x->first;      y->last  = x->last;    }  else    {      y->last->next = x->first;      y->last = x->last;    }}/** Make X empty **/#define ISN_ZERO(X) (X).first=(X).last=0/* Move the ixpansions in sublevel_ixpansions into the current   node on the iter_stack, or discard them if the iter_stack is empty.   We do this at the end of a statement.  */static voidistack_sublevel_to_current (){  /* At the top level we can throw away sublevel's expansions  **/  /* because there is nobody above us to ask for a cleanup **/  if (iter_stack != 0)    /** Merging with empty sublevel list is a no-op **/    if (sublevel_ixpansions.last)      isn_append (&sublevel_ixpansions, iter_stack);  if (iter_stack == 0)    obstack_free (&ixp_obstack, ixp_firstobj);  ISN_ZERO (sublevel_ixpansions);}/* Push a new node on the iter_stack, when we enter a ({...}).  */voidpush_iterator_stack (){  struct iter_stack_node *new_top    = (struct iter_stack_node *)       obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node));  new_top->first = 0;  new_top->last = 0;  new_top->next = iter_stack;  iter_stack = new_top;}/* Pop iter_stack, moving the ixpansions in the node being popped   into sublevel_ixpansions.  */voidpop_iterator_stack (){  if (iter_stack == 0)    abort ();  isn_append (iter_stack, &sublevel_ixpansions);  /** Pop current level node: */  iter_stack = iter_stack->next;}/* Record an iterator expansion ("ixpansion") for IDECL.   The remaining parameters are the notes in the loop entry   and exit rtl.  */static voidadd_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end)     tree idecl;     rtx pro_start, pro_end, epi_start, epi_end;{  struct ixpansion *newix;      /* Do nothing if we are not inside "({...})",     as in that case this expansion can't need subsequent RTL modification.  */  if (iter_stack == 0)    return;  newix = (struct ixpansion *) obstack_alloc (&ixp_obstack,					      sizeof (struct ixpansion));  newix->ixdecl = idecl;  newix->ixprologue_start = pro_start;  newix->ixprologue_end   = pro_end;  newix->ixepilogue_start = epi_start;  newix->ixepilogue_end   = epi_end;  newix->next = iter_stack->first;  iter_stack->first = newix;  if (iter_stack->last == 0)    iter_stack->last = newix;}/* Delete the RTL for all ixpansions for iterator IDECL   in our sublevels.  We do this when we make a larger   containing expansion for IDECL.  */static voiddelete_ixpansion (idecl)     tree idecl;{  struct ixpansion *previx = 0, *ix;  for (ix = sublevel_ixpansions.first; ix; ix = ix->next)    if (ix->ixdecl == idecl)      {	/** zero means that this is a mark for FOR -- **/	/** we do not delete anything, just issue an error. **/	if (ix->ixprologue_start == 0)	  error_with_decl (idecl,			   "`for (%s)' appears within implicit iteration");	else	  {	    rtx insn;	    /* We delete all insns, including notes because leaving loop */	    /* notes and barriers produced by iterator expansion would */	    /* be misleading to other phases */	    for (insn = NEXT_INSN (ix->ixprologue_start);		 insn != ix->ixprologue_end;		 insn = NEXT_INSN (insn)) 	      delete_insn (insn);	    for (insn = NEXT_INSN (ix->ixepilogue_start);		 insn != ix->ixepilogue_end;		 insn = NEXT_INSN (insn)) 	      delete_insn (insn);	  }	/* Delete this ixpansion from sublevel_ixpansions.  */	if (previx)	  previx->next = ix->next;	else 	  sublevel_ixpansions.first = ix->next;	if (sublevel_ixpansions.last == ix)	  sublevel_ixpansions.last = previx;      }    else      previx = ix;}#ifdef DEBUG_ITERATORS/* The functions below are for use from source level debugger.   They print short forms of iterator lists and the iterator stack.  *//* Print the name of the iterator D.  */voidprdecl (d)     tree d;{  if (d)    {      if (TREE_CODE (d) == VAR_DECL)	{	  tree tname = DECL_NAME (d);	  char *dname = IDENTIFIER_POINTER (tname);	  fprintf (stderr, dname);	}      else	fprintf (stderr, "<<Not a Decl!!!>>");    }  else    fprintf (stderr, "<<NULL!!>>");}/* Print Iterator List -- names only */treepil (head)     tree head;{  tree current, next;  for (current = head; current; current = next)    {      tree node = TREE_VALUE (current);      prdecl (node);      next = TREE_CHAIN (current);      if (next) fprintf (stderr, ",");    }  fprintf (stderr, "\n");}/* Print IXpansion List */struct ixpansion *pixl (head)     struct ixpansion *head;{  struct ixpansion *current, *next;  fprintf (stderr, "> ");  if (head == 0)    fprintf (stderr, "(empty)");	  for (current=head; current; current = next)    {      tree node = current->ixdecl;      prdecl (node);      next = current->next;      if (next)	fprintf (stderr, ",");    }  fprintf (stderr, "\n");  return head;}/* Print Iterator Stack.  */voidpis (){  struct iter_stack_node *stack_node;  fprintf (stderr, "--SubLevel: ");  pixl (sublevel_ixpansions.first);  fprintf (stderr, "--Stack:--\n");  for (stack_node = iter_stack;       stack_node;       stack_node = stack_node->next)    pixl (stack_node->first);}#endif /* DEBUG_ITERATORS */

⌨️ 快捷键说明

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