summaryrefslogtreecommitdiff
path: root/rts/Apply.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-10-03 09:30:56 +0100
committerSimon Marlow <marlowsd@gmail.com>2012-10-08 09:04:40 +0100
commita7c0387d20c1c9994d1100b14fbb8fb4e28a259e (patch)
treeb95d0a512f951a4a463f1aa5178b0cd5c4fdb410 /rts/Apply.cmm
parentaed37acd4d157791381800d5de960a2461bcbef3 (diff)
downloadhaskell-a7c0387d20c1c9994d1100b14fbb8fb4e28a259e.tar.gz
Produce new-style Cmm from the Cmm parser
The main change here is that the Cmm parser now allows high-level cmm code with argument-passing and function calls. For example: foo ( gcptr a, bits32 b ) { if (b > 0) { // we can make tail calls passing arguments: jump stg_ap_0_fast(a); } return (x,y); } More details on the new cmm syntax are in Note [Syntax of .cmm files] in CmmParse.y. The old syntax is still more-or-less supported for those occasional code fragments that really need to explicitly manipulate the stack. However there are a couple of differences: it is now obligatory to give a list of live GlobalRegs on every jump, e.g. jump %ENTRY_CODE(Sp(0)) [R1]; Again, more details in Note [Syntax of .cmm files]. I have rewritten most of the .cmm files in the RTS into the new syntax, except for AutoApply.cmm which is generated by the genapply program: this file could be generated in the new syntax instead and would probably be better off for it, but I ran out of enthusiasm. Some other changes in this batch: - The PrimOp calling convention is gone, primops now use the ordinary NativeNodeCall convention. This means that primops and "foreign import prim" code must be written in high-level cmm, but they can now take more than 10 arguments. - CmmSink now does constant-folding (should fix #7219) - .cmm files now go through the cmmPipeline, and as a result we generate better code in many cases. All the object files generated for the RTS .cmm files are now smaller. Performance should be better too, but I haven't measured it yet. - RET_DYN frames are removed from the RTS, lots of code goes away - we now have some more canned GC points to cover unboxed-tuples with 2-4 pointers, which will reduce code size a little.
Diffstat (limited to 'rts/Apply.cmm')
-rw-r--r--rts/Apply.cmm72
1 files changed, 37 insertions, 35 deletions
diff --git a/rts/Apply.cmm b/rts/Apply.cmm
index a2d4a7e123..b89abeaff2 100644
--- a/rts/Apply.cmm
+++ b/rts/Apply.cmm
@@ -21,18 +21,16 @@
STRING(stg_ap_0_ret_str,"stg_ap_0_ret... ")
-stg_ap_0_fast
+stg_ap_0_fast ( P_ fun )
{
- // fn is in R1, no args on the stack
-
IF_DEBUG(apply,
- foreign "C" debugBelch(stg_ap_0_ret_str) [R1];
- foreign "C" printClosure(R1 "ptr") [R1]);
+ ccall debugBelch(stg_ap_0_ret_str);
+ ccall printClosure(R1 "ptr"));
IF_DEBUG(sanity,
- foreign "C" checkStackFrame(Sp "ptr") [R1]);
+ ccall checkStackFrame(Sp "ptr"));
- ENTER();
+ ENTER(fun);
}
/* -----------------------------------------------------------------------------
@@ -56,9 +54,9 @@ stg_ap_0_fast
-------------------------------------------------------------------------- */
INFO_TABLE(stg_PAP,/*special layout*/0,0,PAP,"PAP","PAP")
-{ foreign "C" barf("PAP object entered!") never returns; }
+{ ccall barf("PAP object entered!") never returns; }
-stg_PAP_apply
+stg_PAP_apply /* no args => explicit stack */
{
W_ Words;
W_ pap;
@@ -78,7 +76,7 @@ stg_PAP_apply
// this before calling stg_PAP_entry.
Sp_adj(-1);
Sp(0) = R2;
- jump stg_gc_unpt_r1;
+ jump stg_gc_unpt_r1 [R1];
}
Sp_adj(-Words);
@@ -86,7 +84,7 @@ stg_PAP_apply
TICK_ENT_PAP();
LDV_ENTER(pap);
#ifdef PROFILING
- foreign "C" enterFunCCS(BaseReg "ptr", StgHeader_ccs(pap) "ptr");
+ ccall enterFunCCS(BaseReg "ptr", StgHeader_ccs(pap) "ptr");
#endif
// Reload the stack
@@ -122,26 +120,26 @@ for:
TICK_ENT_VIA_NODE();
#ifdef NO_ARG_REGS
- jump %GET_ENTRY(UNTAG(R1));
+ jump %GET_ENTRY(UNTAG(R1)) [R1];
#else
W_ info;
info = %GET_FUN_INFO(UNTAG(R1));
W_ type;
type = TO_W_(StgFunInfoExtra_fun_type(info));
if (type == ARG_GEN) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_GEN_BIG) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_BCO) {
Sp_adj(-2);
Sp(1) = R1;
Sp(0) = stg_apply_interp_info;
- jump stg_yield_to_interpreter;
+ jump stg_yield_to_interpreter [];
}
jump W_[stg_ap_stack_entries +
- WDS(TO_W_(StgFunInfoExtra_fun_type(info)))];
+ WDS(TO_W_(StgFunInfoExtra_fun_type(info)))] [R1];
#endif
}
@@ -155,6 +153,7 @@ for:
-------------------------------------------------------------------------- */
INFO_TABLE(stg_AP,/*special layout*/0,0,AP,"AP","AP")
+ /* no args => explicit stack */
{
W_ Words;
W_ ap;
@@ -164,12 +163,12 @@ INFO_TABLE(stg_AP,/*special layout*/0,0,AP,"AP","AP")
Words = TO_W_(StgAP_n_args(ap));
/*
- * Check for stack overflow. IMPORTANT: use a _NP check here,
+ * Check for stack overflow. IMPORTANT: use a _ENTER check here,
* because if the check fails, we might end up blackholing this very
* closure, in which case we must enter the blackhole on return rather
* than continuing to evaluate the now-defunct closure.
*/
- STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame);
+ STK_CHK_ENTER(WDS(Words) + SIZEOF_StgUpdateFrame, R1);
PUSH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
Sp = Sp - SIZEOF_StgUpdateFrame - WDS(Words);
@@ -197,26 +196,26 @@ for:
TICK_ENT_VIA_NODE();
#ifdef NO_ARG_REGS
- jump %GET_ENTRY(UNTAG(R1));
+ jump %GET_ENTRY(UNTAG(R1)) [R1];
#else
W_ info;
info = %GET_FUN_INFO(UNTAG(R1));
W_ type;
type = TO_W_(StgFunInfoExtra_fun_type(info));
if (type == ARG_GEN) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_GEN_BIG) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_BCO) {
Sp_adj(-2);
Sp(1) = R1;
Sp(0) = stg_apply_interp_info;
- jump stg_yield_to_interpreter;
+ jump stg_yield_to_interpreter [];
}
jump W_[stg_ap_stack_entries +
- WDS(TO_W_(StgFunInfoExtra_fun_type(info)))];
+ WDS(TO_W_(StgFunInfoExtra_fun_type(info)))] [R1];
#endif
}
@@ -225,6 +224,7 @@ for:
those generated by the byte-code compiler for inserting breakpoints. */
INFO_TABLE(stg_AP_NOUPD,/*special layout*/0,0,AP,"AP_NOUPD","AP_NOUPD")
+ /* no args => explicit stack */
{
W_ Words;
W_ ap;
@@ -234,12 +234,12 @@ INFO_TABLE(stg_AP_NOUPD,/*special layout*/0,0,AP,"AP_NOUPD","AP_NOUPD")
Words = TO_W_(StgAP_n_args(ap));
/*
- * Check for stack overflow. IMPORTANT: use a _NP check here,
+ * Check for stack overflow. IMPORTANT: use a _ENTER check here,
* because if the check fails, we might end up blackholing this very
* closure, in which case we must enter the blackhole on return rather
* than continuing to evaluate the now-defunct closure.
*/
- STK_CHK_NP(WDS(Words));
+ STK_CHK_ENTER(WDS(Words), R1);
Sp = Sp - WDS(Words);
TICK_ENT_AP();
@@ -265,26 +265,26 @@ for:
TICK_ENT_VIA_NODE();
#ifdef NO_ARG_REGS
- jump %GET_ENTRY(UNTAG(R1));
+ jump %GET_ENTRY(UNTAG(R1)) [R1];
#else
W_ info;
info = %GET_FUN_INFO(UNTAG(R1));
W_ type;
type = TO_W_(StgFunInfoExtra_fun_type(info));
if (type == ARG_GEN) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_GEN_BIG) {
- jump StgFunInfoExtra_slow_apply(info);
+ jump StgFunInfoExtra_slow_apply(info) [R1];
}
if (type == ARG_BCO) {
Sp_adj(-2);
Sp(1) = R1;
Sp(0) = stg_apply_interp_info;
- jump stg_yield_to_interpreter;
+ jump stg_yield_to_interpreter [];
}
jump W_[stg_ap_stack_entries +
- WDS(TO_W_(StgFunInfoExtra_fun_type(info)))];
+ WDS(TO_W_(StgFunInfoExtra_fun_type(info)))] [R1];
#endif
}
@@ -300,6 +300,7 @@ for:
-------------------------------------------------------------------------- */
INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK")
+ /* no args => explicit stack */
{
W_ Words;
W_ ap;
@@ -309,12 +310,12 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK")
Words = StgAP_STACK_size(ap);
/*
- * Check for stack overflow. IMPORTANT: use a _NP check here,
+ * Check for stack overflow. IMPORTANT: use a _ENTER check here,
* because if the check fails, we might end up blackholing this very
* closure, in which case we must enter the blackhole on return rather
* than continuing to evaluate the now-defunct closure.
*/
- STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame + WDS(AP_STACK_SPLIM));
+ STK_CHK_ENTER(WDS(Words) + SIZEOF_StgUpdateFrame + WDS(AP_STACK_SPLIM), R1);
/* ensure there is at least AP_STACK_SPLIM words of headroom available
* after unpacking the AP_STACK. See bug #1466 */
@@ -343,7 +344,7 @@ for:
R1 = StgAP_STACK_fun(ap);
- ENTER();
+ ENTER_R1();
}
/* -----------------------------------------------------------------------------
@@ -352,6 +353,7 @@ for:
INFO_TABLE(stg_AP_STACK_NOUPD,/*special layout*/0,0,AP_STACK,
"AP_STACK_NOUPD","AP_STACK_NOUPD")
+ /* no args => explicit stack */
{
W_ Words;
W_ ap;
@@ -366,7 +368,7 @@ INFO_TABLE(stg_AP_STACK_NOUPD,/*special layout*/0,0,AP_STACK,
* closure, in which case we must enter the blackhole on return rather
* than continuing to evaluate the now-defunct closure.
*/
- STK_CHK_NP(WDS(Words) + WDS(AP_STACK_SPLIM));
+ STK_CHK_ENTER(WDS(Words) + WDS(AP_STACK_SPLIM), R1);
/* ensure there is at least AP_STACK_SPLIM words of headroom available
* after unpacking the AP_STACK. See bug #1466 */
@@ -394,5 +396,5 @@ for:
R1 = StgAP_STACK_fun(ap);
- ENTER();
+ ENTER_R1();
}