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

📄 final.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
  profile_label_no++;  /* If we are doing basic block profiling, remember a printable version     of the function name.  */  if (profile_block_flag)    {      char *junk = "function";      bb_func_label_num =	add_bb_string ((*decl_printable_name) (current_function_decl, &junk), FALSE);    }}static voidprofile_after_prologue (file)     FILE *file;{#ifdef FUNCTION_BLOCK_PROFILER  if (profile_block_flag)    {      FUNCTION_BLOCK_PROFILER (file, profile_label_no);    }#endif /* FUNCTION_BLOCK_PROFILER */#ifndef PROFILE_BEFORE_PROLOGUE  if (profile_flag)    profile_function (file);#endif /* not PROFILE_BEFORE_PROLOGUE */}static voidprofile_function (file)     FILE *file;{  int align = MIN (BIGGEST_ALIGNMENT, POINTER_SIZE);  int sval = current_function_returns_struct;  int cxt = current_function_needs_context;  data_section ();  ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));  ASM_OUTPUT_INTERNAL_LABEL (file, "LP", profile_label_no);  assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);  text_section ();#ifdef STRUCT_VALUE_INCOMING_REGNUM  if (sval)    ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM);#else#ifdef STRUCT_VALUE_REGNUM  if (sval)    ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM);#endif#endif#if 0#ifdef STATIC_CHAIN_INCOMING_REGNUM  if (cxt)    ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_INCOMING_REGNUM);#else#ifdef STATIC_CHAIN_REGNUM  if (cxt)    ASM_OUTPUT_REG_PUSH (file, STATIC_CHAIN_REGNUM);#endif#endif#endif				/* 0 */  FUNCTION_PROFILER (file, profile_label_no);#if 0#ifdef STATIC_CHAIN_INCOMING_REGNUM  if (cxt)    ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_INCOMING_REGNUM);#else#ifdef STATIC_CHAIN_REGNUM  if (cxt)    ASM_OUTPUT_REG_POP (file, STATIC_CHAIN_REGNUM);#endif#endif#endif				/* 0 */#ifdef STRUCT_VALUE_INCOMING_REGNUM  if (sval)    ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM);#else#ifdef STRUCT_VALUE_REGNUM  if (sval)    ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM);#endif#endif}/* Output assembler code for the end of a function.   For clarity, args are same as those of `final_start_function'   even though not all of them are needed.  */voidfinal_end_function (first, file, optimize)     rtx first;     FILE *file;     int optimize;{  if (app_on)    {      fprintf (file, ASM_APP_OFF);      app_on = 0;    }#ifdef SDB_DEBUGGING_INFO  if (write_symbols == SDB_DEBUG)    sdbout_end_function (high_function_linenum);#endif#ifdef DWARF_DEBUGGING_INFO  if (write_symbols == DWARF_DEBUG)    dwarfout_end_function ();#endif#ifdef XCOFF_DEBUGGING_INFO  if (write_symbols == XCOFF_DEBUG)    xcoffout_end_function (file, high_function_linenum);#endif#ifdef FUNCTION_EPILOGUE  /* Finally, output the function epilogue:     code to restore the stack frame and return to the caller.  */  FUNCTION_EPILOGUE (file, get_frame_size ());#endif#ifdef SDB_DEBUGGING_INFO  if (write_symbols == SDB_DEBUG)    sdbout_end_epilogue ();#endif#ifdef DWARF_DEBUGGING_INFO  if (write_symbols == DWARF_DEBUG)    dwarfout_end_epilogue ();#endif#ifdef XCOFF_DEBUGGING_INFO  if (write_symbols == XCOFF_DEBUG)    xcoffout_end_epilogue (file);#endif  bb_func_label_num = -1;	/* not in function, nuke label # */  /* If FUNCTION_EPILOGUE is not defined, then the function body     itself contains return instructions wherever needed.  */}/* Add a block to the linked list that remembers the current line/file/function   for basic block profiling.  Emit the label in front of the basic block and   the instructions that increment the count field.  */static voidadd_bb (file)     FILE *file;{  struct bb_list *ptr = (struct bb_list *) permalloc (sizeof (struct bb_list));  /* Add basic block to linked list.  */  ptr->next = 0;  ptr->line_num = last_linenum;  ptr->file_label_num = bb_file_label_num;  ptr->func_label_num = bb_func_label_num;  *bb_tail = ptr;  bb_tail = &ptr->next;  /* Enable the table of basic-block use counts     to point at the code it applies to.  */  ASM_OUTPUT_INTERNAL_LABEL (file, "LPB", count_basic_blocks);  /* Before first insn of this basic block, increment the     count of times it was entered.  */#ifdef BLOCK_PROFILER  BLOCK_PROFILER (file, count_basic_blocks);  CC_STATUS_INIT;#endif  new_block = 0;  count_basic_blocks++;}/* Add a string to be used for basic block profiling.  */static intadd_bb_string (string, perm_p)     char *string;     int perm_p;{  int len;  struct bb_str *ptr = 0;  if (!string)    {      string = "<unknown>";      perm_p = TRUE;    }  /* Allocate a new string if the current string isn't permanent.  If     the string is permanent search for the same string in other     allocations.  */  len = strlen (string) + 1;  if (!perm_p)    {      char *p = (char *) permalloc (len);      bcopy (string, p, len);      string = p;    }  else    for (ptr = sbb_head; ptr != (struct bb_str *)0; ptr = ptr->next)      if (ptr->string == string)	break;  /* Allocate a new string block if we need to.  */  if (!ptr)    {      ptr = (struct bb_str *) permalloc (sizeof (*ptr));      ptr->next = 0;      ptr->length = len;      ptr->label_num = sbb_label_num++;      ptr->string = string;      *sbb_tail = ptr;      sbb_tail = &ptr->next;    }  return ptr->label_num;}/* Output assembler code for some insns: all or part of a function.   For description of args, see `final_start_function', above.   PRESCAN is 1 if we are not really outputting,     just scanning as if we were outputting.   Prescanning deletes and rearranges insns just like ordinary output.   PRESCAN is -2 if we are outputting after having prescanned.   In this case, don't try to delete or rearrange insns   because that has already been done.   Prescanning is done only on certain machines.  */voidfinal (first, file, optimize, prescan)     rtx first;     FILE *file;     int optimize;     int prescan;{  register rtx insn;  int max_line = 0;  last_ignored_compare = 0;  new_block = 1;  /* Make a map indicating which line numbers appear in this function.     When producing SDB debugging info, delete troublesome line number     notes from inlined functions in other files as well as duplicate     line number notes.  */#ifdef SDB_DEBUGGING_INFO  if (write_symbols == SDB_DEBUG)    {      rtx last = 0;      for (insn = first; insn; insn = NEXT_INSN (insn))	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)	  {	    if ((RTX_INTEGRATED_P (insn)		 && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)		 || (last != 0		     && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)		     && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))	      {		NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;		NOTE_SOURCE_FILE (insn) = 0;		continue;	      }	    last = insn;	    if (NOTE_LINE_NUMBER (insn) > max_line)	      max_line = NOTE_LINE_NUMBER (insn);	  }    }  else#endif    {      for (insn = first; insn; insn = NEXT_INSN (insn))	if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)	  max_line = NOTE_LINE_NUMBER (insn);    }  line_note_exists = (char *) oballoc (max_line + 1);  bzero (line_note_exists, max_line + 1);  for (insn = first; insn; insn = NEXT_INSN (insn))    if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)      line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;  init_recog ();  CC_STATUS_INIT;  /* Output the insns.  */  for (insn = NEXT_INSN (first); insn;)    insn = final_scan_insn (insn, file, optimize, prescan, 0);  /* Do basic-block profiling here     if the last insn was a conditional branch.  */  if (profile_block_flag && new_block)    add_bb (file);}/* The final scan for one insn, INSN.   Args are same as in `final', except that INSN   is the insn being scanned.   Value returned is the next insn to be scanned.   NOPEEPHOLES is the flag to disallow peephole processing (currently   used for within delayed branch sequence output).  */rtxfinal_scan_insn (insn, file, optimize, prescan, nopeepholes)     rtx insn;     FILE *file;     int optimize;     int prescan;     int nopeepholes;{  register int i;  insn_counter++;  /* Ignore deleted insns.  These can occur when we split insns (due to a     template of "#") while not optimizing.  */  if (INSN_DELETED_P (insn))    return NEXT_INSN (insn);  switch (GET_CODE (insn))    {    case NOTE:      if (prescan > 0)	break;      /* Align the beginning of a loop, for higher speed	 on certain machines.  */      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG && optimize > 0)	{#ifdef ASM_OUTPUT_LOOP_ALIGN	  rtx next = next_nonnote_insn (insn);	  if (next && GET_CODE (next) == CODE_LABEL)	    {	      ASM_OUTPUT_LOOP_ALIGN (asm_out_file);	    }#endif	  break;	}      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)	break;      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)	{#ifdef FUNCTION_END_PROLOGUE	  FUNCTION_END_PROLOGUE (file);#endif	  profile_after_prologue (file);	  break;	}#ifdef FUNCTION_BEGIN_EPILOGUE      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)	{	  FUNCTION_BEGIN_EPILOGUE (file);	  break;	}#endif      if (write_symbols == NO_DEBUG)	break;      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)	{#if defined(SDB_DEBUGGING_INFO) && defined(MIPS_DEBUGGING_INFO)	  /* MIPS stabs require the parameter descriptions to be after the	     function entry point rather than before. */	  if (write_symbols == SDB_DEBUG)	    sdbout_begin_function (last_linenum);	  else#endif#ifdef DWARF_DEBUGGING_INFO	  /* This outputs a marker where the function body starts, so it	     must be after the prologue.  */	  if (write_symbols == DWARF_DEBUG)	    dwarfout_begin_function ();#endif	  break;	}      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)	break;			/* An insn that was "deleted" */      if (app_on)	{	  fprintf (file, ASM_APP_OFF);	  app_on = 0;	}      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG	  && (debug_info_level == DINFO_LEVEL_NORMAL	      || debug_info_level == DINFO_LEVEL_VERBOSE#ifdef DWARF_DEBUGGING_INFO	      || write_symbols == DWARF_DEBUG#endif	     )	 )	{	  /* Beginning of a symbol-block.  Assign it a sequence number	     and push the number onto the stack PENDING_BLOCKS.  */	  if (block_depth == max_block_depth)	    {	      /* PENDING_BLOCKS is full; make it longer.  */	      max_block_depth *= 2;	      pending_blocks		= (int *) xrealloc (pending_blocks,				    max_block_depth * sizeof (int));	    }	  pending_blocks[block_depth++] = next_block_index;	  high_block_linenum = last_linenum;	  /* Output debugging info about the symbol-block beginning.  */#ifdef SDB_DEBUGGING_INFO	  if (write_symbols == SDB_DEBUG)	    sdbout_begin_block (file, last_linenum, next_block_index);#endif#ifdef XCOFF_DEBUGGING_INFO	  if (write_symbols == XCOFF_DEBUG)	    xcoffout_begin_block (file, last_linenum, next_block_index);#endif#ifdef DBX_DEBUGGING_INFO	  if (write_symbols == DBX_DEBUG)	    ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index);#endif#ifdef DWARF_DEBUGGING_INFO	  if (write_symbols == DWARF_DEBUG && block_depth > 1)	    dwarfout_begin_block (next_block_index);#endif	  next_block_index++;	}      else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END	       && (debug_info_level == DINFO_LEVEL_NORMAL		   || debug_info_level == DINFO_LEVEL_VERBOSE#ifdef DWARF_DEBUGGING_INFO	           || write_symbols == DWARF_DEBUG#endif	          )	      )	{	  /* End of a symbol-block.  Pop its sequence number off	     PENDING_BLOCKS and output debugging info based on that.  */	  --block_depth;#ifdef XCOFF_DEBUGGING_INFO	  if (write_symbols == XCOFF_DEBUG && block_depth >= 0)	    xcoffout_end_block (file, high_block_linenum,				pending_blocks[block_depth]);#endif#ifdef DBX_DEBUGGING_INFO	  if (write_symbols == DBX_DEBUG && block_depth >= 0)	    ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",				       pending_blocks[block_depth]);#endif#ifdef SDB_DEBUGGING_INFO	  if (write_symbols == SDB_DEBUG && block_depth >= 0)

⌨️ 快捷键说明

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