Skip to content

Commit

Permalink
Merge pull request halide#2188 from halide/srj-rungen
Browse files Browse the repository at this point in the history
Rework RunGetStubs mechanism to be C++-name-mangling-friendly (Take 2)
  • Loading branch information
steven-johnson authored Jul 12, 2017
2 parents ed97f66 + c4bde15 commit f7d2c0d
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 22 deletions.
5 changes: 3 additions & 2 deletions HalideGenerator.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function(halide_add_aot_library AOT_LIBRARY_TARGET)
# Parse arguments
set(options )
set(oneValueArgs GENERATOR_TARGET GENERATOR_NAME GENERATED_FUNCTION)
set(multiValueArgs GENERATOR_ARGS GENERATOR_OUTPUTS)
set(multiValueArgs GENERATOR_ARGS GENERATOR_OUTPUTS FILTER_DEPS)
cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if (args_GENERATED_FUNCTION STREQUAL "")
Expand Down Expand Up @@ -134,9 +134,10 @@ function(halide_add_aot_library AOT_LIBRARY_TARGET)

set(RUNGEN "${AOT_LIBRARY_TARGET}.rungen")
add_executable("${RUNGEN}" "${CMAKE_SOURCE_DIR}/tools/RunGenStubs.cpp")
target_compile_definitions("${RUNGEN}" PRIVATE "-DHL_RUNGEN_FILTER=${AOT_LIBRARY_TARGET}")
target_compile_definitions("${RUNGEN}" PRIVATE "-DHL_RUNGEN_FILTER_HEADER=\"${AOT_LIBRARY_TARGET}.h\"")
target_link_libraries("${RUNGEN}" PRIVATE HalideToolsRunGen)
halide_add_aot_library_dependency("${RUNGEN}" "${AOT_LIBRARY_TARGET}")
target_link_libraries("${RUNGEN}" PRIVATE ${args_FILTER_DEPS})

# Not all Generators will build properly with RunGen (e.g., missing
# external dependencies), so exclude them from the "ALL" targets
Expand Down
5 changes: 2 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,6 @@ test_aotcpp_generators: $(GENERATOR_AOTCPP_TESTS)
# not all will work directly (e.g. due to missing define_externs at link time), so we blacklist
# those known to be broken for plausible reasons.
GENERATOR_BUILD_RUNGEN_TESTS = $(GENERATOR_EXTERNAL_TEST_GENERATORS:$(ROOT_DIR)/test/generator/%_generator.cpp=$(FILTERS_DIR)/%.rungen)
GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/cxx_mangling.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS))
GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/cxx_mangling_define_extern.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS))
GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/define_extern_opencl.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS))
GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/matlab.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS))
Expand Down Expand Up @@ -1248,8 +1247,8 @@ $(BUILD_DIR)/RunGen.o: $(ROOT_DIR)/tools/RunGen.cpp $(RUNTIME_EXPORTED_INCLUDES)
@mkdir -p $(BUILD_DIR)
$(CXX) -c $< $(TEST_CXX_FLAGS) $(IMAGE_IO_CXX_FLAGS) -I$(INCLUDE_DIR) -I $(SRC_DIR)/runtime -I$(ROOT_DIR)/tools -o $@

$(FILTERS_DIR)/%.rungen: $(BUILD_DIR)/RunGen.o $(BIN_DIR)/$(TARGET)/runtime.a $(ROOT_DIR)/tools/RunGenStubs.cpp $(FILTERS_DIR)/%.a
$(CXX) -DHL_RUNGEN_FILTER=$* $^ $(TEST_LD_FLAGS) $(IMAGE_IO_LIBS) -o $@
$(FILTERS_DIR)/%.rungen: $(BUILD_DIR)/RunGen.o $(BIN_DIR)/$(TARGET)/runtime.a $(ROOT_DIR)/tools/RunGenStubs.cpp $(FILTERS_DIR)/%.a
$(CXX) -std=c++11 -DHL_RUNGEN_FILTER_HEADER=\"$*.h\" -I$(FILTERS_DIR) $^ $(TEST_LD_FLAGS) $(IMAGE_IO_LIBS) -o $@

RUNARGS ?=

Expand Down
24 changes: 24 additions & 0 deletions src/CodeGen_C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,30 @@ void CodeGen_C::compile(const LoweredFunc &f) {
}
stream << "\n";
}

if (is_header() && f.linkage == LoweredFunc::ExternalPlusMetadata) {
// C syntax for function-that-returns-function-pointer is fun.
const string getter = R"INLINE_CODE(
// This allows the includer of this file to get the argv/metadata entry points
// for this file without needing to know the specific function names;
// if HALIDE_GET_STANDARD_ARGV_FUNCTION is defined before this file is
// included, an inline function with that name is provided that return
// a function pointer to the _argv() entry point (similarly,
// HALIDE_GET_STANDARD_METADATA_FUNCTION -> _metadata() entry point).
#ifdef HALIDE_GET_STANDARD_ARGV_FUNCTION
inline int (*HALIDE_GET_STANDARD_ARGV_FUNCTION())(void**) {
return $NAME$_argv;
}
#endif
#ifdef HALIDE_GET_STANDARD_METADATA_FUNCTION
inline const struct halide_filter_metadata_t* (*HALIDE_GET_STANDARD_METADATA_FUNCTION())() {
return $NAME$_metadata;
}
#endif
)INLINE_CODE";
stream << replace_all(getter, "$NAME$", f.name) << "\n\n";
}
}

void CodeGen_C::compile(const Buffer<> &buffer) {
Expand Down
7 changes: 3 additions & 4 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,12 @@ function(halide_define_aot_test NAME)
GENERATOR_TARGET "${NAME}.generator"
GENERATOR_NAME "${args_GENERATOR_NAME}"
GENERATED_FUNCTION "${args_GENERATED_FUNCTION}"
GENERATOR_ARGS "target=${args_GENERATOR_HALIDE_TARGET}" "${args_GENERATOR_ARGS}")
GENERATOR_ARGS "target=${args_GENERATOR_HALIDE_TARGET}" "${args_GENERATOR_ARGS}"
FILTER_DEPS "${args_FILTER_DEPS}")
halide_add_aot_library_dependency("${TARGET}" "${AOT_LIBRARY_TARGET}")
endif()

foreach(F ${args_FILTER_DEPS})
target_link_libraries("${TARGET}" PRIVATE ${F})
endforeach()
target_link_libraries("${TARGET}" PRIVATE ${args_FILTER_DEPS})

endfunction(halide_define_aot_test)

Expand Down
19 changes: 6 additions & 13 deletions tools/RunGenStubs.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
#ifndef HL_RUNGEN_FILTER
#error "You must define HL_RUNGEN_FILTER"
#endif
#define HALIDE_GET_STANDARD_ARGV_FUNCTION halide_rungen_redirect_argv_getter
#define HALIDE_GET_STANDARD_METADATA_FUNCTION halide_rungen_redirect_metadata_getter

#define HL_RUNGEN_NAME__(prefix, suffix) prefix##suffix
#define HL_RUNGEN_NAME_(prefix, suffix) HL_RUNGEN_NAME__(prefix, suffix)
#define HL_RUNGEN_NAME(suffix) HL_RUNGEN_NAME_(HL_RUNGEN_FILTER, suffix)

struct halide_filter_metadata_t;

extern "C" int HL_RUNGEN_NAME(_argv)(void **args);
extern "C" const struct halide_filter_metadata_t *HL_RUNGEN_NAME(_metadata)();
// This is legal C, as long as the macro expands to a single quoted (or <>-enclosed) string literal
#include HL_RUNGEN_FILTER_HEADER

extern "C" int halide_rungen_redirect_argv(void **args) {
return HL_RUNGEN_NAME(_argv)(args);
return halide_rungen_redirect_argv_getter()(args);
}

extern "C" const struct halide_filter_metadata_t *halide_rungen_redirect_metadata() {
return HL_RUNGEN_NAME(_metadata)();
return halide_rungen_redirect_metadata_getter()();
}

0 comments on commit f7d2c0d

Please sign in to comment.