From 3d8745a6212fe3e3388284e35a4cd58ed4c2a7ae Mon Sep 17 00:00:00 2001
From: Andrea Shepard <andrea@special-circumstanc.es>
Date: Sat, 16 Nov 2019 00:54:13 +0000
Subject: [PATCH] Introduce name/label macros for LLVM backend

---
 src/backends/llvm/llvm.h | 18 ++++++++
 src/parsers/ch.c         | 92 ++++++++++------------------------------
 2 files changed, 40 insertions(+), 70 deletions(-)

diff --git a/src/backends/llvm/llvm.h b/src/backends/llvm/llvm.h
index aab534a5..368a4b0e 100644
--- a/src/backends/llvm/llvm.h
+++ b/src/backends/llvm/llvm.h
@@ -10,6 +10,24 @@
 #include <llvm-c/Core.h>
 #pragma GCC diagnostic pop
 
+/* LLVM methods use these to generate names for labels, etc. */
+
+#define H_LLVM_DECLARE_NAME(s) \
+  char * s##_name = NULL; \
+  int s##_name_len = 0;
+
+#define H_LLVM_COMPUTE_NAME(s, p) \
+  s##_name_len = snprintf(NULL, 0, #s "_%p", (p)); \
+  s##_name = h_new(char, s##_name_len + 1); \
+  snprintf( s##_name, s##_name_len + 1, #s "_%p", (p));
+
+#define H_LLVM_FREE_NAME(s) \
+  if ( s##_name ) { \
+    h_free( s##_name); \
+    s##_name = NULL; \
+    s##_name_len = 0; \
+  }
+
 /* The typedef is in internal.h */
 
 struct HLLVMParserCompileContext_ {
diff --git a/src/parsers/ch.c b/src/parsers/ch.c
index 858887d2..d1babe6a 100644
--- a/src/parsers/ch.c
+++ b/src/parsers/ch.c
@@ -58,20 +58,13 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
   /* Allocator */
   HAllocator *mm__ = NULL;
   /* Names */
-  char *ch_entry_name = NULL;
-  int ch_entry_name_len = 0;
-  char *ch_success_name = NULL;
-  int ch_success_name_len = 0;
-  char *ch_end_name = NULL;
-  int ch_end_name_len = 0;
-  char *ch_read_bits_name = NULL;
-  int ch_read_bits_name_len = 0;
-  char *ch_r_name = NULL;
-  int ch_r_name_len = 0;
-  char *ch_icmp_name = NULL;
-  int ch_icmp_name_len = 0;
-  char *ch_rv_name = NULL;
-  int ch_rv_name_len = 0;
+  H_LLVM_DECLARE_NAME(ch_entry);
+  H_LLVM_DECLARE_NAME(ch_success);
+  H_LLVM_DECLARE_NAME(ch_end);
+  H_LLVM_DECLARE_NAME(ch_read_bits);
+  H_LLVM_DECLARE_NAME(ch_r);
+  H_LLVM_DECLARE_NAME(ch_icmp);
+  H_LLVM_DECLARE_NAME(ch_rv);
   /* Basic blocks we will be using */
   LLVMBasicBlockRef entry, success, end;
   /* Args for call to h_read_bits() */
@@ -104,17 +97,11 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
   /*
    * Set up basic blocks: entry, success and failure branches, then exit
    */
-  ch_entry_name_len = snprintf(NULL, 0, "ch_entry_%p", p);
-  ch_entry_name = h_new(char, ch_entry_name_len + 1);
-  snprintf(ch_entry_name, ch_entry_name_len + 1, "ch_entry_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_entry, p);
   entry = LLVMAppendBasicBlock(ctxt->func, ch_entry_name);
-  ch_success_name_len = snprintf(NULL, 0, "ch_success_%p", p);
-  ch_success_name = h_new(char, ch_success_name_len + 1);
-  snprintf(ch_success_name, ch_success_name_len + 1, "ch_success_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_success, p);
   success = LLVMAppendBasicBlock(ctxt->func, ch_success_name);
-  ch_end_name_len = snprintf(NULL, 0, "ch_end_%p", p);
-  ch_end_name = h_new(char, ch_end_name_len + 1);
-  snprintf(ch_end_name, ch_end_name_len + 1, "ch_end_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_end, p);
   end = LLVMAppendBasicBlock(ctxt->func, ch_end_name);
 
   /* Basic block: entry */
@@ -132,17 +119,12 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
    * %read_bits = call i64 @h_read_bits(%struct.HInputStream_* %8,
    *                                    i32 8, i8 signext 0)
    */
-  ch_read_bits_name_len = snprintf(NULL, 0, "ch_read_bits_%p", p);
-  ch_read_bits_name = h_new(char, ch_read_bits_name_len + 1);
-  snprintf(ch_read_bits_name, ch_read_bits_name_len + 1,
-           "ch_read_bits_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_read_bits, p);
   bits = LLVMBuildCall(ctxt->builder,
                        LLVMGetNamedFunction(ctxt->mod, "h_read_bits"),
                        bits_args, 3, ch_read_bits_name);
   /* %2 = trunc i64 %read_bits to i8 */
-  ch_r_name_len = snprintf(NULL, 0, "ch_r_%p", p);
-  ch_r_name = h_new(char, ch_r_name_len + 1);
-  snprintf(ch_r_name, ch_r_name_len + 1, "ch_r_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_r, p);
   r = LLVMBuildTrunc(ctxt->builder, bits, LLVMInt8Type(), ch_r_name);
 
   /*
@@ -150,9 +132,7 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
    *
    * %"c == r" = icmp eq i8 -94, %2 ; the -94 comes from c_
    */
-  ch_icmp_name_len = snprintf(NULL, 0, "ch_icmp_%p", p);
-  ch_icmp_name = h_new(char, ch_icmp_name_len + 1);
-  snprintf(ch_icmp_name, ch_icmp_name_len + 1, "ch_icmp_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_icmp, p);
   cval = (uint8_t)(uintptr_t)(p->env);
   c = LLVMConstInt(LLVMInt8Type(), cval, 0);
   icmp = LLVMBuildICmp(ctxt->builder, LLVMIntEQ, c, r, ch_icmp_name);
@@ -178,9 +158,7 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
    * %rv = phi %struct.HParseResult_.3* [ %make_result, %ch_success ],
    *       [ null, %ch_entry ]
    */
-  ch_rv_name_len = snprintf(NULL, 0, "ch_rv_%p", p);
-  ch_rv_name = h_new(char, ch_rv_name_len + 1);
-  snprintf(ch_rv_name, ch_rv_name_len + 1, "ch_rv_%p", p);
+  H_LLVM_COMPUTE_NAME(ch_rv, p);
   rv = LLVMBuildPhi(ctxt->builder, ctxt->llvm_parseresultptr, ch_rv_name);
   rv_phi_incoming_blocks[0] = success;
   rv_phi_incoming_values[0] = mr;
@@ -190,40 +168,14 @@ static bool ch_llvm(HLLVMParserCompileContext *ctxt,
   /* Pass rv out to caller */
   *res = rv;
 
-  if (ch_entry_name) {
-    h_free(ch_entry_name);
-    ch_entry_name = NULL;
-  }
-
-  if (ch_success_name) {
-    h_free(ch_success_name);
-    ch_success_name = NULL;
-  }
-
-  if (ch_end_name) {
-    h_free(ch_end_name);
-    ch_end_name = NULL;
-  }
-
-  if (ch_read_bits_name) {
-    h_free(ch_read_bits_name);
-    ch_read_bits_name = NULL;
-  }
-
-  if (ch_r_name) {
-    h_free(ch_r_name);
-    ch_r_name = NULL;
-  }
-
-  if (ch_icmp_name) {
-    h_free(ch_icmp_name);
-    ch_icmp_name = NULL;
-  }
-
-  if (ch_rv_name) {
-    h_free(ch_rv_name);
-    ch_rv_name = NULL;
-  }
+  /* Free any names we constructed */
+  H_LLVM_FREE_NAME(ch_entry);
+  H_LLVM_FREE_NAME(ch_success);
+  H_LLVM_FREE_NAME(ch_end);
+  H_LLVM_FREE_NAME(ch_read_bits);
+  H_LLVM_FREE_NAME(ch_r);
+  H_LLVM_FREE_NAME(ch_icmp);
+  H_LLVM_FREE_NAME(ch_rv);
 
   return true;
 }
-- 
GitLab