From 5d13b848d53734c8dc7b1cc6c17d4a8f85d7015c Mon Sep 17 00:00:00 2001 From: Andrea Shepard <andrea@special-circumstanc.es> Date: Thu, 14 Nov 2019 00:45:36 +0000 Subject: [PATCH] HParser-specific labels for LLVM IR in token.c --- src/parsers/token.c | 341 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 311 insertions(+), 30 deletions(-) diff --git a/src/parsers/token.c b/src/parsers/token.c index f63bbbee..66012540 100644 --- a/src/parsers/token.c +++ b/src/parsers/token.c @@ -82,20 +82,88 @@ static bool token_ctrvm(HRVMProg *prog, void *env) { static bool token_llvm_with_global( HLLVMParserCompileContext *ctxt, + HParser *p, HToken *t, LLVMValueRef *res) { + /* Allocator*/ + HAllocator *mm__ = NULL; + /* Names */ + char *tok_glob_entry_name = NULL; + int tok_glob_entry_name_len = 0; + char *tok_glob_loop_start_name = NULL; + int tok_glob_loop_start_name_len = 0; + char *tok_glob_loop_middle_name = NULL; + int tok_glob_loop_middle_name_len = 0; + char *tok_glob_loop_incr_name = NULL; + int tok_glob_loop_incr_name_len = 0; + char *tok_glob_success_name = NULL; + int tok_glob_success_name_len = 0; + char *tok_glob_end_name = NULL; + int tok_glob_end_name_len = 0; + char *tok_glob_str_name = NULL; + int tok_glob_str_name_len = 0; + char *tok_glob_i_name = NULL; + int tok_glob_i_name_len = 0; + char *tok_glob_icmp_i_len_name = NULL; + int tok_glob_icmp_i_len_name_len = 0; + char *tok_glob_cptr_name = NULL; + int tok_glob_cptr_name_len = 0; + char *tok_glob_c_name = NULL; + int tok_glob_c_name_len = 0; + char *tok_glob_read_bits_name = NULL; + int tok_glob_read_bits_name_len = 0; + char *tok_glob_r_name = NULL; + int tok_glob_r_name_len = 0; + char *tok_glob_icmp_c_r_name = NULL; + int tok_glob_icmp_c_r_name_len = 0; + char *tok_glob_i_incr_name = NULL; + int tok_glob_i_incr_name_len = 0; + char *tok_glob_rv_name = NULL; + int tok_glob_rv_name_len = 0; + /* Basic blocks */ + LLVMBasicBlockRef entry, loop_start, loop_middle, loop_incr, success, end; + /* Values */ LLVMValueRef bits_args[3], bits, i, i_init, i_incr, str, str_const, len; LLVMValueRef r, c, mr, icmp_i_len, icmp_c_r, rv; LLVMValueRef c_gep_indices[2], c_gep; - LLVMBasicBlockRef entry, loop_start, loop_middle, loop_incr, success, end; + + /* Unpack allocator */ + mm__ = ctxt->mm__; /* Set up basic blocks: entry, success and exit branches */ - entry = LLVMAppendBasicBlock(ctxt->func, "tok_seq_entry"); - loop_start = LLVMAppendBasicBlock(ctxt->func, "tok_seq_loop_start"); - loop_middle = LLVMAppendBasicBlock(ctxt->func, "tok_seq_loop_middle"); - loop_incr = LLVMAppendBasicBlock(ctxt->func, "tok_seq_loop_incr"); - success = LLVMAppendBasicBlock(ctxt->func, "tok_seq_success"); - end = LLVMAppendBasicBlock(ctxt->func, "tok_seq_end"); + tok_glob_entry_name_len = snprintf(NULL, 0, "tok_glob_entry_%p", p); + tok_glob_entry_name = h_new(char, tok_glob_entry_name_len + 1); + snprintf(tok_glob_entry_name, tok_glob_entry_name_len + 1, + "tok_glob_entry_%p", p); + entry = LLVMAppendBasicBlock(ctxt->func, tok_glob_entry_name); + tok_glob_loop_start_name_len = + snprintf(NULL, 0, "tok_glob_loop_start_%p", p); + tok_glob_loop_start_name = h_new(char, tok_glob_loop_start_name_len + 1); + snprintf(tok_glob_loop_start_name, tok_glob_loop_start_name_len + 1, + "tok_glob_loop_start_%p", p); + loop_start = LLVMAppendBasicBlock(ctxt->func, tok_glob_loop_start_name); + tok_glob_loop_middle_name_len = + snprintf(NULL, 0, "tok_glob_loop_middle_%p", p); + tok_glob_loop_middle_name = h_new(char, tok_glob_loop_middle_name_len + 1); + snprintf(tok_glob_loop_middle_name, tok_glob_loop_middle_name_len + 1, + "tok_glob_loop_middle_%p", p); + loop_middle = LLVMAppendBasicBlock(ctxt->func, tok_glob_loop_middle_name); + tok_glob_loop_incr_name_len = + snprintf(NULL, 0, "tok_glob_loop_incr_%p", p); + tok_glob_loop_incr_name = h_new(char, tok_glob_loop_incr_name_len + 1); + snprintf(tok_glob_loop_incr_name, tok_glob_loop_incr_name_len + 1, + "tok_glob_loop_incr_%p", p); + loop_incr = LLVMAppendBasicBlock(ctxt->func, tok_glob_loop_incr_name); + tok_glob_success_name_len = snprintf(NULL, 0, "tok_glob_success_%p", p); + tok_glob_success_name = h_new(char, tok_glob_success_name_len + 1); + snprintf(tok_glob_success_name, tok_glob_success_name_len + 1, + "tok_glob_success_%p", p); + success = LLVMAppendBasicBlock(ctxt->func, tok_glob_success_name); + tok_glob_end_name_len = snprintf(NULL, 0, "tok_glob_end_%p", p); + tok_glob_end_name = h_new(char, tok_glob_end_name_len + 1); + snprintf(tok_glob_end_name, tok_glob_end_name_len + 1, + "tok_glob_end_%p", p); + end = LLVMAppendBasicBlock(ctxt->func, tok_glob_end_name); /* Branch to entry block */ LLVMBuildBr(ctxt->builder, entry); @@ -105,8 +173,12 @@ static bool token_llvm_with_global( * Get our string into the globals as a constant; skip the null termination * and save a byte since we can compare to length in the loop. */ + tok_glob_str_name_len = snprintf(NULL, 0, "tok_glob_str_%p", p); + tok_glob_str_name = h_new(char, tok_glob_str_name_len + 1); + snprintf(tok_glob_str_name, tok_glob_str_name_len + 1, + "tok_glob_str_%p", p); str_const = LLVMConstString((const char *)(t->str), t->len, 1); - str = LLVMAddGlobal(ctxt->mod, LLVMArrayType(LLVMInt8Type(), t->len), "tok_str"); + str = LLVMAddGlobal(ctxt->mod, LLVMArrayType(LLVMInt8Type(), t->len), tok_glob_str_name); LLVMSetLinkage(str, LLVMInternalLinkage); LLVMSetGlobalConstant(str, 1); LLVMSetInitializer(str, str_const); @@ -124,7 +196,11 @@ static bool token_llvm_with_global( LLVMPositionBuilderAtEnd(ctxt->builder, loop_start); /* Keep an index counter */ - i = LLVMBuildPhi(ctxt->builder, ctxt->llvm_size_t, "i"); + tok_glob_i_name_len = snprintf(NULL, 0, "tok_glob_i_%p", p); + tok_glob_i_name = h_new(char, tok_glob_i_name_len + 1); + snprintf(tok_glob_i_name, tok_glob_i_name_len + 1, + "tok_glob_i_%p", p); + i = LLVMBuildPhi(ctxt->builder, ctxt->llvm_size_t, tok_glob_i_name); i_init = LLVMConstInt(ctxt->llvm_size_t, 0, 0); /* * We'll need another one once we know the value of i at the end of @@ -136,36 +212,72 @@ static bool token_llvm_with_global( * Compare i to token string length (i.e., have we hit the end of the * token?); if ==, branch to success, if <, continue loop. */ - icmp_i_len = LLVMBuildICmp(ctxt->builder, LLVMIntULT, i, len, "i < len"); + tok_glob_icmp_i_len_name_len = + snprintf(NULL, 0, "tok_glob_icmp_i_len_%p", p); + tok_glob_icmp_i_len_name = h_new(char, tok_glob_icmp_i_len_name_len + 1); + snprintf(tok_glob_icmp_i_len_name, tok_glob_icmp_i_len_name_len + 1, + "tok_glob_icmp_i_len_%p", p); + icmp_i_len = LLVMBuildICmp(ctxt->builder, LLVMIntULT, i, len, + tok_glob_icmp_i_len_name); LLVMBuildCondBr(ctxt->builder, icmp_i_len, loop_middle, success); /* Basic block loop_middle */ LLVMPositionBuilderAtEnd(ctxt->builder, loop_middle); /* Get a char from the token string */ + tok_glob_cptr_name_len = snprintf(NULL, 0, "tok_glob_cptr_%p", p); + tok_glob_cptr_name = h_new(char, tok_glob_cptr_name_len + 1); + snprintf(tok_glob_cptr_name, tok_glob_cptr_name_len + 1, + "tok_glob_cptr_%p", p); c_gep_indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); c_gep_indices[1] = i; - c_gep = LLVMBuildInBoundsGEP(ctxt->builder, str, c_gep_indices, 2, "c_p"); - c = LLVMBuildLoad(ctxt->builder, c_gep, "c"); + c_gep = LLVMBuildInBoundsGEP(ctxt->builder, str, c_gep_indices, 2, + tok_glob_cptr_name); + tok_glob_c_name_len = snprintf(NULL, 0, "tok_glob_c_%p", p); + tok_glob_c_name = h_new(char, tok_glob_c_name_len + 1); + snprintf(tok_glob_c_name, tok_glob_c_name_len + 1, + "tok_glob_c_%p", p); + c = LLVMBuildLoad(ctxt->builder, c_gep, tok_glob_c_name); /* Read one char from input */ + tok_glob_read_bits_name_len = + snprintf(NULL, 0, "tok_glob_read_bits_%p", p); + tok_glob_read_bits_name = h_new(char, tok_glob_read_bits_name_len + 1); + snprintf(tok_glob_read_bits_name, tok_glob_read_bits_name_len + 1, + "tok_glob_read_bits_%p", p); bits = LLVMBuildCall(ctxt->builder, - LLVMGetNamedFunction(ctxt->mod, "h_read_bits"), bits_args, 3, "read_bits"); + LLVMGetNamedFunction(ctxt->mod, "h_read_bits"), + bits_args, 3, tok_glob_read_bits_name); /* Clamp to i8 */ - r = LLVMBuildTrunc(ctxt->builder, bits, LLVMInt8Type(), ""); + tok_glob_r_name_len = snprintf(NULL, 0, "tok_glob_r_%p", p); + tok_glob_r_name = h_new(char, tok_glob_r_name_len + 1); + snprintf(tok_glob_r_name, tok_glob_r_name_len + 1, + "tok_glob_r_%p", p); + r = LLVMBuildTrunc(ctxt->builder, bits, LLVMInt8Type(), + tok_glob_r_name); /* * Compare c and r; if !=, token mismatches, break out of loop and * fail. If ==, increment counter and go to next iteration. */ - icmp_c_r = LLVMBuildICmp(ctxt->builder, LLVMIntEQ, c, r, "c == r"); + tok_glob_icmp_c_r_name_len = + snprintf(NULL, 0, "tok_glob_icmp_c_r_%p", p); + tok_glob_icmp_c_r_name = h_new(char, tok_glob_icmp_c_r_name_len + 1); + snprintf(tok_glob_icmp_c_r_name, tok_glob_icmp_c_r_name_len + 1, + "tok_glob_icmp_c_r_%p", p); + icmp_c_r = LLVMBuildICmp(ctxt->builder, LLVMIntEQ, c, r, + tok_glob_icmp_c_r_name); LLVMBuildCondBr(ctxt->builder, icmp_c_r, loop_incr, end); /* Basic block loop_incr */ LLVMPositionBuilderAtEnd(ctxt->builder, loop_incr); /* End of loop, 2nd LLVMAddIncoming() for i */ + tok_glob_i_incr_name_len = snprintf(NULL, 0, "tok_glob_i_incr_%p", p); + tok_glob_i_incr_name = h_new(char, tok_glob_i_incr_name_len + 1); + snprintf(tok_glob_i_incr_name, tok_glob_i_incr_name_len + 1, + "tok_glob_i_incr_%p", p); i_incr = LLVMBuildAdd(ctxt->builder, i, - LLVMConstInt(ctxt->llvm_size_t, 1, 0), "i_incr"); + LLVMConstInt(ctxt->llvm_size_t, 1, 0), tok_glob_i_incr_name); LLVMAddIncoming(i, &i_incr, &loop_incr, 1); /* Next iteration */ @@ -179,7 +291,11 @@ static bool token_llvm_with_global( /* Basic block: end */ LLVMPositionBuilderAtEnd(ctxt->builder, end); /* phi the token or a null depending on where we came from */ - rv = LLVMBuildPhi(ctxt->builder, ctxt->llvm_parseresultptr, "rv"); + tok_glob_rv_name_len = snprintf(NULL, 0, "tok_glob_rv_%p", p); + tok_glob_rv_name = h_new(char, tok_glob_rv_name_len + 1); + snprintf(tok_glob_rv_name, tok_glob_rv_name_len + 1, + "tok_glob_rv_%p", p); + rv = LLVMBuildPhi(ctxt->builder, ctxt->llvm_parseresultptr, tok_glob_rv_name); LLVMBasicBlockRef rv_phi_incoming_blocks[] = { success, loop_middle @@ -189,9 +305,91 @@ static bool token_llvm_with_global( LLVMConstNull(ctxt->llvm_parseresultptr) }; LLVMAddIncoming(rv, rv_phi_incoming_values, rv_phi_incoming_blocks, 2); + /* Pass it back out */ *res = rv; + /* Free names */ + if (tok_glob_entry_name) { + h_free(tok_glob_entry_name); + tok_glob_entry_name = NULL; + } + + if (tok_glob_loop_start_name) { + h_free(tok_glob_loop_start_name); + tok_glob_loop_start_name = NULL; + } + + if (tok_glob_loop_middle_name) { + h_free(tok_glob_loop_middle_name); + tok_glob_loop_middle_name = NULL; + } + + if (tok_glob_loop_incr_name) { + h_free(tok_glob_loop_incr_name); + tok_glob_loop_incr_name = NULL; + } + + if (tok_glob_success_name) { + h_free(tok_glob_success_name); + tok_glob_success_name = NULL; + } + + if (tok_glob_end_name) { + h_free(tok_glob_end_name); + tok_glob_end_name = NULL; + } + + if (tok_glob_str_name) { + h_free(tok_glob_str_name); + tok_glob_str_name = NULL; + } + + if (tok_glob_i_name) { + h_free(tok_glob_i_name); + tok_glob_i_name = NULL; + } + + if (tok_glob_icmp_i_len_name) { + h_free(tok_glob_icmp_i_len_name); + tok_glob_icmp_i_len_name = NULL; + } + + if (tok_glob_cptr_name) { + h_free(tok_glob_cptr_name); + tok_glob_cptr_name = NULL; + } + + if (tok_glob_c_name) { + h_free(tok_glob_c_name); + tok_glob_c_name = NULL; + } + + if (tok_glob_read_bits_name) { + h_free(tok_glob_read_bits_name); + tok_glob_read_bits_name = NULL; + } + + if (tok_glob_r_name) { + h_free(tok_glob_r_name); + tok_glob_r_name = NULL; + } + + if (tok_glob_icmp_c_r_name) { + h_free(tok_glob_icmp_c_r_name); + tok_glob_icmp_c_r_name = NULL; + } + + if (tok_glob_i_incr_name) { + h_free(tok_glob_i_incr_name); + tok_glob_i_incr_name = NULL; + } + + if (tok_glob_rv_name) { + h_free(tok_glob_rv_name); + tok_glob_rv_name = NULL; + } + return true; } @@ -202,12 +400,33 @@ static bool token_llvm_with_global( static bool token_llvm_with_sequential_comparisons( HLLVMParserCompileContext *ctxt, + HParser *p, HToken *t, LLVMValueRef *res) { + /* Allocator */ HAllocator *mm__; + /* Names */ + char *tok_seq_entry_name = NULL; + int tok_seq_entry_name_len = 0; + char *tok_seq_success_name = NULL; + int tok_seq_success_name_len = 0; + char *tok_seq_end_name = NULL; + int tok_seq_end_name_len = 0; + char *tok_seq_read_bits_name = NULL; + int tok_seq_read_bits_name_len = 0; + char *tok_seq_r_name = NULL; + int tok_seq_r_name_len = 0; + char *tok_seq_icmp_name = NULL; + int tok_seq_icmp_name_len = 0; + char *tok_seq_matched_name = NULL; + int tok_seq_matched_name_len = 0; + char *tok_seq_rv_name = NULL; + int tok_seq_rv_name_len = 0; + /* Basic blocks */ + LLVMBasicBlockRef entry, success, end, next_char; + /* Values */ LLVMValueRef bits, r, c, icmp, mr, rv; LLVMValueRef bits_args[3]; - LLVMBasicBlockRef entry, success, end, next_char; char name[64]; int i; @@ -215,9 +434,21 @@ static bool token_llvm_with_sequential_comparisons( mm__ = ctxt->mm__; /* Set up basic blocks: entry, success and exit branches */ - entry = LLVMAppendBasicBlock(ctxt->func, "tok_seq_entry"); - success = LLVMAppendBasicBlock(ctxt->func, "tok_seq_success"); - end = LLVMAppendBasicBlock(ctxt->func, "tok_seq_end"); + tok_seq_entry_name_len = snprintf(NULL, 0, "tok_seq_entry_%p", p); + tok_seq_entry_name = h_new(char, tok_seq_entry_name_len + 1); + snprintf(tok_seq_entry_name, tok_seq_entry_name_len + 1, + "tok_seq_entry_%p", p); + entry = LLVMAppendBasicBlock(ctxt->func, tok_seq_entry_name); + tok_seq_success_name_len = snprintf(NULL, 0, "tok_seq_success_%p", p); + tok_seq_success_name = h_new(char, tok_seq_success_name_len + 1); + snprintf(tok_seq_success_name, tok_seq_success_name_len + 1, + "tok_seq_success_%p", p); + success = LLVMAppendBasicBlock(ctxt->func, tok_seq_success_name); + tok_seq_end_name_len = snprintf(NULL, 0, "tok_seq_end_%p", p); + tok_seq_end_name = h_new(char, tok_seq_end_name_len + 1); + snprintf(tok_seq_end_name, tok_seq_end_name_len + 1, + "tok_seq_end_%p", p); + end = LLVMAppendBasicBlock(ctxt->func, tok_seq_end_name); /* Branch to entry block */ LLVMBuildBr(ctxt->builder, entry); @@ -235,17 +466,40 @@ static bool token_llvm_with_sequential_comparisons( LLVMBasicBlockRef curr_char = entry; for (i = 0; i < t->len; ++i) { /* Read a char */ + tok_seq_read_bits_name_len = + snprintf(NULL, 0, "tok_seq_read_bits_%d_%p", i, p); + tok_seq_read_bits_name = h_new(char, tok_seq_read_bits_name_len + 1); + snprintf(tok_seq_read_bits_name, tok_seq_read_bits_name_len + 1, + "tok_seq_read_bits_%d_%p", i, p); bits = LLVMBuildCall(ctxt->builder, - LLVMGetNamedFunction(ctxt->mod, "h_read_bits"), bits_args, 3, "read_bits"); + LLVMGetNamedFunction(ctxt->mod, "h_read_bits"), bits_args, 3, tok_seq_read_bits_name); + h_free(tok_seq_read_bits_name); + tok_seq_read_bits_name = NULL; /* Clamp to i8 */ - r = LLVMBuildTrunc(ctxt->builder, bits, LLVMInt8Type(), ""); + tok_seq_r_name_len = snprintf(NULL, 0, "tok_seq_r_%d_%p", i, p); + tok_seq_r_name = h_new(char, tok_seq_r_name_len + 1); + snprintf(tok_seq_r_name, tok_seq_r_name_len + 1, "tok_seq_r_%d_%p", i, p); + r = LLVMBuildTrunc(ctxt->builder, bits, LLVMInt8Type(), tok_seq_r_name); + h_free(tok_seq_r_name); + tok_seq_r_name = NULL; /* Comparison */ + tok_seq_icmp_name_len = snprintf(NULL, 0, "tok_seq_icmp_%d_%p", i, p); + tok_seq_icmp_name = h_new(char, tok_seq_icmp_name_len + 1); + snprintf(tok_seq_icmp_name, tok_seq_icmp_name_len + 1, + "tok_seq_icmp_%d_%p", i, p); c = LLVMConstInt(LLVMInt8Type(), t->str[i], 0); - snprintf(name, 64, "t->str[%d] == r", i); - icmp = LLVMBuildICmp(ctxt->builder, LLVMIntEQ, c, r, name); + icmp = LLVMBuildICmp(ctxt->builder, LLVMIntEQ, c, r, tok_seq_icmp_name); + h_free(tok_seq_icmp_name); + tok_seq_icmp_name = NULL; /* Next basic block */ - snprintf(name, 64, "tok_matched_%d", i); - next_char = LLVMAppendBasicBlock(ctxt->func, name); + tok_seq_matched_name_len = + snprintf(NULL, 0, "tok_seq_matched_%d_%p", i, p); + tok_seq_matched_name = h_new(char, tok_seq_matched_name_len + 1); + snprintf(tok_seq_matched_name, tok_seq_matched_name_len + 1, + "tok_seq_matched_%d_%p", i, p); + next_char = LLVMAppendBasicBlock(ctxt->func, tok_seq_matched_name); + h_free(tok_seq_matched_name); + tok_seq_matched_name = NULL; /* Conditional branch */ LLVMBuildCondBr(ctxt->builder, icmp, next_char, end); /* Fill in our row in the phi tables */ @@ -272,14 +526,41 @@ static bool token_llvm_with_sequential_comparisons( /* End block: return a token if we made one */ LLVMPositionBuilderAtEnd(ctxt->builder, end); /* phi the token or a null depending on where we came from */ - rv = LLVMBuildPhi(ctxt->builder, ctxt->llvm_parseresultptr, "rv"); + tok_seq_rv_name_len = snprintf(NULL, 0, "tok_seq_rv_%p", p); + tok_seq_rv_name = h_new(char, tok_seq_rv_name_len + 1); + snprintf(tok_seq_rv_name, tok_seq_rv_name_len + 1, "tok_seq_rv_%p", p); + rv = LLVMBuildPhi(ctxt->builder, ctxt->llvm_parseresultptr, + tok_seq_rv_name); LLVMAddIncoming(rv, values_into_phi, bbs_into_phi, 1 + t->len); + /* Free the stuff we allocated to build the phi */ h_free(bbs_into_phi); h_free(values_into_phi); + /* Pass it back out */ *res = rv; + /* Free names */ + if (tok_seq_entry_name) { + h_free(tok_seq_entry_name); + tok_seq_entry_name = NULL; + } + + if (tok_seq_success_name) { + h_free(tok_seq_success_name); + tok_seq_success_name = NULL; + } + + if (tok_seq_end_name) { + h_free(tok_seq_end_name); + tok_seq_end_name = NULL; + } + + if (tok_seq_rv_name) { + h_free(tok_seq_rv_name); + tok_seq_rv_name = NULL; + } + return true; } @@ -310,9 +591,9 @@ static bool token_llvm(HLLVMParserCompileContext *ctxt, */ if (t->len > TOKEN_LENGTH_USE_GLOBAL_CUTOFF && t->len > 0) { - return token_llvm_with_global(ctxt, t, res); + return token_llvm_with_global(ctxt, p, t, res); } else { - return token_llvm_with_sequential_comparisons(ctxt, t, res); + return token_llvm_with_sequential_comparisons(ctxt, p, t, res); } } -- GitLab