root/lj_target.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. exitstub_addr_

   1 /*
   2 ** Definitions for target CPU.
   3 ** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
   4 */
   5 
   6 #ifndef _LJ_TARGET_H
   7 #define _LJ_TARGET_H
   8 
   9 #include "lj_def.h"
  10 #include "lj_arch.h"
  11 
  12 /* -- Registers and spill slots ------------------------------------------- */
  13 
  14 /* Register type (uint8_t in ir->r). */
  15 typedef uint32_t Reg;
  16 
  17 /* The hi-bit is NOT set for an allocated register. This means the value
  18 ** can be directly used without masking. The hi-bit is set for a register
  19 ** allocation hint or for RID_INIT, RID_SINK or RID_SUNK.
  20 */
  21 #define RID_NONE                0x80
  22 #define RID_MASK                0x7f
  23 #define RID_INIT                (RID_NONE|RID_MASK)
  24 #define RID_SINK                (RID_INIT-1)
  25 #define RID_SUNK                (RID_INIT-2)
  26 
  27 #define ra_noreg(r)             ((r) & RID_NONE)
  28 #define ra_hasreg(r)            (!((r) & RID_NONE))
  29 
  30 /* The ra_hashint() macro assumes a previous test for ra_noreg(). */
  31 #define ra_hashint(r)           ((r) < RID_SUNK)
  32 #define ra_gethint(r)           ((Reg)((r) & RID_MASK))
  33 #define ra_sethint(rr, r)       rr = (uint8_t)((r)|RID_NONE)
  34 #define ra_samehint(r1, r2)     (ra_gethint((r1)^(r2)) == 0)
  35 
  36 /* Spill slot 0 means no spill slot has been allocated. */
  37 #define SPS_NONE                0
  38 
  39 #define ra_hasspill(s)          ((s) != SPS_NONE)
  40 
  41 /* Combined register and spill slot (uint16_t in ir->prev). */
  42 typedef uint32_t RegSP;
  43 
  44 #define REGSP(r, s)             ((r) + ((s) << 8))
  45 #define REGSP_HINT(r)           ((r)|RID_NONE)
  46 #define REGSP_INIT              REGSP(RID_INIT, 0)
  47 
  48 #define regsp_reg(rs)           ((rs) & 255)
  49 #define regsp_spill(rs)         ((rs) >> 8)
  50 #define regsp_used(rs) \
  51   (((rs) & ~REGSP(RID_MASK, 0)) != REGSP(RID_NONE, 0))
  52 
  53 /* -- Register sets ------------------------------------------------------- */
  54 
  55 /* Bitset for registers. 32 registers suffice for most architectures.
  56 ** Note that one set holds bits for both GPRs and FPRs.
  57 */
  58 #if LJ_TARGET_PPC || LJ_TARGET_MIPS
  59 typedef uint64_t RegSet;
  60 #else
  61 typedef uint32_t RegSet;
  62 #endif
  63 
  64 #define RID2RSET(r)             (((RegSet)1) << (r))
  65 #define RSET_EMPTY              ((RegSet)0)
  66 #define RSET_RANGE(lo, hi)      ((RID2RSET((hi)-(lo))-1) << (lo))
  67 
  68 #define rset_test(rs, r)        ((int)((rs) >> (r)) & 1)
  69 #define rset_set(rs, r)         (rs |= RID2RSET(r))
  70 #define rset_clear(rs, r)       (rs &= ~RID2RSET(r))
  71 #define rset_exclude(rs, r)     (rs & ~RID2RSET(r))
  72 #if LJ_TARGET_PPC || LJ_TARGET_MIPS
  73 #define rset_picktop(rs)        ((Reg)(__builtin_clzll(rs)^63))
  74 #define rset_pickbot(rs)        ((Reg)__builtin_ctzll(rs))
  75 #else
  76 #define rset_picktop(rs)        ((Reg)lj_fls(rs))
  77 #define rset_pickbot(rs)        ((Reg)lj_ffs(rs))
  78 #endif
  79 
  80 /* -- Register allocation cost -------------------------------------------- */
  81 
  82 /* The register allocation heuristic keeps track of the cost for allocating
  83 ** a specific register:
  84 **
  85 ** A free register (obviously) has a cost of 0 and a 1-bit in the free mask.
  86 **
  87 ** An already allocated register has the (non-zero) IR reference in the lowest
  88 ** bits and the result of a blended cost-model in the higher bits.
  89 **
  90 ** The allocator first checks the free mask for a hit. Otherwise an (unrolled)
  91 ** linear search for the minimum cost is used. The search doesn't need to
  92 ** keep track of the position of the minimum, which makes it very fast.
  93 ** The lowest bits of the minimum cost show the desired IR reference whose
  94 ** register is the one to evict.
  95 **
  96 ** Without the cost-model this degenerates to the standard heuristics for
  97 ** (reverse) linear-scan register allocation. Since code generation is done
  98 ** in reverse, a live interval extends from the last use to the first def.
  99 ** For an SSA IR the IR reference is the first (and only) def and thus
 100 ** trivially marks the end of the interval. The LSRA heuristics says to pick
 101 ** the register whose live interval has the furthest extent, i.e. the lowest
 102 ** IR reference in our case.
 103 **
 104 ** A cost-model should take into account other factors, like spill-cost and
 105 ** restore- or rematerialization-cost, which depend on the kind of instruction.
 106 ** E.g. constants have zero spill costs, variant instructions have higher
 107 ** costs than invariants and PHIs should preferably never be spilled.
 108 **
 109 ** Here's a first cut at simple, but effective blended cost-model for R-LSRA:
 110 ** - Due to careful design of the IR, constants already have lower IR
 111 **   references than invariants and invariants have lower IR references
 112 **   than variants.
 113 ** - The cost in the upper 16 bits is the sum of the IR reference and a
 114 **   weighted score. The score currently only takes into account whether
 115 **   the IRT_ISPHI bit is set in the instruction type.
 116 ** - The PHI weight is the minimum distance (in IR instructions) a PHI
 117 **   reference has to be further apart from a non-PHI reference to be spilled.
 118 ** - It should be a power of two (for speed) and must be between 2 and 32768.
 119 **   Good values for the PHI weight seem to be between 40 and 150.
 120 ** - Further study is required.
 121 */
 122 #define REGCOST_PHI_WEIGHT      64
 123 
 124 /* Cost for allocating a specific register. */
 125 typedef uint32_t RegCost;
 126 
 127 /* Note: assumes 16 bit IRRef1. */
 128 #define REGCOST(cost, ref)      ((RegCost)(ref) + ((RegCost)(cost) << 16))
 129 #define regcost_ref(rc)         ((IRRef1)(rc))
 130 
 131 #define REGCOST_T(t) \
 132   ((RegCost)((t)&IRT_ISPHI) * (((RegCost)(REGCOST_PHI_WEIGHT)<<16)/IRT_ISPHI))
 133 #define REGCOST_REF_T(ref, t)   (REGCOST((ref), (ref)) + REGCOST_T((t)))
 134 
 135 /* -- Target-specific definitions ----------------------------------------- */
 136 
 137 #if LJ_TARGET_X86ORX64
 138 #include "lj_target_x86.h"
 139 #elif LJ_TARGET_ARM
 140 #include "lj_target_arm.h"
 141 #elif LJ_TARGET_PPC
 142 #include "lj_target_ppc.h"
 143 #elif LJ_TARGET_MIPS
 144 #include "lj_target_mips.h"
 145 #else
 146 #error "Missing include for target CPU"
 147 #endif
 148 
 149 #ifdef EXITSTUBS_PER_GROUP
 150 /* Return the address of an exit stub. */
 151 static LJ_AINLINE char *exitstub_addr_(char **group, uint32_t exitno)
 152 {
 153   lua_assert(group[exitno / EXITSTUBS_PER_GROUP] != NULL);
 154   return (char *)group[exitno / EXITSTUBS_PER_GROUP] +
 155          EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP);
 156 }
 157 /* Avoid dependence on lj_jit.h if only including lj_target.h. */
 158 #define exitstub_addr(J, exitno) \
 159   ((MCode *)exitstub_addr_((char **)((J)->exitstubgroup), (exitno)))
 160 #endif
 161 
 162 #endif

/* [<][>][^][v][top][bottom][index][help] */