mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-15 09:00:29 +08:00
[ARC] Rework code for profiling.
gcc/ 2016-12-16 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/arc.h (LINK_SPEC): Tidy up. (ENDFILE_SPEC): Likewise. (LIB_SPEC): Likewise. (STARTFILE_SPEC): Include gcrt0 when profiling. (FUNCTION_PROFILER): Use __mcount. * config/arc/arc.opt (mucb-mcount): Remove. * doc/invoke.texi (ARC): Remove mucb-mcount doc. * arc/arc-protos.h (arc_profile_call): Remove. * config/arc/arc.c (write_profile_sections): Likewise. (arc_profile_call): Likewise. (unspec_prof_hash): Likewise. (unspec_prof_htab_eq): Likewise. (arc_legitimate_constant_p): Remove UNSPEC_PROF. (arc_reorg): Remove call to write_profile_sections. * config/arc/arc.md (call): Remove call to arc_profile_call. (call_value): Likewise. (sibcall): Likewise. (sibcall_value): Likewise. (define_constants): Remove UNSPEC_PROF. libgcc/ * config.host (arc*-*-linux-uclibc*): Remove libgmon, crtg, and crtgend. (arc*-*-elf*): Likewise. * config/arc/t-arc: Remove old gmon lib targets. * config/arc/crtg.S: Remove. * config/arc/crtgend.S: Likewise. * config/arc/gmon/atomic.h: Likewise. * config/arc/gmon/auxreg.h: Likewise. * config/arc/gmon/dcache_linesz.S: Likewise. * config/arc/gmon/gmon.c: Likewise. * config/arc/gmon/machine-gmon.h: Likewise. * config/arc/gmon/mcount.c: Likewise. * config/arc/gmon/prof-freq-stub.S: Likewise. * config/arc/gmon/prof-freq.c: Likewise. * config/arc/gmon/profil.S: Likewise. * config/arc/gmon/sys/gmon.h: Likewise. * config/arc/gmon/sys/gmon_out.h: Likewise. * config/arc/t-arc-newlib: Likewise. * config/arc/t-arc700-uClibc: Renamed to t-arc-uClibc. From-SVN: r243742
This commit is contained in:
parent
d476b53c36
commit
e04ea1daa9
@ -1,3 +1,25 @@
|
||||
2016-12-16 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* config/arc/arc.h (LINK_SPEC): Tidy up.
|
||||
(ENDFILE_SPEC): Likewise.
|
||||
(LIB_SPEC): Likewise.
|
||||
(STARTFILE_SPEC): Include gcrt0 when profiling.
|
||||
(FUNCTION_PROFILER): Use __mcount.
|
||||
* config/arc/arc.opt (mucb-mcount): Remove.
|
||||
* doc/invoke.texi (ARC): Remove mucb-mcount doc.
|
||||
* arc/arc-protos.h (arc_profile_call): Remove.
|
||||
* config/arc/arc.c (write_profile_sections): Likewise.
|
||||
(arc_profile_call): Likewise.
|
||||
(unspec_prof_hash): Likewise.
|
||||
(unspec_prof_htab_eq): Likewise.
|
||||
(arc_legitimate_constant_p): Remove UNSPEC_PROF.
|
||||
(arc_reorg): Remove call to write_profile_sections.
|
||||
* config/arc/arc.md (call): Remove call to arc_profile_call.
|
||||
(call_value): Likewise.
|
||||
(sibcall): Likewise.
|
||||
(sibcall_value): Likewise.
|
||||
(define_constants): Remove UNSPEC_PROF.
|
||||
|
||||
2016-12-16 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* config/arc/arc.md (mulsidi_600): Change to insn_and_split,
|
||||
|
@ -70,7 +70,6 @@ extern bool arc_raw_symbolic_reference_mentioned_p (rtx, bool);
|
||||
extern bool arc_legitimate_pic_operand_p (rtx);
|
||||
extern bool arc_is_longcall_p (rtx);
|
||||
extern bool arc_is_shortcall_p (rtx);
|
||||
extern bool arc_profile_call (rtx callee);
|
||||
extern bool valid_brcc_with_delay_p (rtx *);
|
||||
extern bool small_data_pattern (rtx , machine_mode);
|
||||
extern rtx arc_rewrite_small_data (rtx);
|
||||
|
@ -3610,97 +3610,6 @@ arc_print_operand_address (FILE *file , rtx addr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called via walk_stores. DATA points to a hash table we can use to
|
||||
establish a unique SYMBOL_REF for each counter, which corresponds to
|
||||
a caller-callee pair.
|
||||
X is a store which we want to examine for an UNSPEC_PROF, which
|
||||
would be an address loaded into a register, or directly used in a MEM.
|
||||
If we found an UNSPEC_PROF, if we encounter a new counter the first time,
|
||||
write out a description and a data allocation for a 32 bit counter.
|
||||
Also, fill in the appropriate symbol_ref into each UNSPEC_PROF instance. */
|
||||
|
||||
static void
|
||||
write_profile_sections (rtx dest ATTRIBUTE_UNUSED, rtx x, void *data)
|
||||
{
|
||||
rtx *srcp, src;
|
||||
htab_t htab = (htab_t) data;
|
||||
rtx *slot;
|
||||
|
||||
if (GET_CODE (x) != SET)
|
||||
return;
|
||||
srcp = &SET_SRC (x);
|
||||
if (MEM_P (*srcp))
|
||||
srcp = &XEXP (*srcp, 0);
|
||||
else if (MEM_P (SET_DEST (x)))
|
||||
srcp = &XEXP (SET_DEST (x), 0);
|
||||
src = *srcp;
|
||||
if (GET_CODE (src) != CONST)
|
||||
return;
|
||||
src = XEXP (src, 0);
|
||||
if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_PROF)
|
||||
return;
|
||||
|
||||
gcc_assert (XVECLEN (src, 0) == 3);
|
||||
if (!htab_elements (htab))
|
||||
{
|
||||
output_asm_insn (".section .__arc_profile_desc, \"a\"\n"
|
||||
"\t.long %0 + 1\n",
|
||||
&XVECEXP (src, 0, 0));
|
||||
}
|
||||
slot = (rtx *) htab_find_slot (htab, src, INSERT);
|
||||
if (*slot == HTAB_EMPTY_ENTRY)
|
||||
{
|
||||
static int count_nr;
|
||||
char buf[24];
|
||||
rtx count;
|
||||
|
||||
*slot = src;
|
||||
sprintf (buf, "__prof_count%d", count_nr++);
|
||||
count = gen_rtx_SYMBOL_REF (Pmode, xstrdup (buf));
|
||||
XVECEXP (src, 0, 2) = count;
|
||||
output_asm_insn (".section\t.__arc_profile_desc, \"a\"\n"
|
||||
"\t.long\t%1\n"
|
||||
"\t.section\t.__arc_profile_counters, \"aw\"\n"
|
||||
"\t.type\t%o2, @object\n"
|
||||
"\t.size\t%o2, 4\n"
|
||||
"%o2:\t.zero 4",
|
||||
&XVECEXP (src, 0, 0));
|
||||
*srcp = count;
|
||||
}
|
||||
else
|
||||
*srcp = XVECEXP (*slot, 0, 2);
|
||||
}
|
||||
|
||||
/* Hash function for UNSPEC_PROF htab. Use both the caller's name and
|
||||
the callee's name (if known). */
|
||||
|
||||
static hashval_t
|
||||
unspec_prof_hash (const void *x)
|
||||
{
|
||||
const_rtx u = (const_rtx) x;
|
||||
const_rtx s1 = XVECEXP (u, 0, 1);
|
||||
|
||||
return (htab_hash_string (XSTR (XVECEXP (u, 0, 0), 0))
|
||||
^ (s1->code == SYMBOL_REF ? htab_hash_string (XSTR (s1, 0)) : 0));
|
||||
}
|
||||
|
||||
/* Equality function for UNSPEC_PROF htab. Two pieces of UNSPEC_PROF rtl
|
||||
shall refer to the same counter if both caller name and callee rtl
|
||||
are identical. */
|
||||
|
||||
static int
|
||||
unspec_prof_htab_eq (const void *x, const void *y)
|
||||
{
|
||||
const_rtx u0 = (const_rtx) x;
|
||||
const_rtx u1 = (const_rtx) y;
|
||||
const_rtx s01 = XVECEXP (u0, 0, 1);
|
||||
const_rtx s11 = XVECEXP (u1, 0, 1);
|
||||
|
||||
return (!strcmp (XSTR (XVECEXP (u0, 0, 0), 0),
|
||||
XSTR (XVECEXP (u1, 0, 0), 0))
|
||||
&& rtx_equal_p (s01, s11));
|
||||
}
|
||||
|
||||
/* Conditional execution support.
|
||||
|
||||
This is based on the ARM port but for now is much simpler.
|
||||
@ -5438,7 +5347,6 @@ arc_legitimate_constant_p (machine_mode mode, rtx x)
|
||||
case UNSPEC_TLS_GD:
|
||||
case UNSPEC_TLS_IE:
|
||||
case UNSPEC_TLS_OFF:
|
||||
case UNSPEC_PROF:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@ -6359,47 +6267,6 @@ arc_is_shortcall_p (rtx sym_ref)
|
||||
|
||||
}
|
||||
|
||||
/* Emit profiling code for calling CALLEE. Return true if a special
|
||||
call pattern needs to be generated. */
|
||||
|
||||
bool
|
||||
arc_profile_call (rtx callee)
|
||||
{
|
||||
rtx from = XEXP (DECL_RTL (current_function_decl), 0);
|
||||
|
||||
if (TARGET_UCB_MCOUNT)
|
||||
/* Profiling is done by instrumenting the callee. */
|
||||
return false;
|
||||
|
||||
if (CONSTANT_P (callee))
|
||||
{
|
||||
rtx count_ptr
|
||||
= gen_rtx_CONST (Pmode,
|
||||
gen_rtx_UNSPEC (Pmode,
|
||||
gen_rtvec (3, from, callee,
|
||||
CONST0_RTX (Pmode)),
|
||||
UNSPEC_PROF));
|
||||
rtx counter = gen_rtx_MEM (SImode, count_ptr);
|
||||
/* ??? The increment would better be done atomically, but as there is
|
||||
no proper hardware support, that would be too expensive. */
|
||||
emit_move_insn (counter,
|
||||
force_reg (SImode, plus_constant (SImode, counter, 1)));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx count_list_ptr
|
||||
= gen_rtx_CONST (Pmode,
|
||||
gen_rtx_UNSPEC (Pmode,
|
||||
gen_rtvec (3, from, CONST0_RTX (Pmode),
|
||||
CONST0_RTX (Pmode)),
|
||||
UNSPEC_PROF));
|
||||
emit_move_insn (gen_rtx_REG (Pmode, 8), count_list_ptr);
|
||||
emit_move_insn (gen_rtx_REG (Pmode, 9), callee);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Worker function for TARGET_RETURN_IN_MEMORY. */
|
||||
|
||||
static bool
|
||||
@ -6621,25 +6488,6 @@ arc_reorg (void)
|
||||
cfun->machine->arc_reorg_started = 1;
|
||||
arc_reorg_in_progress = 1;
|
||||
|
||||
/* Emit special sections for profiling. */
|
||||
if (crtl->profile)
|
||||
{
|
||||
section *save_text_section;
|
||||
rtx_insn *insn;
|
||||
int size = get_max_uid () >> 4;
|
||||
htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq,
|
||||
NULL);
|
||||
|
||||
save_text_section = in_section;
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
if (NONJUMP_INSN_P (insn))
|
||||
walk_stores (PATTERN (insn), write_profile_sections, htab);
|
||||
if (htab_elements (htab))
|
||||
in_section = 0;
|
||||
switch_to_section (save_text_section);
|
||||
htab_delete (htab);
|
||||
}
|
||||
|
||||
/* Link up loop ends with their loop start. */
|
||||
{
|
||||
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||
|
@ -121,12 +121,11 @@ extern const char *arc_cpu_to_as (int argc, const char **argv);
|
||||
-X %{mbig-endian:-EB} \
|
||||
%{EB} %{EL} \
|
||||
%{marclinux*} \
|
||||
%{!marclinux*: %{pg|p|profile:-marclinux_prof;: -marclinux}} \
|
||||
%{!marclinux*: -marclinux} \
|
||||
%{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \
|
||||
%{shared:-shared}"
|
||||
#else
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}\
|
||||
%{pg|p:-marcelf_prof;mA7|mARC700|mcpu=arc700|mcpu=ARC700: -marcelf}"
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}"
|
||||
#endif
|
||||
|
||||
#if DEFAULT_LIBC != LIBC_UCLIBC
|
||||
@ -135,7 +134,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv);
|
||||
#define EXTRA_SPECS \
|
||||
{ "arc_tls_extra_start_spec", ARC_TLS_EXTRA_START_SPEC }, \
|
||||
|
||||
#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti%O%s %{pg|p:crtg.o%s} " \
|
||||
#define STARTFILE_SPEC "%{pg|p:gcrt0.o%s}%{!pg:%{!p:crt0.o%s}} crti%O%s " \
|
||||
"%(arc_tls_extra_start_spec) crtbegin.o%s"
|
||||
#else
|
||||
#define STARTFILE_SPEC \
|
||||
@ -143,7 +142,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv);
|
||||
#endif
|
||||
|
||||
#if DEFAULT_LIBC != LIBC_UCLIBC
|
||||
#define ENDFILE_SPEC "%{pg|p:crtgend.o%s} crtend.o%s crtn%O%s"
|
||||
#define ENDFILE_SPEC "crtend.o%s crtn%O%s"
|
||||
#else
|
||||
#define ENDFILE_SPEC \
|
||||
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC)
|
||||
@ -154,12 +153,11 @@ extern const char *arc_cpu_to_as (int argc, const char **argv);
|
||||
#define LIB_SPEC \
|
||||
"%{pthread:-lpthread} \
|
||||
%{shared:-lc} \
|
||||
%{!shared:%{pg|p|profile:-lgmon -u profil --defsym __profil=profil} -lc}"
|
||||
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
|
||||
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
||||
#else
|
||||
#undef LIB_SPEC
|
||||
/* -lc_p not present for arc-elf32-* : ashwin */
|
||||
#define LIB_SPEC "%{!shared:%{g*:-lg} %{pg|p:-lgmon} -lc}"
|
||||
#define LIB_SPEC "%{!shared:%{g*:-lg} -lc}"
|
||||
#endif
|
||||
|
||||
#ifndef DRIVER_ENDIAN_SELF_SPECS
|
||||
@ -916,12 +914,14 @@ extern int arc_initial_elimination_offset(int from, int to);
|
||||
(OFFSET) = arc_initial_elimination_offset ((FROM), (TO))
|
||||
|
||||
/* Output assembler code to FILE to increment profiler label # LABELNO
|
||||
for profiling a function entry.
|
||||
We actually emit the profiler code at the call site, so leave this one
|
||||
empty. */
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
if (TARGET_UCB_MCOUNT) \
|
||||
fprintf (FILE, "\t%s\n", arc_output_libcall ("__mcount"))
|
||||
for profiling a function entry. */
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO) \
|
||||
do { \
|
||||
if (flag_pic) \
|
||||
fprintf (FILE, "\tbl\t__mcount@plt\n"); \
|
||||
else \
|
||||
fprintf (FILE, "\tbl\t__mcount\n"); \
|
||||
} while (0);
|
||||
|
||||
#define NO_PROFILE_COUNTERS 1
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
;; Saurabh Verma (saurabh.verma@codito.com)
|
||||
;; Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
|
||||
;;
|
||||
;; Profiling support and performance improvements by
|
||||
;; Performance improvements by
|
||||
;; Joern Rennecke (joern.rennecke@embecosm.com)
|
||||
;;
|
||||
|
||||
@ -165,9 +165,7 @@
|
||||
])
|
||||
|
||||
(define_constants
|
||||
[(UNSPEC_PROF 18) ; profile callgraph counter
|
||||
|
||||
(R0_REG 0)
|
||||
[(R0_REG 0)
|
||||
(R1_REG 1)
|
||||
(R2_REG 2)
|
||||
(R3_REG 3)
|
||||
@ -4108,13 +4106,6 @@
|
||||
|
||||
gcc_assert (MEM_P (operands[0]));
|
||||
callee = XEXP (operands[0], 0);
|
||||
if (crtl->profile && arc_profile_call (callee))
|
||||
{
|
||||
emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
|
||||
\"_mcount_call\"),
|
||||
operands[1]));
|
||||
DONE;
|
||||
}
|
||||
/* This is to decide if we should generate indirect calls by loading the
|
||||
32 bit address of the callee into a register before performing the
|
||||
branch and link - this exposes cse opportunities.
|
||||
@ -4177,14 +4168,6 @@
|
||||
|
||||
gcc_assert (MEM_P (operands[1]));
|
||||
callee = XEXP (operands[1], 0);
|
||||
if (crtl->profile && arc_profile_call (callee))
|
||||
{
|
||||
emit_call_insn (gen_call_value_prof (operands[0],
|
||||
gen_rtx_SYMBOL_REF (Pmode,
|
||||
\"_mcount_call\"),
|
||||
operands[2]));
|
||||
DONE;
|
||||
}
|
||||
/* See the comment in define_expand \"call\". */
|
||||
if (GET_CODE (callee) != REG
|
||||
&& (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
|
||||
@ -4667,13 +4650,6 @@
|
||||
|
||||
if (operands[2] == NULL_RTX)
|
||||
operands[2] = const0_rtx;
|
||||
if (crtl->profile && arc_profile_call (callee))
|
||||
{
|
||||
emit_insn (gen_sibcall_prof
|
||||
(gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
|
||||
operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
if (GET_CODE (callee) != REG
|
||||
&& (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
|
||||
XEXP (operands[0], 0) = force_reg (Pmode, callee);
|
||||
@ -4693,13 +4669,6 @@
|
||||
|
||||
if (operands[3] == NULL_RTX)
|
||||
operands[3] = const0_rtx;
|
||||
if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
|
||||
{
|
||||
emit_insn (gen_sibcall_value_prof
|
||||
(operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
|
||||
operands[2], operands[3]));
|
||||
DONE;
|
||||
}
|
||||
if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
|
||||
XEXP (operands[1], 0) = force_reg (Pmode, callee);
|
||||
}"
|
||||
|
@ -409,10 +409,6 @@ mlra-priority-noncompact
|
||||
Target RejectNegative Var(arc_lra_prioritytag, ARC_LRA_PRIORITY_NONCOMPACT)
|
||||
Reduce priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY.
|
||||
|
||||
mucb-mcount
|
||||
Target Report Var(TARGET_UCB_MCOUNT)
|
||||
instrument with mcount calls as in the ucb code.
|
||||
|
||||
; backward-compatibility aliases, translated by DRIVER_SELF_SPECS
|
||||
|
||||
mEA
|
||||
|
@ -611,7 +611,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-mcrc -mdsp-packa -mdvbf -mlock -mmac-d16 -mmac-24 -mrtsc -mswape @gol
|
||||
-mtelephony -mxy -misize -mannotate-align -marclinux -marclinux_prof @gol
|
||||
-mlong-calls -mmedium-calls -msdata @gol
|
||||
-mucb-mcount -mvolatile-cache -mtp-regno=@var{regno} @gol
|
||||
-mvolatile-cache -mtp-regno=@var{regno} @gol
|
||||
-malign-call -mauto-modify-reg -mbbit-peephole -mno-brcc @gol
|
||||
-mcase-vector-pcrel -mcompact-casesi -mno-cond-exec -mearly-cbranchsi @gol
|
||||
-mexpand-adddi -mindexed-loads -mlra -mlra-priority-none @gol
|
||||
@ -14726,12 +14726,6 @@ Do not generate sdata references. This is the default for tool chains
|
||||
built for @w{@code{arc-linux-uclibc}} and @w{@code{arceb-linux-uclibc}}
|
||||
targets.
|
||||
|
||||
@item -mucb-mcount
|
||||
@opindex mucb-mcount
|
||||
Instrument with mcount calls as used in UCB code. I.e. do the
|
||||
counting in the callee, not the caller. By default ARC instrumentation
|
||||
counts in the caller.
|
||||
|
||||
@item -mvolatile-cache
|
||||
@opindex mvolatile-cache
|
||||
Use ordinarily cached memory accesses for volatile references. This is the
|
||||
|
@ -1,3 +1,25 @@
|
||||
2016-12-16 Claudiu Zissulescu <claziss@synopsys.com>
|
||||
|
||||
* config.host (arc*-*-linux-uclibc*): Remove libgmon, crtg, and
|
||||
crtgend.
|
||||
(arc*-*-elf*): Likewise.
|
||||
* config/arc/t-arc: Remove old gmon lib targets.
|
||||
* config/arc/crtg.S: Remove.
|
||||
* config/arc/crtgend.S: Likewise.
|
||||
* config/arc/gmon/atomic.h: Likewise.
|
||||
* config/arc/gmon/auxreg.h: Likewise.
|
||||
* config/arc/gmon/dcache_linesz.S: Likewise.
|
||||
* config/arc/gmon/gmon.c: Likewise.
|
||||
* config/arc/gmon/machine-gmon.h: Likewise.
|
||||
* config/arc/gmon/mcount.c: Likewise.
|
||||
* config/arc/gmon/prof-freq-stub.S: Likewise.
|
||||
* config/arc/gmon/prof-freq.c: Likewise.
|
||||
* config/arc/gmon/profil.S: Likewise.
|
||||
* config/arc/gmon/sys/gmon.h: Likewise.
|
||||
* config/arc/gmon/sys/gmon_out.h: Likewise.
|
||||
* config/arc/t-arc-newlib: Likewise.
|
||||
* config/arc/t-arc700-uClibc: Renamed to t-arc-uClibc.
|
||||
|
||||
2016-12-12 George Spelvin <linux@sciencehorizons.net>
|
||||
|
||||
* config/avr/lib1funcs.S (__ashrdi3): Fix typo from r243545.
|
||||
|
@ -368,13 +368,13 @@ alpha*-dec-*vms*)
|
||||
md_unwind_header=alpha/vms-unwind.h
|
||||
;;
|
||||
arc*-*-elf*)
|
||||
tmake_file="arc/t-arc-newlib arc/t-arc"
|
||||
extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o"
|
||||
extra_parts="${extra_parts} crttls.o"
|
||||
tmake_file="arc/t-arc"
|
||||
extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o"
|
||||
extra_parts="$extra_parts crttls.o"
|
||||
;;
|
||||
arc*-*-linux-uclibc*)
|
||||
tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc700-uClibc arc/t-arc"
|
||||
extra_parts="$extra_parts crti.o crtn.o libgmon.a crtg.o crtgend.o"
|
||||
tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc-uClibc arc/t-arc"
|
||||
extra_parts="$extra_parts crti.o crtn.o"
|
||||
extra_parts="$extra_parts crttls.o"
|
||||
;;
|
||||
arm-wrs-vxworks)
|
||||
|
@ -1,51 +0,0 @@
|
||||
/* Code to start and stop profiling for the Synopsys DesignWare ARC CPU.
|
||||
|
||||
Copyright (C) 1994-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
.section .init
|
||||
.global _init
|
||||
.global _fini
|
||||
.global __monstartup
|
||||
mov_s r0,_init
|
||||
mov_s r1,_fini
|
||||
jl __monstartup
|
||||
|
||||
.section .__arc_profile_desc, "a"
|
||||
.global __arc_profile_desc_secstart
|
||||
.balign 4
|
||||
__arc_profile_desc_secstart:
|
||||
.section .__arc_profile_forward, "a"
|
||||
.global __arc_profile_forward_secstart
|
||||
.balign 4
|
||||
__arc_profile_forward_secstart:
|
||||
.section .__arc_profile_counters, "aw"
|
||||
.global __arc_profile_counters_secstart
|
||||
.balign 4
|
||||
__arc_profile_counters_secstart:
|
||||
|
||||
.section .fini
|
||||
.global _mcleanup
|
||||
jl _mcleanup
|
@ -1,33 +0,0 @@
|
||||
/* Code to start and stop profiling for the Synopsys DesignWare ARC CPU.
|
||||
|
||||
Copyright (C) 1994-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
.section .__arc_profile_desc, "a"
|
||||
.global __arc_profile_desc_secend
|
||||
__arc_profile_desc_secend:
|
||||
.section .__arc_profile_forward, "a"
|
||||
.global __arc_profile_forward_secend
|
||||
__arc_profile_forward_secend:
|
@ -1,26 +0,0 @@
|
||||
/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* File deliberately left blank. */
|
@ -1,35 +0,0 @@
|
||||
/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define LP_START 0x02
|
||||
#define LP_END 0x03
|
||||
#define IDENTITY 0x04
|
||||
#define STATUS32 0x0a
|
||||
#define COUNT0 0x21 /* Timer 0 count */
|
||||
#define CONTROL0 0x22 /* Timer 0 control */
|
||||
#define LIMIT0 0x23 /* Timer 0 limit */
|
||||
#define INT_VECTOR_BASE 0x25
|
||||
#define D_CACHE_BUILD 0x72
|
||||
#define DC_FLDL 0x4c
|
@ -1,57 +0,0 @@
|
||||
/* This file contains code to do profiling.
|
||||
|
||||
Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../asm.h"
|
||||
#include "auxreg.h"
|
||||
/* This file contains code to do profiling. */
|
||||
.weak __profile_timer_cycles
|
||||
.global __profile_timer_cycles
|
||||
.set __profile_timer_cycles, 200
|
||||
.text
|
||||
; For Arctangent-A5, if no data cache is present, a read of the
|
||||
; cache build register returns the ID register. For ARC600 and
|
||||
; later, the version field will be zero.
|
||||
.global __dcache_linesz
|
||||
.balign 4
|
||||
__dcache_linesz:
|
||||
#if !defined (__EM__) && !defined (__HS__)
|
||||
lr r12,[D_CACHE_BUILD]
|
||||
extb_s r0,r12
|
||||
breq_s r0,0,.Lsz_nocache
|
||||
brge r0,0x20,.Lsz_havecache
|
||||
lr r0,[IDENTITY]
|
||||
breq r12,r0,.Lsz_nocache
|
||||
.Lsz_havecache:
|
||||
lsr_s r12,r12,16
|
||||
mov_s r0,16
|
||||
bmsk_s r12,r12,3
|
||||
asl_s r0,r0,r12
|
||||
j_s [blink]
|
||||
.Lsz_nocache:
|
||||
#endif /* !__EM__ && !__HS__ */
|
||||
mov_s r0,1
|
||||
j_s [blink]
|
@ -1,450 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#if 0
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/gmon.h>
|
||||
#include <sys/gmon_out.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if 0
|
||||
#include <libc-internal.h>
|
||||
#include <not-cancel.h>
|
||||
|
||||
#ifdef USE_IN_LIBIO
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
#endif
|
||||
#define internal_function
|
||||
#define weak_alias(fun,aliasid) extern __typeof(fun) aliasid __attribute__ ((weak, alias (#fun)));
|
||||
#define __libc_enable_secure 0
|
||||
|
||||
/* Head of basic-block list or NULL. */
|
||||
struct __bb *__bb_head attribute_hidden;
|
||||
|
||||
struct gmonparam _gmonparam attribute_hidden = { GMON_PROF_OFF };
|
||||
|
||||
/*
|
||||
* See profil(2) where this is described:
|
||||
*/
|
||||
static int s_scale;
|
||||
#define SCALE_1_TO_1 0x10000L
|
||||
|
||||
#define ERR(s) write (STDERR_FILENO, s, sizeof (s) - 1)
|
||||
|
||||
void moncontrol (int mode);
|
||||
void __moncontrol (int mode);
|
||||
static void write_hist (int fd) internal_function;
|
||||
static void write_call_graph (int fd) internal_function;
|
||||
static void write_bb_counts (int fd) internal_function;
|
||||
|
||||
/*
|
||||
* Control profiling
|
||||
* profiling is what mcount checks to see if
|
||||
* all the data structures are ready.
|
||||
*/
|
||||
void
|
||||
__moncontrol (int mode)
|
||||
{
|
||||
struct gmonparam *p = &_gmonparam;
|
||||
|
||||
/* Don't change the state if we ran into an error. */
|
||||
if (p->state == GMON_PROF_ERROR)
|
||||
return;
|
||||
|
||||
if (mode)
|
||||
{
|
||||
/* start */
|
||||
__profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
|
||||
p->state = GMON_PROF_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* stop */
|
||||
__profil(NULL, 0, 0, 0);
|
||||
p->state = GMON_PROF_OFF;
|
||||
}
|
||||
}
|
||||
weak_alias (__moncontrol, moncontrol)
|
||||
|
||||
|
||||
void
|
||||
__monstartup (u_long lowpc, u_long highpc)
|
||||
{
|
||||
register int o;
|
||||
char *cp;
|
||||
struct gmonparam *p = &_gmonparam;
|
||||
int linesz;
|
||||
|
||||
/*
|
||||
* round lowpc and highpc to multiples of the density we're using
|
||||
* so the rest of the scaling (here and in gprof) stays in ints.
|
||||
*/
|
||||
p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||
if (sizeof *p->froms % sizeof(HISTCOUNTER) != 0)
|
||||
{
|
||||
p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||
p->textsize = p->highpc - p->lowpc;
|
||||
p->kcountsize = ROUNDUP((p->textsize + HISTFRACTION - 1) / HISTFRACTION,
|
||||
sizeof (*p->froms));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Avoid odd scales by rounding up highpc to get kcountsize rounded. */
|
||||
p->textsize = ROUNDUP (highpc - p->lowpc,
|
||||
HISTFRACTION * sizeof (*p->froms));
|
||||
p->highpc = p->lowpc + p->textsize;
|
||||
p->kcountsize = p->textsize / HISTFRACTION;
|
||||
}
|
||||
p->hashfraction = HASHFRACTION;
|
||||
p->log_hashfraction = -1;
|
||||
/* The following test must be kept in sync with the corresponding
|
||||
test in mcount.c. */
|
||||
if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) {
|
||||
/* if HASHFRACTION is a power of two, mcount can use shifting
|
||||
instead of integer division. Precompute shift amount. */
|
||||
p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1;
|
||||
}
|
||||
p->tolimit = p->textsize * ARCDENSITY / 100;
|
||||
if (p->tolimit < MINARCS)
|
||||
p->tolimit = MINARCS;
|
||||
else if (p->tolimit > MAXARCS)
|
||||
p->tolimit = MAXARCS;
|
||||
p->tossize = p->tolimit * sizeof(struct tostruct);
|
||||
|
||||
/* p->kcount must not share cache lines with the adjacent data, because
|
||||
we use uncached accesses while profiling. */
|
||||
linesz = __dcache_linesz ();
|
||||
cp = calloc (ROUNDUP (p->kcountsize, linesz) + p->tossize
|
||||
+ (linesz - 1), 1);
|
||||
if (! cp)
|
||||
{
|
||||
ERR("monstartup: out of memory\n");
|
||||
p->tos = NULL;
|
||||
p->state = GMON_PROF_ERROR;
|
||||
/* In case we loose the error state due to a race,
|
||||
prevent invalid writes also by clearing tolimit. */
|
||||
p->tolimit = 0;
|
||||
return;
|
||||
}
|
||||
p->tos = (struct tostruct *)cp;
|
||||
cp += p->tossize;
|
||||
cp = (char *) ROUNDUP ((ptrdiff_t) cp, linesz);
|
||||
p->kcount = (HISTCOUNTER *)cp;
|
||||
cp += ROUNDUP (p->kcountsize, linesz);
|
||||
|
||||
p->tos[0].link = 0;
|
||||
|
||||
o = p->highpc - p->lowpc;
|
||||
if (p->kcountsize < (u_long) o)
|
||||
{
|
||||
#ifndef hp300
|
||||
s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1;
|
||||
#else
|
||||
/* avoid floating point operations */
|
||||
int quot = o / p->kcountsize;
|
||||
|
||||
if (quot >= 0x10000)
|
||||
s_scale = 1;
|
||||
else if (quot >= 0x100)
|
||||
s_scale = 0x10000 / quot;
|
||||
else if (o >= 0x800000)
|
||||
s_scale = 0x1000000 / (o / (p->kcountsize >> 8));
|
||||
else
|
||||
s_scale = 0x1000000 / ((o << 8) / p->kcountsize);
|
||||
#endif
|
||||
} else
|
||||
s_scale = SCALE_1_TO_1;
|
||||
|
||||
__moncontrol(1);
|
||||
}
|
||||
weak_alias (__monstartup, monstartup)
|
||||
|
||||
|
||||
static void
|
||||
internal_function
|
||||
write_hist (int fd)
|
||||
{
|
||||
u_char tag = GMON_TAG_TIME_HIST;
|
||||
struct arc_gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *))));
|
||||
int r;
|
||||
|
||||
if (_gmonparam.kcountsize > 0)
|
||||
{
|
||||
*(char **) thdr.low_pc = (char *) _gmonparam.lowpc;
|
||||
*(char **) thdr.high_pc = (char *) _gmonparam.highpc;
|
||||
*(int32_t *) thdr.hist_size = (_gmonparam.kcountsize
|
||||
/ sizeof (HISTCOUNTER));
|
||||
*(int32_t *) thdr.prof_rate = __profile_frequency ();
|
||||
strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen));
|
||||
thdr.dimen_abbrev = 's';
|
||||
|
||||
r = write (fd, &tag, sizeof tag);
|
||||
if (r != sizeof tag)
|
||||
return;
|
||||
r = write (fd, &thdr, sizeof thdr);
|
||||
if (r != sizeof thdr)
|
||||
return;
|
||||
r = write (fd,_gmonparam.kcount, _gmonparam.kcountsize);
|
||||
if ((unsigned) r != _gmonparam.kcountsize)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
internal_function
|
||||
write_call_graph (int fd)
|
||||
{
|
||||
#define NARCS_PER_WRITE 64
|
||||
#define BYTES_PER_ARC (1 + sizeof (struct gmon_cg_arc_record))
|
||||
#define BYTES_PER_WRITE (BYTES_PER_ARC * NARCS_PER_WRITE)
|
||||
ARCINDEX to_index;
|
||||
u_long frompc, selfpc, count;
|
||||
char buffer[BYTES_PER_WRITE], *p;
|
||||
u_long *prof_desc = __arc_profile_desc_secstart;
|
||||
u_long *prof_count = __arc_profile_counters_secstart;
|
||||
u_long *prof_desc_end = __arc_profile_desc_secend;
|
||||
u_long *prof_forward = __arc_profile_forward_secstart;
|
||||
|
||||
for (p = buffer; p < buffer + BYTES_PER_WRITE; p += BYTES_PER_ARC)
|
||||
*p = GMON_TAG_CG_ARC;
|
||||
p = buffer;
|
||||
frompc = *prof_desc++ & -2;
|
||||
while (prof_desc < prof_desc_end)
|
||||
{
|
||||
selfpc = *prof_desc++;
|
||||
if (selfpc & 1)
|
||||
{
|
||||
frompc = selfpc & -2;
|
||||
selfpc = *prof_desc++;
|
||||
}
|
||||
count = *prof_count++;
|
||||
if (selfpc)
|
||||
{
|
||||
struct arc
|
||||
{
|
||||
char *frompc;
|
||||
char *selfpc;
|
||||
int32_t count;
|
||||
}
|
||||
arc;
|
||||
|
||||
if (!count)
|
||||
continue;
|
||||
arc.frompc = (char *) frompc;
|
||||
arc.selfpc = (char *) selfpc;
|
||||
arc.count = count;
|
||||
memcpy (p + 1, &arc, sizeof arc);
|
||||
p += 1 + sizeof arc;
|
||||
|
||||
if (p == buffer + BYTES_PER_WRITE)
|
||||
{
|
||||
write (fd, buffer, BYTES_PER_WRITE);
|
||||
p = buffer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (to_index = count;
|
||||
to_index != 0;
|
||||
to_index = _gmonparam.tos[to_index].link)
|
||||
{
|
||||
struct arc
|
||||
{
|
||||
char *frompc;
|
||||
char *selfpc;
|
||||
int32_t count;
|
||||
}
|
||||
arc;
|
||||
|
||||
arc.frompc = (char *) frompc;
|
||||
arc.selfpc = (char *) _gmonparam.tos[to_index].selfpc;
|
||||
arc.count = _gmonparam.tos[to_index].count;
|
||||
memcpy (p + 1, &arc, sizeof arc);
|
||||
p += 1 + sizeof arc;
|
||||
|
||||
if (p == buffer + BYTES_PER_WRITE)
|
||||
{
|
||||
write (fd, buffer, BYTES_PER_WRITE);
|
||||
p = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (prof_forward < __arc_profile_forward_secend)
|
||||
{
|
||||
/* ??? The 'call count' is actually supposed to be a fixed point
|
||||
factor, with 16 bits each before and after the point.
|
||||
It would be much nicer if we figured out the actual number
|
||||
of calls to the caller, and multiplied that with the fixed point
|
||||
factor to arrive at the estimated calls for the callee. */
|
||||
memcpy (p + 1, prof_forward, 3 * sizeof *prof_forward);
|
||||
prof_forward += 3;
|
||||
p += 1 + 3 * sizeof *prof_forward;
|
||||
if (p == buffer + BYTES_PER_WRITE)
|
||||
{
|
||||
write (fd, buffer, BYTES_PER_WRITE);
|
||||
p = buffer;
|
||||
}
|
||||
}
|
||||
if (p != buffer)
|
||||
write (fd, buffer, p - buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
internal_function
|
||||
write_bb_counts (int fd)
|
||||
{
|
||||
struct __bb *grp;
|
||||
u_char tag = GMON_TAG_BB_COUNT;
|
||||
size_t ncounts;
|
||||
size_t i;
|
||||
|
||||
struct { unsigned long address; long count; } bbbody[8];
|
||||
size_t nfilled;
|
||||
|
||||
/* Write each group of basic-block info (all basic-blocks in a
|
||||
compilation unit form a single group). */
|
||||
|
||||
for (grp = __bb_head; grp; grp = grp->next)
|
||||
{
|
||||
ncounts = grp->ncounts;
|
||||
write (fd, &tag, 1);
|
||||
write (fd, &ncounts, sizeof ncounts);
|
||||
for (nfilled = i = 0; i < ncounts; ++i)
|
||||
{
|
||||
if (nfilled == sizeof (bbbody) / sizeof (bbbody[0]))
|
||||
{
|
||||
write (fd, bbbody, sizeof bbbody);
|
||||
nfilled = 0;
|
||||
}
|
||||
|
||||
bbbody[nfilled].address = grp->addresses[i];
|
||||
bbbody[nfilled++].count = grp->counts[i];
|
||||
}
|
||||
if (nfilled > 0)
|
||||
write (fd, bbbody, nfilled * sizeof bbbody[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_gmon (void)
|
||||
{
|
||||
struct gmon_hdr ghdr __attribute__ ((aligned (__alignof__ (int))));
|
||||
int fd = -1;
|
||||
char *env;
|
||||
|
||||
#ifndef O_NOFOLLOW
|
||||
# define O_NOFOLLOW 0
|
||||
#endif
|
||||
|
||||
env = getenv ("GMON_OUT_PREFIX");
|
||||
if (env != NULL && !__libc_enable_secure)
|
||||
{
|
||||
size_t len = strlen (env);
|
||||
char buf[len + 20];
|
||||
snprintf (buf, sizeof (buf), "%s.%u", env, getpid ());
|
||||
fd = open (buf, O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW, 0666);
|
||||
}
|
||||
|
||||
if (fd == -1)
|
||||
{
|
||||
fd = open ("gmon.out", O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW,
|
||||
0666);
|
||||
if (fd < 0)
|
||||
{
|
||||
perror ("_mcleanup: gmon.out");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* write gmon.out header: */
|
||||
memset (&ghdr, '\0', sizeof (struct gmon_hdr));
|
||||
memcpy (&ghdr.cookie[0], GMON_MAGIC, sizeof (ghdr.cookie));
|
||||
*(int32_t *) ghdr.version = GMON_VERSION;
|
||||
write (fd, &ghdr, sizeof (struct gmon_hdr));
|
||||
|
||||
/* write PC histogram: */
|
||||
write_hist (fd);
|
||||
|
||||
/* write call-graph: */
|
||||
write_call_graph (fd);
|
||||
|
||||
/* write basic-block execution counts: */
|
||||
write_bb_counts (fd);
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__write_profiling (void)
|
||||
{
|
||||
int save = _gmonparam.state;
|
||||
_gmonparam.state = GMON_PROF_OFF;
|
||||
if (save == GMON_PROF_ON)
|
||||
write_gmon ();
|
||||
_gmonparam.state = save;
|
||||
}
|
||||
#ifndef SHARED
|
||||
/* This symbol isn't used anywhere in the DSO and it is not exported.
|
||||
This would normally mean it should be removed to get the same API
|
||||
in static libraries. But since profiling is special in static libs
|
||||
anyway we keep it. But not when building the DSO since some
|
||||
quality assurance tests will otherwise trigger. */
|
||||
weak_alias (__write_profiling, write_profiling)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
_mcleanup (void)
|
||||
{
|
||||
__moncontrol (0);
|
||||
|
||||
if (_gmonparam.state != GMON_PROF_ERROR)
|
||||
write_gmon ();
|
||||
|
||||
/* free the memory. */
|
||||
if (_gmonparam.tos != NULL)
|
||||
free (_gmonparam.tos);
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef MACHINE_GMON_H
|
||||
#define MACHINE_GMON_H
|
||||
|
||||
/* We can't fake out own <sys/types.h> header because the newlib / uclibc
|
||||
headers in GCC_FOR_TARGET take precedence. */
|
||||
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
|
||||
#define __THROW
|
||||
|
||||
extern int __dcache_linesz (void);
|
||||
|
||||
#define _MCOUNT_DECL(countp, selfpc) \
|
||||
static inline void _mcount_internal (void *countp, u_long selfpc)
|
||||
|
||||
extern void _mcount (void);
|
||||
extern void _mcount_call (void);
|
||||
|
||||
/* N.B.: the calling point might be a sibcall, thus blink does not necessarily
|
||||
hold the caller's address. r8 doesn't hold the caller's address, either,
|
||||
but rather a pointer to the counter data structure associated with the
|
||||
caller.
|
||||
This function must be compiled with optimization turned on in order to
|
||||
enable a sibcall for the final call to selfpc; this is important when trying
|
||||
to profile a program with deep tail-recursion that would get a stack
|
||||
overflow otherwise. */
|
||||
#define MCOUNT \
|
||||
void \
|
||||
_mcount_call (void) \
|
||||
{ \
|
||||
register void *countp __asm("r8"); \
|
||||
register u_long selfpc __asm("r9"); \
|
||||
_mcount_internal (countp, selfpc); \
|
||||
((void (*)(void)) selfpc) (); \
|
||||
}
|
||||
|
||||
extern int __profil (u_short *,size_t, size_t, u_int);
|
||||
|
||||
#endif /* MACHINE_GMON_H */
|
@ -1,206 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(lint) && !defined(KERNEL) && defined(LIBC_SCCS)
|
||||
static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include <sys/gmon.h>
|
||||
|
||||
/* This file provides the machine-dependent definitions of the _MCOUNT_DECL
|
||||
and MCOUNT macros. */
|
||||
#include <machine-gmon.h>
|
||||
|
||||
#include <atomic.h>
|
||||
|
||||
/*
|
||||
* mcount is called on entry to each function compiled with the profiling
|
||||
* switch set. _mcount(), which is declared in a machine-dependent way
|
||||
* with _MCOUNT_DECL, does the actual work and is either inlined into a
|
||||
* C routine or called by an assembly stub. In any case, this magic is
|
||||
* taken care of by the MCOUNT definition in <machine/profile.h>.
|
||||
*
|
||||
* _mcount updates data structures that represent traversals of the
|
||||
* program's call graph edges. frompc and selfpc are the return
|
||||
* address and function address that represents the given call graph edge.
|
||||
*
|
||||
* Note: the original BSD code used the same variable (frompcindex) for
|
||||
* both frompcindex and frompc. Any reasonable, modern compiler will
|
||||
* perform this optimization.
|
||||
*/
|
||||
_MCOUNT_DECL(count_ptr, selfpc) /* _mcount; may be static, inline, etc */
|
||||
{
|
||||
register ARCINDEX *frompcindex;
|
||||
register struct tostruct *top, *prevtop;
|
||||
register struct gmonparam *p;
|
||||
register ARCINDEX toindex;
|
||||
|
||||
/* Check for nested function trampoline. */
|
||||
if (selfpc & 2)
|
||||
selfpc = *(u_long *) (selfpc + 10);
|
||||
|
||||
p = &_gmonparam;
|
||||
/*
|
||||
* check that we are profiling
|
||||
* and that we aren't recursively invoked.
|
||||
*/
|
||||
#if 0
|
||||
if (catomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY,
|
||||
GMON_PROF_ON))
|
||||
return;
|
||||
#elif defined (__ARC700__)
|
||||
/* ??? This could temporarily lose the ERROR / OFF condition in a race,
|
||||
but doing an actual compare_and_exchange would be too costly. It would
|
||||
be better if we had a semaphore independent of the 'sticky' state, but
|
||||
then we could run into ABI compatibility problems with the size of struct
|
||||
gmonparam. */
|
||||
{
|
||||
u_long old_state;
|
||||
|
||||
__asm ("ex %0,%1": "=r" (old_state), "+m" (p->state)
|
||||
: "0" (GMON_PROF_BUSY));
|
||||
if (old_state != GMON_PROF_ON)
|
||||
{
|
||||
switch (old_state)
|
||||
{
|
||||
case GMON_PROF_OFF:
|
||||
__asm ("ex %0,%1": "+r" (old_state), "+m" (p->state));
|
||||
if (old_state == GMON_PROF_BUSY
|
||||
/* Switching off while we say we are busy while profiling
|
||||
was actually already switched off is all right. */
|
||||
|| old_state == GMON_PROF_OFF)
|
||||
break;
|
||||
/* It is not clear if we should allow switching on
|
||||
profiling at this point, and how to handle further races.
|
||||
For now, record an error in this case. */
|
||||
/* Fall through. */
|
||||
default: /* We expect here only GMON_PROF_ERROR. */
|
||||
p->state = GMON_PROF_ERROR;
|
||||
break;
|
||||
case GMON_PROF_BUSY: break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else /* ??? No semaphore primitives available. */
|
||||
if (p->state != GMON_PROF_ON)
|
||||
return;
|
||||
p->state = GMON_PROF_BUSY;
|
||||
#endif
|
||||
|
||||
frompcindex = count_ptr;
|
||||
toindex = *frompcindex;
|
||||
if (toindex == 0) {
|
||||
/*
|
||||
* first time traversing this arc
|
||||
*/
|
||||
toindex = ++p->tos[0].link;
|
||||
if (toindex >= (ARCINDEX) p->tolimit)
|
||||
/* halt further profiling */
|
||||
goto overflow;
|
||||
|
||||
*frompcindex = toindex;
|
||||
top = &p->tos[toindex];
|
||||
top->selfpc = selfpc;
|
||||
top->count = 1;
|
||||
top->link = 0;
|
||||
goto done;
|
||||
}
|
||||
top = &p->tos[toindex];
|
||||
if (top->selfpc == selfpc) {
|
||||
/*
|
||||
* arc at front of chain; usual case.
|
||||
*/
|
||||
top->count++;
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* have to go looking down chain for it.
|
||||
* top points to what we are looking at,
|
||||
* prevtop points to previous top.
|
||||
* we know it is not at the head of the chain.
|
||||
*/
|
||||
for (; /* goto done */; ) {
|
||||
if (top->link == 0) {
|
||||
/*
|
||||
* top is end of the chain and none of the chain
|
||||
* had top->selfpc == selfpc.
|
||||
* so we allocate a new tostruct
|
||||
* and link it to the head of the chain.
|
||||
*/
|
||||
toindex = ++p->tos[0].link;
|
||||
if (toindex >= (ARCINDEX) p->tolimit)
|
||||
goto overflow;
|
||||
|
||||
top = &p->tos[toindex];
|
||||
top->selfpc = selfpc;
|
||||
top->count = 1;
|
||||
top->link = *frompcindex;
|
||||
*frompcindex = toindex;
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* otherwise, check the next arc on the chain.
|
||||
*/
|
||||
prevtop = top;
|
||||
top = &p->tos[top->link];
|
||||
if (top->selfpc == selfpc) {
|
||||
/*
|
||||
* there it is.
|
||||
* increment its count
|
||||
* move it to the head of the chain.
|
||||
*/
|
||||
top->count++;
|
||||
toindex = prevtop->link;
|
||||
prevtop->link = top->link;
|
||||
top->link = *frompcindex;
|
||||
*frompcindex = toindex;
|
||||
goto done;
|
||||
}
|
||||
|
||||
}
|
||||
done:
|
||||
p->state = GMON_PROF_ON;
|
||||
return;
|
||||
overflow:
|
||||
p->state = GMON_PROF_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Actual definition of mcount function. Defined in <machine/profile.h>,
|
||||
* which is included by <sys/gmon.h>.
|
||||
*/
|
||||
MCOUNT
|
@ -1,40 +0,0 @@
|
||||
/* This file contains code to do profiling.
|
||||
|
||||
Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../asm.h"
|
||||
/* This file contains code to do profiling. */
|
||||
.weak __profile_frequency_value
|
||||
.global __profile_frequency_value
|
||||
.set __profile_frequency_value, 1000
|
||||
.text
|
||||
.balign 4
|
||||
.global __profile_frequency
|
||||
FUNC(__profile_frequency)
|
||||
__profile_frequency:
|
||||
mov_s r0,__profile_frequency_value
|
||||
j_s [blink]
|
||||
ENDFUNC(__profile_frequency)
|
@ -1,60 +0,0 @@
|
||||
/* Return frequency of ticks reported by profil. Generic version. */
|
||||
/*-
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#if 0
|
||||
#include <libc-internal.h>
|
||||
#else
|
||||
#include "sys/gmon.h"
|
||||
#endif
|
||||
|
||||
int
|
||||
__profile_frequency (void)
|
||||
{
|
||||
/*
|
||||
* Discover the tick frequency of the machine if something goes wrong,
|
||||
* we return 0, an impossible hertz.
|
||||
*/
|
||||
struct itimerval tim;
|
||||
|
||||
tim.it_interval.tv_sec = 0;
|
||||
tim.it_interval.tv_usec = 1;
|
||||
tim.it_value.tv_sec = 0;
|
||||
tim.it_value.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &tim, 0);
|
||||
setitimer(ITIMER_REAL, 0, &tim);
|
||||
if (tim.it_interval.tv_usec < 2)
|
||||
return 0;
|
||||
return (1000000 / tim.it_interval.tv_usec);
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/* This file contains code to do profiling.
|
||||
|
||||
Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "../asm.h"
|
||||
#include "auxreg.h"
|
||||
/* This file contains code to do profiling. */
|
||||
.weak __profile_timer_cycles
|
||||
.global __profile_timer_cycles
|
||||
.set __profile_timer_cycles, 200
|
||||
|
||||
.section .bss
|
||||
.global __profil_offset
|
||||
.align 4
|
||||
.type __profil_offset, @object
|
||||
.size __profil_offset, 4
|
||||
__profil_offset:
|
||||
.zero 4
|
||||
|
||||
.text
|
||||
.global __dcache_linesz
|
||||
.global __profil
|
||||
FUNC(__profil)
|
||||
#if !defined (__EM__) && !defined (__HS__)
|
||||
.Lstop_profiling:
|
||||
sr r0,[CONTROL0]
|
||||
j_s [blink]
|
||||
.balign 4
|
||||
__profil:
|
||||
.Lprofil:
|
||||
breq_s r0,0,.Lstop_profiling
|
||||
; r0: buf r1: bufsiz r2: offset r3: scale
|
||||
bxor.f r3,r3,15; scale must be 0x8000, i.e. 1/2; generate 0.
|
||||
push_s blink
|
||||
lsr_s r2,r2,1
|
||||
mov_s r8,r0
|
||||
flag.ne 1 ; halt if wrong scale
|
||||
sub_s r0,r0,r2
|
||||
st r0,[__profil_offset]
|
||||
bl __dcache_linesz
|
||||
pop_s blink
|
||||
bbit1.d r0,0,nocache
|
||||
mov_s r0,r8
|
||||
#ifdef __ARC700__
|
||||
add_s r1,r1,31
|
||||
lsr.f lp_count,r1,5
|
||||
lpne 2f
|
||||
sr r0,[DC_FLDL]
|
||||
add_s r0,r0,32
|
||||
#else /* !__ARC700__ */
|
||||
# FIX ME: set up loop according to cache line size
|
||||
lr r12,[D_CACHE_BUILD]
|
||||
sub_s r0,r0,16
|
||||
sub_s r1,r1,1
|
||||
lsr_s r12,r12,16
|
||||
asr_s r1,r1,4
|
||||
bmsk_s r12,r12,3
|
||||
asr_s r1,r1,r12
|
||||
add.f lp_count,r1,1
|
||||
mov_s r1,16
|
||||
asl_s r1,r1,r12
|
||||
lpne 2f
|
||||
add r0,r0,r1
|
||||
sr r0,[DC_FLDL]
|
||||
#endif /* __ARC700__ */
|
||||
2: b_s .Lcounters_cleared
|
||||
nocache:
|
||||
.Lcounters_cleared:
|
||||
lr r1,[INT_VECTOR_BASE] ; disable timer0 interrupts
|
||||
sr r3,[CONTROL0]
|
||||
sr r3,[COUNT0]
|
||||
0: ld_s r0,[pcl,1f-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF
|
||||
0: ld_s r12,[pcl,1f+4-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF + 4
|
||||
st_s r0,[r1,24]; timer0 uses vector3
|
||||
st_s r12,[r1,24+4]; timer0 uses vector3
|
||||
;sr 10000,[LIMIT0]
|
||||
sr __profile_timer_cycles,[LIMIT0]
|
||||
mov_s r12,3 ; enable timer interrupts; count only when not halted.
|
||||
sr r12,[CONTROL0]
|
||||
lr r12,[STATUS32]
|
||||
bset_s r12,r12,1 ; allow level 1 interrupts
|
||||
flag r12
|
||||
mov_s r0,0
|
||||
j_s [blink]
|
||||
.balign 4
|
||||
1: j __profil_irq
|
||||
#else
|
||||
__profil:
|
||||
.balign 4
|
||||
mov_s r0,-1
|
||||
j_s [blink]
|
||||
#endif /* !__EM__ && !__HS__ */
|
||||
ENDFUNC(__profil)
|
||||
|
||||
FUNC(__profil_irq)
|
||||
.balign 4 ; make final jump unaligned to avoid delay penalty
|
||||
.balign 32,0,12 ; make sure the code spans no more that two cache lines
|
||||
nop_s
|
||||
__profil_irq:
|
||||
#if !defined (__EM__) && !defined (__HS__)
|
||||
push_s r0
|
||||
ld r0,[__profil_offset]
|
||||
push_s r1
|
||||
lsr r1,ilink1,2
|
||||
push_s r2
|
||||
ldw.as.di r2,[r0,r1]
|
||||
add1 r0,r0,r1
|
||||
ld_s r1,[sp,4]
|
||||
add_s r2,r2,1
|
||||
bbit1 r2,16,nostore
|
||||
stw.di r2,[r0]
|
||||
nostore:ld.ab r2,[sp,8]
|
||||
pop_s r0
|
||||
j.f [ilink1]
|
||||
#else
|
||||
rtie
|
||||
#endif /* !__EM__ && !__HS__ */
|
||||
ENDFUNC(__profil_irq)
|
||||
|
||||
; could save one cycle if the counters were allocated at link time and
|
||||
; the contents of __profil_offset were pre-computed at link time, like this:
|
||||
#if 0
|
||||
; __profil_offset needs to be PROVIDEd as __profile_base-text/4
|
||||
.global __profil_offset
|
||||
.balign 4
|
||||
__profil_irq:
|
||||
push_s r0
|
||||
lsr r0,ilink1,2
|
||||
add1 r0,__profil_offset,r0
|
||||
push_s r1
|
||||
ldw.di r1,[r0]
|
||||
|
||||
|
||||
add_s r1,r1,1
|
||||
bbit1 r1,16,nostore
|
||||
stw.di r1,[r0]
|
||||
nostore:pop_s r1
|
||||
pop_s r0
|
||||
j [ilink1]
|
||||
#endif /* 0 */
|
@ -1,217 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)gmon.h 8.2 (Berkeley) 1/4/94
|
||||
*/
|
||||
|
||||
#ifndef _SYS_GMON_H
|
||||
#define _SYS_GMON_H 1
|
||||
|
||||
#if 0
|
||||
#include <features.h>
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include "machine-gmon.h"
|
||||
#define attribute_hidden __attribute__ ((visibility("hidden")))
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* See gmon_out.h for gmon.out format.
|
||||
*/
|
||||
|
||||
/* structure emitted by "gcc -a". This must match struct bb in
|
||||
gcc/libgcc2.c. It is OK for gcc to declare a longer structure as
|
||||
long as the members below are present. */
|
||||
struct __bb
|
||||
{
|
||||
long zero_word;
|
||||
const char *filename;
|
||||
long *counts;
|
||||
long ncounts;
|
||||
struct __bb *next;
|
||||
const unsigned long *addresses;
|
||||
};
|
||||
|
||||
extern struct __bb *__bb_head;
|
||||
|
||||
/*
|
||||
* histogram counters are unsigned shorts (according to the kernel).
|
||||
*/
|
||||
#define HISTCOUNTER unsigned short
|
||||
|
||||
/*
|
||||
* fraction of text space to allocate for histogram counters here, 1/2
|
||||
*/
|
||||
#define HISTFRACTION 2
|
||||
|
||||
/*
|
||||
* Fraction of text space to allocate for from hash buckets.
|
||||
* The value of HASHFRACTION is based on the minimum number of bytes
|
||||
* of separation between two subroutine call points in the object code.
|
||||
* Given MIN_SUBR_SEPARATION bytes of separation the value of
|
||||
* HASHFRACTION is calculated as:
|
||||
*
|
||||
* HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
|
||||
*
|
||||
* For example, on the VAX, the shortest two call sequence is:
|
||||
*
|
||||
* calls $0,(r0)
|
||||
* calls $0,(r0)
|
||||
*
|
||||
* which is separated by only three bytes, thus HASHFRACTION is
|
||||
* calculated as:
|
||||
*
|
||||
* HASHFRACTION = 3 / (2 * 2 - 1) = 1
|
||||
*
|
||||
* Note that the division above rounds down, thus if MIN_SUBR_FRACTION
|
||||
* is less than three, this algorithm will not work!
|
||||
*
|
||||
* In practice, however, call instructions are rarely at a minimal
|
||||
* distance. Hence, we will define HASHFRACTION to be 2 across all
|
||||
* architectures. This saves a reasonable amount of space for
|
||||
* profiling data structures without (in practice) sacrificing
|
||||
* any granularity.
|
||||
*/
|
||||
#define HASHFRACTION 2
|
||||
|
||||
/*
|
||||
* Percent of text space to allocate for tostructs.
|
||||
* This is a heuristic; we will fail with a warning when profiling programs
|
||||
* with a very large number of very small functions, but that's
|
||||
* normally OK.
|
||||
* 2 is probably still a good value for normal programs.
|
||||
* Profiling a test case with 64000 small functions will work if
|
||||
* you raise this value to 3 and link statically (which bloats the
|
||||
* text size, thus raising the number of arcs expected by the heuristic).
|
||||
*/
|
||||
#define ARCDENSITY 3
|
||||
|
||||
/*
|
||||
* Always allocate at least this many tostructs. This
|
||||
* hides the inadequacy of the ARCDENSITY heuristic, at least
|
||||
* for small programs.
|
||||
*/
|
||||
#define MINARCS 50
|
||||
|
||||
/*
|
||||
* The type used to represent indices into gmonparam.tos[].
|
||||
*/
|
||||
#define ARCINDEX u_long
|
||||
|
||||
/*
|
||||
* Maximum number of arcs we want to allow.
|
||||
* Used to be max representable value of ARCINDEX minus 2, but now
|
||||
* that ARCINDEX is a long, that's too large; we don't really want
|
||||
* to allow a 48 gigabyte table.
|
||||
* The old value of 1<<16 wasn't high enough in practice for large C++
|
||||
* programs; will 1<<20 be adequate for long? FIXME
|
||||
*/
|
||||
#define MAXARCS (1 << 20)
|
||||
|
||||
struct tostruct {
|
||||
u_long selfpc;
|
||||
long count;
|
||||
ARCINDEX link;
|
||||
};
|
||||
|
||||
/*
|
||||
* a raw arc, with pointers to the calling site and
|
||||
* the called site and a count.
|
||||
*/
|
||||
struct rawarc {
|
||||
u_long raw_frompc;
|
||||
u_long raw_selfpc;
|
||||
long raw_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* general rounding functions.
|
||||
*/
|
||||
#define ROUNDDOWN(x,y) (((x)/(y))*(y))
|
||||
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
|
||||
|
||||
/*
|
||||
* The profiling data structures are housed in this structure.
|
||||
*/
|
||||
struct gmonparam {
|
||||
long int state;
|
||||
u_short *kcount;
|
||||
u_long kcountsize;
|
||||
ARCINDEX *froms;
|
||||
u_long fromssize;
|
||||
struct tostruct *tos;
|
||||
u_long tossize;
|
||||
long tolimit;
|
||||
u_long lowpc;
|
||||
u_long highpc;
|
||||
u_long textsize;
|
||||
u_long hashfraction;
|
||||
long log_hashfraction;
|
||||
};
|
||||
extern struct gmonparam _gmonparam;
|
||||
|
||||
/*
|
||||
* Possible states of profiling.
|
||||
*/
|
||||
#define GMON_PROF_ON 0
|
||||
#define GMON_PROF_BUSY 1
|
||||
#define GMON_PROF_ERROR 2
|
||||
#define GMON_PROF_OFF 3
|
||||
|
||||
/*
|
||||
* Sysctl definitions for extracting profiling information from the kernel.
|
||||
*/
|
||||
#define GPROF_STATE 0 /* int: profiling enabling variable */
|
||||
#define GPROF_COUNT 1 /* struct: profile tick count buffer */
|
||||
#define GPROF_FROMS 2 /* struct: from location hash bucket */
|
||||
#define GPROF_TOS 3 /* struct: destination/count structure */
|
||||
#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* Set up data structures and start profiling. */
|
||||
extern void __monstartup (u_long __lowpc, u_long __highpc) __THROW;
|
||||
extern void monstartup (u_long __lowpc, u_long __highpc) __THROW;
|
||||
|
||||
/* Clean up profiling and write out gmon.out. */
|
||||
extern void _mcleanup (void) __THROW;
|
||||
|
||||
extern void __write_profiling (void);
|
||||
extern int attribute_hidden __profile_frequency (void);
|
||||
|
||||
extern u_long __arc_profile_desc_secstart[], __arc_profile_desc_secend[];
|
||||
extern u_long __arc_profile_forward_secstart[], __arc_profile_forward_secend[];
|
||||
extern u_long __arc_profile_counters_secstart[];
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* sys/gmon.h */
|
@ -1,55 +0,0 @@
|
||||
/* Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
on behalf of Synopsys Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
Under Section 7 of GPL version 3, you are granted additional
|
||||
permissions described in the GCC Runtime Library Exception, version
|
||||
3.1, as published by the Free Software Foundation.
|
||||
|
||||
You should have received a copy of the GNU General Public License and
|
||||
a copy of the GCC Runtime Library Exception along with this program;
|
||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define GMON_TAG_TIME_HIST 0
|
||||
#define GMON_TAG_CG_ARC 1
|
||||
#define GMON_TAG_BB_COUNT 2
|
||||
|
||||
#define GMON_MAGIC "gmon"
|
||||
#define GMON_VERSION 1
|
||||
|
||||
struct arc_gmon_hist_hdr
|
||||
{
|
||||
char low_pc[4];
|
||||
char high_pc[4];
|
||||
char hist_size[4];
|
||||
char prof_rate[4];
|
||||
char dimen[15];
|
||||
char dimen_abbrev;
|
||||
};
|
||||
|
||||
struct gmon_cg_arc_record
|
||||
{
|
||||
char afrompc[4];
|
||||
char selfpc[4];
|
||||
char count[4];
|
||||
};
|
||||
|
||||
struct gmon_hdr
|
||||
{
|
||||
char cookie[4];
|
||||
char version[4];
|
||||
char c[12];
|
||||
};
|
@ -62,42 +62,5 @@ fp-bit.c: $(srcdir)/fp-bit.c
|
||||
|
||||
# .init/.fini section routines
|
||||
|
||||
crtg.o: $(srcdir)/config/arc/crtg.S
|
||||
$(crt_compile) -c -x assembler-with-cpp $<
|
||||
|
||||
crtgend.o: $(srcdir)/config/arc/crtgend.S
|
||||
$(crt_compile) -c -x assembler-with-cpp $<
|
||||
|
||||
crttls.o: $(srcdir)/config/arc/crttls.S
|
||||
$(crt_compile) -c -x assembler-with-cpp $<
|
||||
|
||||
mcount.o: $(srcdir)/config/arc/gmon/mcount.c
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< \
|
||||
-fcall-saved-r0 -fcall-saved-r1 -fcall-saved-r2 -fcall-saved-r3 \
|
||||
-fcall-saved-r4 -fcall-saved-r5 -fcall-saved-r6 -fcall-saved-r7 \
|
||||
-fomit-frame-pointer
|
||||
|
||||
gmon.o: $(srcdir)/config/arc/gmon/gmon.c
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -mno-sdata -c $< \
|
||||
-fno-strict-aliasing \
|
||||
-Wno-extra # suppress inane warning about missing initializer.
|
||||
# Adding initializers for the remaining elements of gmonparam would
|
||||
# make the code more brittle.
|
||||
|
||||
prof-freq-stub.o: $(srcdir)/config/arc/gmon/prof-freq-stub.S
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $<
|
||||
|
||||
prof-freq.o: $(srcdir)/config/arc/gmon/prof-freq.c
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $<
|
||||
|
||||
dcache_linesz.o: $(srcdir)/config/arc/gmon/dcache_linesz.S
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $<
|
||||
|
||||
profil.o: $(srcdir)/config/arc/gmon/profil.S
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $<
|
||||
|
||||
profil-uclibc.o: $(srcdir)/config/arc/gmon/profil-uclibc.c
|
||||
$(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $<
|
||||
|
||||
libgmon.a: mcount.o gmon.o dcache_linesz.o $(PROFILE_OSDEP)
|
||||
$(AR_CREATE_FOR_TARGET) $@ $^
|
||||
|
@ -1,22 +0,0 @@
|
||||
# GCC Makefile fragment for the Synopsys DesignWare ARC CPU with newlib.
|
||||
|
||||
# Copyright (C) 2007-2016 Free Software Foundation, Inc.
|
||||
# Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
|
||||
# on behalf of Synopsys Inc.
|
||||
|
||||
# This file is part of GCC.
|
||||
|
||||
# GCC is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3, or (at your option) any later version.
|
||||
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
PROFILE_OSDEP = prof-freq-stub.o profil.o
|
@ -33,8 +33,6 @@ CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
|
||||
# Compile libgcc2.a with pic.
|
||||
TARGET_LIBGCC2_CFLAGS = -fPIC
|
||||
|
||||
PROFILE_OSDEP = prof-freq.o
|
||||
|
||||
# Override t-slibgcc-elf-ver to hide some lib1func
|
||||
# routines which should not be called via PLT.
|
||||
SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/arc/libgcc-excl.ver
|
Loading…
x
Reference in New Issue
Block a user