Ajout du profiling par gprof (ocamlopt -p)

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@2025 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
master
Xavier Leroy 1998-08-06 13:27:38 +00:00
parent 33cf52bd2c
commit 49521cb928
10 changed files with 154 additions and 36 deletions

View File

@ -425,6 +425,8 @@ runtimeopt:
cd asmrun; $(MAKE) all
if test -f stdlib/libasmrun.a; then :; else \
ln -s ../asmrun/libasmrun.a stdlib/libasmrun.a; fi
if test -f stdlib/libasmrunp.a; then :; else \
ln -s ../asmrun/libasmrunp.a stdlib/libasmrunp.a; fi
clean::
cd asmrun; $(MAKE) clean
rm -f stdlib/libasmrun.a

View File

@ -674,6 +674,17 @@ let emit_instr i =
let rec emit_all i =
match i.desc with Lend -> () | _ -> emit_instr i; emit_all i.next
(* Emission of profiling prelude *)
let emit_profile() =
match Config.system with
"digital" ->
` nop\n`;
` unop\n`;
` nop\n`;
` unop\n`
| _ -> () (*not supported yet*)
(* Emission of a function declaration *)
let emit_fundecl (fundecl, needs_gp) =
@ -688,6 +699,7 @@ let emit_fundecl (fundecl, needs_gp) =
` .align 4\n`;
` .globl {emit_symbol fundecl.fun_name}\n`;
` .ent {emit_symbol fundecl.fun_name}\n`;
if !Clflags.gprofile then emit_profile();
`{emit_symbol fundecl.fun_name}:\n`;
let n = frame_size() in
if n > 0 then

View File

@ -171,7 +171,10 @@ let make_startup_file filename info_list =
close_out oc
let call_linker file_list startup_file =
let libname = "libasmrun" ^ ext_lib in
let libname =
if !Clflags.gprofile
then "libasmrunp" ^ ext_lib
else "libasmrun" ^ ext_lib in
let runtime_lib =
try
find_in_path !load_path libname
@ -199,8 +202,9 @@ let call_linker file_list startup_file =
(String.concat " " (List.rev file_list))
| _ ->
if not !Clflags.output_c_object then
Printf.sprintf "%s -o %s -I%s %s %s %s -L%s %s %s %s"
Printf.sprintf "%s %s -o %s -I%s %s %s %s -L%s %s %s %s"
Config.native_c_compiler
(if !Clflags.gprofile then "-pg" else "")
!Clflags.exec_name
Config.standard_library
(String.concat " " (List.rev !Clflags.ccopts))
@ -234,7 +238,10 @@ let object_file_name name =
(* Main entry point *)
let link objfiles =
let objfiles = "stdlib.cmxa" :: (objfiles @ ["std_exit.cmx"]) in
let objfiles =
if !Clflags.gprofile
then "stdlib.p.cmxa" :: (objfiles @ ["std_exit.p.cmx"])
else "stdlib.cmxa" :: (objfiles @ ["std_exit.cmx"]) in
let units_tolink = List.fold_right scan_file objfiles [] in
Array.iter remove_required Runtimedef.builtin_exceptions;
if not (StringSet.is_empty !missing_globals) then

View File

@ -693,6 +693,21 @@ let emit_float_constant (lbl, cst) =
` .data\n`;
`{emit_label lbl}: .double {emit_string cst}\n`
(* Emission of the profiling prelude *)
let emit_profile () =
match Config.system with
"linux_elf" ->
` pushl %eax\n`;
` movl %esp, %ebp\n`;
` pushl %ecx\n`;
` pushl %edx\n`;
` call {emit_symbol "mcount"}\n`;
` popl %edx\n`;
` popl %ecx\n`;
` popl %eax\n`
| _ -> () (*unsupported yet*)
(* Emission of a function declaration *)
let fundecl fundecl =
@ -707,6 +722,7 @@ let fundecl fundecl =
emit_align 4;
` .globl {emit_symbol fundecl.fun_name}\n`;
`{emit_symbol fundecl.fun_name}:\n`;
if !Clflags.gprofile then emit_profile();
let n = frame_size() - 4 in
if n > 0 then
` subl ${emit_int n}, %esp\n`;

View File

