Skip to content

Commit

Permalink
[JIT] Use bitmap for free register set
Browse files Browse the repository at this point in the history
Registers are represented as small integers. A bitmap supports all the
operations we need for registers in constant time and space.
  • Loading branch information
bdw committed Dec 10, 2018
1 parent 74a6f5a commit 85ec95b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 30 deletions.
4 changes: 4 additions & 0 deletions src/core/bitmap.h
Expand Up @@ -32,6 +32,10 @@ MVM_STATIC_INLINE void MVM_bitmap_set(MVMBitmap *bits, MVMint32 idx) {
bits[idx >> 6] |= (UINT64_C(1) << (idx & 0x3f));
}

MVM_STATIC_INLINE void MVM_bitmap_set_low(MVMBitmap *bits, MVMint32 idx) {
*bits |= (UINT64_C(1) << (idx & 0x3f));
}

MVM_STATIC_INLINE MVMuint64 MVM_bitmap_get(MVMBitmap *bits, MVMint32 idx) {
return bits[idx >> 6] & (UINT64_C(1) << (idx & 0x3f));
}
Expand Down
2 changes: 1 addition & 1 deletion src/jit/expr.h
Expand Up @@ -19,7 +19,7 @@ MVM_JIT_EXPR_OPS(MVM_JIT_OP_ENUM)
};

/* samcv++ for this trick */
#define MVM_STATIC_ASSERT(x) typedef char __ASSERT[(x)?1:-1];
#define MVM_STATIC_ASSERT(x) typedef char __ASSERT[(x)?1:-1]

/* Tree node information for easy access and use during compilation (a
symbol table entry of sorts) */
Expand Down
2 changes: 1 addition & 1 deletion src/jit/internal.h
Expand Up @@ -98,7 +98,7 @@ enum {
MVM_JIT_ARCH_GPR(MVM_JIT_REG)
};
enum {
MVM_JIT_ARCH_NUM(MVM_JIT_REG)
MVM_JIT_ARCH_FPR(MVM_JIT_REG)
};
/* it's a ridiculous, dangerous macro and it shouldn't escape */
#undef __COMMA__
Expand Down
33 changes: 10 additions & 23 deletions src/jit/linear_scan.c
Expand Up @@ -5,9 +5,6 @@
static MVMint8 available_gpr[] = {
MVM_JIT_ARCH_AVAILABLE_GPR(MVM_JIT_REG)
};
static MVMint8 available_num[] = {
MVM_JIT_ARCH_NUM(MVM_JIT_REG)
};
/* bitmap, so make it '|' to combine the shifted register numbers */
#undef __COMMA__
#define __COMMA__ |
Expand Down Expand Up @@ -99,11 +96,8 @@ typedef struct {
/* Spilled values */
MVM_VECTOR_DECL(MVMint32, spilled);


/* Register handout ring */
MVMint8 reg_ring[MAX_ACTIVE];
MVMint32 reg_give, reg_take;

/* Currently free registers */
MVMBitmap reg_free;
} RegisterAllocator;


Expand Down Expand Up @@ -343,22 +337,18 @@ MVMint32 values_cmp_last_ref(LiveRange *values, MVMint32 a, MVMint32 b) {
#define NEXT_IN_RING(a,x) (((x)+1) == MVM_ARRAY_SIZE(a) ? 0 : ((x)+1))
MVMint8 get_register(MVMThreadContext *tc, RegisterAllocator *alc, MVMJitStorageClass reg_cls) {
/* ignore storage class for now */
MVMint8 reg_num;
reg_num = alc->reg_ring[alc->reg_take];
MVMint8 reg_num = MVM_FFS(alc->reg_free) - 1;
if (reg_num >= 0) {
/* not empty */
alc->reg_ring[alc->reg_take] = -1; /* mark used */
alc->reg_take = NEXT_IN_RING(alc->reg_ring, alc->reg_take);
MVM_bitmap_delete(&alc->reg_free, reg_num);
}
return reg_num;
}

void free_register(MVMThreadContext *tc, RegisterAllocator *alc, MVMJitStorageClass reg_cls, MVMint8 reg_num) {
if (alc->reg_ring[alc->reg_give] != -1) {
MVM_oops(tc, "No space to release register %d to ring", reg_num);
if (MVM_bitmap_get_low(alc->reg_free, reg_num)) {
MVM_oops(tc, "Register %d is already free", reg_num);
}
alc->reg_ring[alc->reg_give] = reg_num;
alc->reg_give = NEXT_IN_RING(alc->reg_ring, alc->reg_give);
MVM_bitmap_set_low(&alc->reg_free, reg_num);
}

void assign_register(MVMThreadContext *tc, RegisterAllocator *alc, MVMJitTileList *list,
Expand Down Expand Up @@ -576,8 +566,8 @@ static void determine_live_ranges(MVMThreadContext *tc, RegisterAllocator *alc,
}
if (MVM_JIT_TILE_YIELDS_VALUE(tile) && MVM_JIT_EXPR_INFO(tree, node)->type != 0) {
LiveRange *range = alc->values + value_set_find(alc->sets, node)->idx;
// compare only the lower bits, because (for the moment) we don't care about signed/unsigned
// difference, not for storage anyway
/* compare only the lower bits, because (for storage purposes) we
* don't care about the signed/unsigned disticntion */
_ASSERT(range->reg_type == 0 || (range->reg_type & 0xf) == (MVM_JIT_EXPR_INFO(tree, node)->type & 0xf),
"Register types do not match between value and node");
/* shift to match MVM_reg_types. should arguably be a macro maybe */
Expand Down Expand Up @@ -1135,10 +1125,7 @@ void MVM_jit_linear_scan_allocate(MVMThreadContext *tc, MVMJitCompiler *compiler
alc.active_top = 0;
memset(alc.active, -1, sizeof(alc.active));

alc.reg_give = alc.reg_take = 0;
memcpy(alc.reg_ring, available_gpr,
sizeof(available_gpr));

alc.reg_free = AVAILABLE_GPR_BITMAP;
/* run algorithm */
determine_live_ranges(tc, &alc, list);
linear_scan(tc, &alc, list);
Expand Down
26 changes: 21 additions & 5 deletions src/jit/x64/arch.h
Expand Up @@ -18,15 +18,23 @@
_(R15)


#define MVM_JIT_ARCH_NUM(_) \
#define MVM_JIT_ARCH_FPR(_) \
_(XMM0) __COMMA__ \
_(XMM1) __COMMA__ \
_(XMM2) __COMMA__ \
_(XMM3) __COMMA__ \
_(XMM4) __COMMA__ \
_(XMM5) __COMMA__ \
_(XMM6) __COMMA__ \
_(XMM7)
_(XMM7) __COMMA__ \
_(XMM8) __COMMA__ \
_(XMM9) __COMMA__ \
_(XMM10) __COMMA__ \
_(XMM11) __COMMA__ \
_(XMM12) __COMMA__ \
_(XMM13) __COMMA__ \
_(XMM14) __COMMA__ \
_(XMM15)


#if MVM_JIT_PLATFORM == MVM_JIT_PLATFORM_POSIX
Expand Down Expand Up @@ -66,8 +74,15 @@

/* SSE used for arguments */

#define MVM_JIT_ARCH_ARG_NUM(_) \
MVM_JIT_ARCH_NUM(_)
#define MVM_JIT_ARCH_ARG_FPR(_) \
_(XMM0) __COMMA__ \
_(XMM1) __COMMA__ \
_(XMM2) __COMMA__ \
_(XMM3) __COMMA__ \
_(XMM4) __COMMA__ \
_(XMM5) __COMMA__ \
_(XMM6) __COMMA__ \
_(XMM7)

#else

Expand Down Expand Up @@ -95,7 +110,7 @@
_(RDX) __COMMA__ \
_(R8) __COMMA__ \
_(R9)
#define MVM_JIT_ARCH_ARG_NUM(_) \
#define MVM_JIT_ARCH_ARG_FPR(_) \
_(XMM0) __COMMA__ \
_(XMM1) __COMMA__ \
_(XMM2) __COMMA__ \
Expand All @@ -104,3 +119,4 @@

/* Frame declarations */
#define MVM_JIT_ARCH_NUM_GPR 16
#define MVM_JIT_ARCH_NUM_FPR 16

0 comments on commit 85ec95b

Please sign in to comment.