Skip to content

Commit c52b7ec

Browse files
committed
arc: Update PROFILE_HOOK to support Linux's ftrace
Ftrace is a Linux internal tracer which helps developers to find what is going on inisde the kernel. The way this works is the _mcount function call (placed at the start of every kernel function, produced by the -pg switch in gcc), starts of pointing to a simple return in the stack. The ARCv2 ABI does not enable us to perform full function tracing (aka ftrace_graph with entry and exit) due to the fact that the blink (return address) is pushed first on the stack. However, providing the location of blink in the current stack enables some ftrace capabilities. This patch updates the ARC's profile hook for Linux targets, by providing two arguments to `_mcount` profile function. First argument is blink value, and the second argument is the blink location in the current function stack. As PROFILE_HOOK is called in the expand, and the stack layout is known after register allocation, we use an unspec to mark the mcount second argument move which needs to be updated latter on. gcc/ * config/arc/arc-protos.h (arc_get_arg_ptr): Declare. (arc_profile_hook): Likewise. * config/arc/arc.cc (arc_profile_hook): New function. (arc_get_arg_ptr): Likewise. * config/arc/arc.md (UNSPEC_ARC_MCOUNT): New define. (mcount_stack): New pattern. * config/arc/linux.h (PROFILE_HOOK): Update hook. Signed-off-by: Claudiu Zissulescu <claziss@gmail.com>
1 parent 4305c12 commit c52b7ec

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

gcc/config/arc/arc-protos.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ extern bool arc_check_mov_const (HOST_WIDE_INT );
5050
extern bool arc_split_mov_const (rtx *);
5151
extern bool arc_can_use_return_insn (void);
5252
extern bool arc_split_move_p (rtx *);
53+
extern unsigned int arc_get_arg_ptr (void);
5354
#endif /* RTX_CODE */
5455

5556

@@ -97,5 +98,6 @@ extern void arc_eh_return_address_location (rtx);
9798
extern bool arc_is_jli_call_p (rtx);
9899
extern void arc_file_end (void);
99100
extern bool arc_is_secure_call_p (rtx);
101+
extern void arc_profile_hook (void);
100102

101103
rtl_opt_pass * make_pass_arc_predicate_delay_insns (gcc::context *ctxt);

gcc/config/arc/arc.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10988,6 +10988,47 @@ arc_insn_cost (rtx_insn *insn, bool speed)
1098810988
return cost;
1098910989
}
1099010990

10991+
/* Worker for PROFILE_HOOK. The ARC profile hook uses the blink
10992+
register and a constant which is the location of the current blink
10993+
stack slot. First, the second argument (the blink stack slot
10994+
location) is initialized with minus one, and, latter, when the
10995+
stack structure is known, this argument is updated with the right
10996+
value (see arc_get_arg_ptr). */
10997+
10998+
void
10999+
arc_profile_hook (void)
11000+
{
11001+
rtx fun, r0, r1;
11002+
11003+
/* First argument is BLINK. */
11004+
r0 = get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM);
11005+
11006+
/* This hook is called in the expand, thus, the stack size is
11007+
unknown. We need to mark the move instruction, and properly
11008+
update it after reload. */
11009+
r1 = gen_reg_rtx (SImode);
11010+
emit_insn (gen_mcount_stack (r1, constm1_rtx));
11011+
11012+
fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
11013+
emit_library_call (fun, LCT_NORMAL, VOIDmode, r0, Pmode, r1, SImode);
11014+
}
11015+
11016+
/* Returns the location of BLINK in the stack, which is the location
11017+
indicated by the ARG_POINTER_REGNUM. */
11018+
11019+
unsigned int
11020+
arc_get_arg_ptr (void)
11021+
{
11022+
struct arc_frame_info *frame_info;
11023+
11024+
if (!cfun->machine->frame_info.initialized)
11025+
arc_compute_frame_size ();
11026+
11027+
frame_info = &cfun->machine->frame_info;
11028+
11029+
return frame_info->total_size - frame_info->pretend_size;
11030+
}
11031+
1099111032
#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
1099211033
#define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
1099311034

gcc/config/arc/arc.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
UNSPEC_ARC_VMAC2HU
138138
UNSPEC_ARC_VMPY2H
139139
UNSPEC_ARC_VMPY2HU
140+
UNSPEC_ARC_MCOUNT
140141

141142
VUNSPEC_ARC_RTIE
142143
VUNSPEC_ARC_SYNC
@@ -6596,6 +6597,23 @@ archs4x, archs4xd"
65966597
[(set_attr "length" "8")]
65976598
)
65986599

6600+
;; This pattern is used by profile hook to initialize the mcount
6601+
;; second argument with the right value where the blink is located in
6602+
;; current stack.
6603+
(define_insn_and_split "mcount_stack"
6604+
[(set (match_operand:SI 0 "register_operand" "=r")
6605+
(unspec:SI [(match_operand:SI 1 "immediate_operand" "i")]
6606+
UNSPEC_ARC_MCOUNT))]
6607+
""
6608+
"#"
6609+
"reload_completed"
6610+
[(set (match_dup 0) (match_dup 1))]
6611+
"
6612+
{
6613+
operands[1] = GEN_INT (arc_get_arg_ptr ());
6614+
}"
6615+
[(set_attr "length" "8")])
6616+
65996617
;; include the arc-FPX instructions
66006618
(include "fpx.md")
66016619

gcc/config/arc/linux.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,7 @@ along with GCC; see the file COPYING3. If not see
126126

127127
/* Emit rtl for profiling. Output assembler code to FILE
128128
to call "_mcount" for profiling a function entry. */
129-
#define PROFILE_HOOK(LABEL) \
130-
{ \
131-
rtx fun, rt; \
132-
rt = get_hard_reg_initial_val (Pmode, RETURN_ADDR_REGNUM); \
133-
fun = gen_rtx_SYMBOL_REF (Pmode, "_mcount"); \
134-
emit_library_call (fun, LCT_NORMAL, VOIDmode, rt, Pmode); \
135-
}
129+
#define PROFILE_HOOK(LABEL) arc_profile_hook()
136130

137131
/* Enter/Leave ops are default off for linux targets. */
138132
#undef TARGET_CODE_DENSITY_FRAME_DEFAULT

0 commit comments

Comments
 (0)