Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How best to produce executable machine code from grin #24

Closed
LSLeary opened this issue Feb 12, 2019 · 2 comments
Closed

How best to produce executable machine code from grin #24

LSLeary opened this issue Feb 12, 2019 · 2 comments

Comments

@LSLeary
Copy link
Contributor

LSLeary commented Feb 12, 2019

This low level stuff isn't really my area (I usually just write Haskell), and I had a bit of trouble with this. In particular:

  • Trying to properly control the grin cli via its options only caused it to crash with pattern match failures.
  • No main / entry point is produced.
  • _prim_int_print is an unknown symbol. I found a note saying it was ad-hoc and would be removed, but it seems that references to it can be produced even when it's not used directly.

For now I've muddled my way to a (perhaps naive) solution:

prim.c

#include <stdio.h>
#include <stdint.h>

int64_t grinMain();

void _prim_int_print(int64_t i) {
  printf("%ld", i);
}

int main() {
  return (int)grinMain();
}

compile

#!/usr/bin/env sh

grin "$1.grin"                      &&
llc-7 -filetype=obj .output/*.ll    &&
mkdir -p exes                       &&
gcc -o "exes/$1" .output/*.o prim.c &&
rm -r .output/

This works for some small grin snippets such as:

test-return.grin

grinMain = pure 42

test-print.grin

grinMain =
  j <- pure (CInt 23)
  print j

print i =
  (CInt i') <- pure i
  _prim_int_print i'

test-add.grin

grinMain =
  n1 <- pure (CInt 42)
  n2 <- pure (CInt 10000)
  n3 <- add n1 n2
  (CInt r) <- pure n3
  _prim_int_print r

add m n =
  (CInt m') <- pure m
  (CInt n') <- pure n
  s1 <- _prim_int_add m' n'
  s2 <- pure (CInt s1)
  pure s2

test-indirect-add.grin

grinMain =
  t1 <- store (CInt 1)
  t2 <- store (CInt 10000)
  t3 <- store (Fadd t1 t2)
  (CInt r') <- eval t3
  _prim_int_print r'

add m n =
  (CInt m') <- eval m
  (CInt n') <- eval n
  b' <- _prim_int_add m' n'
  pure (CInt b')

eval q =
  v <- fetch q
  case v of
    (CInt x'1) -> pure v
    (Fadd a b) -> w <- add a b
                  update q w
                  pure w

However it doesn't work for the examples in test-data/dead-data-elimination, and I'm not sure whether the issue originates in the examples themselves (are they currently expected to fail?), in the grin compiler, or in my process. Compiling the pnode source fails with

PipelineStep: JITLLVM
grin: user error (Pattern match failure in do expression at src/Reducer/LLVM/JIT.hs:71:13-38)

which presumably is actually one of the first two options, but more troubling is that the length source does compile, then execution fails with a segmentation fault.

@csabahruska
Copy link
Member

The correct main C module looks like this:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

extern int64_t _heap_ptr_;
int64_t grinMain();

int64_t _prim_int_print(int64_t i) {
  printf("%ld\n", i);
  return i;
}

int main() {
  int64_t* heap = malloc(100*1024*1024);
  _heap_ptr_ = (int64_t)heap;
  grinMain();
  printf("used memory: %ld bytes\n", (uint64_t)_heap_ptr_ - (uint64_t)heap);
  free(heap);
  return 0;
}

This code allocates the heap area also.
Currently GRIN does not have a linker compiler phase. For testing we use the GRIN interpreter.
We will add a simple linker phase to GRIN in 1-3 months.

@LSLeary
Copy link
Contributor Author

LSLeary commented Feb 14, 2019

Ok, just got to testing this. It works, and makes sense! Thanks, I didn't think about allocation, or that the smaller examples might be working because they don't need it. I've also taken note of the --eval option (which I guess is what you mean by interpreter); that works too.

@LSLeary LSLeary closed this as completed Feb 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants