Try out unboxing integers.

This commit is contained in:
Danila Fedorin 2020-09-10 17:32:16 -07:00
parent 362d9b05dc
commit 30b7b4143b
2 changed files with 14 additions and 16 deletions

View File

@ -225,12 +225,7 @@ Value* llvm_context::unwrap_gmachine_stack_ptr(Value* g) {
} }
Value* llvm_context::unwrap_num(Value* v) { Value* llvm_context::unwrap_num(Value* v) {
auto num_ptr_type = PointerType::getUnqual(struct_types.at("node_num")); return builder.CreatePtrToInt(v, IntegerType::getInt32Ty(ctx));
auto cast = builder.CreatePointerCast(v, num_ptr_type);
auto offset_0 = create_i32(0);
auto offset_1 = create_i32(1);
auto int_ptr = builder.CreateGEP(cast, { offset_0, offset_1 });
return builder.CreateLoad(int_ptr);
} }
Value* llvm_context::create_num(Function* f, Value* v) { Value* llvm_context::create_num(Function* f, Value* v) {
auto alloc_num_f = functions.at("alloc_num"); auto alloc_num_f = functions.at("alloc_num");

View File

@ -1,9 +1,13 @@
#include <bits/stdint-intn.h>
#include <stdint.h> #include <stdint.h>
#include <assert.h> #include <assert.h>
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
#include "runtime.h" #include "runtime.h"
#define INT_MARKER (1l << 63)
#define IS_INT(n) ((uint64_t) n & INT_MARKER)
struct node_base* alloc_node() { struct node_base* alloc_node() {
struct node_base* new_node = malloc(sizeof(struct node_app)); struct node_base* new_node = malloc(sizeof(struct node_app));
new_node->gc_next = NULL; new_node->gc_next = NULL;
@ -21,10 +25,7 @@ struct node_app* alloc_app(struct node_base* l, struct node_base* r) {
} }
struct node_num* alloc_num(int32_t n) { struct node_num* alloc_num(int32_t n) {
struct node_num* node = (struct node_num*) alloc_node(); return (struct node_num*) (INT_MARKER | n);
node->base.tag = NODE_NUM;
node->value = n;
return node;
} }
struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) { struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) {
@ -49,7 +50,7 @@ void free_node_direct(struct node_base* n) {
} }
void gc_visit_node(struct node_base* n) { void gc_visit_node(struct node_base* n) {
if(n->gc_reachable) return; if(IS_INT(n) || n->gc_reachable) return;
n->gc_reachable = 1; n->gc_reachable = 1;
if(n->tag == NODE_APP) { if(n->tag == NODE_APP) {
@ -169,6 +170,7 @@ void gmachine_split(struct gmachine* g, size_t n) {
} }
struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) { struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) {
if(IS_INT(b)) return b;
g->gc_node_count++; g->gc_node_count++;
b->gc_next = g->gc_nodes; b->gc_next = g->gc_nodes;
g->gc_nodes = b; g->gc_nodes = b;
@ -208,7 +210,9 @@ void unwind(struct gmachine* g) {
while(1) { while(1) {
struct node_base* peek = stack_peek(s, 0); struct node_base* peek = stack_peek(s, 0);
if(peek->tag == NODE_APP) { if(IS_INT(peek)) {
break;
} else if(peek->tag == NODE_APP) {
struct node_app* n = (struct node_app*) peek; struct node_app* n = (struct node_app*) peek;
stack_push(s, n->left); stack_push(s, n->left);
} else if(peek->tag == NODE_GLOBAL) { } else if(peek->tag == NODE_GLOBAL) {
@ -234,7 +238,9 @@ void unwind(struct gmachine* g) {
extern void f_main(struct gmachine* s); extern void f_main(struct gmachine* s);
void print_node(struct node_base* n) { void print_node(struct node_base* n) {
if(n->tag == NODE_APP) { if(IS_INT(n)) {
printf("%d", (int32_t) n);
} else if(n->tag == NODE_APP) {
struct node_app* app = (struct node_app*) n; struct node_app* app = (struct node_app*) n;
print_node(app->left); print_node(app->left);
putchar(' '); putchar(' ');
@ -246,9 +252,6 @@ void print_node(struct node_base* n) {
printf("(Global: %p)", global->function); printf("(Global: %p)", global->function);
} else if(n->tag == NODE_IND) { } else if(n->tag == NODE_IND) {
print_node(((struct node_ind*) n)->next); print_node(((struct node_ind*) n)->next);
} else if(n->tag == NODE_NUM) {
struct node_num* num = (struct node_num*) n;
printf("%d", num->value);
} }
} }