From 75948c96eadddc64d7fe82aeb4b43d69e368bb37 Mon Sep 17 00:00:00 2001
From: Andrea Shepard <andrea@persephoneslair.org>
Date: Wed, 9 Nov 2016 06:29:22 +0000
Subject: [PATCH] Fix most of ch_llvm()

---
 src/backends/llvm.c | 29 +++++++++++++++++++++++------
 src/llvm.h          |  3 ++-
 src/parsers/ch.c    | 25 ++++++++++++++-----------
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/src/backends/llvm.c b/src/backends/llvm.c
index 9915c38b..7d559c07 100644
--- a/src/backends/llvm.c
+++ b/src/backends/llvm.c
@@ -17,9 +17,26 @@ typedef struct HLLVMParser_ {
 
 void h_llvm_declare_common(LLVMModuleRef mod) {
   llvm_inputstream = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HInputStream_"), 0);
-  llvm_arena = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HArena_"), 0);
-  llvm_parsedtoken = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParsedToken_"), 0);
-  llvm_parseresult = LLVMPointerType(LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParseResult_"), 0);
+  llvm_arena = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HArena_");
+  llvm_arenaptr = LLVMPointerType(llvm_arena, 0);
+  llvm_parsedtoken = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParsedToken_");
+  LLVMTypeRef llvm_parsedtoken_struct_types[] = {
+    LLVMInt32Type(), // actually an enum value
+    LLVMInt64Type(), // actually this is a union; the largest thing in it is 64 bits
+    LLVMInt64Type(), // FIXME sizeof(size_t) will be 32 bits on 32-bit platforms
+    LLVMInt64Type(), // FIXME ditto
+    LLVMInt8Type()
+  };
+  LLVMStructSetBody(llvm_parsedtoken, llvm_parsedtoken_struct_types, 5, 0);
+  llvm_parsedtokenptr = LLVMPointerType(llvm_parsedtoken, 0);
+  llvm_parseresult = LLVMStructCreateNamed(LLVMGetGlobalContext(), "struct.HParseResult_");
+  LLVMTypeRef llvm_parseresult_struct_types[] = {
+    llvm_parsedtokenptr,
+    LLVMInt64Type(),
+    llvm_arenaptr
+  };
+  LLVMStructSetBody(llvm_parseresult, llvm_parseresult_struct_types, 3, 0);
+  llvm_parseresultptr = LLVMPointerType(llvm_parseresult, 0);
   LLVMTypeRef readbits_pt[] = {
     llvm_inputstream,
     LLVMInt32Type(),
@@ -37,9 +54,9 @@ void h_llvm_declare_common(LLVMModuleRef mod) {
 
   LLVMTypeRef makeresult_pt[] = {
     llvm_arena,
-    llvm_parsedtoken
+    llvm_parsedtokenptr
   };
-  LLVMTypeRef makeresult_ret = LLVMFunctionType(llvm_parseresult, makeresult_pt, 2, 0);
+  LLVMTypeRef makeresult_ret = LLVMFunctionType(llvm_parseresultptr, makeresult_pt, 2, 0);
   LLVMAddFunction(mod, "make_result", makeresult_ret);
   char* dump = LLVMPrintModuleToString(mod);
   fprintf(stderr, "\n\n%s\n\n", dump);
@@ -56,7 +73,7 @@ int h_llvm_compile(HAllocator* mm__, HParser* parser, const void* params) {
     llvm_inputstream,
     llvm_arena
   };
-  LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresult, param_types, 2, 0);
+  LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresultptr, param_types, 2, 0);
   LLVMValueRef parse_func = LLVMAddFunction(mod, name, ret_type);
   // Parse function is now declared; time to define itt
   LLVMBuilderRef builder = LLVMCreateBuilder();
diff --git a/src/llvm.h b/src/llvm.h
index b37036df..8d9c2dbd 100644
--- a/src/llvm.h
+++ b/src/llvm.h
@@ -6,6 +6,7 @@
 #include <llvm-c/Core.h>
 #pragma GCC diagnostic pop
 
-LLVMTypeRef llvm_inputstream, llvm_arena, llvm_parsedtoken, llvm_parseresult;
+LLVMTypeRef llvm_inputstream, llvm_arena, llvm_arenaptr, llvm_parsedtoken, llvm_parsedtokenptr;
+LLVMTypeRef llvm_parseresult, llvm_parseresultptr;
 
 #endif // #ifndef HAMMER_LLVM__H
diff --git a/src/parsers/ch.c b/src/parsers/ch.c
index e4975791..5b9dbdfc 100644
--- a/src/parsers/ch.c
+++ b/src/parsers/ch.c
@@ -53,7 +53,7 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) {
     llvm_inputstream,
     llvm_arena
   };
-  LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresult, param_types, 2, 0);
+  LLVMTypeRef ret_type = LLVMFunctionType(llvm_parseresultptr, param_types, 2, 0);
   LLVMValueRef ch = LLVMAddFunction(mod, "ch", ret_type);
   // get the parameter array to use later with h_bits
   LLVMValueRef bits_args[3];
@@ -67,10 +67,10 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) {
   LLVMBasicBlockRef end = LLVMAppendBasicBlock(ch, "ch_end");
   LLVMPositionBuilderAtEnd(builder, entry);
   // %1 = alloca %struct.HParseResult_*, align 8
-  LLVMValueRef ret = LLVMBuildAlloca(builder, llvm_parseresult, "ret");
+  LLVMValueRef ret = LLVMBuildAlloca(builder, llvm_parseresultptr, "ret");
   // skip %2 through %c because we have these from arguments, and %r because we'll get it later
   // %tok = alloca %struct.HParsedToken_*, align 8
-  LLVMValueRef tok = LLVMBuildAlloca(builder, llvm_parsedtoken, "tok");
+  // LLVMValueRef tok = LLVMBuildAlloca(builder, llvm_parsedtokenptr, "tok");
   // skip next instr through %8
   // %9 = call i64 @h_read_bits(%struct.HInputStream_* %8, i32 8, i8 signext 0)
   LLVMValueRef bits = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_read_bits"), bits_args, 3, "h_read_bits");
@@ -93,9 +93,11 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) {
   // %20 = call noalias i8* @h_arena_malloc(%struct.HArena_* %19, i64 48)
   LLVMValueRef amalloc = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "h_arena_malloc"), amalloc_args, 2, "h_arena_malloc");
   // %21 = bitcast i8* %20 to %struct.HParsedToken_*
