RTS tidyup sweep, first phase
[ghc-hetmet.git] / includes / Cmm.h
index d47e6fd..aba5c2e 100644 (file)
@@ -25,7 +25,7 @@
  *       - Hp += n  ==> Hp_adj(n)
  *       - R1.i   ==>  R1   (similarly for R1.w, R1.cl etc.)
  *       - You need to explicitly dereference variables; eg. 
- *             context_switch   ==>  CInt[context_switch]
+ *             alloc_blocks   ==>  CInt[alloc_blocks]
  *       - convert all word offsets into byte offsets:
  *             - e ==> WDS(e)
  *       - sizeofW(StgFoo)  ==>  SIZEOF_StgFoo
@@ -66,7 +66,6 @@
 #define CMINUSMINUS 1
 
 #include "ghcconfig.h"
-#include "RtsConfig.h"
 
 /* -----------------------------------------------------------------------------
    Types 
@@ -88,6 +87,7 @@
 #define I16 bits16
 #define I32 bits32
 #define I64 bits64
+#define P_  gcptr
 
 #if SIZEOF_VOID_P == 4
 #define W_ bits32
 #endif
 
 /*
- * The RTS must UNTAG a pointer before dereferencing it.
- * The use of UNTAG follows the following rules of thumb:
- *
- * - Any pointer might be tagged.
- * - Except the pointers that are passed in R1 to RTS functions.
- * - R1 is also untagged when entering constructor code.
- * 
- * TODO:
- *
- * - Remove redundancies of tagging and untagging in code generation.
- * - Optimize getTag or dataToTag# ?
- *
+ * The RTS must sometimes UNTAG a pointer before dereferencing it.
+ * See the wiki page Commentary/Rts/HaskellExecution/PointerTagging 
  */
 #define TAG_MASK ((1 << TAG_BITS) - 1)
 #define UNTAG(p) (p & ~TAG_MASK)
        name : bits8[] str;                     \
   }                                            \
 
+#ifdef TABLES_NEXT_TO_CODE
+#define RET_LBL(f) f##_info
+#else
+#define RET_LBL(f) f##_ret
+#endif
+
+#ifdef TABLES_NEXT_TO_CODE
+#define ENTRY_LBL(f) f##_info
+#else
+#define ENTRY_LBL(f) f##_entry
+#endif
+
 /* -----------------------------------------------------------------------------
    Byte/word macros
 
    Indirections can contain tagged pointers, so their tag is checked.
    -------------------------------------------------------------------------- */
 
+#ifdef PROFILING
+
+// When profiling, we cannot shortcut ENTER() by checking the tag,
+// because LDV profiling relies on entering closures to mark them as
+// "used".
+
+#define LOAD_INFO \
+    info = %INFO_PTR(UNTAG(P1));
+
+#define UNTAG_R1 \
+    P1 = UNTAG(P1);
+
+#else
+
+#define LOAD_INFO                               \
+  if (GETTAG(P1) != 0) {                        \
+      jump %ENTRY_CODE(Sp(0));                  \
+  }                                             \
+  info = %INFO_PTR(P1);
+
+#define UNTAG_R1 /* nothing */
+
+#endif
+
 #define ENTER()                                                \
  again:                                                        \
   W_ info;                                             \
-  if (GETTAG(R1) != 0) {                                \
-      jump %ENTRY_CODE(Sp(0));                         \
-  }                                                     \
-  info = %INFO_PTR(R1);                                        \
+  LOAD_INFO                                             \
   switch [INVALID_OBJECT .. N_CLOSURE_TYPES]           \
          (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) {      \
   case                                                 \
     IND_OLDGEN_PERM,                                   \
     IND_STATIC:                                                \
    {                                                   \
-      R1 = StgInd_indirectee(R1);                      \
+      P1 = StgInd_indirectee(P1);                      \
       goto again;                                      \
    }                                                   \
   case                                                 \
     FUN_0_1,                                           \
     FUN_2_0,                                           \
     FUN_1_1,                                           \
+    FUN_0_2,                                           \
     FUN_STATIC,                                         \
     BCO,                                               \
     PAP:                                               \
    }                                                   \
   default:                                             \
    {                                                   \
+      UNTAG_R1                                          \
       jump %ENTRY_CODE(info);                          \
    }                                                   \
   }
    Constants.
    -------------------------------------------------------------------------- */
 
-#include "Constants.h"
+#include "rts/Constants.h"
 #include "DerivedConstants.h"
-#include "ClosureTypes.h"
-#include "StgFun.h"
-#include "OSThreads.h"
-#include "SMP.h"
+#include "rts/storage/ClosureTypes.h"
+#include "rts/storage/FunTypes.h"
+#include "rts/storage/SMPClosureOps.h"
+#include "rts/OSThreads.h"
 
 /*
  * Need MachRegs, because some of the RTS code is conditionally
  * compiled based on REG_R1, REG_R2, etc.
  */
 #define STOLEN_X86_REGS 4
-#include "MachRegs.h"
+#include "stg/MachRegs.h"
 
-#include "Liveness.h"
-#include "StgLdvProf.h"
+#include "rts/storage/Liveness.h"
+#include "rts/prof/LDV.h"
 
 #undef BLOCK_SIZE
 #undef MBLOCK_SIZE
-#include "Block.h"  /* For Bdescr() */
+#include "rts/storage/Block.h"  /* For Bdescr() */
 
 
-/* Can't think of a better place to put this. */
-#if SIZEOF_mp_limb_t != SIZEOF_VOID_P
-#error mp_limb_t != StgWord: assumptions in PrimOps.cmm are now false
-#endif
-
 #define MyCapability()  (BaseReg - OFFSET_Capability_r)
 
 /* -------------------------------------------------------------------------
 #define END_TSO_QUEUE             stg_END_TSO_QUEUE_closure
 #define END_INVARIANT_CHECK_QUEUE stg_END_INVARIANT_CHECK_QUEUE_closure
 
-#define dirtyTSO(tso) \
-    StgTSO_flags(tso) = StgTSO_flags(tso) | TSO_DIRTY::I32;
-
 #define recordMutableCap(p, gen, regs)                                 \
   W_ __bd;                                                             \
   W_ mut_list;                                                         \
   bdescr_free(__bd) = free + WDS(1);
 
 #define recordMutable(p, regs)                                  \
-      W_ __p;                                                   \
+      P_ __p;                                                   \
       W_ __bd;                                                  \
       W_ __gen;                                                 \
       __p = p;                                                  \