@ -4,6 +4,7 @@ CC=$(NATIVECC)
FLAGS=-I../byterun -DNATIVE_CODE -DTARGET_$(ARCH) -DSYS_$(SYSTEM)
CFLAGS=$(FLAGS) -O $(NATIVECCCOMPOPTS)
DFLAGS=$(FLAGS) -g -DDEBUG $(NATIVECCCOMPOPTS)
PFLAGS=$(FLAGS) -pg -DPROFILING $(NATIVECCCOMPOPTS)
COBJS=startup.o main.o fail.o roots.o signals.o \
misc.o freelist.o major_gc.o minor_gc.o memory.o alloc.o compare.o ints.o \
@ -15,8 +16,9 @@ ASMOBJS=$(ARCH).o
OBJS=$(COBJS) $(ASMOBJS)
DOBJS=$(COBJS:.o=.d.o) $(ASMOBJS)
POBJS=$(COBJS:.o=.p.o) $(ASMOBJS:.o=.p.o)
all: libasmrun.a
all: libasmrun.a libasmrunp.a
libasmrun.a: $(OBJS)
rm -f libasmrun.a
@ -28,9 +30,14 @@ libasmrund.a: $(DOBJS)
ar rc libasmrund.a $(DOBJS)
$(RANLIB) libasmrund.a
libasmrunp.a: $(POBJS)
rm -f libasmrunp.a
ar rc libasmrunp.a $(POBJS)
$(RANLIB) libasmrunp.a
install:
cp libasmrun.a $(LIBDIR)
cd $(LIBDIR); $(RANLIB) libasmrun.a
cp libasmrun.a libasmrunp.a $(LIBDIR)
cd $(LIBDIR); $(RANLIB) libasmrun.a libasmrunp.a
power.o: power-$(SYSTEM).o
cp power-$(SYSTEM).o power.o
@ -100,17 +107,26 @@ LINKEDFILES=misc.c freelist.c major_gc.c minor_gc.c memory.c alloc.c array.c \
clean::
rm -f $(LINKEDFILES)
.SUFFIXES: .S .d.o
.SUFFIXES: .S .d.o .p.o
.S.o:
$(ASPP) $(ASPPFLAGS) -o $*.o $*.S
.S.p.o:
$(ASPP) $(ASPPFLAGS) -DPROFILING -o $*.p.o $*.S
.c.d.o:
@ if test -f $*.o; then mv $*.o $*.f.o; else :; fi
$(CC) -c $(DFLAGS) $<
mv $*.o $*.d.o
@ if test -f $*.f.o; then mv $*.f.o $*.o; else :; fi
.c.p.o:
@ if test -f $*.o; then mv $*.o $*.f.o; else :; fi
$(CC) -c $(PFLAGS) $<
mv $*.o $*.p.o
@ if test -f $*.f.o; then mv $*.f.o $*.o; else :; fi
clean::
rm -f *.o *.s *.a *~

View File

@ -13,6 +13,12 @@
/* Asm part of the runtime system, Alpha processor */
#if defined(PROFILING) && defined(SYS_digital)
#define PROFILE nop; unop; nop; unop
#else
#define PROFILE
#endif
/* Allocation */
.text
@ -27,6 +33,7 @@
.globl caml_alloc1
.ent caml_alloc1
.align 3
PROFILE
caml_alloc1:
.prologue 0
subq $13, 16, $13
@ -40,6 +47,7 @@ $100: ldiq $25, 16
.globl caml_alloc2
.ent caml_alloc2
.align 3
PROFILE
caml_alloc2:
.prologue 0
subq $13, 24, $13
@ -53,6 +61,7 @@ $101: ldiq $25, 24
.globl caml_alloc3
.ent caml_alloc3
.align 3
PROFILE
caml_alloc3:
.prologue 0
subq $13, 32, $13
@ -66,6 +75,7 @@ $102: ldiq $25, 32
.globl caml_alloc
.ent caml_alloc
.align 3
PROFILE
caml_alloc:
.prologue 0
subq $13, $25, $13
@ -79,6 +89,7 @@ caml_alloc:
.globl caml_call_gc
.ent caml_call_gc
.align 3
PROFILE
caml_call_gc:
.prologue 0
ldiq $25, 0
@ -213,6 +224,7 @@ $103: ldgp $gp, 0($27)
.globl caml_c_call
.ent caml_c_call
.align 3
PROFILE
caml_c_call:
.prologue 0
/* Preserve return address and caller's $gp in callee-save registers */
@ -249,6 +261,7 @@ $104: ldgp $gp, 0($25)
.globl caml_start_program
.ent caml_start_program
.align 3
PROFILE
caml_start_program:
ldgp $gp, 0($27)
lda $25, caml_program
@ -359,6 +372,7 @@ $109: ldgp $gp, 0($26)
.globl raise_caml_exception
.ent raise_caml_exception
.align 3
PROFILE
raise_caml_exception:
ldgp $gp, 0($27)
mov $16, $0 /* Move exn bucket */
@ -377,6 +391,7 @@ raise_caml_exception:
.globl callback
.ent callback
.align 3
PROFILE
callback:
/* Initial shuffling of arguments */
ldgp $gp, 0($27)
@ -390,6 +405,7 @@ callback:
.globl callback2
.ent callback2
.align 3
PROFILE
callback2:
ldgp $gp, 0($27)
mov $16, $25
@ -403,6 +419,7 @@ callback2:
.globl callback3
.ent callback3
.align 3
PROFILE
callback3:
ldgp $gp, 0($27)
mov $16, $25