-  LLVMValueRef cast1 = LLVMBuildBitCast(builder, amalloc, llvm_parsedtoken, "");
+  LLVMValueRef tok = LLVMBuildBitCast(builder, amalloc, llvm_parsedtokenptr, "");
+
   // store %struct.HParsedToken_* %21, %struct.HParsedToken_** %tok, align 8
-  LLVMBuildStore(builder, cast1, tok);
+  // LLVMBuildStore(builder, cast1, tok);
+
   // %22 = load %struct.HParsedToken_** %tok, align 8
   // %23 = getelementptr inbounds %struct.HParsedToken_* %22, i32 0, i32 0
   LLVMValueRef bounds1[] = {
@@ -123,23 +125,24 @@ static bool ch_llvm(LLVMBuilderRef builder, LLVMModuleRef mod, void* env) {
   // %33 = call %struct.HParseResult_* @make_result(%struct.HArena_* %31, %struct.HParsedToken_* %32)
   LLVMValueRef result_args[] = { arena, tok };
   LLVMValueRef mr = LLVMBuildCall(builder, LLVMGetNamedFunction(mod, "make_result"), result_args, 2, "make_result");
-  // store %struct.HParseResult_* %33, %struct.HParseResult_** %1
+  // store %struct.HParseResult_* %33, %struct.HParseResult_** %ret
   LLVMBuildStore(builder, mr, ret);
   // br label %35
   LLVMBuildBr(builder, end);
   
   // ; <label>:34 - failure case
   LLVMPositionBuilderAtEnd(builder, fail);
-  // store %struct.HParseResult* null, %struct.HParseResult_** %1
-  LLVMBuildStore(builder, LLVMConstNull(llvm_parseresult), ret);
+  // store %struct.HParseResult* null, %struct.HParseResult_** %ret
+  LLVMBuildStore(builder, LLVMConstNull(llvm_parseresultptr), ret);
   // br label %35
   LLVMBuildBr(builder, end);
 
   // ; <label>:35
   LLVMPositionBuilderAtEnd(builder, end);
-  // %36 = load %struct.HParseResult_** %1
-  // ret %struct.HParseResult_* %36
-  LLVMBuildRet(builder, ret);
+  // %rv = load %struct.HParseResult_** %ret
+  LLVMValueRef rv = LLVMBuildLoad(builder, ret, "rv");
+  // ret %struct.HParseResult_* %rv
+  LLVMBuildRet(builder, rv);
   return true;
 }
 
-- 
GitLab