[project @ 1996-07-25 20:43:49 by partain]
[ghc-hetmet.git] / ghc / includes / CostCentre.lh
index 05297e2..a633907 100644 (file)
@@ -15,7 +15,7 @@ environment to be defined, despite the fact that we don't have CostCentre
 fields in closures.
 
 \begin{code}
-#if defined(USE_COST_CENTRES) || defined(CONCURRENT)
+#if defined(PROFILING) || defined(CONCURRENT)
 
 # define CC_EXTERN(cc_ident)                                   \
      extern struct cc CAT2(cc_ident,_struct);                  \
@@ -28,7 +28,7 @@ extern CostCentre Registered_CC;/* registered cost centre list */
 CC_EXTERN(CC_MAIN);            /* initial MAIN cost centre */
 CC_EXTERN(CC_GC);              /* Garbage Collection cost center */
 
-# ifdef GUM
+# ifdef PAR
 CC_EXTERN(CC_MSG);             /* Communications cost center */
 CC_EXTERN(CC_IDLE);             /* Idle-time cost centre */
 # endif
@@ -44,22 +44,22 @@ The compiler declares a static block for each @_scc_@ annotation in the
 source using the @CC_DECLARE@ macro where @label@, @module@ and
 @group@ are strings and @ident@ the cost centre identifier.
 
-\begin{code}
-# define CC_IS_CAF  'C'
-# define CC_IS_DICT 'D'
-# define CC_IS_SUBSUMED 'S'
-# define CC_IS_BORING '\0'
+\begin{code} 
+# define CC_IS_CAF      'c'
+# define CC_IS_DICT     'd'
+# define CC_IS_SUBSUMED 's'
+# define CC_IS_BORING   'B'
 
 # define STATIC_CC_REF(cc_ident) &CAT2(cc_ident,_struct)
 # define DYN_CC_REF(cc_ident)    cc_ident /* unused */
 
-# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local) \
-     is_local struct cc CAT2(cc_ident,_struct)                 \
-       = {NOT_REGISTERED, UNHASHED, name, module, group,       \
-          subsumed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};       \
+# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local)      \
+     is_local struct cc CAT2(cc_ident,_struct)                         \
+       = {NOT_REGISTERED, UNHASHED, name, module, group,               \
+          subsumed, INIT_CC_STATS};                                    \
      is_local CostCentre cc_ident = STATIC_CC_REF(cc_ident)
 
-#endif /* defined(USE_COST_CENTRES) || defined(CONCURRENT) */
+#endif /* defined(PROFILING) || defined(CONCURRENT) */
 \end{code}
 
 Definitions relating to the profiling field as a whole.
@@ -79,13 +79,13 @@ Definitions relating to the profiling field as a whole.
 %************************************************************************
 
 The cost-centre profiling is only on if the driver turns on
-@USE_COST_CENTRES@.
+@PROFILING@.
 
 These are the {\em dummy} definitions in force if we do {\em NOT}
-turn on @USE_COST_CENTRES@.  Get them out of the way....
+turn on @PROFILING@.  Get them out of the way....
 
 \begin{code}
-#if !defined(USE_COST_CENTRES)
+#if !defined(PROFILING)
 
 /*** Declaration Definitions ***/
 
@@ -96,7 +96,9 @@ turn on @USE_COST_CENTRES@.  Get them out of the way....
 # define SET_CC_HDR(closure, cc)       /* Dont set CC header */
 # define SET_STATIC_CC_HDR(cc)         /* No static CC header */
 
-# define SET_CCC(cc_ident,is_dupd)
+# define SET_CCC(cc_ident,do_scc_count)
+# define SET_DICT_CCC(cc_ident,do_scc_count)
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_count)
 
 # define RESTORE_CCC(cc)
 
@@ -104,6 +106,9 @@ turn on @USE_COST_CENTRES@.  Get them out of the way....
 # define ENTER_CC_TCL(closure)
 # define ENTER_CC_F(cc)
 # define ENTER_CC_FCL(closure)
+# define ENTER_CC_FSUB()
+# define ENTER_CC_FCAF(cc)
+# define ENTER_CC_FLOAD(cc)
 # define ENTER_CC_PAP(cc)
 # define ENTER_CC_PAP_CL(closure)
 
@@ -114,13 +119,13 @@ turn on @USE_COST_CENTRES@.  Get them out of the way....
 # define CC_ALLOC(cc, size, kind)
 # define HEAP_PROFILE_CLOSURE(closure,size)
 
-# ifndef GUM
+# ifndef PAR
 #  define START_TIME_PROFILER
 #  define RESTART_TIME_PROFILER
 #  define STOP_TIME_PROFILER
 # endif
 
