%
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-% $Id: CgClosure.lhs,v 1.54 2002/01/02 12:32:18 simonmar Exp $
+% $Id: CgClosure.lhs,v 1.55 2002/02/14 11:56:03 njn Exp $
%
\section[CgClosure]{Code generation for closures}
is_box = case body of { StgApp fun [] -> True; _ -> False }
- body_code = profCtrC SLIT("TICK_ENT_THK") [] `thenC`
+ ticky_ent_lit = if (isStaticClosure closure_info)
+ then SLIT("TICK_ENT_STATIC_THK")
+ else SLIT("TICK_ENT_DYN_THK")
+
+ body_code = profCtrC ticky_ent_lit [] `thenC`
-- node always points when profiling, so this is ok:
ldvEnter `thenC`
thunkWrapper closure_info body_label (
enterCostCentreCode closure_info cc IsThunk is_box `thenC`
cgExpr body
)
+
\end{code}
If there is {\em at least one argument}, then this closure is in
--slow_entry_code = forceHeapCheck [] True slow_entry_code'
slow_entry_code
- = profCtrC SLIT("TICK_ENT_FUN_STD") [
+ = profCtrC slow_ticky_ent_lit [
CLbl ticky_ctr_label DataPtrRep
] `thenC`
mkCString (_PK_ (map (showTypeCategory . idType) all_args))
]
let prof =
- profCtrC SLIT("TICK_ENT_FUN_DIRECT") [
+ profCtrC fast_ticky_ent_lit [
CLbl ticky_ctr_label DataPtrRep
]
where
ticky_ctr_label = mkRednCountsLabel name
+ (slow_ticky_ent_lit, fast_ticky_ent_lit) =
+ if (isStaticClosure closure_info)
+ then (SLIT("TICK_ENT_STATIC_FUN_STD"), SLIT("TICK_ENT_STATIC_FUN_DIRECT"))
+ else (SLIT("TICK_ENT_DYN_FUN_STD"), SLIT("TICK_ENT_DYN_FUN_DIRECT"))
+
stg_arity = length all_args
lf_info = closureLFInfo closure_info
-- info-table contains the information we need.
(static_ci,_) = layOutStaticConstr con_name data_con typePrimRep arg_tys
- body = initC comp_info (
- profCtrC SLIT("TICK_ENT_CON") [CReg node] `thenC`
- ldvEnter `thenC`
- body_code)
+ static_body = initC comp_info (
+ profCtrC SLIT("TICK_ENT_STATIC_CON") [CReg node] `thenC`
+ ldv_enter_and_body_code)
+
+ closure_body = initC comp_info (
+ profCtrC SLIT("TICK_ENT_DYN_CON") [CReg node] `thenC`
+ ldv_enter_and_body_code)
+
+ ldv_enter_and_body_code = ldvEnter `thenC` body_code
con_descr = occNameUserString (getOccName data_con)
closure_code = if zero_arity_con then
AbsCNop
else
- CClosureInfoAndCode closure_info body Nothing con_descr
+ CClosureInfoAndCode closure_info closure_body Nothing con_descr
- static_code = CClosureInfoAndCode static_ci body Nothing con_descr
+ static_code = CClosureInfoAndCode static_ci static_body Nothing con_descr
zero_arity_con = isNullaryDataCon data_con
-- We used to check that all the arg-sizes were zero, but we don't
/* ----------------------------------------------------------------------------
- * $Id: StgTicky.h,v 1.10 2000/08/07 23:37:23 qrczak Exp $
+ * $Id: StgTicky.h,v 1.11 2002/02/14 11:56:04 njn Exp $
*
* (c) The AQUA project, Glasgow University, 1994-1997
* (c) The GHC Team, 1998-1999
#define TICK_ENT_VIA_NODE() ENT_VIA_NODE_ctr++
-#define TICK_ENT_THK() ENT_THK_ctr++ /* thunk */
+#define TICK_ENT_STATIC_THK(n) ENT_STATIC_THK_ctr++
+#define TICK_ENT_DYN_THK(n) ENT_DYN_THK_ctr++
typedef struct _StgEntCounter {
unsigned registeredp:16, /* 0 == no, 1 == yes */
/* The slow entry point for a function always goes to
the fast entry point, which will register the stats block,
so no need to do so here */
-#define TICK_ENT_FUN_STD(f_ct) \
+#define TICK_ENT_STATIC_FUN_STD(f_ct) \
f_ct.slow_entry_count++; \
- ENT_FUN_STD_ctr++ /* The total one */
+ ENT_STATIC_FUN_STD_ctr++ /* The static total one */
-#define TICK_ENT_FUN_DIRECT(f_ct) \
+#define TICK_ENT_DYN_FUN_STD(f_ct) \
+ f_ct.slow_entry_count++; \
+ ENT_DYN_FUN_STD_ctr++ /* The dynamic total one */
+
+#define TICK_ENT_FUN_DIRECT_BODY(f_ct) \
{ \
if ( ! f_ct.registeredp ) { \
/* hook this one onto the front of the list */ \
} \
f_ct.entry_count += 1; \
} \
- ENT_FUN_DIRECT_ctr++ /* The total one */
+
+#define TICK_ENT_STATIC_FUN_DIRECT(f_ct) \
+ TICK_ENT_FUN_DIRECT_BODY(f_ct) \
+ ENT_STATIC_FUN_DIRECT_ctr++ /* The static total one */
+
+#define TICK_ENT_DYN_FUN_DIRECT(f_ct) \
+ TICK_ENT_FUN_DIRECT_BODY(f_ct) \
+ ENT_DYN_FUN_DIRECT_ctr++ /* The dynamic total one */
extern StgEntCounter top_ct;
extern StgEntCounter *ticky_entry_ctrs;
-#define TICK_ENT_CON(n) ENT_CON_ctr++ /* enter constructor */
-#define TICK_ENT_IND(n) ENT_IND_ctr++ /* enter indirection */
+#define TICK_ENT_STATIC_CON(n) ENT_STATIC_CON_ctr++ /* enter static constructor */
+#define TICK_ENT_DYN_CON(n) ENT_DYN_CON_ctr++ /* enter dynamic constructor */
+#define TICK_ENT_STATIC_IND(n) ENT_STATIC_IND_ctr++ /* enter static indirection */
+#define TICK_ENT_DYN_IND(n) ENT_DYN_IND_ctr++ /* enter dynamic indirection */
#define TICK_ENT_PERM_IND(n) ENT_PERM_IND_ctr++ /* enter permanent indirection */
#define TICK_ENT_PAP(n) ENT_PAP_ctr++ /* enter PAP */
#define TICK_ENT_AP_UPD(n) ENT_AP_UPD_ctr++ /* enter AP_UPD */
#endif
EXTERN unsigned long ENT_VIA_NODE_ctr INIT(0);
-EXTERN unsigned long ENT_THK_ctr INIT(0);
-EXTERN unsigned long ENT_FUN_STD_ctr INIT(0);
-EXTERN unsigned long ENT_FUN_DIRECT_ctr INIT(0);
-EXTERN unsigned long ENT_CON_ctr INIT(0);
-EXTERN unsigned long ENT_IND_ctr INIT(0);
+EXTERN unsigned long ENT_STATIC_THK_ctr INIT(0);
+EXTERN unsigned long ENT_DYN_THK_ctr INIT(0);
+EXTERN unsigned long ENT_STATIC_FUN_STD_ctr INIT(0);
+EXTERN unsigned long ENT_DYN_FUN_STD_ctr INIT(0);
+EXTERN unsigned long ENT_STATIC_FUN_DIRECT_ctr INIT(0);
+EXTERN unsigned long ENT_DYN_FUN_DIRECT_ctr INIT(0);
+EXTERN unsigned long ENT_STATIC_CON_ctr INIT(0);
+EXTERN unsigned long ENT_DYN_CON_ctr INIT(0);
+EXTERN unsigned long ENT_STATIC_IND_ctr INIT(0);
+EXTERN unsigned long ENT_DYN_IND_ctr INIT(0);
EXTERN unsigned long ENT_PERM_IND_ctr INIT(0);
EXTERN unsigned long ENT_PAP_ctr INIT(0);
EXTERN unsigned long ENT_AP_UPD_ctr INIT(0);
#define TICK_ENT_VIA_NODE()
-#define TICK_ENT_THK()
-#define TICK_ENT_FUN_STD(n)
-#define TICK_ENT_FUN_DIRECT(n)
+#define TICK_ENT_STATIC_THK()
+#define TICK_ENT_DYN_THK()
+#define TICK_ENT_STATIC_FUN_STD(n)
+#define TICK_ENT_DYN_FUN_STD(n)
+#define TICK_ENT_STATIC_FUN_DIRECT(n)
+#define TICK_ENT_DYN_FUN_DIRECT(n)
-#define TICK_ENT_CON(n)
-#define TICK_ENT_IND(n)
+#define TICK_ENT_STATIC_CON(n)
+#define TICK_ENT_DYN_CON(n)
+#define TICK_ENT_STATIC_IND(n)
+#define TICK_ENT_DYN_IND(n)
#define TICK_ENT_PERM_IND(n)
#define TICK_ENT_PAP(n)
#define TICK_ENT_AP_UPD(n)
/* -----------------------------------------------------------------------------
- * $Id: StgMiscClosures.hc,v 1.73 2002/02/12 15:17:22 simonmar Exp $
+ * $Id: StgMiscClosures.hc,v 1.74 2002/02/14 11:56:05 njn Exp $
*
* (c) The GHC Team, 1998-2000
*
STGFUN(stg_IND_entry)
{
FB_
- TICK_ENT_IND(Node); /* tick */
+ TICK_ENT_DYN_IND(Node); /* tick */
R1.p = (P_) ((StgInd*)R1.p)->indirectee;
TICK_ENT_VIA_NODE();
JMP_(GET_ENTRY(R1.cl));
STGFUN(stg_IND_STATIC_entry)
{
FB_
- TICK_ENT_IND(Node); /* tick */
+ TICK_ENT_STATIC_IND(Node); /* tick */
R1.p = (P_) ((StgIndStatic*)R1.p)->indirectee;
TICK_ENT_VIA_NODE();
JMP_(GET_ENTRY(R1.cl));
{
FB_
/* Don't add INDs to granularity cost */
- /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
+ /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
#if defined(TICKY_TICKY) && !defined(PROFILING)
/* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */
STGFUN(stg_IND_OLDGEN_entry)
{
FB_
- TICK_ENT_IND(Node); /* tick */
+ TICK_ENT_STATIC_IND(Node); /* tick */
R1.p = (P_) ((StgInd*)R1.p)->indirectee;
TICK_ENT_VIA_NODE();
JMP_(GET_ENTRY(R1.cl));
STGFUN(stg_IND_OLDGEN_PERM_entry)
{
FB_
- /* Dont: TICK_ENT_IND(Node); for ticky-ticky; this ind is here only to help profiling */
+ /* Dont: TICK_ENT_STATIC_IND(Node); for ticky-ticky; this ind is here only to help profiling */
#if defined(TICKY_TICKY) && !defined(PROFILING)
/* TICKY_TICKY && !PROFILING means PERM_IND *replaces* an IND, rather than being extra */
/* -----------------------------------------------------------------------------
- * $Id: Ticky.c,v 1.13 2001/08/14 13:40:09 sewardj Exp $
+ * $Id: Ticky.c,v 1.14 2002/02/14 11:56:05 njn Exp $
*
* (c) The AQUA project, Glasgow University, 1992-1997
* (c) The GHC Team, 1998-1999
unsigned long tot_wds = /* total words */
tot_adm_wds + tot_gds_wds + tot_slp_wds;
+ unsigned long tot_thk_enters = ENT_STATIC_THK_ctr + ENT_DYN_THK_ctr;
+ unsigned long tot_con_enters = ENT_STATIC_CON_ctr + ENT_DYN_CON_ctr;
+ unsigned long tot_fun_direct_enters = ENT_STATIC_FUN_DIRECT_ctr + ENT_DYN_FUN_DIRECT_ctr;
+ unsigned long tot_fun_std_enters = ENT_STATIC_FUN_STD_ctr + ENT_DYN_FUN_STD_ctr;
+ unsigned long tot_ind_enters = ENT_STATIC_IND_ctr + ENT_DYN_IND_ctr;
+
unsigned long tot_enters =
- ENT_CON_ctr + ENT_FUN_DIRECT_ctr +
- ENT_IND_ctr + ENT_PERM_IND_ctr + ENT_PAP_ctr + ENT_THK_ctr;
+ tot_con_enters + tot_fun_direct_enters +
+ tot_ind_enters + ENT_PERM_IND_ctr + ENT_PAP_ctr + tot_thk_enters;
unsigned long jump_direct_enters =
tot_enters - ENT_VIA_NODE_ctr;
unsigned long bypass_enters =
- ENT_FUN_DIRECT_ctr -
- (ENT_FUN_STD_ctr - UPD_PAP_IN_NEW_ctr);
+ tot_fun_direct_enters -
+ (tot_fun_std_enters - UPD_PAP_IN_NEW_ctr);
unsigned long tot_returns =
RET_NEW_ctr + RET_OLD_ctr + RET_UNBOXED_TUP_ctr +
jump_direct_enters,
PC(INTAVG(jump_direct_enters,tot_enters)));
fprintf(tf,"%7ld (%5.1f%%) thunks\n",
- ENT_THK_ctr,
- PC(INTAVG(ENT_THK_ctr,tot_enters)));
+ tot_thk_enters,
+ PC(INTAVG(tot_thk_enters,tot_enters)));
fprintf(tf,"%7ld (%5.1f%%) data values\n",
- ENT_CON_ctr,
- PC(INTAVG(ENT_CON_ctr,tot_enters)));
+ tot_con_enters,
+ PC(INTAVG(tot_con_enters,tot_enters)));
fprintf(tf,"%7ld (%5.1f%%) function values\n\t\t [of which %ld (%.1f%%) bypassed arg-satisfaction chk]\n",
- ENT_FUN_DIRECT_ctr,
- PC(INTAVG(ENT_FUN_DIRECT_ctr,tot_enters)),
+ tot_fun_direct_enters,
+ PC(INTAVG(tot_fun_direct_enters,tot_enters)),
bypass_enters,
- PC(INTAVG(bypass_enters,ENT_FUN_DIRECT_ctr)));
+ PC(INTAVG(bypass_enters,tot_fun_direct_enters)));
fprintf(tf,"%7ld (%5.1f%%) partial applications\n",
ENT_PAP_ctr,
PC(INTAVG(ENT_PAP_ctr,tot_enters)));
fprintf(tf,"%7ld (%5.1f%%) normal indirections\n",
- ENT_IND_ctr,
- PC(INTAVG(ENT_IND_ctr,tot_enters)));
+ tot_ind_enters,
+ PC(INTAVG(tot_ind_enters,tot_enters)));
fprintf(tf,"%7ld (%5.1f%%) permanent indirections\n",
ENT_PERM_IND_ctr,
PC(INTAVG(ENT_PERM_IND_ctr,tot_enters)));
#endif
PR_CTR(ENT_VIA_NODE_ctr);
- PR_CTR(ENT_CON_ctr);
- PR_CTR(ENT_FUN_STD_ctr);
- PR_CTR(ENT_FUN_DIRECT_ctr);
- PR_CTR(ENT_IND_ctr);
+ PR_CTR(ENT_STATIC_CON_ctr);
+ PR_CTR(ENT_DYN_CON_ctr);
+ PR_CTR(ENT_STATIC_FUN_STD_ctr);
+ PR_CTR(ENT_DYN_FUN_STD_ctr);
+ PR_CTR(ENT_STATIC_FUN_DIRECT_ctr);
+ PR_CTR(ENT_DYN_FUN_DIRECT_ctr);
+ PR_CTR(ENT_STATIC_IND_ctr);
+ PR_CTR(ENT_DYN_IND_ctr);
/* The counters ENT_PERM_IND and UPD_{NEW,OLD}_PERM_IND are not dumped
* at the end of execution unless update squeezing is turned off (+RTS
PR_CTR(ENT_PAP_ctr);
PR_CTR(ENT_AP_UPD_ctr);
PR_CTR(ENT_BH_ctr);
- PR_CTR(ENT_THK_ctr);
+ PR_CTR(ENT_STATIC_THK_ctr);
+ PR_CTR(ENT_DYN_THK_ctr);
PR_CTR(RET_NEW_ctr);
PR_CTR(RET_OLD_ctr);