[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:
Claudiu Zissulescu 2016-12-16 13:56:21 +01:00 committed by Claudiu Zissulescu
parent d476b53c36
commit e04ea1daa9
25 changed files with 66 additions and 1736 deletions

View File

@ -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,

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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);
}"

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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. */

View File

@ -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

View File

@ -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]

View File

@ -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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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];
};

View File

@ -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) $@ $^

View File

@ -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

View File

@ -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