Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
92832bb5
Commit
92832bb5
authored
Sep 02, 1993
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update basic block profiling.
From-SVN: r5249
parent
9d436547
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
473 additions
and
68 deletions
+473
-68
gcc/Makefile.in
+1
-1
gcc/config/m68k/sun3.h
+13
-0
gcc/final.c
+277
-49
gcc/libgcc2.c
+182
-18
No files found.
gcc/Makefile.in
View file @
92832bb5
...
@@ -971,7 +971,7 @@ reorg.o : reorg.c $(CONFIG_H) $(RTL_H) conditions.h hard-reg-set.h \
...
@@ -971,7 +971,7 @@ reorg.o : reorg.c $(CONFIG_H) $(RTL_H) conditions.h hard-reg-set.h \
flags.h output.h
flags.h output.h
sched.o
:
sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h
\
sched.o
:
sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h
\
flags.h insn-config.h insn-attr.h
flags.h insn-config.h insn-attr.h
final.o
:
final.c $(CONFIG_H) $(RTL_H) gvarargs.h flags.h regs.h
\
final.o
:
final.c $(CONFIG_H) $(RTL_H)
$(TREE_H)
gvarargs.h flags.h regs.h
\
recog.h conditions.h insn-config.h insn-attr.h real.h output.h
\
recog.h conditions.h insn-config.h insn-attr.h real.h output.h
\
hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h
hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h
recog.o
:
recog.c $(CONFIG_H) $(RTL_H)
\
recog.o
:
recog.c $(CONFIG_H) $(RTL_H)
\
...
...
gcc/config/m68k/sun3.h
View file @
92832bb5
...
@@ -275,3 +275,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -275,3 +275,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
asm_fprintf (FILE, "%I0r%s", dstr); \
asm_fprintf (FILE, "%I0r%s", dstr); \
} \
} \
} while (0)
} while (0)
#undef BLOCK_PROFILER_CODE
#define BLOCK_PROFILER_CODE \
extern int ___tcov_init; \
\
__bb_init_func (blocks) \
struct bb *blocks; \
{ \
if (! ___tcov_init) \
___tcov_init_func (); \
\
___bb_link (blocks->filename, blocks->counts, blocks->ncounts); \
}
gcc/final.c
View file @
92832bb5
...
@@ -45,6 +45,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
...
@@ -45,6 +45,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "config.h"
#include "gvarargs.h"
#include "gvarargs.h"
#include "tree.h"
#include "rtl.h"
#include "rtl.h"
#include "regs.h"
#include "regs.h"
#include "insn-config.h"
#include "insn-config.h"
...
@@ -137,6 +138,9 @@ static rtx debug_insn = 0;
...
@@ -137,6 +138,9 @@ static rtx debug_insn = 0;
/* Line number of last NOTE. */
/* Line number of last NOTE. */
static
int
last_linenum
;
static
int
last_linenum
;
/* Filename of last NOTE. */
static
char
*
last_filename
;
/* Number of basic blocks seen so far;
/* Number of basic blocks seen so far;
used if profile_block_flag is set. */
used if profile_block_flag is set. */
static
int
count_basic_blocks
;
static
int
count_basic_blocks
;
...
@@ -239,6 +243,37 @@ rtx final_sequence;
...
@@ -239,6 +243,37 @@ rtx final_sequence;
/* Indexed by line number, nonzero if there is a note for that line. */
/* Indexed by line number, nonzero if there is a note for that line. */
static
char
*
line_note_exists
;
static
char
*
line_note_exists
;
/* Linked list to hold line numbers for each basic block. */
struct
bb_list
{
struct
bb_list
*
next
;
/* pointer to next basic block */
int
line_num
;
/* line number */
int
file_label_num
;
/* LPBC<n> label # for stored filename */
int
func_label_num
;
/* LPBC<n> label # for stored function name */
};
static
struct
bb_list
*
bb_head
=
0
;
/* Head of basic block list */
static
struct
bb_list
**
bb_tail
=
&
bb_head
;
/* Ptr to store next bb ptr */
static
int
bb_file_label_num
=
-
1
;
/* Current label # for file */
static
int
bb_func_label_num
=
-
1
;
/* Current label # for func */
/* Linked list to hold the strings for each file and function name output. */
struct
bb_str
{
struct
bb_str
*
next
;
/* pointer to next string */
char
*
string
;
/* string */
int
label_num
;
/* label number */
int
length
;
/* string length */
};
static
struct
bb_str
*
sbb_head
=
0
;
/* Head of string list. */
static
struct
bb_str
**
sbb_tail
=
&
sbb_head
;
/* Ptr to store next bb str */
static
int
sbb_label_num
=
0
;
/* Last label used */
static
int
add_bb_string
PROTO
((
char
*
,
int
));
static
void
add_bb
PROTO
((
FILE
*
));
/* Initialize data in final at the beginning of a compilation. */
/* Initialize data in final at the beginning of a compilation. */
...
@@ -264,34 +299,81 @@ end_final (filename)
...
@@ -264,34 +299,81 @@ end_final (filename)
if
(
profile_block_flag
)
if
(
profile_block_flag
)
{
{
char
name
[
12
];
char
name
[
20
];
int
align
=
exact_log2
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
);
int
size
=
(
INT_TYPE_SIZE
/
BITS_PER_UNIT
)
*
count_basic_blocks
;
int
rounded
=
size
;
struct
bb_list
*
ptr
;
struct
bb_str
*
sptr
;
rounded
+=
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
)
-
1
;
rounded
=
(
rounded
/
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
)
*
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
));
data_section
();
data_section
();
/* Output the main header, of
6
words:
/* Output the main header, of
10
words:
0: 1 if this file's initialized, else 0.
0: 1 if this file's initialized, else 0.
1: address of file name.
1: address of file name (LPBX1).
2: address of table of counts.
2: address of table of counts (LPBX2).
4: number of counts in the table.
3: number of counts in the table.
5: always 0, for compatibility with Sun.
4: always 0, for compatibility with Sun.
6: extra word added by GNU: address of address table
which contains addresses of basic blocks,
The following are GNU extensions:
in parallel with the table of counts. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
5: address of table of start addrs of basic blocks (LPBX3).
exact_log2
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
));
6: Number of bytes in this header.
7: address of table of function names (LPBX4).
8: address of table of line numbers (LPBX5) or 0.
9: address of table of file names (LPBX6) or 0. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
align
);
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
0
);
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
0
);
/* zero word */
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
/* address of filename */
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
1
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
1
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
/* address of count table */
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
2
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
2
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
/* count of the # of basic blocks */
assemble_integer
(
GEN_INT
(
count_basic_blocks
),
UNITS_PER_WORD
,
1
);
assemble_integer
(
GEN_INT
(
count_basic_blocks
),
UNITS_PER_WORD
,
1
);
/* zero word (link field) */
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
/* address of basic block start address table */
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
3
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
3
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
/* Output the file name. */
/* byte count for extended structure. */
assemble_integer
(
GEN_INT
(
10
*
UNITS_PER_WORD
),
UNITS_PER_WORD
,
1
);
/* address of function name table */
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
4
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
/* address of line number and filename tables if debugging. */
if
(
write_symbols
!=
NO_DEBUG
)
{
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
5
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
6
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
}
else
{
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
}
/* Output the file name changing the suffix to .d for Sun tcov
compatibility. */
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
1
);
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
1
);
{
{
int
len
=
strlen
(
filename
);
int
len
=
strlen
(
filename
);
...
@@ -302,29 +384,98 @@ end_final (filename)
...
@@ -302,29 +384,98 @@ end_final (filename)
assemble_string
(
data_file
,
strlen
(
data_file
)
+
1
);
assemble_string
(
data_file
,
strlen
(
data_file
)
+
1
);
}
}
/* Realign data section. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
exact_log2
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
));
/* Make space for the table of counts. */
/* Make space for the table of counts. */
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
2
);
if
(
flag_no_common
||
size
==
0
)
if
(
count_basic_blocks
!=
0
)
{
assemble_zeros
(
INT_TYPE_SIZE
/
BITS_PER_UNIT
*
count_basic_blocks
);
/* Realign data section. */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
align
);
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
2
);
if
(
size
!=
0
)
assemble_zeros
(
size
);
}
else
{
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
2
);
#ifdef ASM_OUTPUT_SHARED_LOCAL
if
(
flag_shared_data
)
ASM_OUTPUT_SHARED_LOCAL
(
asm_out_file
,
name
,
size
,
rounded
);
else
#endif
#ifdef ASM_OUTPUT_ALIGNED_LOCAL
ASM_OUTPUT_ALIGNED_LOCAL
(
asm_out_file
,
name
,
size
,
align
);
#else
ASM_OUTPUT_LOCAL
(
asm_out_file
,
name
,
size
,
rounded
);
#endif
}
/* Output
the table of addresses.
*/
/* Output
any basic block strings
*/
readonly_data_section
();
readonly_data_section
();
if
(
sbb_head
)
{
ASM_OUTPUT_ALIGN
(
asm_out_file
,
align
);
for
(
sptr
=
sbb_head
;
sptr
!=
0
;
sptr
=
sptr
->
next
)
{
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBC"
,
sptr
->
label_num
);
assemble_string
(
sptr
->
string
,
sptr
->
length
);
}
}
/* Output the table of addresses. */
/* Realign in new section */
/* Realign in new section */
ASM_OUTPUT_ALIGN
(
asm_out_file
,
ASM_OUTPUT_ALIGN
(
asm_out_file
,
align
);
floor_log2
(
BIGGEST_ALIGNMENT
/
BITS_PER_UNIT
));
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
3
);
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
3
);
for
(
i
=
0
;
i
<
count_basic_blocks
;
i
++
)
for
(
i
=
0
;
i
<
count_basic_blocks
;
i
++
)
{
{
char
name
[
12
];
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPB"
,
i
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPB"
,
i
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
UNITS_PER_WORD
,
1
);
}
}
/* Output the table of function names. */
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
4
);
for
((
ptr
=
bb_head
),
(
i
=
0
);
ptr
!=
0
;
(
ptr
=
ptr
->
next
),
i
++
)
{
if
(
ptr
->
func_label_num
>=
0
)
{
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBC"
,
ptr
->
func_label_num
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
}
else
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
}
for
(
;
i
<
count_basic_blocks
;
i
++
)
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
if
(
write_symbols
!=
NO_DEBUG
)
{
/* Output the table of line numbers. */
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
5
);
for
((
ptr
=
bb_head
),
(
i
=
0
);
ptr
!=
0
;
(
ptr
=
ptr
->
next
),
i
++
)
assemble_integer
(
GEN_INT
(
ptr
->
line_num
),
UNITS_PER_WORD
,
1
);
for
(
;
i
<
count_basic_blocks
;
i
++
)
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
/* Output the table of file names. */
ASM_OUTPUT_INTERNAL_LABEL
(
asm_out_file
,
"LPBX"
,
6
);
for
((
ptr
=
bb_head
),
(
i
=
0
);
ptr
!=
0
;
(
ptr
=
ptr
->
next
),
i
++
)
{
if
(
ptr
->
file_label_num
>=
0
)
{
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBC"
,
ptr
->
file_label_num
);
assemble_integer
(
gen_rtx
(
SYMBOL_REF
,
Pmode
,
name
),
UNITS_PER_WORD
,
1
);
}
else
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
}
for
(
;
i
<
count_basic_blocks
;
i
++
)
assemble_integer
(
const0_rtx
,
UNITS_PER_WORD
,
1
);
}
/* End with the address of the table of addresses,
/* End with the address of the table of addresses,
so we can find it easily, as the last word in the file's text. */
so we can find it easily, as the last word in the file's text. */
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
3
);
ASM_GENERATE_INTERNAL_LABEL
(
name
,
"LPBX"
,
3
);
...
@@ -761,6 +912,15 @@ final_start_function (first, file, optimize)
...
@@ -761,6 +912,15 @@ final_start_function (first, file, optimize)
profile_after_prologue
(
file
);
profile_after_prologue
(
file
);
profile_label_no
++
;
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
void
static
void
...
@@ -894,10 +1054,93 @@ final_end_function (first, file, optimize)
...
@@ -894,10 +1054,93 @@ final_end_function (first, file, optimize)
xcoffout_end_epilogue
(
file
);
xcoffout_end_epilogue
(
file
);
#endif
#endif
bb_func_label_num
=
-
1
;
/* not in function, nuke label # */
/* If FUNCTION_EPILOGUE is not defined, then the function body
/* If FUNCTION_EPILOGUE is not defined, then the function body
itself contains return instructions wherever needed. */
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
void
add_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
int
add_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.
/* Output assembler code for some insns: all or part of a function.
For description of args, see `final_start_function', above.
For description of args, see `final_start_function', above.
...
@@ -974,19 +1217,7 @@ final (first, file, optimize, prescan)
...
@@ -974,19 +1217,7 @@ final (first, file, optimize, prescan)
/* Do basic-block profiling here
/* Do basic-block profiling here
if the last insn was a conditional branch. */
if the last insn was a conditional branch. */
if
(
profile_block_flag
&&
new_block
)
if
(
profile_block_flag
&&
new_block
)
{
add_bb
(
file
);
new_block
=
0
;
/* 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
count_basic_blocks
++
;
}
}
}
/* The final scan for one insn, INSN.
/* The final scan for one insn, INSN.
...
@@ -1354,19 +1585,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
...
@@ -1354,19 +1585,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
/* Do basic-block profiling when we reach a new block.
/* Do basic-block profiling when we reach a new block.
Done here to avoid jump tables. */
Done here to avoid jump tables. */
if
(
profile_block_flag
&&
new_block
)
if
(
profile_block_flag
&&
new_block
)
{
add_bb
(
file
);
new_block
=
0
;
/* 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
count_basic_blocks
++
;
}
if
(
GET_CODE
(
body
)
==
ASM_INPUT
)
if
(
GET_CODE
(
body
)
==
ASM_INPUT
)
{
{
...
@@ -1777,6 +1996,15 @@ output_source_line (file, insn)
...
@@ -1777,6 +1996,15 @@ output_source_line (file, insn)
char
ltext_label_name
[
100
];
char
ltext_label_name
[
100
];
register
char
*
filename
=
NOTE_SOURCE_FILE
(
insn
);
register
char
*
filename
=
NOTE_SOURCE_FILE
(
insn
);
/* Remember filename for basic block profiling.
Filenames are allocated on the permanent obstack
or are passed in ARGV, so we don't have to save
the string. */
if
(
profile_block_flag
&&
last_filename
!=
filename
)
bb_file_label_num
=
add_bb_string
(
filename
,
TRUE
);
last_filename
=
filename
;
last_linenum
=
NOTE_LINE_NUMBER
(
insn
);
last_linenum
=
NOTE_LINE_NUMBER
(
insn
);
if
(
write_symbols
!=
NO_DEBUG
)
if
(
write_symbols
!=
NO_DEBUG
)
...
...
gcc/libgcc2.c
View file @
92832bb5
...
@@ -1285,35 +1285,199 @@ __eprintf (string, expression, line, filename)
...
@@ -1285,35 +1285,199 @@ __eprintf (string, expression, line, filename)
#endif
#endif
#ifdef L_bb
#ifdef L_bb
/* Avoid warning from ranlib about empty object file. */
void
__bb_avoid_warning
()
{}
#if defined (__sun__) && defined (__mc68000__)
/* Structure emitted by -a */
struct
bb
struct
bb
{
{
int
initialized
;
long
zero_word
;
char
*
filename
;
const
char
*
filename
;
int
*
counts
;
long
*
counts
;
int
ncounts
;
long
ncounts
;
int
zero_word
;
struct
bb
*
next
;
int
*
addresses
;
const
unsigned
long
*
addresses
;
/* Older GCC's did not emit these fields. */
long
nwords
;
const
char
**
functions
;
const
long
*
line_nums
;
const
char
**
filenames
;
};
};
extern
int
___tcov_init
;
#ifdef BLOCK_PROFILER_CODE
BLOCK_PROFILER_CODE
#else
/* Simple minded basic block profiling output dumper for
systems that don't provde tcov support. At present,
it requires atexit and stdio. */
#include <stdio.h>
__bb_init_func
(
blocks
)
#ifdef HAVE_ATEXIT
struct
bb
*
blocks
;
extern
void
atexit
(
void
(
*
)
(
void
));
#define ON_EXIT(FUNC,ARG) atexit ((FUNC))
#else
#ifdef sun
extern
void
on_exit
(
void
*
,
void
*
);
#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
#endif
#endif
static
struct
bb
*
bb_head
=
(
struct
bb
*
)
0
;
/* Return the number of digits needed to print a value */
/* __inline__ */
static
int
num_digits
(
long
value
,
int
base
)
{
{
if
(
!
___tcov_init
)
int
minus
=
(
value
<
0
&&
base
!=
16
);
___tcov_init_func
();
unsigned
long
v
=
(
minus
)
?
-
value
:
value
;
int
ret
=
minus
;
___bb_link
(
blocks
->
filename
,
blocks
->
counts
,
blocks
->
ncounts
);
do
{
v
/=
base
;
ret
++
;
}
while
(
v
);
return
ret
;
}
}
void
__bb_exit_func
(
void
)
{
FILE
*
file
=
fopen
(
"bb.out"
,
"a"
);
long
time_value
;
if
(
!
file
)
perror
(
"bb.out"
);
else
{
struct
bb
*
ptr
;
/* This is somewhat type incorrect, but it avoids worrying about
exactly where time.h is included from. It should be ok unless
a void * differs from other pointer formats, or if sizeof(long)
is < sizeof (time_t). It would be nice if we could assume the
use of rationale standards here. */
time
((
void
*
)
&
time_value
);
fprintf
(
file
,
"Basic block profiling finished on %s
\n
"
,
ctime
((
void
*
)
&
time_value
));
/* We check the length field explicitly in order to allow compatibility
with older GCC's which did not provide it. */
for
(
ptr
=
bb_head
;
ptr
!=
(
struct
bb
*
)
0
;
ptr
=
ptr
->
next
)
{
int
i
;
int
func_p
=
(
ptr
->
nwords
>=
sizeof
(
struct
bb
)
&&
ptr
->
nwords
<=
1000
);
int
line_p
=
(
func_p
&&
ptr
->
line_nums
);
int
file_p
=
(
func_p
&&
ptr
->
filenames
);
long
ncounts
=
ptr
->
ncounts
;
long
cnt_max
=
0
;
long
line_max
=
0
;
long
addr_max
=
0
;
int
file_len
=
0
;
int
func_len
=
0
;
int
blk_len
=
num_digits
(
ncounts
,
10
);
int
cnt_len
;
int
line_len
;
int
addr_len
;
fprintf
(
file
,
"File %s, %ld basic blocks
\n\n
"
,
ptr
->
filename
,
ncounts
);
/* Get max values for each field. */
for
(
i
=
0
;
i
<
ncounts
;
i
++
)
{
const
char
*
p
;
int
len
;
if
(
cnt_max
<
ptr
->
counts
[
i
])
cnt_max
=
ptr
->
counts
[
i
];
if
(
addr_max
<
ptr
->
addresses
[
i
])
addr_max
=
ptr
->
addresses
[
i
];
if
(
line_p
&&
line_max
<
ptr
->
line_nums
[
i
])
line_max
=
ptr
->
line_nums
[
i
];
if
(
func_p
)
{
p
=
(
ptr
->
functions
[
i
])
?
(
ptr
->
functions
[
i
])
:
"<none>"
;
len
=
strlen
(
p
);
if
(
func_len
<
len
)
func_len
=
len
;
}
if
(
file_p
)
{
p
=
(
ptr
->
filenames
[
i
])
?
(
ptr
->
filenames
[
i
])
:
"<none>"
;
len
=
strlen
(
p
);
if
(
file_len
<
len
)
file_len
=
len
;
}
}
addr_len
=
num_digits
(
addr_max
,
16
);
cnt_len
=
num_digits
(
cnt_max
,
10
);
line_len
=
num_digits
(
line_max
,
10
);
/* Now print out the basic block information. */
for
(
i
=
0
;
i
<
ncounts
;
i
++
)
{
fprintf
(
file
,
" Block #%*d: executed %*ld time(s) address=0x%.*lx"
,
blk_len
,
i
+
1
,
cnt_len
,
ptr
->
counts
[
i
],
addr_len
,
ptr
->
addresses
[
i
]);
if
(
func_p
)
fprintf
(
file
,
" function=%-*s"
,
func_len
,
(
ptr
->
functions
[
i
])
?
ptr
->
functions
[
i
]
:
"<none>"
);
if
(
line_p
)
fprintf
(
file
,
" line=%*d"
,
line_len
,
ptr
->
line_nums
[
i
]);
if
(
file_p
)
fprintf
(
file
,
" file=%s"
,
(
ptr
->
filenames
[
i
])
?
ptr
->
filenames
[
i
]
:
"<none>"
);
fprintf
(
file
,
"
\n
"
);
}
fprintf
(
file
,
"
\n
"
);
fflush
(
file
);
}
fprintf
(
file
,
"
\n\n
"
);
fclose
(
file
);
}
}
void
__bb_init_func
(
struct
bb
*
blocks
)
{
/* User is supposed to check whether the first word is non-0,
but just in case.... */
if
(
blocks
->
zero_word
)
return
;
#ifdef ON_EXIT
/* Initialize destructor. */
if
(
!
bb_head
)
ON_EXIT
(
__bb_exit_func
,
0
);
#endif
#endif
#endif
/* Set up linked list. */
blocks
->
zero_word
=
1
;
blocks
->
next
=
bb_head
;
bb_head
=
blocks
;
}
#endif
/* !BLOCK_PROFILER_CODE */
#endif
/* L_bb */
/* frills for C++ */
/* frills for C++ */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment