Skip to content

Commit 77a3093

Browse files
authored
Optimize zeroing (#389)
1 parent 64acb8e commit 77a3093

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

playground/umka.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/umka_gen.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,31 @@ static Instruction *getPrevInstr(CodeGen *gen, int depth)
9393
}
9494

9595

96+
static bool optimizePushLocalPtr(CodeGen *gen, int offset)
97+
{
98+
Instruction *prev = getPrevInstr(gen, 1), *prev2 = getPrevInstr(gen, 2);
99+
100+
// Optimization: PUSH_LOCAL_PTR + ZERO + PUSH_LOCAL_PTR -> PUSH_LOCAL_PTR_ZERO
101+
if (prev && prev->opcode == OP_ZERO &&
102+
prev2 && prev2->opcode == OP_PUSH_LOCAL_PTR)
103+
{
104+
if (offset == prev2->operand.intVal)
105+
{
106+
const int size = prev->operand.intVal;
107+
108+
genRemoveInstr(gen);
109+
genRemoveInstr(gen);
110+
genPushLocalPtrZero(gen, offset, size);
111+
112+
genUnnotify(gen);
113+
return true;
114+
}
115+
}
116+
117+
return false;
118+
}
119+
120+
96121
static bool optimizePushReg(CodeGen *gen, int regIndex)
97122
{
98123
Instruction *prev = getPrevInstr(gen, 1);
@@ -433,7 +458,17 @@ void genPushGlobalPtr(CodeGen *gen, void *ptrVal)
433458

434459
void genPushLocalPtr(CodeGen *gen, int offset)
435460
{
436-
const Instruction instr = {.opcode = OP_PUSH_LOCAL_PTR, .tokKind = TOK_NONE, .typeKind = TYPE_NONE, .operand.intVal = offset};
461+
if (!optimizePushLocalPtr(gen, offset))
462+
{
463+
const Instruction instr = {.opcode = OP_PUSH_LOCAL_PTR, .tokKind = TOK_NONE, .typeKind = TYPE_NONE, .operand.intVal = offset};
464+
genAddInstr(gen, &instr);
465+
}
466+
}
467+
468+
469+
void genPushLocalPtrZero(CodeGen *gen, int offset, int size)
470+
{
471+
const Instruction instr = {.opcode = OP_PUSH_LOCAL_PTR_ZERO, .tokKind = TOK_NONE, .typeKind = TYPE_NONE, .operand.int32Val = {offset, size}};
437472
genAddInstr(gen, &instr);
438473
}
439474

src/umka_gen.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,17 @@ void genFree(CodeGen *gen);
4848

4949
void genNop(CodeGen *gen);
5050

51-
void genPushIntConst (CodeGen *gen, int64_t intVal);
52-
void genPushUIntConst(CodeGen *gen, uint64_t uintVal);
53-
void genPushRealConst(CodeGen *gen, double realVal);
54-
void genPushGlobalPtr(CodeGen *gen, void *ptrVal);
55-
void genPushLocalPtr (CodeGen *gen, int offset);
56-
void genPushLocal (CodeGen *gen, TypeKind typeKind, int offset);
57-
void genPushReg (CodeGen *gen, int regIndex);
58-
void genPushStruct (CodeGen *gen, int size);
59-
void genPushUpvalue (CodeGen *gen);
60-
void genPushZero (CodeGen *gen, int slots);
51+
void genPushIntConst (CodeGen *gen, int64_t intVal);
52+
void genPushUIntConst (CodeGen *gen, uint64_t uintVal);
53+
void genPushRealConst (CodeGen *gen, double realVal);
54+
void genPushGlobalPtr (CodeGen *gen, void *ptrVal);
55+
void genPushLocalPtr (CodeGen *gen, int offset);
56+
void genPushLocalPtrZero(CodeGen *gen, int offset, int size);
57+
void genPushLocal (CodeGen *gen, TypeKind typeKind, int offset);
58+
void genPushReg (CodeGen *gen, int regIndex);
59+
void genPushStruct (CodeGen *gen, int size);
60+
void genPushUpvalue (CodeGen *gen);
61+
void genPushZero (CodeGen *gen, int slots);
6162

6263
void genPop (CodeGen *gen);
6364
void genPopReg(CodeGen *gen, int regIndex);

src/umka_vm.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ static const char *opcodeSpelling [] =
2929
"PUSH",
3030
"PUSH_ZERO",
3131
"PUSH_LOCAL_PTR",
32+
"PUSH_LOCAL_PTR_ZERO",
3233
"PUSH_LOCAL",
3334
"PUSH_REG",
3435
"PUSH_STRUCT",
@@ -2494,15 +2495,22 @@ static FORCE_INLINE void doPushZero(Fiber *fiber, Error *error)
24942495

24952496
static FORCE_INLINE void doPushLocalPtr(Fiber *fiber)
24962497
{
2497-
// Local variable addresses are offsets (in bytes) from the stack/heap frame base pointer
24982498
(--fiber->top)->ptrVal = (int8_t *)fiber->base + fiber->code[fiber->ip].operand.intVal;
24992499
fiber->ip++;
25002500
}
25012501

25022502

2503+
static FORCE_INLINE void doPushLocalPtrZero(Fiber *fiber)
2504+
{
2505+
(--fiber->top)->ptrVal = (int8_t *)fiber->base + fiber->code[fiber->ip].operand.int32Val[0];
2506+
int size = fiber->code[fiber->ip].operand.int32Val[1];
2507+
memset(fiber->top->ptrVal, 0, size);
2508+
fiber->ip++;
2509+
}
2510+
2511+
25032512
static FORCE_INLINE void doPushLocal(Fiber *fiber, Error *error)
25042513
{
2505-
// Local variable addresses are offsets (in bytes) from the stack/heap frame base pointer
25062514
(--fiber->top)->ptrVal = (int8_t *)fiber->base + fiber->code[fiber->ip].operand.intVal;
25072515
doBasicDeref(fiber->top, fiber->code[fiber->ip].typeKind, error);
25082516
fiber->ip++;
@@ -3325,6 +3333,7 @@ static FORCE_INLINE void vmLoop(VM *vm)
33253333
case OP_PUSH: doPush(fiber, error); break;
33263334
case OP_PUSH_ZERO: doPushZero(fiber, error); break;
33273335
case OP_PUSH_LOCAL_PTR: doPushLocalPtr(fiber); break;
3336+
case OP_PUSH_LOCAL_PTR_ZERO: doPushLocalPtrZero(fiber); break;
33283337
case OP_PUSH_LOCAL: doPushLocal(fiber, error); break;
33293338
case OP_PUSH_REG: doPushReg(fiber); break;
33303339
case OP_PUSH_STRUCT: doPushStruct(fiber, error); break;
@@ -3489,6 +3498,7 @@ int vmAsm(int ip, Instruction *code, DebugInfo *debugPerInstr, char *buf, int si
34893498
chars += snprintf(buf + chars, nonneg(size - chars), " %s (%lld)", fnName, (long long int)instr->operand.intVal);
34903499
break;
34913500
}
3501+
case OP_PUSH_LOCAL_PTR_ZERO:
34923502
case OP_GET_ARRAY_PTR: chars += snprintf(buf + chars, nonneg(size - chars), " %d %d", (int)instr->operand.int32Val[0], (int)instr->operand.int32Val[1]); break;
34933503
case OP_CALL_EXTERN: chars += snprintf(buf + chars, nonneg(size - chars), " %p", instr->operand.ptrVal); break;
34943504
case OP_CALL_BUILTIN: chars += snprintf(buf + chars, nonneg(size - chars), " %s", builtinSpelling[instr->operand.builtinVal]); break;

src/umka_vm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef enum
3636
OP_PUSH,
3737
OP_PUSH_ZERO,
3838
OP_PUSH_LOCAL_PTR,
39+
OP_PUSH_LOCAL_PTR_ZERO,
3940
OP_PUSH_LOCAL,
4041
OP_PUSH_REG,
4142
OP_PUSH_STRUCT,

0 commit comments

Comments
 (0)