-#endif /* !defined(USE_COST_CENTRES) */
+#endif /* !defined(PROFILING) */
 \end{code}
 
 %************************************************************************
@@ -142,7 +147,7 @@ an additional cost centre field within the fixed header of all
 closures. This is adjacent to the info pointer.
 
 \begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
 
 CC_EXTERN(CC_SUBSUMED);        /* top level fns SUBSUMED cost centre */
 CC_EXTERN(CC_OVERHEAD);        /* costs due only to profiling machinery */
@@ -151,10 +156,8 @@ CC_EXTERN(CC_DONTZuCARE);          /* placeholder only */
 CC_EXTERN(CC_CAFs);            /* prelude cost centre (CAFs  only) */
 CC_EXTERN(CC_DICTs);           /* prelude cost centre (DICTs only) */
 
-# define IS_CAF_OR_DICT_CC(cc) \
-    (((cc)->is_subsumed == CC_IS_CAF) || ((cc)->is_subsumed == CC_IS_DICT))
-
-# define IS_SUBSUMED_CC(cc) ((cc)->is_subsumed == CC_IS_SUBSUMED)
+# define IS_CAF_OR_DICT_OD_SUB_CC(cc) \
+    ((cc)->is_subsumed & ' ')  /* tests for lower case character */
 
 \end{code}
 
@@ -200,14 +203,23 @@ not count the entry to avoid large counts arising from simple
 recursion.  (Huh?  WDP 94/07)
 
 \begin{code}
-# define SET_CCC_X(cc,is_dupd)                                                 \
-       do {                                                                    \
-       if (!(is_dupd)) { CCC->sub_scc_count++; } /* inc subcc count of CCC */  \
-       CCC = (CostCentre)(cc);         /* set CCC to ident cc */               \
-       if (!(is_dupd)) { CCC->scc_count++; }    /* inc scc count of new CCC*/  \
+# define SET_CCC_X(cc,do_subcc_count,do_subdict_count,do_scc_count)                            \
+       do {                                                                                    \
+       if ((do_subcc_count)) { CCC->sub_scc_count++; }       /* inc subcc count of CCC */      \
+       if ((do_subdict_count)) { CCC->sub_dictcc_count++; }  /* inc sub dict count of CCC */   \
+       CCC = (CostCentre)(cc);                               /* set CCC to ident cc */         \
+       ASSERT_IS_REGISTERED(CCC,1);                                                            \
+       if ((do_scc_count)) { CCC->scc_count++; }             /* inc scc count of new CCC*/     \
        } while(0)
 
-# define SET_CCC(cc_ident,is_dupd) SET_CCC_X(STATIC_CC_REF(cc_ident),is_dupd)
+# define SET_CCC(cc_ident,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),do_scc_count,0,do_scc_count)
+
+# define SET_DICT_CCC(cc_ident,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),0,do_scc_count,do_scc_count)
+
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),do_sub_count,0,do_scc_count)
 \end{code}
 
 We have this @RESTORE_CCC@ macro, rather than just an assignment,
@@ -225,9 +237,9 @@ On entry to top level CAFs we count the scc ...
 # define ENTER_CC_CAF_X(cc)                                            \
        do {                                                            \
        CCC->sub_cafcc_count++; /* inc subcaf count of CCC */           \
-       CCC = (CostCentre)(cc);         /* set CCC to ident cc */       \
+       CCC = (CostCentre)(cc); /* set CCC to ident cc */               \
        ASSERT_IS_REGISTERED(CCC,1);                                    \
-       CCC->cafcc_count++; /* inc cafcc count of CCC */                \
+       CCC->scc_count++;       /* inc scc count of CAF cc */           \
        } while(0)
 
 # define ENTER_CC_CAF(cc_ident)   ENTER_CC_CAF_X(STATIC_CC_REF(cc_ident))
@@ -236,14 +248,14 @@ On entry to top level CAFs we count the scc ...
 
 On entering a closure we only count the enter to thunks ...
 \begin{code}