View File

@ -19,12 +19,26 @@
#if defined(SYS_linux_elf) || defined(SYS_solaris)
#define G(x) x
#define L(x) .L##x
#define FUNCTION_ALIGN 4
#else
#define G(x) _##x
#define L(x) L##x
#define FUNCTION_ALIGN 2
#endif
#if defined(PROFILING) && defined(SYS_linux_elf)
#define PROFILE_CAML \
pushl %eax; movl %esp, %ebp; pushl %ecx; pushl %edx; \
call mcount; \
popl %edx; popl %ecx; popl %eax
#define PROFILE_C \
pushl %ebp; movl %esp, %ebp; call mcount; popl %ebp
#else
#define PROFILE_CAML
#define PROFILE_C
#endif
/* Allocation */
.text
@ -35,13 +49,14 @@
.globl G(caml_alloc)
G(caml_call_gc):
PROFILE_CAML
/* Record lowest stack address and return address */
movl 0(%esp), %eax
movl %eax, G(caml_last_return_address)
leal 4(%esp), %eax
movl %eax, G(caml_bottom_of_stack)
/* Build array of registers, save it into caml_gc_regs */
L105: pushl %ebp
L(105): pushl %ebp
pushl %edi
pushl %esi
pushl %edx
@ -64,58 +79,62 @@ L105: pushl %ebp
.align FUNCTION_ALIGN
G(caml_alloc1):
PROFILE_CAML
movl G(young_ptr), %eax
subl $8, %eax
movl %eax, G(young_ptr)
cmpl G(young_limit), %eax
jb L100
jb L(100)
ret
L100: movl 0(%esp), %eax
L(100): movl 0(%esp), %eax
movl %eax, G(caml_last_return_address)
leal 4(%esp), %eax
movl %eax, G(caml_bottom_of_stack)
call L105
call L(105)
jmp G(caml_alloc1)
.align FUNCTION_ALIGN
G(caml_alloc2):
PROFILE_CAML
movl G(young_ptr), %eax
subl $12, %eax
movl %eax, G(young_ptr)
cmpl G(young_limit), %eax
jb L101
jb L(101)
ret
L101: movl 0(%esp), %eax
L(101): movl 0(%esp), %eax
movl %eax, G(caml_last_return_address)
leal 4(%esp), %eax
movl %eax, G(caml_bottom_of_stack)
call L105
call L(105)
jmp G(caml_alloc2)
.align FUNCTION_ALIGN
G(caml_alloc3):
PROFILE_CAML
movl G(young_ptr), %eax
subl $16, %eax
movl %eax, G(young_ptr)
cmpl G(young_limit), %eax
jb L102
jb L(102)
ret
L102: movl 0(%esp), %eax
L(102): movl 0(%esp), %eax
movl %eax, G(caml_last_return_address)
leal 4(%esp), %eax
movl %eax, G(caml_bottom_of_stack)
call L105
call L(105)
jmp G(caml_alloc3)
.align FUNCTION_ALIGN
G(caml_alloc):
PROFILE_CAML
subl G(young_ptr), %eax /* eax = size - young_ptr */
negl %eax /* eax = young_ptr - size */
cmpl G(young_limit), %eax
jb L103
jb L(103)
movl %eax, G(young_ptr)
ret
L103: subl G(young_ptr), %eax /* eax = - size */
L(103): subl G(young_ptr), %eax /* eax = - size */
negl %eax /* eax = size */
pushl %eax /* save desired size */
subl %eax, G(young_ptr) /* must update young_ptr */
@ -123,7 +142,7 @@ L103: subl G(young_ptr), %eax /* eax = - size */
movl %eax, G(caml_last_return_address)
leal 8(%esp), %eax
movl %eax, G(caml_bottom_of_stack)
call L105
call L(105)
popl %eax /* recover desired size */
jmp G(caml_alloc)
@ -132,6 +151,7 @@ L103: subl G(young_ptr), %eax /* eax = - size */
.globl G(caml_c_call)
.align FUNCTION_ALIGN
G(caml_c_call):
PROFILE_CAML
/* Record lowest stack address and return address */
movl (%esp), %edx
movl %edx, G(caml_last_return_address)
@ -145,6 +165,7 @@ G(caml_c_call):
.globl G(caml_start_program)
.align FUNCTION_ALIGN
G(caml_start_program):
PROFILE_C
/* Save callee-save registers */
pushl %ebx
pushl %esi
@ -153,18 +174,18 @@ G(caml_start_program):
/* Initial entry point is caml_program */
movl $ G(caml_program), %esi
/* Common code for caml_start_program and callback* */
L106:
L(106):
/* Build a callback link */
pushl G(caml_gc_regs)
pushl G(caml_last_return_address)
pushl G(caml_bottom_of_stack)
/* Build an exception handler */
pushl $L108
pushl $ L(108)
pushl G(caml_exception_pointer)
movl %esp, G(caml_exception_pointer)
/* Call the Caml code */
call *%esi
L107:
L(107):
/* Pop the exception handler */
popl G(caml_exception_pointer)
popl %esi /* dummy register */
@ -179,7 +200,7 @@ L107:
popl %ebx
/* Return to caller. */
ret
L108:
L(108):
/* Exception handler*/
/* Pop the callback link, restoring the global variables */
popl G(caml_bottom_of_stack)
@ -195,6 +216,7 @@ L108:
.globl G(raise_caml_exception)
.align FUNCTION_ALIGN
G(raise_caml_exception):
PROFILE_C
movl 4(%esp), %eax
movl G(caml_exception_pointer), %esp
popl G(caml_exception_pointer)
@ -205,6 +227,7 @@ G(raise_caml_exception):
.globl G(callback)
.align FUNCTION_ALIGN
G(callback):
PROFILE_C
/* Save callee-save registers */
pushl %ebx
pushl %esi
@ -214,11 +237,12 @@ G(callback):
movl 20(%esp), %ebx /* closure */
movl 24(%esp), %eax /* argument */
movl 0(%ebx), %esi /* code pointer */
jmp L106
jmp L(106)
.globl G(callback2)
.align FUNCTION_ALIGN
G(callback2):
PROFILE_C
/* Save callee-save registers */
pushl %ebx
pushl %esi
@ -229,11 +253,12 @@ G(callback2):
movl 24(%esp), %eax /* first argument */
movl 28(%esp), %ebx /* second argument */
movl $ G(caml_apply2), %esi /* code pointer */
jmp L106
jmp L(106)
.globl G(callback3)
.align FUNCTION_ALIGN
G(callback3):
PROFILE_C
/* Save callee-save registers */
pushl %ebx
pushl %esi
@ -245,13 +270,13 @@ G(callback3):
movl 28(%esp), %ebx /* second argument */
movl 32(%esp), %ecx /* third argument */
movl $ G(caml_apply3), %esi /* code pointer */
jmp L106
jmp L(106)
.data
.globl G(system_frametable)
G(system_frametable):
.long 1 /* one descriptor */
.long L107 /* return address into callback */
.long L(107) /* return address into callback */
#ifndef SYS_solaris
.word -1 /* negative frame size => use callback link */
.word 0 /* no roots here */

