Skip to content

Instantly share code, notes, and snippets.

@ckoparkar
Created April 11, 2018 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ckoparkar/f97828bd53c0a2e97cddd3c0de4fd858 to your computer and use it in GitHub Desktop.
Save ckoparkar/f97828bd53c0a2e97cddd3c0de4fd858 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <stdio.h>
// #include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <alloca.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h> // For va_start etc
#include <errno.h>
#define KB (1 * 1000lu)
#define MB (KB * 1000lu)
#define GB (MB * 1000lu)
// Initial size of BigInfinite buffers
static long long global_init_biginf_buf_size = (5 * GB);
// Initial size of Infinite buffers
static long long global_init_inf_buf_size = 64 * KB;
static long long global_size_param = 1;
static long long global_iters_param = 1;
static char* global_benchfile_param = NULL;
// Sequential for now:
static const int num_workers = 1;
#define REDIRECTION_NODE_SIZE 9
#define MAX(a,b) (((a)>(b))?(a):(b))
// Helpers and debugging:
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
#ifdef BUMPALLOC
// #define DEBUG
#warning "Using bump allocator."
char* heap_ptr = (char*)NULL;
char* saved_heap_ptr_stack[100];
int num_saved_heap_ptr = 0;
// Requires -std=gnu11
int dbgprintf(const char *format, ...)
{
int code = 0;
va_list args;
va_start(args, format);
#ifdef DEBUG
code = vprintf(format, args);
#endif
va_end(args);
return code;
}
// For simplicity just use a single large slab:
void INITALLOC() {
if (! heap_ptr)
{
// Use a fixed address in debug mode for easy reading:
#ifdef DEBUG
// heap_ptr = (char*)mmap(0x010000000000, global_init_biginf_buf_size, PROT_READ|PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, -1, 0);
heap_ptr = (char*)mmap(0x010000000000, global_init_biginf_buf_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (heap_ptr == MAP_FAILED) {
fprintf(stderr, "Error: mmap failed: %s\n", strerror(errno));
abort();
}
#else
heap_ptr = (char*)malloc(global_init_biginf_buf_size);
#endif
dbgprintf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size);
}
dbgprintf("BUMPALLOC/INITALLOC DONE: heap_ptr = %p\n", heap_ptr);
}
#ifdef DEBUG
char* my_abort() {
fprintf(stderr, "Error: this thread's heap was not initalized.\n");
abort();
return NULL;
}
void* ALLOC(int n) {
if (!heap_ptr) my_abort();
char* old = heap_ptr;
printf("ALLOC: %d bytes, returning %p\n", n, old);
// heap_ptr += 16 * n; // Optional padding for debugging.
heap_ptr += n;
return old;
}
#else
// #define ALLOC(n) (do heap_ptr += n)
void* ALLOC(int n) { char* old= heap_ptr; heap_ptr += n; return old; }
#endif // DEBUG
// Snapshot the current heap pointer value across all threads.
void save_alloc_state() {
dbgprintf(" Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr);
saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr;
num_saved_heap_ptr++;
dbgprintf("\n");
}
void restore_alloc_state() {
if(num_saved_heap_ptr <= 0) {
fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne");
abort();
}
num_saved_heap_ptr--;
dbgprintf("Restoring(%p): pos %d, discarding %p",
saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, heap_ptr);
heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr];
}
#else
// Regular malloc mode:
void INITALLOC() {}
void save_alloc_state() {}
void restore_alloc_state() {}
#define ALLOC(n) malloc(n)
#endif // BUMPALLOC
#define ALLOC_PACKED(n) ALLOC(n)
// --------------------------------------------------------------------------------
typedef char TagTyPacked; // Must be consistent with codegen in Target.hs
typedef char TagTyBoxed; // Must be consistent with codegen in Target.hs
typedef long long IntTy;
typedef IntTy SymTy;
typedef char* PtrTy;
typedef char* CursorTy;
typedef struct dict_item {
struct dict_item * next;
int key;
union {
int intval;
void * ptrval;
};
} dict_item_t;
dict_item_t * dict_alloc() {
return ALLOC(sizeof(dict_item_t));
}
dict_item_t *dict_insert_int(dict_item_t *ptr, SymTy key, IntTy val) {
dict_item_t *ret = dict_alloc();
ret->key = key;
ret->intval = val;
ret->next = ptr;
return ret;
}
IntTy dict_lookup_int(dict_item_t *ptr, SymTy key) {
while (ptr != 0) {
if (ptr->key == key) {
return ptr->intval;
} else {
ptr = ptr->next;
}
}
printf("Error, key %lld not found!\n",key);
exit(1);
}
char* read_benchfile_param() {
if (global_benchfile_param == NULL) {
fprintf(stderr, "read_benchfile_param: benchmark input file was not set!\n");
exit(1);
} else
return global_benchfile_param;
}
// Could try alloca() here. Better yet, we could keep our own,
// separate stack and insert our own code to restore the pointer
// before any function that (may have) called ALLOC_SCOPED returns.
// #define ALLOC_SCOPED() alloca(1024)
#define ALLOC_SCOPED(n) alloca(n)
// #define ALLOC_SCOPED() alloc_scoped()
// Stack allocation is either too small or blows our stack.
// We need a way to make a giant stack if we want to use alloca.
// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size)
// Our global pointer. No parallelism.
// static char* stack_scoped_region;
// char* alloc_scoped() { return stack_scoped_region; }
// fun fact: __ prefix is actually reserved and this is an undefined behavior.
// These functions must be provided by the code generator.
void __main_expr();
void show_usage(char** argv)
{
printf("\n");
printf("This binary was generated by the Gibbon compiler.\n");
printf("\n");
printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]);
printf("\n");
printf("Options:\n");
printf(" --buffer-size <bytes> Set the buffer size (default %lld).\n", global_init_biginf_buf_size);
printf(" --bench-input <path> Set the input file read for benchmarking. Applies only\n");
printf(" IF the program was *compiled* with --bench-fun. \n");
return;
}
double avg(const double* arr, int n)
{
double sum = 0.0;
for(int i=0; i<n; i++) sum += arr[i];
return sum / (double)n;
}
double difftimespecs(struct timespec* t0, struct timespec* t1)
{
return (double)(t1->tv_sec - t0->tv_sec)
+ ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0);
}
int compare_doubles(const void *a, const void *b)
{
const double *da = (const double *) a;
const double *db = (const double *) b;
return (*da > *db) - (*da < *db);
}
/* Representation of regions at runtime:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| serialized data ...... | size (int) | refcount (int/ptr) | outset (ptr) |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The metadata after the serialized data serves various purposes:
- size: Used during bounds checking to calculate the size of the next region in the linked list.
- refcount and outset: Whenever an inter-region indirection is created, we record that information
using these two fields. Consier an example where we create an indirection from region A that points to
something in region B. Then A's outset will have that pointer in it, and B's refcount will be bumped
by 1. Note that the refcount doesn't necessarily have to be an `int` for every chunk of the region
(when using "infinite-regions"). The first chunk in the chain has the actual refcount, and every other
chunk has a reference to it.
*/
typedef struct RegionTy_struct {
int refcount;
CursorTy start_ptr;
} RegionTy;
typedef struct RegionFooter_struct {
IntTy size;
CursorTy refcount_ptr;
CursorTy outset_ptr;
CursorTy next;
} RegionFooter;
RegionTy* alloc_region(IntTy size) {
// Allocate the first chunk
IntTy total_size = size + sizeof(RegionFooter);
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + size;
RegionTy* reg = malloc(sizeof(RegionTy));
reg->refcount = 0;
reg->start_ptr = start;
// Write the footer
RegionFooter* footer = (RegionFooter *) end;
footer->size = size;
footer->refcount_ptr = &(reg->refcount);
footer->outset_ptr = NULL;
footer-> next = NULL;
*(RegionFooter *) end = *footer;
return reg;
}
typedef struct ChunkTy_struct {
CursorTy start_ptr;
CursorTy end_ptr;
} ChunkTy;
inline ChunkTy alloc_chunk(CursorTy end_ptr) {
// Get size from current footer
RegionFooter* footer = (RegionFooter *) end_ptr;
IntTy newsize = footer->size * 2;
IntTy total_size = newsize + sizeof(RegionFooter);
// Allocate
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + newsize;
// Link the next chunk's footer
footer->next = end;
// Write the footer
RegionFooter* new_footer = (RegionFooter *) end;
new_footer->size = newsize;
new_footer->refcount_ptr = footer->refcount_ptr;
new_footer->outset_ptr = NULL;
new_footer->next = NULL;
*(RegionFooter *) end = *new_footer;
return (ChunkTy) {start , end};
}
// Almost the same as 'alloc_chunk'. But this doesn't set
// some of the footer arguments and results in ~15-20% speedup.
// Inlining and the no-gc flag seem to work best.
// Do not use '-g' with when using this function!
//
// TODO: Why no-gc ?
inline ChunkTy alloc_chunk_no_gc(CursorTy end_ptr) {
// Get size from current footer
RegionFooter* footer = (RegionFooter *) end_ptr;
IntTy newsize = footer->size * 2;
IntTy total_size = newsize + sizeof(RegionFooter);
// Allocate
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + newsize;
/* // Link the next chunk's footer */
/* footer->next = end; */
// Write the footer
RegionFooter* new_footer = (RegionFooter *) end;
new_footer->size = newsize;
/* new_footer->refcount_ptr = footer->refcount_ptr; */
/* new_footer->outset_ptr = NULL; */
/* new_footer->next = NULL; */
*(RegionFooter *) end = *new_footer;
return (ChunkTy) {start , end};
}
int get_ref_count(CursorTy end_ptr) {
RegionFooter footer = *(RegionFooter *) end_ptr;
return *(footer.refcount_ptr);
}
// If B -> A, bump A's refcount, and update B's offset ptr
IntTy bump_ref_count(CursorTy end_b, CursorTy end_a) {
// Bump refcount
RegionFooter footer_a = *(RegionFooter *) end_a;
int refcount = *(footer_a.refcount_ptr);
*(int *) footer_a.refcount_ptr = refcount + 1;
// Add A to B's outset
RegionFooter* footer_b = (RegionFooter *) end_b;
if (footer_b->outset_ptr == NULL) {
footer_b->outset_ptr = end_a;
} else if (footer_b->outset_ptr != end_a) {
printf("Outset isn't a real set yet..");
}
return refcount;
}
void free_region(CursorTy reg_start, CursorTy reg_end) {
RegionFooter footer = *(RegionFooter *) reg_end;
CursorTy next_chunk = footer.next;
// Decrement refcounts of all regions `reg` points to
if (footer.outset_ptr != NULL) {
RegionFooter* xyz = (RegionFooter *) footer.outset_ptr;
*(xyz->refcount_ptr) = *(xyz->refcount_ptr) - 1;
}
// Free all chunks if recount is 0
if (*(footer.refcount_ptr) == 0) {
while (next_chunk != NULL) {
footer = *(RegionFooter *) next_chunk;
free(next_chunk - footer.size);
next_chunk = footer.next;
}
free(reg_start);
} else {
#ifdef DEBUG
printf("free_region: refcount non-zero.\n");
#endif
}
}
/* -------------------------------------------------------------------------------- */
int main(int argc, char** argv)
{
// parameters to parse:
//
// num iterations: How many times to repeat a benchmark.
// tree size: An integer passes to `build_tree()`.
struct rlimit lim;
int code;
if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) {
fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code);
abort();
}
// lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack.
lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack.
// lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this.
// WARNING: Haven't yet figured out why this doesn't work on MacOS...
#ifndef __APPLE__
code = setrlimit(RLIMIT_STACK, &lim);
while (code) {
fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code);
lim.rlim_cur /= 2;
// lim.rlim_max /= 2;
if(lim.rlim_cur < 100 * 1024) {
fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n");
break; // abort();
}
int code = setrlimit(RLIMIT_STACK, &lim);
}
#endif
// TODO: atoi() error checking
int got_numargs = 0; // How many numeric arguments have we got.
int i;
for (i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
show_usage(argv);
exit(0);
}
else if (strcmp(argv[i], "--buffer-size") == 0 && i < argc - 1)
{
global_init_biginf_buf_size = atoll(argv[i + 1]);
i++;
}
else if ((strcmp(argv[i], "--bench-input") == 0)) {
if (i+1 >= argc) {
fprintf(stderr, "Not enough arguments after -file, expected <file>.\n");
show_usage(argv);
exit(1);
}
global_benchfile_param = argv[i+1];
i++;
}
// If present, we expect the two arguments to be <size> <iters>
else if (got_numargs >= 2) {
fprintf(stderr, "Extra arguments left over: ");
for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]);
show_usage(argv);
exit(1);
} else {
if (got_numargs == 0) {
global_size_param = atoll(argv[i]);
got_numargs ++;
} else {
global_iters_param = atoll(argv[i]);
}
}
}
INITALLOC();
#ifdef BUMPALLOC
// save_alloc_state();
#endif
__main_expr();
return 0;
}
typedef struct Int64Prod_struct {
IntTy field0;
} Int64Prod;
typedef struct Int64CursorProd_struct {
IntTy field0;
CursorTy field1;
} Int64CursorProd;
typedef struct TagProd_struct {
TagTyPacked field0;
} TagProd;
typedef struct TagInt64Prod_struct {
TagTyPacked field0;
IntTy field1;
} TagInt64Prod;
typedef struct TagCursorProd_struct {
TagTyPacked field0;
CursorTy field1;
} TagCursorProd;
typedef struct TagCursorCursorProd_struct {
TagTyPacked field0;
CursorTy field1;
CursorTy field2;
} TagCursorCursorProd;
typedef struct CursorProd_struct {
CursorTy field0;
} CursorProd;
typedef struct CursorInt64Prod_struct {
CursorTy field0;
IntTy field1;
} CursorInt64Prod;
typedef struct CursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
} CursorCursorProd;
typedef struct CursorCursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
CursorTy field2;
} CursorCursorCursorProd;
typedef struct CursorCursorCursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
CursorTy field2;
CursorTy field3;
} CursorCursorCursorCursorProd;
typedef struct PtrProd_struct {
PtrTy field0;
} PtrProd;
typedef struct PtrCursorProd_struct {
PtrTy field0;
CursorTy field1;
} PtrCursorProd;
CursorCursorCursorCursorProd __attribute__((pure)) add1(CursorTy pvrtmp207,
CursorTy pvrtmp208,
CursorTy pvrtmp209,
CursorTy pvrtmp210);
CursorInt64Prod __attribute__((pure)) sumtree(CursorTy pvrtmp228,
CursorTy pvrtmp229);
CursorCursorCursorProd __attribute__((pure)) buildtree(CursorTy pvrtmp239,
CursorTy pvrtmp240,
IntTy pvrtmp241);
CursorCursorCursorCursorProd __attribute__((pure)) copy_Tree(CursorTy pvrtmp253,
CursorTy pvrtmp254,
CursorTy pvrtmp255,
CursorTy pvrtmp256);
PtrCursorProd unpack_Tree(CursorTy p274);
PtrTy print_Tree(CursorTy p289);
CursorCursorCursorCursorProd add1(CursorTy pvrtmp207, CursorTy pvrtmp208,
CursorTy pvrtmp209, CursorTy pvrtmp210)
{
CursorTy end_r33 = (CursorTy) pvrtmp207;
CursorTy end_r34 = (CursorTy) pvrtmp208;
CursorTy loc32 = (CursorTy) pvrtmp209;
CursorTy loc31 = (CursorTy) pvrtmp210;
CursorTy tr2 = (CursorTy) pvrtmp210;
TagTyPacked tmpval211 = *tr2;
CursorTy tmpcur212 = tr2 + 1;
switch227:
;
switch (tmpval211) {
case 0:
{
CursorTy tr2144 = (CursorTy) tmpcur212;
CursorTy case56 = (CursorTy) tr2144;
IntTy tmpval213 = *(IntTy *) case56;
CursorTy tmpcur214 = case56 + sizeof(IntTy);
IntTy n3 = (IntTy) tmpval213;
CursorTy end_n3 = (CursorTy) tmpcur214;
CursorTy jump115 = case56 + (IntTy) 8;
IntTy fltPkd14 = n3 + (IntTy) 1;
if (loc32 + 18 > end_r34) {
ChunkTy new_chunk0 = alloc_chunk_no_gc(end_r34);
CursorTy chunk_start1 = new_chunk0.start_ptr;
CursorTy chunk_end2 = new_chunk0.end_ptr;
end_r34 = chunk_end2;
*(TagTyPacked *) loc32 = 100;
CursorTy redir = loc32 + 1;
*(CursorTy *) redir = chunk_start1;
loc32 = chunk_start1;
}
*loc32 = 0;
CursorTy writetag146 = loc32 + 1;
*(IntTy *) writetag146 = fltPkd14;
CursorTy writecur147 = writetag146 + sizeof(IntTy);
CursorTy pvrtmp216 = (CursorTy) writecur147;
CursorTy pvrtmp215 = (CursorTy) loc32;
CursorTy taildc116 = (CursorTy) pvrtmp215;
CursorTy end_taildc116 = (CursorTy) pvrtmp216;
return (CursorCursorCursorCursorProd) {end_r34, jump115, taildc116,
end_taildc116};
break;
}
case 100:
{
CursorTy tmpcur303 = *(CursorTy *) tmpcur212;
CursorTy tmpaftercur304 = tmpcur212 + 8;
TagTyPacked tagtmp305 = *tmpcur303;
CursorTy tailtmp306 = tmpcur303 + 1;
tmpval211 = tagtmp305;
tmpcur212 = tailtmp306;
goto switch227;
break;
}
case 90:
{
CursorTy tmpcur303 = *(CursorTy *) tmpcur212;
CursorTy tmpaftercur304 = tmpcur212 + 8;
TagTyPacked tagtmp305 = *tmpcur303;
CursorTy tailtmp306 = tmpcur303 + 1;
tmpval211 = tagtmp305;
tmpcur212 = tailtmp306;
goto switch227;
break;
}
default:
{
CursorTy tr2149 = (CursorTy) tmpcur212;
CursorTy case61 = (CursorTy) tr2149;
CursorTy x4 = (CursorTy) case61;
CursorTy loc72 = loc32 + (IntTy) 1;
CursorCursorCursorCursorProd tmp_struct3 = add1(end_r33, end_r34,
loc72, x4);
CursorTy pvrtmp217 = tmp_struct3.field0;
CursorTy pvrtmp218 = tmp_struct3.field1;
CursorTy pvrtmp219 = tmp_struct3.field2;
CursorTy pvrtmp220 = tmp_struct3.field3;
CursorTy fltPkd15 = (CursorTy) pvrtmp219;
CursorTy end_fltPkd15 = (CursorTy) pvrtmp220;
CursorTy end_r34135 = (CursorTy) pvrtmp217;
CursorTy endof117 = (CursorTy) pvrtmp218;
CursorTy case62 = (CursorTy) endof117;
CursorTy y5 = (CursorTy) case62;
CursorTy loc74 = (CursorTy) end_fltPkd15;
CursorCursorCursorCursorProd tmp_struct4 = add1(end_r33, end_r34135,
loc74, y5);
CursorTy pvrtmp221 = tmp_struct4.field0;
CursorTy pvrtmp222 = tmp_struct4.field1;
CursorTy pvrtmp223 = tmp_struct4.field2;
CursorTy pvrtmp224 = tmp_struct4.field3;
CursorTy fltPkd16 = (CursorTy) pvrtmp223;
CursorTy end_fltPkd16 = (CursorTy) pvrtmp224;
CursorTy end_r34135136 = (CursorTy) pvrtmp221;
CursorTy endof118 = (CursorTy) pvrtmp222;
*loc32 = 1;
CursorTy writetag152 = loc32 + 1;
CursorTy writecur153 = (CursorTy) end_fltPkd15;
CursorTy writecur154 = (CursorTy) end_fltPkd16;
CursorTy pvrtmp226 = (CursorTy) writecur154;
CursorTy pvrtmp225 = (CursorTy) loc32;
CursorTy taildc119 = (CursorTy) pvrtmp225;
CursorTy end_taildc119 = (CursorTy) pvrtmp226;
return (CursorCursorCursorCursorProd) {end_r34135136, endof118,
taildc119, end_taildc119};
}
}
}
CursorInt64Prod sumtree(CursorTy pvrtmp228, CursorTy pvrtmp229)
{
CursorTy end_r36 = (CursorTy) pvrtmp228;
CursorTy loc35 = (CursorTy) pvrtmp229;
CursorTy tr6 = (CursorTy) pvrtmp229;
TagTyPacked tmpval230 = *tr6;
CursorTy tmpcur231 = tr6 + 1;
switch238:
;
switch (tmpval230) {
case 0:
{
CursorTy tr6157 = (CursorTy) tmpcur231;
CursorTy case77 = (CursorTy) tr6157;
IntTy tmpval232 = *(IntTy *) case77;
CursorTy tmpcur233 = case77 + sizeof(IntTy);
IntTy n7 = (IntTy) tmpval232;
CursorTy end_n7 = (CursorTy) tmpcur233;
CursorTy jump120 = case77 + (IntTy) 8;
return (CursorInt64Prod) {jump120, n7};
break;
}
case 100:
{
CursorTy tmpcur307 = *(CursorTy *) tmpcur231;
CursorTy tmpaftercur308 = tmpcur231 + 8;
TagTyPacked tagtmp309 = *tmpcur307;
CursorTy tailtmp310 = tmpcur307 + 1;
tmpval230 = tagtmp309;
tmpcur231 = tailtmp310;
goto switch238;
break;
}
case 90:
{
CursorTy tmpcur307 = *(CursorTy *) tmpcur231;
CursorTy tmpaftercur308 = tmpcur231 + 8;
TagTyPacked tagtmp309 = *tmpcur307;
CursorTy tailtmp310 = tmpcur307 + 1;
tmpval230 = tagtmp309;
tmpcur231 = tailtmp310;
goto switch238;
break;
}
default:
{
CursorTy tr6159 = (CursorTy) tmpcur231;
CursorTy case78 = (CursorTy) tr6159;
CursorTy x8 = (CursorTy) case78;
CursorInt64Prod tmp_struct5 = sumtree(end_r36, x8);
CursorTy pvrtmp234 = tmp_struct5.field0;
IntTy pvrtmp235 = tmp_struct5.field1;
CursorTy endof121 = (CursorTy) pvrtmp234;
IntTy sumx10 = (IntTy) pvrtmp235;
CursorTy case79 = (CursorTy) endof121;
CursorTy y9 = (CursorTy) case79;
CursorInt64Prod tmp_struct6 = sumtree(end_r36, y9);
CursorTy pvrtmp236 = tmp_struct6.field0;
IntTy pvrtmp237 = tmp_struct6.field1;
CursorTy endof122 = (CursorTy) pvrtmp236;
IntTy sumy11 = (IntTy) pvrtmp237;
IntTy tailprim123 = sumx10 + sumy11;
return (CursorInt64Prod) {endof122, tailprim123};
}
}
}
CursorCursorCursorProd buildtree(CursorTy pvrtmp239, CursorTy pvrtmp240,
IntTy pvrtmp241)
{
CursorTy end_r38 = (CursorTy) pvrtmp239;
CursorTy loc37 = (CursorTy) pvrtmp240;
IntTy n12 = (IntTy) pvrtmp241;
IntTy fltIf17 = n12 == (IntTy) 0;
switch252:
;
switch (fltIf17) {
case 0:
{
IntTy fltAp19 = n12 - (IntTy) 1;
CursorTy loc90 = loc37 + (IntTy) 1;
CursorCursorCursorProd tmp_struct7 = buildtree(end_r38, loc90,
fltAp19);
CursorTy pvrtmp244 = tmp_struct7.field0;
CursorTy pvrtmp245 = tmp_struct7.field1;
CursorTy pvrtmp246 = tmp_struct7.field2;
CursorTy fltPkd18 = (CursorTy) pvrtmp245;
CursorTy end_fltPkd18 = (CursorTy) pvrtmp246;
CursorTy end_r38137 = (CursorTy) pvrtmp244;
CursorTy loc92 = (CursorTy) end_fltPkd18;
IntTy fltAp21 = n12 - (IntTy) 1;
CursorCursorCursorProd tmp_struct8 = buildtree(end_r38137, loc92,
fltAp21);
CursorTy pvrtmp247 = tmp_struct8.field0;
CursorTy pvrtmp248 = tmp_struct8.field1;
CursorTy pvrtmp249 = tmp_struct8.field2;
CursorTy fltPkd20 = (CursorTy) pvrtmp248;
CursorTy end_fltPkd20 = (CursorTy) pvrtmp249;
CursorTy end_r38137138 = (CursorTy) pvrtmp247;
*loc37 = 1;
CursorTy writetag168 = loc37 + 1;
CursorTy writecur169 = (CursorTy) end_fltPkd18;
CursorTy writecur170 = (CursorTy) end_fltPkd20;
CursorTy pvrtmp251 = (CursorTy) writecur170;
CursorTy pvrtmp250 = (CursorTy) loc37;
CursorTy taildc125 = (CursorTy) pvrtmp250;
CursorTy end_taildc125 = (CursorTy) pvrtmp251;
return (CursorCursorCursorProd) {end_r38137138, taildc125,
end_taildc125};
break;
}
default:
{
if (loc37 + 18 > end_r38) {
ChunkTy new_chunk9 = alloc_chunk_no_gc(end_r38);
CursorTy chunk_start10 = new_chunk9.start_ptr;
CursorTy chunk_end11 = new_chunk9.end_ptr;
end_r38 = chunk_end11;
*(TagTyPacked *) loc37 = 100;
CursorTy redir = loc37 + 1;
*(CursorTy *) redir = chunk_start10;
loc37 = chunk_start10;
}
*loc37 = 0;
CursorTy writetag163 = loc37 + 1;
*(IntTy *) writetag163 = (IntTy) 1;
CursorTy writecur164 = writetag163 + sizeof(IntTy);
CursorTy pvrtmp243 = (CursorTy) writecur164;
CursorTy pvrtmp242 = (CursorTy) loc37;
CursorTy taildc124 = (CursorTy) pvrtmp242;
CursorTy end_taildc124 = (CursorTy) pvrtmp243;
return (CursorCursorCursorProd) {end_r38, taildc124, end_taildc124};
}
}
}
CursorCursorCursorCursorProd copy_Tree(CursorTy pvrtmp253, CursorTy pvrtmp254,
CursorTy pvrtmp255, CursorTy pvrtmp256)
{
CursorTy end_r41 = (CursorTy) pvrtmp253;
CursorTy end_r42 = (CursorTy) pvrtmp254;
CursorTy loc40 = (CursorTy) pvrtmp255;
CursorTy loc39 = (CursorTy) pvrtmp256;
CursorTy arg22 = (CursorTy) pvrtmp256;
TagTyPacked tmpval257 = *arg22;
CursorTy tmpcur258 = arg22 + 1;
switch273:
;
switch (tmpval257) {
case 0:
{
CursorTy arg22173 = (CursorTy) tmpcur258;
CursorTy case95 = (CursorTy) arg22173;
IntTy tmpval259 = *(IntTy *) case95;
CursorTy tmpcur260 = case95 + sizeof(IntTy);
IntTy x23 = (IntTy) tmpval259;
CursorTy end_x23 = (CursorTy) tmpcur260;
CursorTy jump126 = case95 + (IntTy) 8;
if (loc40 + 18 > end_r42) {
ChunkTy new_chunk12 = alloc_chunk_no_gc(end_r42);
CursorTy chunk_start13 = new_chunk12.start_ptr;
CursorTy chunk_end14 = new_chunk12.end_ptr;
end_r42 = chunk_end14;
*(TagTyPacked *) loc40 = 100;
CursorTy redir = loc40 + 1;
*(CursorTy *) redir = chunk_start13;
loc40 = chunk_start13;
}
*loc40 = 0;
CursorTy writetag175 = loc40 + 1;
*(IntTy *) writetag175 = x23;
CursorTy writecur176 = writetag175 + sizeof(IntTy);
CursorTy pvrtmp262 = (CursorTy) writecur176;
CursorTy pvrtmp261 = (CursorTy) loc40;
CursorTy taildc127 = (CursorTy) pvrtmp261;
CursorTy end_taildc127 = (CursorTy) pvrtmp262;
return (CursorCursorCursorCursorProd) {end_r42, jump126, taildc127,
end_taildc127};
break;
}
case 100:
{
CursorTy tmpcur311 = *(CursorTy *) tmpcur258;
CursorTy tmpaftercur312 = tmpcur258 + 8;
TagTyPacked tagtmp313 = *tmpcur311;
CursorTy tailtmp314 = tmpcur311 + 1;
tmpval257 = tagtmp313;
tmpcur258 = tailtmp314;
goto switch273;
break;
}
case 90:
{
CursorTy tmpcur311 = *(CursorTy *) tmpcur258;
CursorTy tmpaftercur312 = tmpcur258 + 8;
TagTyPacked tagtmp313 = *tmpcur311;
CursorTy tailtmp314 = tmpcur311 + 1;
tmpval257 = tagtmp313;
tmpcur258 = tailtmp314;
goto switch273;
break;
}
default:
{
CursorTy arg22178 = (CursorTy) tmpcur258;
CursorTy case100 = (CursorTy) arg22178;
CursorTy x25 = (CursorTy) case100;
CursorTy loc111 = loc40 + (IntTy) 1;
CursorCursorCursorCursorProd tmp_struct15 = copy_Tree(end_r41,
end_r42,
loc111, x25);
CursorTy pvrtmp263 = tmp_struct15.field0;
CursorTy pvrtmp264 = tmp_struct15.field1;
CursorTy pvrtmp265 = tmp_struct15.field2;
CursorTy pvrtmp266 = tmp_struct15.field3;
CursorTy y27 = (CursorTy) pvrtmp265;
CursorTy end_y27 = (CursorTy) pvrtmp266;
CursorTy end_r42139 = (CursorTy) pvrtmp263;
CursorTy endof128 = (CursorTy) pvrtmp264;
CursorTy case101 = (CursorTy) endof128;
CursorTy x26 = (CursorTy) case101;
CursorTy loc113 = (CursorTy) end_y27;
CursorCursorCursorCursorProd tmp_struct16 = copy_Tree(end_r41,
end_r42139,
loc113, x26);
CursorTy pvrtmp267 = tmp_struct16.field0;
CursorTy pvrtmp268 = tmp_struct16.field1;
CursorTy pvrtmp269 = tmp_struct16.field2;
CursorTy pvrtmp270 = tmp_struct16.field3;
CursorTy y28 = (CursorTy) pvrtmp269;
CursorTy end_y28 = (CursorTy) pvrtmp270;
CursorTy end_r42139140 = (CursorTy) pvrtmp267;
CursorTy endof129 = (CursorTy) pvrtmp268;
*loc40 = 1;
CursorTy writetag181 = loc40 + 1;
CursorTy writecur182 = (CursorTy) end_y27;
CursorTy writecur183 = (CursorTy) end_y28;
CursorTy pvrtmp272 = (CursorTy) writecur183;
CursorTy pvrtmp271 = (CursorTy) loc40;
CursorTy taildc130 = (CursorTy) pvrtmp271;
CursorTy end_taildc130 = (CursorTy) pvrtmp272;
return (CursorCursorCursorCursorProd) {end_r42139140, endof129,
taildc130, end_taildc130};
}
}
}
PtrCursorProd unpack_Tree(CursorTy p274)
{
TagTyPacked tag275 = *p274;
CursorTy tail276 = p274 + 1;
switch288:
;
switch (tag275) {
case 0:
{
IntTy val277 = *(IntTy *) tail276;
CursorTy tail278 = tail276 + sizeof(IntTy);
PtrTy ptr279 = (TagInt64Prod *) ALLOC(sizeof(TagInt64Prod));
((TagInt64Prod *) ptr279)->field0 = tag275;
((TagInt64Prod *) ptr279)->field1 = val277;
return (PtrCursorProd) {ptr279, tail278};
break;
}
case 1:
{
PtrCursorProd tmp_struct17 = unpack_Tree(tail276);
PtrTy ptr280 = tmp_struct17.field0;
CursorTy tail281 = tmp_struct17.field1;
PtrCursorProd tmp_struct18 = unpack_Tree(tail281);
PtrTy ptr282 = tmp_struct18.field0;
CursorTy tail283 = tmp_struct18.field1;
PtrTy ptr284 =
(TagCursorCursorProd *) ALLOC(sizeof(TagCursorCursorProd));
((TagCursorCursorProd *) ptr284)->field0 = tag275;
((TagCursorCursorProd *) ptr284)->field1 = ptr280;
((TagCursorCursorProd *) ptr284)->field2 = ptr282;
return (PtrCursorProd) {ptr284, tail283};
break;
}
case 90:
{
CursorTy next285 = *(CursorTy *) tail276;
CursorTy afternext286 = tail276 + 8;
PtrTy ptr287 = (TagProd *) ALLOC(sizeof(TagProd));
((TagProd *) ptr287)->field0 = tag275;
return (PtrCursorProd) {ptr287, afternext286};
break;
}
default:
{
CursorTy tmpcur315 = *(CursorTy *) tail276;
CursorTy tmpaftercur316 = tail276 + 8;
TagTyPacked tagtmp317 = *tmpcur315;
CursorTy tailtmp318 = tmpcur315 + 1;
tag275 = tagtmp317;
tail276 = tailtmp318;
goto switch288;
}
}
}
PtrTy print_Tree(CursorTy p289)
{
TagTyPacked tag290 = *(TagTyPacked *) p289;
CursorTy tail291 = p289 + sizeof(IntTy);
switch302:
;
switch (tag290) {
case 0:
{
fputs("(Leaf ", stdout);
IntTy val292 = *(IntTy *) tail291;
CursorTy tail293 = tail291 + sizeof(IntTy);
printf("%lld", val292);
fputs(")", stdout);
return tail293;
break;
}
case 1:
{
fputs("(Node ", stdout);
IntTy val294 = *(IntTy *) tail291;
CursorTy tail295 = tail291 + sizeof(IntTy);
CursorTy valcur297 = (CursorTy) val294;
PtrTy temp296 = print_Tree(valcur297);
fputs(" ", stdout);
IntTy val298 = *(IntTy *) tail295;
CursorTy tail299 = tail295 + sizeof(IntTy);
CursorTy valcur301 = (CursorTy) val298;
PtrTy temp300 = print_Tree(valcur301);
fputs(")", stdout);
return tail299;
break;
}
case 90:
{
fputs("(INDIRECTION114 ", stdout);
fputs(")", stdout);
return tail291;
break;
}
default:
{
CursorTy tmpcur319 = *(CursorTy *) tail291;
CursorTy tmpaftercur320 = tail291 + 8;
TagTyPacked tagtmp321 = *tmpcur319;
CursorTy tailtmp322 = tmpcur319 + 1;
tag290 = tagtmp321;
tail291 = tailtmp322;
goto switch302;
}
}
}
void __main_expr()
{
RegionTy *region190 = alloc_region(global_init_inf_buf_size);
CursorTy r53 = region190->start_ptr;
IntTy sizeof_end_r53191 = global_init_inf_buf_size;
CursorTy end_r53 = r53 + sizeof_end_r53191;
RegionTy *region192 = alloc_region(global_init_inf_buf_size);
CursorTy r52 = region192->start_ptr;
IntTy sizeof_end_r52193 = global_init_inf_buf_size;
CursorTy end_r52 = r52 + sizeof_end_r52193;
IntTy fltAp13 = global_size_param;
CursorTy loc48 = (CursorTy) r53;
CursorCursorCursorProd tmp_struct19 = buildtree(end_r53, loc48, fltAp13);
CursorTy pvrtmp194 = tmp_struct19.field0;
CursorTy pvrtmp195 = tmp_struct19.field1;
CursorTy pvrtmp196 = tmp_struct19.field2;
CursorTy tr00 = (CursorTy) pvrtmp195;
CursorTy end_tr00 = (CursorTy) pvrtmp196;
CursorTy end_r53141 = (CursorTy) pvrtmp194;
CursorTy loc51 = (CursorTy) r52;
CursorTy pvrtmp201;
CursorTy pvrtmp202;
struct timespec begin_pvrtmp201;
clock_gettime(CLOCK_MONOTONIC_RAW, &begin_pvrtmp201);
for (long long iters_pvrtmp201 = 0; iters_pvrtmp201 < global_iters_param;
iters_pvrtmp201++) {
if (iters_pvrtmp201 != global_iters_param - 1)
save_alloc_state();
CursorCursorCursorCursorProd tmp_struct20 = add1(end_r53141, end_r52,
loc51, tr00);
CursorTy pvrtmp197 = tmp_struct20.field0;
CursorTy pvrtmp198 = tmp_struct20.field1;
CursorTy pvrtmp199 = tmp_struct20.field2;
CursorTy pvrtmp200 = tmp_struct20.field3;
CursorTy tailapp131 = (CursorTy) pvrtmp199;
CursorTy end_tailapp131 = (CursorTy) pvrtmp200;
CursorTy end_r52142 = (CursorTy) pvrtmp197;
CursorTy endof132 = (CursorTy) pvrtmp198;
pvrtmp201 = tailapp131;
pvrtmp202 = end_tailapp131;
if (iters_pvrtmp201 != global_iters_param - 1)
restore_alloc_state();
}
struct timespec end_pvrtmp201;
clock_gettime(CLOCK_MONOTONIC_RAW, &end_pvrtmp201);
double batchtime21 = difftimespecs(&begin_pvrtmp201, &end_pvrtmp201);
double selftimed22 = batchtime21 / global_iters_param;
printf("ITERS: %lld\n", global_iters_param);
printf("SIZE: %lld\n", global_size_param);
printf("BATCHTIME: %lf\n", batchtime21);
printf("SELFTIMED: %lf\n", selftimed22);
CursorTy pvrtmp204 = (CursorTy) pvrtmp202;
CursorTy pvrtmp203 = (CursorTy) pvrtmp201;
CursorTy tr11 = (CursorTy) pvrtmp203;
CursorTy end_tr11 = (CursorTy) pvrtmp204;
CursorInt64Prod tmp_struct23 = sumtree(end_r52, tr11);
CursorTy pvrtmp205 = tmp_struct23.field0;
IntTy pvrtmp206 = tmp_struct23.field1;
CursorTy endof134 = (CursorTy) pvrtmp205;
IntTy tailapp133 = (IntTy) pvrtmp206;
printf("%lld", tailapp133);
fputs("\n", stdout);
return;
}
#include <assert.h>
#include <stdio.h>
// #include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <alloca.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdarg.h> // For va_start etc
#include <errno.h>
#define KB (1 * 1000lu)
#define MB (KB * 1000lu)
#define GB (MB * 1000lu)
// Initial size of BigInfinite buffers
static long long global_init_biginf_buf_size = (5 * GB);
// Initial size of Infinite buffers
static long long global_init_inf_buf_size = 64 * KB;
static long long global_size_param = 1;
static long long global_iters_param = 1;
static char* global_benchfile_param = NULL;
// Sequential for now:
static const int num_workers = 1;
#define REDIRECTION_NODE_SIZE 9
#define MAX(a,b) (((a)>(b))?(a):(b))
// Helpers and debugging:
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
#ifdef BUMPALLOC
// #define DEBUG
#warning "Using bump allocator."
char* heap_ptr = (char*)NULL;
char* saved_heap_ptr_stack[100];
int num_saved_heap_ptr = 0;
// Requires -std=gnu11
int dbgprintf(const char *format, ...)
{
int code = 0;
va_list args;
va_start(args, format);
#ifdef DEBUG
code = vprintf(format, args);
#endif
va_end(args);
return code;
}
// For simplicity just use a single large slab:
void INITALLOC() {
if (! heap_ptr)
{
// Use a fixed address in debug mode for easy reading:
#ifdef DEBUG
// heap_ptr = (char*)mmap(0x010000000000, global_init_biginf_buf_size, PROT_READ|PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, -1, 0);
heap_ptr = (char*)mmap(0x010000000000, global_init_biginf_buf_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (heap_ptr == MAP_FAILED) {
fprintf(stderr, "Error: mmap failed: %s\n", strerror(errno));
abort();
}
#else
heap_ptr = (char*)malloc(global_init_biginf_buf_size);
#endif
dbgprintf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size);
}
dbgprintf("BUMPALLOC/INITALLOC DONE: heap_ptr = %p\n", heap_ptr);
}
#ifdef DEBUG
char* my_abort() {
fprintf(stderr, "Error: this thread's heap was not initalized.\n");
abort();
return NULL;
}
void* ALLOC(int n) {
if (!heap_ptr) my_abort();
char* old = heap_ptr;
printf("ALLOC: %d bytes, returning %p\n", n, old);
// heap_ptr += 16 * n; // Optional padding for debugging.
heap_ptr += n;
return old;
}
#else
// #define ALLOC(n) (do heap_ptr += n)
void* ALLOC(int n) { char* old= heap_ptr; heap_ptr += n; return old; }
#endif // DEBUG
// Snapshot the current heap pointer value across all threads.
void save_alloc_state() {
dbgprintf(" Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr);
saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr;
num_saved_heap_ptr++;
dbgprintf("\n");
}
void restore_alloc_state() {
if(num_saved_heap_ptr <= 0) {
fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne");
abort();
}
num_saved_heap_ptr--;
dbgprintf("Restoring(%p): pos %d, discarding %p",
saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, heap_ptr);
heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr];
}
#else
// Regular malloc mode:
void INITALLOC() {}
void save_alloc_state() {}
void restore_alloc_state() {}
#define ALLOC(n) malloc(n)
#endif // BUMPALLOC
#define ALLOC_PACKED(n) ALLOC(n)
// --------------------------------------------------------------------------------
typedef char TagTyPacked; // Must be consistent with codegen in Target.hs
typedef char TagTyBoxed; // Must be consistent with codegen in Target.hs
typedef long long IntTy;
typedef IntTy SymTy;
typedef char* PtrTy;
typedef char* CursorTy;
typedef struct dict_item {
struct dict_item * next;
int key;
union {
int intval;
void * ptrval;
};
} dict_item_t;
dict_item_t * dict_alloc() {
return ALLOC(sizeof(dict_item_t));
}
dict_item_t *dict_insert_int(dict_item_t *ptr, SymTy key, IntTy val) {
dict_item_t *ret = dict_alloc();
ret->key = key;
ret->intval = val;
ret->next = ptr;
return ret;
}
IntTy dict_lookup_int(dict_item_t *ptr, SymTy key) {
while (ptr != 0) {
if (ptr->key == key) {
return ptr->intval;
} else {
ptr = ptr->next;
}
}
printf("Error, key %lld not found!\n",key);
exit(1);
}
char* read_benchfile_param() {
if (global_benchfile_param == NULL) {
fprintf(stderr, "read_benchfile_param: benchmark input file was not set!\n");
exit(1);
} else
return global_benchfile_param;
}
// Could try alloca() here. Better yet, we could keep our own,
// separate stack and insert our own code to restore the pointer
// before any function that (may have) called ALLOC_SCOPED returns.
// #define ALLOC_SCOPED() alloca(1024)
#define ALLOC_SCOPED(n) alloca(n)
// #define ALLOC_SCOPED() alloc_scoped()
// Stack allocation is either too small or blows our stack.
// We need a way to make a giant stack if we want to use alloca.
// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size)
// Our global pointer. No parallelism.
// static char* stack_scoped_region;
// char* alloc_scoped() { return stack_scoped_region; }
// fun fact: __ prefix is actually reserved and this is an undefined behavior.
// These functions must be provided by the code generator.
void __main_expr();
void show_usage(char** argv)
{
printf("\n");
printf("This binary was generated by the Gibbon compiler.\n");
printf("\n");
printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]);
printf("\n");
printf("Options:\n");
printf(" --buffer-size <bytes> Set the buffer size (default %lld).\n", global_init_biginf_buf_size);
printf(" --bench-input <path> Set the input file read for benchmarking. Applies only\n");
printf(" IF the program was *compiled* with --bench-fun. \n");
return;
}
double avg(const double* arr, int n)
{
double sum = 0.0;
for(int i=0; i<n; i++) sum += arr[i];
return sum / (double)n;
}
double difftimespecs(struct timespec* t0, struct timespec* t1)
{
return (double)(t1->tv_sec - t0->tv_sec)
+ ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0);
}
int compare_doubles(const void *a, const void *b)
{
const double *da = (const double *) a;
const double *db = (const double *) b;
return (*da > *db) - (*da < *db);
}
/* Representation of regions at runtime:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| serialized data ...... | size (int) | refcount (int/ptr) | outset (ptr) |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The metadata after the serialized data serves various purposes:
- size: Used during bounds checking to calculate the size of the next region in the linked list.
- refcount and outset: Whenever an inter-region indirection is created, we record that information
using these two fields. Consier an example where we create an indirection from region A that points to
something in region B. Then A's outset will have that pointer in it, and B's refcount will be bumped
by 1. Note that the refcount doesn't necessarily have to be an `int` for every chunk of the region
(when using "infinite-regions"). The first chunk in the chain has the actual refcount, and every other
chunk has a reference to it.
*/
typedef struct RegionTy_struct {
int refcount;
CursorTy start_ptr;
} RegionTy;
typedef struct RegionFooter_struct {
IntTy size;
CursorTy refcount_ptr;
CursorTy outset_ptr;
CursorTy next;
} RegionFooter;
RegionTy* alloc_region(IntTy size) {
// Allocate the first chunk
IntTy total_size = size + sizeof(RegionFooter);
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + size;
RegionTy* reg = malloc(sizeof(RegionTy));
reg->refcount = 0;
reg->start_ptr = start;
// Write the footer
RegionFooter* footer = (RegionFooter *) end;
footer->size = size;
footer->refcount_ptr = &(reg->refcount);
footer->outset_ptr = NULL;
footer-> next = NULL;
*(RegionFooter *) end = *footer;
return reg;
}
typedef struct ChunkTy_struct {
CursorTy start_ptr;
CursorTy end_ptr;
} ChunkTy;
inline ChunkTy alloc_chunk(CursorTy end_ptr) {
// Get size from current footer
RegionFooter* footer = (RegionFooter *) end_ptr;
IntTy newsize = footer->size * 2;
IntTy total_size = newsize + sizeof(RegionFooter);
// Allocate
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + newsize;
// Link the next chunk's footer
footer->next = end;
// Write the footer
RegionFooter* new_footer = (RegionFooter *) end;
new_footer->size = newsize;
new_footer->refcount_ptr = footer->refcount_ptr;
new_footer->outset_ptr = NULL;
new_footer->next = NULL;
*(RegionFooter *) end = *new_footer;
return (ChunkTy) {start , end};
}
// Almost the same as 'alloc_chunk'. But this doesn't set
// some of the footer arguments and results in ~15-20% speedup.
// Inlining and the no-gc flag seem to work best.
// Do not use '-g' with when using this function!
//
// TODO: Why no-gc ?
inline ChunkTy alloc_chunk_no_gc(CursorTy end_ptr) {
// Get size from current footer
RegionFooter* footer = (RegionFooter *) end_ptr;
IntTy newsize = footer->size * 2;
IntTy total_size = newsize + sizeof(RegionFooter);
// Allocate
CursorTy start = ALLOC_PACKED(total_size);
CursorTy end = start + newsize;
/* // Link the next chunk's footer */
/* footer->next = end; */
// Write the footer
RegionFooter* new_footer = (RegionFooter *) end;
new_footer->size = newsize;
/* new_footer->refcount_ptr = footer->refcount_ptr; */
/* new_footer->outset_ptr = NULL; */
/* new_footer->next = NULL; */
*(RegionFooter *) end = *new_footer;
return (ChunkTy) {start , end};
}
int get_ref_count(CursorTy end_ptr) {
RegionFooter footer = *(RegionFooter *) end_ptr;
return *(footer.refcount_ptr);
}
// If B -> A, bump A's refcount, and update B's offset ptr
IntTy bump_ref_count(CursorTy end_b, CursorTy end_a) {
// Bump refcount
RegionFooter footer_a = *(RegionFooter *) end_a;
int refcount = *(footer_a.refcount_ptr);
*(int *) footer_a.refcount_ptr = refcount + 1;
// Add A to B's outset
RegionFooter* footer_b = (RegionFooter *) end_b;
if (footer_b->outset_ptr == NULL) {
footer_b->outset_ptr = end_a;
} else if (footer_b->outset_ptr != end_a) {
printf("Outset isn't a real set yet..");
}
return refcount;
}
void free_region(CursorTy reg_start, CursorTy reg_end) {
RegionFooter footer = *(RegionFooter *) reg_end;
CursorTy next_chunk = footer.next;
// Decrement refcounts of all regions `reg` points to
if (footer.outset_ptr != NULL) {
RegionFooter* xyz = (RegionFooter *) footer.outset_ptr;
*(xyz->refcount_ptr) = *(xyz->refcount_ptr) - 1;
}
// Free all chunks if recount is 0
if (*(footer.refcount_ptr) == 0) {
while (next_chunk != NULL) {
footer = *(RegionFooter *) next_chunk;
free(next_chunk - footer.size);
next_chunk = footer.next;
}
free(reg_start);
} else {
#ifdef DEBUG
printf("free_region: refcount non-zero.\n");
#endif
}
}
/* -------------------------------------------------------------------------------- */
int main(int argc, char** argv)
{
// parameters to parse:
//
// num iterations: How many times to repeat a benchmark.
// tree size: An integer passes to `build_tree()`.
struct rlimit lim;
int code;
if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) {
fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code);
abort();
}
// lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack.
lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack.
// lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this.
// WARNING: Haven't yet figured out why this doesn't work on MacOS...
#ifndef __APPLE__
code = setrlimit(RLIMIT_STACK, &lim);
while (code) {
fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code);
lim.rlim_cur /= 2;
// lim.rlim_max /= 2;
if(lim.rlim_cur < 100 * 1024) {
fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n");
break; // abort();
}
int code = setrlimit(RLIMIT_STACK, &lim);
}
#endif
// TODO: atoi() error checking
int got_numargs = 0; // How many numeric arguments have we got.
int i;
for (i = 1; i < argc; ++i)
{
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
show_usage(argv);
exit(0);
}
else if (strcmp(argv[i], "--buffer-size") == 0 && i < argc - 1)
{
global_init_biginf_buf_size = atoll(argv[i + 1]);
i++;
}
else if ((strcmp(argv[i], "--bench-input") == 0)) {
if (i+1 >= argc) {
fprintf(stderr, "Not enough arguments after -file, expected <file>.\n");
show_usage(argv);
exit(1);
}
global_benchfile_param = argv[i+1];
i++;
}
// If present, we expect the two arguments to be <size> <iters>
else if (got_numargs >= 2) {
fprintf(stderr, "Extra arguments left over: ");
for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]);
show_usage(argv);
exit(1);
} else {
if (got_numargs == 0) {
global_size_param = atoll(argv[i]);
got_numargs ++;
} else {
global_iters_param = atoll(argv[i]);
}
}
}
INITALLOC();
#ifdef BUMPALLOC
// save_alloc_state();
#endif
__main_expr();
return 0;
}
typedef struct Int64Prod_struct {
IntTy field0;
} Int64Prod;
typedef struct Int64CursorProd_struct {
IntTy field0;
CursorTy field1;
} Int64CursorProd;
typedef struct TagProd_struct {
TagTyPacked field0;
} TagProd;
typedef struct TagInt64Prod_struct {
TagTyPacked field0;
IntTy field1;
} TagInt64Prod;
typedef struct TagCursorProd_struct {
TagTyPacked field0;
CursorTy field1;
} TagCursorProd;
typedef struct TagCursorCursorProd_struct {
TagTyPacked field0;
CursorTy field1;
CursorTy field2;
} TagCursorCursorProd;
typedef struct CursorProd_struct {
CursorTy field0;
} CursorProd;
typedef struct CursorInt64Prod_struct {
CursorTy field0;
IntTy field1;
} CursorInt64Prod;
typedef struct CursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
} CursorCursorProd;
typedef struct CursorCursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
CursorTy field2;
} CursorCursorCursorProd;
typedef struct CursorCursorCursorCursorProd_struct {
CursorTy field0;
CursorTy field1;
CursorTy field2;
CursorTy field3;
} CursorCursorCursorCursorProd;
typedef struct PtrProd_struct {
PtrTy field0;
} PtrProd;
typedef struct PtrCursorProd_struct {
PtrTy field0;
CursorTy field1;
} PtrCursorProd;
CursorCursorCursorCursorProd __attribute__((pure)) add1(CursorTy pvrtmp207,
CursorTy pvrtmp208,
CursorTy pvrtmp209,
CursorTy pvrtmp210);
CursorInt64Prod __attribute__((pure)) sumtree(CursorTy pvrtmp228,
CursorTy pvrtmp229);
CursorCursorCursorProd __attribute__((pure)) buildtree(CursorTy pvrtmp239,
CursorTy pvrtmp240,
IntTy pvrtmp241);
CursorCursorCursorCursorProd __attribute__((pure)) copy_Tree(CursorTy pvrtmp253,
CursorTy pvrtmp254,
CursorTy pvrtmp255,
CursorTy pvrtmp256);
PtrCursorProd unpack_Tree(CursorTy p274);
PtrTy print_Tree(CursorTy p289);
CursorCursorCursorCursorProd add1(CursorTy pvrtmp207, CursorTy pvrtmp208,
CursorTy pvrtmp209, CursorTy pvrtmp210)
{
CursorTy end_r33 = (CursorTy) pvrtmp207;
CursorTy end_r34 = (CursorTy) pvrtmp208;
CursorTy loc32 = (CursorTy) pvrtmp209;
CursorTy loc31 = (CursorTy) pvrtmp210;
CursorTy tr2 = (CursorTy) pvrtmp210;
TagTyPacked tmpval211 = *tr2;
CursorTy tmpcur212 = tr2 + 1;
switch227:
;
switch (tmpval211) {
case 0:
{
CursorTy tr2144 = (CursorTy) tmpcur212;
CursorTy case56 = (CursorTy) tr2144;
IntTy tmpval213 = *(IntTy *) case56;
CursorTy tmpcur214 = case56 + sizeof(IntTy);
IntTy n3 = (IntTy) tmpval213;
CursorTy end_n3 = (CursorTy) tmpcur214;
CursorTy jump115 = case56 + (IntTy) 8;
IntTy fltPkd14 = n3 + (IntTy) 1;
if (loc32 + 18 > end_r34) {
ChunkTy new_chunk0 = alloc_chunk(end_r34);
CursorTy chunk_start1 = new_chunk0.start_ptr;
CursorTy chunk_end2 = new_chunk0.end_ptr;
end_r34 = chunk_end2;
*(TagTyPacked *) loc32 = 100;
CursorTy redir = loc32 + 1;
*(CursorTy *) redir = chunk_start1;
loc32 = chunk_start1;
}
*loc32 = 0;
CursorTy writetag146 = loc32 + 1;
*(IntTy *) writetag146 = fltPkd14;
CursorTy writecur147 = writetag146 + sizeof(IntTy);
CursorTy pvrtmp216 = (CursorTy) writecur147;
CursorTy pvrtmp215 = (CursorTy) loc32;
CursorTy taildc116 = (CursorTy) pvrtmp215;
CursorTy end_taildc116 = (CursorTy) pvrtmp216;
return (CursorCursorCursorCursorProd) {end_r34, jump115, taildc116,
end_taildc116};
break;
}
case 100:
{
CursorTy tmpcur303 = *(CursorTy *) tmpcur212;
CursorTy tmpaftercur304 = tmpcur212 + 8;
TagTyPacked tagtmp305 = *tmpcur303;
CursorTy tailtmp306 = tmpcur303 + 1;
tmpval211 = tagtmp305;
tmpcur212 = tailtmp306;
goto switch227;
break;
}
case 90:
{
CursorTy tmpcur303 = *(CursorTy *) tmpcur212;
CursorTy tmpaftercur304 = tmpcur212 + 8;
TagTyPacked tagtmp305 = *tmpcur303;
CursorTy tailtmp306 = tmpcur303 + 1;
tmpval211 = tagtmp305;
tmpcur212 = tailtmp306;
goto switch227;
break;
}
default:
{
CursorTy tr2149 = (CursorTy) tmpcur212;
CursorTy case61 = (CursorTy) tr2149;
CursorTy x4 = (CursorTy) case61;
CursorTy loc72 = loc32 + (IntTy) 1;
CursorCursorCursorCursorProd tmp_struct3 = add1(end_r33, end_r34,
loc72, x4);
CursorTy pvrtmp217 = tmp_struct3.field0;
CursorTy pvrtmp218 = tmp_struct3.field1;
CursorTy pvrtmp219 = tmp_struct3.field2;
CursorTy pvrtmp220 = tmp_struct3.field3;
CursorTy fltPkd15 = (CursorTy) pvrtmp219;
CursorTy end_fltPkd15 = (CursorTy) pvrtmp220;
CursorTy end_r34135 = (CursorTy) pvrtmp217;
CursorTy endof117 = (CursorTy) pvrtmp218;
CursorTy case62 = (CursorTy) endof117;
CursorTy y5 = (CursorTy) case62;
CursorTy loc74 = (CursorTy) end_fltPkd15;
CursorCursorCursorCursorProd tmp_struct4 = add1(end_r33, end_r34135,
loc74, y5);
CursorTy pvrtmp221 = tmp_struct4.field0;
CursorTy pvrtmp222 = tmp_struct4.field1;
CursorTy pvrtmp223 = tmp_struct4.field2;
CursorTy pvrtmp224 = tmp_struct4.field3;
CursorTy fltPkd16 = (CursorTy) pvrtmp223;
CursorTy end_fltPkd16 = (CursorTy) pvrtmp224;
CursorTy end_r34135136 = (CursorTy) pvrtmp221;
CursorTy endof118 = (CursorTy) pvrtmp222;
*loc32 = 1;
CursorTy writetag152 = loc32 + 1;
CursorTy writecur153 = (CursorTy) end_fltPkd15;
CursorTy writecur154 = (CursorTy) end_fltPkd16;
CursorTy pvrtmp226 = (CursorTy) writecur154;
CursorTy pvrtmp225 = (CursorTy) loc32;
CursorTy taildc119 = (CursorTy) pvrtmp225;
CursorTy end_taildc119 = (CursorTy) pvrtmp226;
return (CursorCursorCursorCursorProd) {end_r34135136, endof118,
taildc119, end_taildc119};
}
}
}
CursorInt64Prod sumtree(CursorTy pvrtmp228, CursorTy pvrtmp229)
{
CursorTy end_r36 = (CursorTy) pvrtmp228;
CursorTy loc35 = (CursorTy) pvrtmp229;
CursorTy tr6 = (CursorTy) pvrtmp229;
TagTyPacked tmpval230 = *tr6;
CursorTy tmpcur231 = tr6 + 1;
switch238:
;
switch (tmpval230) {
case 0:
{
CursorTy tr6157 = (CursorTy) tmpcur231;
CursorTy case77 = (CursorTy) tr6157;
IntTy tmpval232 = *(IntTy *) case77;
CursorTy tmpcur233 = case77 + sizeof(IntTy);
IntTy n7 = (IntTy) tmpval232;
CursorTy end_n7 = (CursorTy) tmpcur233;
CursorTy jump120 = case77 + (IntTy) 8;
return (CursorInt64Prod) {jump120, n7};
break;
}
case 100:
{
CursorTy tmpcur307 = *(CursorTy *) tmpcur231;
CursorTy tmpaftercur308 = tmpcur231 + 8;
TagTyPacked tagtmp309 = *tmpcur307;
CursorTy tailtmp310 = tmpcur307 + 1;
tmpval230 = tagtmp309;
tmpcur231 = tailtmp310;
goto switch238;
break;
}
case 90:
{
CursorTy tmpcur307 = *(CursorTy *) tmpcur231;
CursorTy tmpaftercur308 = tmpcur231 + 8;
TagTyPacked tagtmp309 = *tmpcur307;
CursorTy tailtmp310 = tmpcur307 + 1;
tmpval230 = tagtmp309;
tmpcur231 = tailtmp310;
goto switch238;
break;
}
default:
{
CursorTy tr6159 = (CursorTy) tmpcur231;
CursorTy case78 = (CursorTy) tr6159;
CursorTy x8 = (CursorTy) case78;
CursorInt64Prod tmp_struct5 = sumtree(end_r36, x8);
CursorTy pvrtmp234 = tmp_struct5.field0;
IntTy pvrtmp235 = tmp_struct5.field1;
CursorTy endof121 = (CursorTy) pvrtmp234;
IntTy sumx10 = (IntTy) pvrtmp235;
CursorTy case79 = (CursorTy) endof121;
CursorTy y9 = (CursorTy) case79;
CursorInt64Prod tmp_struct6 = sumtree(end_r36, y9);
CursorTy pvrtmp236 = tmp_struct6.field0;
IntTy pvrtmp237 = tmp_struct6.field1;
CursorTy endof122 = (CursorTy) pvrtmp236;
IntTy sumy11 = (IntTy) pvrtmp237;
IntTy tailprim123 = sumx10 + sumy11;
return (CursorInt64Prod) {endof122, tailprim123};
}
}
}
CursorCursorCursorProd buildtree(CursorTy pvrtmp239, CursorTy pvrtmp240,
IntTy pvrtmp241)
{
CursorTy end_r38 = (CursorTy) pvrtmp239;
CursorTy loc37 = (CursorTy) pvrtmp240;
IntTy n12 = (IntTy) pvrtmp241;
IntTy fltIf17 = n12 == (IntTy) 0;
switch252:
;
switch (fltIf17) {
case 0:
{
IntTy fltAp19 = n12 - (IntTy) 1;
CursorTy loc90 = loc37 + (IntTy) 1;
CursorCursorCursorProd tmp_struct7 = buildtree(end_r38, loc90,
fltAp19);
CursorTy pvrtmp244 = tmp_struct7.field0;
CursorTy pvrtmp245 = tmp_struct7.field1;
CursorTy pvrtmp246 = tmp_struct7.field2;
CursorTy fltPkd18 = (CursorTy) pvrtmp245;
CursorTy end_fltPkd18 = (CursorTy) pvrtmp246;
CursorTy end_r38137 = (CursorTy) pvrtmp244;
CursorTy loc92 = (CursorTy) end_fltPkd18;
IntTy fltAp21 = n12 - (IntTy) 1;
CursorCursorCursorProd tmp_struct8 = buildtree(end_r38137, loc92,
fltAp21);
CursorTy pvrtmp247 = tmp_struct8.field0;
CursorTy pvrtmp248 = tmp_struct8.field1;
CursorTy pvrtmp249 = tmp_struct8.field2;
CursorTy fltPkd20 = (CursorTy) pvrtmp248;
CursorTy end_fltPkd20 = (CursorTy) pvrtmp249;
CursorTy end_r38137138 = (CursorTy) pvrtmp247;
*loc37 = 1;
CursorTy writetag168 = loc37 + 1;
CursorTy writecur169 = (CursorTy) end_fltPkd18;
CursorTy writecur170 = (CursorTy) end_fltPkd20;
CursorTy pvrtmp251 = (CursorTy) writecur170;
CursorTy pvrtmp250 = (CursorTy) loc37;
CursorTy taildc125 = (CursorTy) pvrtmp250;
CursorTy end_taildc125 = (CursorTy) pvrtmp251;
return (CursorCursorCursorProd) {end_r38137138, taildc125,
end_taildc125};
break;
}
default:
{
if (loc37 + 18 > end_r38) {
ChunkTy new_chunk9 = alloc_chunk(end_r38);
CursorTy chunk_start10 = new_chunk9.start_ptr;
CursorTy chunk_end11 = new_chunk9.end_ptr;
end_r38 = chunk_end11;
*(TagTyPacked *) loc37 = 100;
CursorTy redir = loc37 + 1;
*(CursorTy *) redir = chunk_start10;
loc37 = chunk_start10;
}
*loc37 = 0;
CursorTy writetag163 = loc37 + 1;
*(IntTy *) writetag163 = (IntTy) 1;
CursorTy writecur164 = writetag163 + sizeof(IntTy);
CursorTy pvrtmp243 = (CursorTy) writecur164;
CursorTy pvrtmp242 = (CursorTy) loc37;
CursorTy taildc124 = (CursorTy) pvrtmp242;
CursorTy end_taildc124 = (CursorTy) pvrtmp243;
return (CursorCursorCursorProd) {end_r38, taildc124, end_taildc124};
}
}
}
CursorCursorCursorCursorProd copy_Tree(CursorTy pvrtmp253, CursorTy pvrtmp254,
CursorTy pvrtmp255, CursorTy pvrtmp256)
{
CursorTy end_r41 = (CursorTy) pvrtmp253;
CursorTy end_r42 = (CursorTy) pvrtmp254;
CursorTy loc40 = (CursorTy) pvrtmp255;
CursorTy loc39 = (CursorTy) pvrtmp256;
CursorTy arg22 = (CursorTy) pvrtmp256;
TagTyPacked tmpval257 = *arg22;
CursorTy tmpcur258 = arg22 + 1;
switch273:
;
switch (tmpval257) {
case 0:
{
CursorTy arg22173 = (CursorTy) tmpcur258;
CursorTy case95 = (CursorTy) arg22173;
IntTy tmpval259 = *(IntTy *) case95;
CursorTy tmpcur260 = case95 + sizeof(IntTy);
IntTy x23 = (IntTy) tmpval259;
CursorTy end_x23 = (CursorTy) tmpcur260;
CursorTy jump126 = case95 + (IntTy) 8;
if (loc40 + 18 > end_r42) {
ChunkTy new_chunk12 = alloc_chunk(end_r42);
CursorTy chunk_start13 = new_chunk12.start_ptr;
CursorTy chunk_end14 = new_chunk12.end_ptr;
end_r42 = chunk_end14;
*(TagTyPacked *) loc40 = 100;
CursorTy redir = loc40 + 1;
*(CursorTy *) redir = chunk_start13;
loc40 = chunk_start13;
}
*loc40 = 0;
CursorTy writetag175 = loc40 + 1;
*(IntTy *) writetag175 = x23;
CursorTy writecur176 = writetag175 + sizeof(IntTy);
CursorTy pvrtmp262 = (CursorTy) writecur176;
CursorTy pvrtmp261 = (CursorTy) loc40;
CursorTy taildc127 = (CursorTy) pvrtmp261;
CursorTy end_taildc127 = (CursorTy) pvrtmp262;
return (CursorCursorCursorCursorProd) {end_r42, jump126, taildc127,
end_taildc127};
break;
}
case 100:
{
CursorTy tmpcur311 = *(CursorTy *) tmpcur258;
CursorTy tmpaftercur312 = tmpcur258 + 8;
TagTyPacked tagtmp313 = *tmpcur311;
CursorTy tailtmp314 = tmpcur311 + 1;
tmpval257 = tagtmp313;
tmpcur258 = tailtmp314;
goto switch273;
break;
}
case 90:
{
CursorTy tmpcur311 = *(CursorTy *) tmpcur258;
CursorTy tmpaftercur312 = tmpcur258 + 8;
TagTyPacked tagtmp313 = *tmpcur311;
CursorTy tailtmp314 = tmpcur311 + 1;
tmpval257 = tagtmp313;
tmpcur258 = tailtmp314;
goto switch273;
break;
}
default:
{
CursorTy arg22178 = (CursorTy) tmpcur258;
CursorTy case100 = (CursorTy) arg22178;
CursorTy x25 = (CursorTy) case100;
CursorTy loc111 = loc40 + (IntTy) 1;
CursorCursorCursorCursorProd tmp_struct15 = copy_Tree(end_r41,
end_r42,
loc111, x25);
CursorTy pvrtmp263 = tmp_struct15.field0;
CursorTy pvrtmp264 = tmp_struct15.field1;
CursorTy pvrtmp265 = tmp_struct15.field2;
CursorTy pvrtmp266 = tmp_struct15.field3;
CursorTy y27 = (CursorTy) pvrtmp265;
CursorTy end_y27 = (CursorTy) pvrtmp266;
CursorTy end_r42139 = (CursorTy) pvrtmp263;
CursorTy endof128 = (CursorTy) pvrtmp264;
CursorTy case101 = (CursorTy) endof128;
CursorTy x26 = (CursorTy) case101;
CursorTy loc113 = (CursorTy) end_y27;
CursorCursorCursorCursorProd tmp_struct16 = copy_Tree(end_r41,
end_r42139,
loc113, x26);
CursorTy pvrtmp267 = tmp_struct16.field0;
CursorTy pvrtmp268 = tmp_struct16.field1;
CursorTy pvrtmp269 = tmp_struct16.field2;
CursorTy pvrtmp270 = tmp_struct16.field3;
CursorTy y28 = (CursorTy) pvrtmp269;
CursorTy end_y28 = (CursorTy) pvrtmp270;
CursorTy end_r42139140 = (CursorTy) pvrtmp267;
CursorTy endof129 = (CursorTy) pvrtmp268;
*loc40 = 1;
CursorTy writetag181 = loc40 + 1;
CursorTy writecur182 = (CursorTy) end_y27;
CursorTy writecur183 = (CursorTy) end_y28;
CursorTy pvrtmp272 = (CursorTy) writecur183;
CursorTy pvrtmp271 = (CursorTy) loc40;
CursorTy taildc130 = (CursorTy) pvrtmp271;
CursorTy end_taildc130 = (CursorTy) pvrtmp272;
return (CursorCursorCursorCursorProd) {end_r42139140, endof129,
taildc130, end_taildc130};
}
}
}
PtrCursorProd unpack_Tree(CursorTy p274)
{
TagTyPacked tag275 = *p274;
CursorTy tail276 = p274 + 1;
switch288:
;
switch (tag275) {
case 0:
{
IntTy val277 = *(IntTy *) tail276;
CursorTy tail278 = tail276 + sizeof(IntTy);
PtrTy ptr279 = (TagInt64Prod *) ALLOC(sizeof(TagInt64Prod));
((TagInt64Prod *) ptr279)->field0 = tag275;
((TagInt64Prod *) ptr279)->field1 = val277;
return (PtrCursorProd) {ptr279, tail278};
break;
}
case 1:
{
PtrCursorProd tmp_struct17 = unpack_Tree(tail276);
PtrTy ptr280 = tmp_struct17.field0;
CursorTy tail281 = tmp_struct17.field1;
PtrCursorProd tmp_struct18 = unpack_Tree(tail281);
PtrTy ptr282 = tmp_struct18.field0;
CursorTy tail283 = tmp_struct18.field1;
PtrTy ptr284 =
(TagCursorCursorProd *) ALLOC(sizeof(TagCursorCursorProd));
((TagCursorCursorProd *) ptr284)->field0 = tag275;
((TagCursorCursorProd *) ptr284)->field1 = ptr280;
((TagCursorCursorProd *) ptr284)->field2 = ptr282;
return (PtrCursorProd) {ptr284, tail283};
break;
}
case 90:
{
CursorTy next285 = *(CursorTy *) tail276;
CursorTy afternext286 = tail276 + 8;
PtrTy ptr287 = (TagProd *) ALLOC(sizeof(TagProd));
((TagProd *) ptr287)->field0 = tag275;
return (PtrCursorProd) {ptr287, afternext286};
break;
}
default:
{
CursorTy tmpcur315 = *(CursorTy *) tail276;
CursorTy tmpaftercur316 = tail276 + 8;
TagTyPacked tagtmp317 = *tmpcur315;
CursorTy tailtmp318 = tmpcur315 + 1;
tag275 = tagtmp317;
tail276 = tailtmp318;
goto switch288;
}
}
}
PtrTy print_Tree(CursorTy p289)
{
TagTyPacked tag290 = *(TagTyPacked *) p289;
CursorTy tail291 = p289 + sizeof(IntTy);
switch302:
;
switch (tag290) {
case 0:
{
fputs("(Leaf ", stdout);
IntTy val292 = *(IntTy *) tail291;
CursorTy tail293 = tail291 + sizeof(IntTy);
printf("%lld", val292);
fputs(")", stdout);
return tail293;
break;
}
case 1:
{
fputs("(Node ", stdout);
IntTy val294 = *(IntTy *) tail291;
CursorTy tail295 = tail291 + sizeof(IntTy);
CursorTy valcur297 = (CursorTy) val294;
PtrTy temp296 = print_Tree(valcur297);
fputs(" ", stdout);
IntTy val298 = *(IntTy *) tail295;
CursorTy tail299 = tail295 + sizeof(IntTy);
CursorTy valcur301 = (CursorTy) val298;
PtrTy temp300 = print_Tree(valcur301);
fputs(")", stdout);
return tail299;
break;
}
case 90:
{
fputs("(INDIRECTION114 ", stdout);
fputs(")", stdout);
return tail291;
break;
}
default:
{
CursorTy tmpcur319 = *(CursorTy *) tail291;
CursorTy tmpaftercur320 = tail291 + 8;
TagTyPacked tagtmp321 = *tmpcur319;
CursorTy tailtmp322 = tmpcur319 + 1;
tag290 = tagtmp321;
tail291 = tailtmp322;
goto switch302;
}
}
}
void __main_expr()
{
RegionTy *region190 = alloc_region(global_init_inf_buf_size);
CursorTy r53 = region190->start_ptr;
IntTy sizeof_end_r53191 = global_init_inf_buf_size;
CursorTy end_r53 = r53 + sizeof_end_r53191;
RegionTy *region192 = alloc_region(global_init_inf_buf_size);
CursorTy r52 = region192->start_ptr;
IntTy sizeof_end_r52193 = global_init_inf_buf_size;
CursorTy end_r52 = r52 + sizeof_end_r52193;
IntTy fltAp13 = global_size_param;
CursorTy loc48 = (CursorTy) r53;
CursorCursorCursorProd tmp_struct19 = buildtree(end_r53, loc48, fltAp13);
CursorTy pvrtmp194 = tmp_struct19.field0;
CursorTy pvrtmp195 = tmp_struct19.field1;
CursorTy pvrtmp196 = tmp_struct19.field2;
CursorTy tr00 = (CursorTy) pvrtmp195;
CursorTy end_tr00 = (CursorTy) pvrtmp196;
CursorTy end_r53141 = (CursorTy) pvrtmp194;
CursorTy loc51 = (CursorTy) r52;
CursorTy pvrtmp201;
CursorTy pvrtmp202;
struct timespec begin_pvrtmp201;
clock_gettime(CLOCK_MONOTONIC_RAW, &begin_pvrtmp201);
for (long long iters_pvrtmp201 = 0; iters_pvrtmp201 < global_iters_param;
iters_pvrtmp201++) {
if (iters_pvrtmp201 != global_iters_param - 1)
save_alloc_state();
CursorCursorCursorCursorProd tmp_struct20 = add1(end_r53141, end_r52,
loc51, tr00);
CursorTy pvrtmp197 = tmp_struct20.field0;
CursorTy pvrtmp198 = tmp_struct20.field1;
CursorTy pvrtmp199 = tmp_struct20.field2;
CursorTy pvrtmp200 = tmp_struct20.field3;
CursorTy tailapp131 = (CursorTy) pvrtmp199;
CursorTy end_tailapp131 = (CursorTy) pvrtmp200;
CursorTy end_r52142 = (CursorTy) pvrtmp197;
CursorTy endof132 = (CursorTy) pvrtmp198;
pvrtmp201 = tailapp131;
pvrtmp202 = end_tailapp131;
if (iters_pvrtmp201 != global_iters_param - 1)
restore_alloc_state();
}
struct timespec end_pvrtmp201;
clock_gettime(CLOCK_MONOTONIC_RAW, &end_pvrtmp201);
double batchtime21 = difftimespecs(&begin_pvrtmp201, &end_pvrtmp201);
double selftimed22 = batchtime21 / global_iters_param;
printf("ITERS: %lld\n", global_iters_param);
printf("SIZE: %lld\n", global_size_param);
printf("BATCHTIME: %lf\n", batchtime21);
printf("SELFTIMED: %lf\n", selftimed22);
CursorTy pvrtmp204 = (CursorTy) pvrtmp202;
CursorTy pvrtmp203 = (CursorTy) pvrtmp201;
CursorTy tr11 = (CursorTy) pvrtmp203;
CursorTy end_tr11 = (CursorTy) pvrtmp204;
CursorInt64Prod tmp_struct23 = sumtree(end_r52, tr11);
CursorTy pvrtmp205 = tmp_struct23.field0;
IntTy pvrtmp206 = tmp_struct23.field1;
CursorTy endof134 = (CursorTy) pvrtmp205;
IntTy tailapp133 = (IntTy) pvrtmp206;
printf("%lld", tailapp133);
fputs("\n", stdout);
free_region(r52, end_r52);
free(region192);
free_region(r53, end_r53);
free(region190);
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment