From 81616aeb748542f188c02e40f380b3ce5444862b Mon Sep 17 00:00:00 2001 From: Andrea Shepard <andrea@persephoneslair.org> Date: Sun, 20 Nov 2016 23:18:30 +0000 Subject: [PATCH] Make LLVM backend a build-time option --- SConstruct | 1 + src/SConscript | 3 ++- src/backends/llvm/llvm.c | 4 ++++ src/backends/llvm/llvm.h | 6 ++++++ src/backends/missing.c | 23 +++++++++++++++++++++++ src/backends/missing.h | 7 +++++++ src/hammer.c | 16 ++++++++++++++++ src/hammer.h | 4 ++++ src/internal.h | 7 +++++++ src/parsers/bits.c | 10 +++++++++- src/parsers/ch.c | 10 +++++++++- src/parsers/charset.c | 10 +++++++++- src/t_parser.c | 2 ++ 13 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/backends/missing.c create mode 100644 src/backends/missing.h diff --git a/SConstruct b/SConstruct index 707690c8..e4034548 100644 --- a/SConstruct +++ b/SConstruct @@ -119,6 +119,7 @@ if GetOption("use_llvm"): # Overridable default path to llvm-config env['LLVM_CONFIG'] = "llvm-config" env["LLVM_CONFIG"] = os.getenv("LLVM_CONFIG") or env["LLVM_CONFIG"] + env.MergeFlags("-DHAMMER_LLVM_BACKEND") if GetOption("coverage"): env.Append(CFLAGS=["--coverage"], diff --git a/src/SConscript b/src/SConscript index cdbe6c73..1495f42b 100644 --- a/src/SConscript +++ b/src/SConscript @@ -32,6 +32,7 @@ parsers_headers = [ backends_headers = [ "backends/regex.h", "backends/contextfree.h" + "backends/missing.h" ] parsers = ['parsers/%s.c'%s for s in @@ -65,7 +66,7 @@ parsers = ['parsers/%s.c'%s for s in 'value']] backends = ['backends/%s.c' % s for s in - ['packrat', 'llk', 'regex', 'glr', 'lalr', 'lr', 'lr0']] + ['packrat', 'llk', 'regex', 'glr', 'lalr', 'lr', 'lr0', "missing"]] # Add LLVM backend if enabled if GetOption("use_llvm"): diff --git a/src/backends/llvm/llvm.c b/src/backends/llvm/llvm.c index 523f0b5c..7af7d08a 100644 --- a/src/backends/llvm/llvm.c +++ b/src/backends/llvm/llvm.c @@ -1,3 +1,5 @@ +#ifdef HAMMER_LLVM_BACKEND + #include <llvm-c/Analysis.h> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" @@ -1111,3 +1113,5 @@ HParserBackendVTable h__llvm_backend_vtable = { .parse = h_llvm_parse, .free = h_llvm_free }; + +#endif /* defined(HAMMER_LLVM_BACKEND) */ diff --git a/src/backends/llvm/llvm.h b/src/backends/llvm/llvm.h index 233f3284..36f53fcb 100644 --- a/src/backends/llvm/llvm.h +++ b/src/backends/llvm/llvm.h @@ -1,6 +1,10 @@ +#ifdef HAMMER_LLVM_BACKEND + #ifndef HAMMER_LLVM__H #define HAMMER_LLVM__H +#include "../../internal.h" + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include <llvm-c/Core.h> @@ -18,3 +22,5 @@ void h_llvm_make_tt_suint(LLVMModuleRef mod, LLVMBuilderRef builder, LLVMValueRef r, LLVMValueRef *mr_out); #endif // #ifndef HAMMER_LLVM__H + +#endif /* defined(HAMMER_LLVM_BACKEND) */ diff --git a/src/backends/missing.c b/src/backends/missing.c new file mode 100644 index 00000000..2a46b574 --- /dev/null +++ b/src/backends/missing.c @@ -0,0 +1,23 @@ +#include "missing.h" + +int h_missing_compile(HAllocator* mm__, HParser* parser, const void* params) { + /* Always fail */ + + return -1; +} + +HParseResult *h_missing_parse(HAllocator* mm__, const HParser* parser, HInputStream* stream) { + /* Always fail */ + + return NULL; +} + +void h_missing_free(HParser *parser) { + /* No-op */ +} + +HParserBackendVTable h__missing_backend_vtable = { + .compile = h_missing_compile, /* TODO */ + .parse = h_missing_parse, /* TODO */ + .free = h_missing_free, /* TODO */ +}; diff --git a/src/backends/missing.h b/src/backends/missing.h new file mode 100644 index 00000000..4efe5f35 --- /dev/null +++ b/src/backends/missing.h @@ -0,0 +1,7 @@ +#ifndef HAMMER_BACKENDS_MISSING__H +#define HAMMER_BACKENDS_MISSING__H + +#include "../hammer.h" +#include "../internal.h" + +#endif /* !defined(HAMMER_BACKENDS_MISSING__H) */ diff --git a/src/hammer.c b/src/hammer.c index 2a7d5bc5..6b881554 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -31,7 +31,23 @@ static HParserBackendVTable *backends[PB_MAX + 1] = { &h__llk_backend_vtable, &h__lalr_backend_vtable, &h__glr_backend_vtable, + /* + * Brittleness warning! + * + * We're using an enum as an index into this array (don't blame me...) + * so it's important that this array have the same size and order as + * the corresponding enum values in HParserBackend of src/hammer.h. + * Since callers use those enums as numeric constants to select a + * backend, dropping/reordering them breaks binary compatibility. + * If anyone adds any more optional backends in the future, don't + * #ifdef out those enum values in hammer.h, and do provide the + * 'missing' stub backend as an alternative here. + */ +#ifdef HAMMER_LLVM_BACKEND &h__llvm_backend_vtable, +#else + &h__missing_backend_vtable, +#endif }; diff --git a/src/hammer.h b/src/hammer.h index 821924fa..b86e4ae0 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -46,6 +46,10 @@ typedef enum HParserBackend_ { PB_LLk, PB_LALR, PB_GLR, + /* + * PB_LLVM stays even if no LLVM backend compiled in, since these constants + * are exposed to callers. + */ PB_LLVM, PB_MAX = PB_LLVM } HParserBackend; diff --git a/src/internal.h b/src/internal.h index 24199e29..d0224598 100644 --- a/src/internal.h +++ b/src/internal.h @@ -26,10 +26,12 @@ #include <assert.h> #include <limits.h> #include <string.h> +#ifdef HAMMER_LLVM_BACKEND #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include <llvm-c/Core.h> #pragma GCC diagnostic pop +#endif #include "hammer.h" #include "platform.h" @@ -394,7 +396,10 @@ extern HParserBackendVTable h__packrat_backend_vtable; extern HParserBackendVTable h__llk_backend_vtable; extern HParserBackendVTable h__lalr_backend_vtable; extern HParserBackendVTable h__glr_backend_vtable; +extern HParserBackendVTable h__missing_backend_vtable; +#ifdef HAMMER_LLVM_BACKEND extern HParserBackendVTable h__llvm_backend_vtable; +#endif // }}} // TODO(thequux): Set symbol visibility for these functions so that they aren't exported. @@ -492,7 +497,9 @@ struct HParserVtable_ { bool (*isValidCF)(void *env); bool (*compile_to_rvm)(HRVMProg *prog, void* env); // FIXME: forgot what the bool return value was supposed to mean. void (*desugar)(HAllocator *mm__, HCFStack *stk__, void *env); +#ifdef HAMMER_LLVM_BACKEND bool (*llvm)(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, LLVMModuleRef mod, void *env); +#endif bool higher; // false if primitive }; diff --git a/src/parsers/bits.c b/src/parsers/bits.c index b9096201..d8c90dda 100644 --- a/src/parsers/bits.c +++ b/src/parsers/bits.c @@ -1,10 +1,12 @@ #include <assert.h> +#ifdef HAMMER_LLVM_BACKEND #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include <llvm-c/Core.h> #pragma GCC diagnostic pop -#include "parser_internal.h" #include "../backends/llvm/llvm.h" +#endif +#include "parser_internal.h" struct bits_env { uint8_t length; @@ -22,6 +24,8 @@ static HParseResult* parse_bits(void* env, HParseState *state) { return make_result(state->arena, result); } +#ifdef HAMMER_LLVM_BACKEND + static bool bits_llvm(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, LLVMModuleRef mod, void* env) { @@ -94,6 +98,8 @@ static bool bits_llvm(HAllocator *mm__, return true; } +#endif + static HParsedToken *reshape_bits(const HParseResult *p, void* signedp_p) { // signedp == NULL iff unsigned bool signedp = (signedp_p != NULL); @@ -179,7 +185,9 @@ static const HParserVtable bits_vt = { .isValidCF = h_true, .desugar = desugar_bits, .compile_to_rvm = bits_ctrvm, +#ifdef HAMMER_LLVM_BACKEND .llvm = bits_llvm, +#endif .higher = false, }; diff --git a/src/parsers/ch.c b/src/parsers/ch.c index 08ffebd8..63067ba9 100644 --- a/src/parsers/ch.c +++ b/src/parsers/ch.c @@ -1,11 +1,13 @@ #include <stdint.h> #include <assert.h> +#ifdef HAMMER_LLVM_BACKEND #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include <llvm-c/Core.h> #pragma GCC diagnostic pop -#include "parser_internal.h" #include "../backends/llvm/llvm.h" +#endif +#include "parser_internal.h" static HParseResult* parse_ch(void* env, HParseState *state) { uint8_t c = (uint8_t)(uintptr_t)(env); @@ -46,6 +48,8 @@ static bool ch_ctrvm(HRVMProg *prog, void* env) { return true; } +#ifdef HAMMER_LLVM_BACKEND + static bool ch_llvm(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, LLVMModuleRef mod, void* env) { // Build a new LLVM function to parse a character @@ -110,13 +114,17 @@ static bool ch_llvm(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, return true; } +#endif /* defined(HAMMER_LLVM_BACKEND) */ + static const HParserVtable ch_vt = { .parse = parse_ch, .isValidRegular = h_true, .isValidCF = h_true, .desugar = desugar_ch, .compile_to_rvm = ch_ctrvm, +#ifdef HAMMER_LLVM_BACKEND .llvm = ch_llvm, +#endif .higher = false, }; diff --git a/src/parsers/charset.c b/src/parsers/charset.c index 56ac7b04..741adcd8 100644 --- a/src/parsers/charset.c +++ b/src/parsers/charset.c @@ -1,12 +1,14 @@ #include <assert.h> #include <string.h> #include "../internal.h" +#ifdef HAMMER_LLVM_BACKEND #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" #include <llvm-c/Core.h> #pragma GCC diagnostic pop -#include "parser_internal.h" #include "../backends/llvm/llvm.h" +#endif /* defined(HAMMER_LLVM_BACKEND) */ +#include "parser_internal.h" static HParseResult* parse_charset(void *env, HParseState *state) { uint8_t in = h_read_bits(&state->input_stream, 8, false); @@ -75,6 +77,8 @@ static bool cs_ctrvm(HRVMProg *prog, void *env) { return true; } +#ifdef HAMMER_LLVM_BACKEND + static bool cs_llvm(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, LLVMModuleRef mod, void* env) { /* @@ -144,13 +148,17 @@ static bool cs_llvm(HAllocator *mm__, LLVMBuilderRef builder, LLVMValueRef func, return true; } +#endif /* defined(HAMMER_LLVM_BACKEND) */ + static const HParserVtable charset_vt = { .parse = parse_charset, .isValidRegular = h_true, .isValidCF = h_true, .desugar = desugar_charset, .compile_to_rvm = cs_ctrvm, +#ifdef HAMMER_LLVM_BACKEND .llvm = cs_llvm, +#endif .higher = false, }; diff --git a/src/t_parser.c b/src/t_parser.c index e32f9230..767e0893 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -1024,8 +1024,10 @@ void register_parser_tests(void) { g_test_add_data_func("/core/parser/glr/result_length", GINT_TO_POINTER(PB_GLR), test_result_length); g_test_add_data_func("/core/parser/glr/token_position", GINT_TO_POINTER(PB_GLR), test_token_position); +#ifdef HAMMER_LLVM_BACKEND g_test_add_data_func("/core/parser/llvm/ch", GINT_TO_POINTER(PB_LLVM), test_ch); g_test_add_data_func("/core/parser/llvm/ch_range", GINT_TO_POINTER(PB_LLVM), test_ch_range); g_test_add_data_func("/core/parser/llvm/in", GINT_TO_POINTER(PB_LLVM), test_in); g_test_add_data_func("/core/parser/llvm/not_in", GINT_TO_POINTER(PB_LLVM), test_not_in); +#endif /* defined(HAMMER_LLVM_BACKEND) */ } -- GitLab