-# define ENTER_CC_T(cc)                                                \
-       do {                                                    \
-       CCC = (CostCentre)(cc);                                 \
-       ASSERT_IS_REGISTERED(CCC,1);                            \
-       CCC->thunk_count++; /* inc thunk count of new CCC */    \
+# define ENTER_CC_T(cc)                                        \
+       do {                                            \
+       CCC = (CostCentre)(cc);                         \
+       ASSERT_IS_REGISTERED(CCC,1);                    \
+       CCC_DETAIL_COUNT(CCC->thunk_count);             \
        } while(0)      
 
-# define ENTER_CC_TCL(closure)                                 \
+# define ENTER_CC_TCL(closure)                         \
        ENTER_CC_T(CC_HDR(closure))
 
 /* Here is our special "hybrid" case when we do *not* set the CCC.
@@ -254,31 +266,65 @@ On entering a closure we only count the enter to thunks ...
        do {                                            \
        CostCentre cc = (CostCentre) (centre);          \
        ASSERT_IS_REGISTERED(cc,1);                     \
-       if ( ! IS_CAF_OR_DICT_CC(cc) ) {                \
+       if ( ! IS_CAF_OR_DICT_OR_SUB_CC(cc) ) {         \
            CCC = cc;                                   \
+       } else {                                        \
+           CCC_DETAIL_COUNT(cc->caffun_subsumed);      \
+           CCC_DETAIL_COUNT(CCC->subsumed_caf_count);  \
        }                                               \
-       CCC->function_count++;                          \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
        } while(0)
 
 # define ENTER_CC_FCL(closure)                         \
        ENTER_CC_F(CC_HDR(closure))
 
+# define ENTER_CC_FSUB()                               \
+       do {                                            \
+       CCC_DETAIL_COUNT(CCC->subsumed_fun_count);      \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
+# define ENTER_CC_FCAF(centre)                         \
+       do {                                            \
+       CostCentre cc = (CostCentre) (centre);          \
+       ASSERT_IS_REGISTERED(cc,1);                     \
+       CCC_DETAIL_COUNT(cc->caffun_subsumed);          \
+       CCC_DETAIL_COUNT(CCC->subsumed_caf_count);      \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
+# define ENTER_CC_FLOAD(cc)                            \
+       do {                                            \
+       CCC = (CostCentre)(cc);                         \
+       ASSERT_IS_REGISTERED(CCC,1);                    \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
 /* These ENTER_CC_PAP things are only used in the RTS */
 
 # define ENTER_CC_PAP(centre)                          \
        do {                                            \
        CostCentre cc = (CostCentre) (centre);          \
        ASSERT_IS_REGISTERED(cc,1);                     \
-       if ( ! IS_CAF_OR_DICT_CC(cc) ) {                \
+       if ( ! IS_CAF_OR_DICT_OR_SUB_CC(cc) ) {         \
            CCC = cc;                                   \
+       } else {                                        \
+           CCC_DETAIL_COUNT(cc->caffun_subsumed);      \
+           CCC_DETAIL_COUNT(CCC->subsumed_caf_count);  \
        }                                               \
-       CCC->pap_count++;                               \
+       CCC_DETAIL_COUNT(CCC->pap_count);               \
        } while(0)                      
                                        
 # define ENTER_CC_PAP_CL(closure)                      \
        ENTER_CC_PAP(CC_HDR(closure))
 
-#endif /* USE_COST_CENTRES */
+# if defined(PROFILING_DETAIL_COUNTS)
+# define CCC_DETAIL_COUNT(inc_this) ((inc_this)++)
+# else
+# define CCC_DETAIL_COUNT(inc_this) /*nothing*/
+# endif
+
+#endif /* PROFILING */
 \end{code}
 
 %************************************************************************
@@ -306,7 +352,7 @@ centre. @REGISTER_IMPORT@ pushes a modules registering routine onto
 the register stack.
 
 \begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
 
 extern F_ _regMain (STG_NO_ARGS);
 extern F_ *register_stack;
@@ -317,8 +363,6 @@ extern F_ *register_stack;
 # define POP_REGISTER_STACK                                            \
        *(--register_stack)
 
-extern I_ SM_trace;
-
 # define START_REGISTER_CCS(reg_mod_name)                              \
        static int _module_registered = 0;                              \
        STGFUN(reg_mod_name) {                                          \
@@ -350,16 +394,16 @@ extern I_ SM_trace;
        } while(0);                                                     \
        FUNEND; }
 
-#endif  /* USE_COST_CENTRES */
+#endif  /* PROFILING */
 \end{code}
 
 We don't want to attribute costs to an unregistered cost-centre:
 \begin{code}
-#if !defined(USE_COST_CENTRES) || !defined(DEBUG)
+#if !defined(PROFILING) || !defined(DEBUG)
 # define ASSERT_IS_REGISTERED(cc,chk_not_overhead) /*nothing*/
 #else
 # define ASSERT_IS_REGISTERED(cc,chk_not_overhead)                             \
-       do {                                                                    \
+       do {    /* beware of cc name-capture */                                 \
        CostCentre c_c = (CostCentre) (cc);                                     \
        if (c_c->registered == NOT_REGISTERED) {                                \
            fprintf(stderr,"Entering unregistered CC: %s\n",c_c->label);        \
@@ -400,8 +444,10 @@ reuse @CON_K@ (or something) in runtime/main/StgStartup.lhc.
 Similarily, the SP stuff should probably be the highly uninformative
 @INTERNAL_KIND@.
 
+SOF 4/96: Renamed MallocPtr_K to ForeignObj_K 
+
 \begin{code}
-#if defined(USE_COST_CENTRES)
+#if defined(PROFILING)
 
 # define CON_K         1
 # define FN_K          2
@@ -411,7 +457,7 @@ Similarily, the SP stuff should probably be the highly uninformative
 # define ARR_K         6
 
 # ifndef PAR
-#  define MallocPtr_K  7  /* Malloc Pointer */
+#  define ForeignObj_K 7  /* Malloc Pointer */
 #  define SPT_K                8  /* Stable Pointer Table */
 # endif /* !PAR */
 
@@ -438,7 +484,7 @@ typedef struct ClCat {
 # define CAT_DECLARE(base_name, kind, descr, type) \
        static struct ClCat MK_CAT_IDENT(base_name) = {UNHASHED,-1,kind,descr,type};
 
-#endif /* USE_COST_CENTRES */
+#endif /* PROFILING */
 \end{code}
 
 %************************************************************************
@@ -449,7 +495,7 @@ typedef struct ClCat {
 
 Stuff to do with timer signals:
 \begin{code}
-#if defined(USE_COST_CENTRES) || defined(GUM)
+#if defined(PROFILING) || defined(PAR)
 
 extern I_ time_profiling;      /* Flag indicating if timer/serial profiling is required */
 
@@ -468,11 +514,6 @@ extern void stop_time_profiler(STG_NO_ARGS);
 # define TICK_FREQUENCY                50                      /* ticks per second */
 # define TICK_MILLISECS                (1000/TICK_FREQUENCY)   /* milli-seconds per tick */
 
-# ifdef CONCURRENT
-extern I_ profilerTicks;
-extern I_ tick_millisecs;
-# endif
-
 # define DEFAULT_INTERVAL      TICK_FREQUENCY          /* 1 second */
 
 /* These are never called directly from threaded code */
@@ -480,7 +521,7 @@ extern I_ tick_millisecs;
 # define RESTART_TIME_PROFILER ULTRASAFESTGCALL0(void,(void *),restart_time_profiler)          /*R StgOverflow.lc */
 # define STOP_TIME_PROFILER    ULTRASAFESTGCALL0(void,(void *),stop_time_profiler)             /*R StgOverflow.lc */
 
-# if defined(USE_COST_CENTRES)
+# if defined(PROFILING)
 #  define OR_INTERVAL_EXPIRED  || (interval_expired)           /*R StgMacros.h */
 # endif
 \end{code}
@@ -528,7 +569,7 @@ which to store profiling information based on the return table size
 value(s).
 
 \begin{code}
-# if defined(USE_COST_CENTRES)
+# if defined(PROFILING)
 
 #  define DEFAULT_MAX_CC     4096
 #  define DEFAULT_MAX_MOD     256
@@ -561,7 +602,7 @@ extern ClCategory *index_type_table;
 extern hash_t init_index_type(STG_NO_ARGS);
 extern hash_t index_type PROTO((ClCategory clcat));
 
-# endif /* USE_COST_CENTRES */
+# endif /* PROFILING */
 \end{code}
 
 
@@ -576,19 +617,19 @@ extern hash_t index_type PROTO((ClCategory clcat));
 memory alloc macros.
 
 \begin{code}
-# define CC_TICK(cc)                                                   \
-       do { CostCentre centre = (CostCentre) (cc);                     \
-       ASSERT_IS_REGISTERED(centre,1);                                 \
-       centre->time_ticks += 1;                                        \
+# define CC_TICK(centre)                                               \
+       do { CostCentre cc = (CostCentre) (centre);                     \
+       ASSERT_IS_REGISTERED(cc,1);                                     \
+       cc->time_ticks += 1;                                            \
        } while(0)
 
-# if defined(USE_COST_CENTRES)
-#  define CC_ALLOC(cc, size, kind)                                     \
-       do { CostCentre cc_ = (CostCentre) (cc);                        \
-       ASSERT_IS_REGISTERED(cc_,0/*OK if OVERHEAD*/);                  \
-       cc_->mem_allocs += 1;                                           \
-       cc_->mem_alloc  += (size) - (PROF_FIXED_HDR + AGE_FIXED_HDR);   \
-       } while(0) /* beware name-capture by ASSERT_IS...! */
+# if defined(PROFILING)
+# define CC_ALLOC(centre, size, kind)                                  \
+       do { CostCentre cc = (CostCentre) (centre);                     \
+       ASSERT_IS_REGISTERED(cc,0/*OK if OVERHEAD*/);                   \
+       CCC_DETAIL_COUNT(cc->mem_allocs);                               \
+       cc->mem_alloc += (size) - (PROF_FIXED_HDR + TICKY_FIXED_HDR);   \
+       } while(0) 
 # endif
 \end{code}
 
@@ -600,19 +641,12 @@ memory alloc macros.
 %************************************************************************
 
 \begin{code}
-extern I_  cc_profiling;       /* Are we performing/reporting cc profiling? */
-extern I_  heap_profiling_reqd;        /* Are we performing heap profiling? */
+I_     init_cc_profiling PROTO((I_ rts_argc, char *rts_argv[], char *prog_argv[]));
+void   report_cc_profiling PROTO((I_ final));
 
-# define SORTCC_LABEL  'C'
-# define SORTCC_TIME   'T'
-# define SORTCC_ALLOC  'A'
-extern char cc_profiling_sort; /* How to sort cost centre report */
-
-extern I_  init_cc_profiling PROTO((I_ rts_argc, char *rts_argv[], char *prog_argv[]));
-extern void report_cc_profiling PROTO((I_ final));
-
-extern void cc_register(STG_NO_ARGS);
-extern void cc_sort PROTO((CostCentre *sort, char sort_on));
+void   cc_register(STG_NO_ARGS);
+void   cc_sort PROTO((CostCentre *sort, char sort_on));
+rtsBool cc_to_ignore PROTO((CostCentre));
 \end{code}
 
 %************************************************************************
@@ -622,53 +656,32 @@ extern void cc_sort PROTO((CostCentre *sort, char sort_on));
 %************************************************************************
 
 \begin{code}
-# define HEAP_NO_PROFILING     0       /* N.B. Used as indexes into arrays */
-
-# if defined(USE_COST_CENTRES)
-
-#  define HEAP_BY_CC           1
-#  define HEAP_BY_MOD          2
-#  define HEAP_BY_GRP          3
-#  define HEAP_BY_DESCR                4
-#  define HEAP_BY_TYPE         5
-#  define HEAP_BY_TIME         6
-  
-#  define CCchar    'C'
-#  define MODchar   'M'
-#  define GRPchar   'G'
-#  define DESCRchar 'D'
-#  define TYPEchar  'Y'
-#  define TIMEchar  'T'
-
-extern I_ heap_profile_init PROTO((I_ prof,
-                                  char *select_cc_str,
-                                  char *select_mod_str,
-                                  char *select_grp_str,
-                                  char *select_descr_str,
-                                  char *select_typ_str,
-                                  char *select_kind_str,
-                                  I_  select_age,
-                                  char *argv[]));
-
-extern void heap_profile_finish(STG_NO_ARGS);
-
-extern void heap_profile_setup(STG_NO_ARGS);      /* called at start of heap profile */
-extern void heap_profile_done(STG_NO_ARGS);      /* called at end of heap profile */
-
-extern void (* heap_profile_fn) PROTO((P_ closure,I_ size));
+# if defined(PROFILING)
+
+I_ heap_profile_init PROTO((char *argv[]));
+
+void heap_profile_finish(STG_NO_ARGS);
+
+void heap_profile_setup(STG_NO_ARGS);      /* called at start of heap profile */
+void heap_profile_done(STG_NO_ARGS);     /* called at end of heap profile */
+
+void (* heap_profile_fn) PROTO((P_ closure,I_ size));
 
 extern I_ earlier_ticks;               /* no. of earlier ticks grouped */
 extern hash_t time_intervals;          /* no. of time intervals reported -- 18 */
 
-#  define HEAP_PROFILE_CLOSURE(closure,size) \
-       STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size)                 /*R SM2s.lh */
+# define HEAP_PROFILE_CLOSURE(closure,size)    \
+       do {                                    \
+       if (heap_profile_fn) {                  \
+           STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size); \
+       }} while(0)
 
-# endif        /* USE_COST_CENTRES */
+# endif        /* PROFILING */
 \end{code}
 
 End multi-slurp protection:
 \begin{code}
-#endif /* USE_COST_CENTRES || GUM */
+#endif /* PROFILING || PAR */
 
 #endif /* CostCentre_H */
 \end{code}