View File

@ -63,7 +63,7 @@ let main () =
"<opt> Pass option <opt> to the C compiler and linker";
"-compact", Arg.Clear optimize_for_speed,
" Optimize code size rather than speed";
"-i", Arg.Set print_types, " Print the types";
"-i", Arg.Set print_types, " Print the inferred types";
"-I", Arg.String(fun dir -> include_dirs := dir :: !include_dirs),
"<dir> Add <dir> to the list of include directories";
"-impl", Arg.String process_implementation_file,
@ -82,7 +82,10 @@ let main () =
object_name := s),
"<file> Set output file name to <file> (default a.out)";
"-output-obj", Arg.Unit(fun () -> output_c_object := true),
"Output a C object file instead of an executable";
" Output a C object file instead of an executable";
"-p", Arg.Set gprofile,
" Compile and link with profiling support for \"gprof\"\n\
\t(not supported on all platforms)";
"-pp", Arg.String(fun s -> preprocessor := Some s),
"<command> Pipe sources through preprocessor <command>";
"-S", Arg.Set keep_asm_file, " Keep intermediate assembly file";

View File

@ -19,7 +19,7 @@ OBJS=pervasives.cmo list.cmo char.cmo string.cmo array.cmo sys.cmo \
all: stdlib.cma std_exit.cmo camlheader camlheader_ur
allopt: stdlib.cmxa std_exit.cmx
allopt: stdlib.cmxa std_exit.cmx stdlib.p.cmxa std_exit.p.cmx
install:
cp stdlib.cma std_exit.cmo *.cmi *.mli *.ml camlheader camlheader_ur $(LIBDIR)
@ -34,6 +34,9 @@ stdlib.cma: $(OBJS)
stdlib.cmxa: $(OBJS:.cmo=.cmx)
$(CAMLOPT) -a -o stdlib.cmxa $(OBJS:.cmo=.cmx)
stdlib.p.cmxa: $(OBJS:.cmo=.p.cmx)
$(CAMLOPT) -a -o stdlib.p.cmxa $(OBJS:.cmo=.p.cmx)
camlheader camlheader_ur: header.c ../config/Makefile
if $(SHARPBANGSCRIPTS); then \
echo '#! $(BINDIR)/ocamlrun' > camlheader && \
@ -56,11 +59,20 @@ pervasives.cmo: pervasives.ml
pervasives.cmx: pervasives.ml
$(CAMLOPT) $(OPTCOMPFLAGS) -nopervasives -c pervasives.ml
pervasives.p.cmx: pervasives.ml
@if test -f pervasives.cmx; then mv pervasives.cmx pervasives.n.cmx; else :; fi
@if test -f pervasives.o; then mv pervasives.o pervasives.n.o; else :; fi
$(CAMLOPT) $(OPTCOMPFLAGS) -p -nopervasives -c pervasives.ml
mv pervasives.cmx pervasives.p.cmx
mv pervasives.o pervasives.p.o
@if test -f pervasives.n.cmx; then mv pervasives.n.cmx pervasives.cmx; else :; fi
@if test -f pervasives.n.o; then mv pervasives.n.o pervasives.o; else :; fi
# oo.cmi must be compiled with -nopervasives for applets
oo.cmi: oo.mli
$(CAMLC) $(COMPFLAGS) -nopervasives -c oo.mli
.SUFFIXES: .mli .ml .cmi .cmo .cmx
.SUFFIXES: .mli .ml .cmi .cmo .cmx .p.cmx
.mli.cmi:
$(CAMLC) $(COMPFLAGS) -c $<
@ -71,12 +83,19 @@ oo.cmi: oo.mli
.ml.cmx:
$(CAMLOPT) $(OPTCOMPFLAGS) -c $<
$(OBJS) std_exit.cmo: pervasives.cmi
$(OBJS:.cmo=.cmx) std_exit.cmx: pervasives.cmi
.ml.p.cmx:
@if test -f $*.cmx; then mv $*.cmx $*.n.cmx; else :; fi
@if test -f $*.o; then mv $*.o $*.n.o; else :; fi
$(CAMLOPT) $(OPTCOMPFLAGS) -p -c $<
mv $*.cmx $*.p.cmx
mv $*.o $*.p.o
@if test -f $*.n.cmx; then mv $*.n.cmx $*.cmx; else :; fi
@if test -f $*.n.o; then mv $*.n.o $*.o; else :; fi
$(OBJS) std_exit.cmo: $(COMPILER)
$(OBJS) std_exit.cmo: pervasives.cmi $(COMPILER)
$(OBJS:.cmo=.cmx) std_exit.cmx: pervasives.cmi $(OPTCOMPILER)
$(OBJS:.cmo=.p.cmx) std_exit.p.cmx: pervasives.cmi $(OPTCOMPILER)
$(OBJS:.cmo=.cmi) std_exit.cmi: $(COMPILER)
$(OBJS:.cmo=.cmx) std_exit.cmx: $(OPTCOMPILER)
clean::
rm -f *.cm* *.o *.a

View File

@ -36,6 +36,7 @@ and noassert = ref false (* -noassert *)
and verbose = ref false (* -verbose *)
and use_runtime = ref "" (* -use_runtime ... *)
and make_runtime = ref false (* -make_runtime *)
and gprofile = ref false (* -p *)
let dump_rawlambda = ref false (* -drawlambda *)
and dump_lambda = ref false (* -dlambda *)