diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index c6eebfaac40ce..3d1d4d2e948e9 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -9,7 +9,7 @@ function(mlir_tablegen ofn) tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) - + # Get the current set of include paths for this td file. cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) @@ -37,11 +37,104 @@ endfunction() # allows for generating a clean compile_commands on each configure. file(REMOVE ${CMAKE_BINARY_DIR}/pdll_compile_commands.yml) +# Declare a helper function/copy of tablegen rule for using tablegen without +# additional tblgen specific flags when invoking PDLL generator. +function(_pdll_tablegen project ofn) + cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN}) + # Validate calling context. + if(NOT ${project}_TABLEGEN_EXE) + message(FATAL_ERROR "${project}_TABLEGEN_EXE not set") + endif() + + # Use depfile instead of globbing arbitrary *.td(s) for Ninja. + if(CMAKE_GENERATOR MATCHES "Ninja") + # Make output path relative to build.ninja, assuming located on + # ${CMAKE_BINARY_DIR}. + # CMake emits build targets as relative paths but Ninja doesn't identify + # absolute path (in *.d) as relative path (in build.ninja) + # Note that tblgen is executed on ${CMAKE_BINARY_DIR} as working directory. + file(RELATIVE_PATH ofn_rel + ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}) + set(additional_cmdline + -o ${ofn_rel} + -d ${ofn_rel}.d + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.d + ) + set(local_tds) + set(global_tds) + else() + file(GLOB local_tds "*.td") + file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td") + set(additional_cmdline + -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn} + ) + endif() + + if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS}) + else() + set(LLVM_TARGET_DEFINITIONS_ABSOLUTE + ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS}) + endif() + + if (CMAKE_GENERATOR MATCHES "Visual Studio") + # Visual Studio has problems with llvm-tblgen's native --write-if-changed + # behavior. Since it doesn't do restat optimizations anyway, just don't + # pass --write-if-changed there. + set(tblgen_change_flag) + else() + set(tblgen_change_flag "--write-if-changed") + endif() + + # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list + # (both the target and the file) to have .inc files rebuilt on + # a tablegen change, as cmake does not propagate file-level dependencies + # of custom targets. See the following ticket for more information: + # https://cmake.org/Bug/view.php?id=15858 + # The dependency on both, the target and the file, produces the same + # dependency twice in the result file when + # ("${${project}_TABLEGEN_TARGET}" STREQUAL "${${project}_TABLEGEN_EXE}") + # but lets us having smaller and cleaner code here. + get_directory_property(tblgen_includes INCLUDE_DIRECTORIES) + list(APPEND tblgen_includes ${ARG_EXTRA_INCLUDES}) + # Filter out empty items before prepending each entry with -I + list(REMOVE_ITEM tblgen_includes "") + list(TRANSFORM tblgen_includes PREPEND -I) + + set(tablegen_exe ${${project}_TABLEGEN_EXE}) + set(tablegen_depends ${${project}_TABLEGEN_TARGET} ${tablegen_exe}) + + add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} + COMMAND ${tablegen_exe} ${ARG_UNPARSED_ARGUMENTS} -I ${CMAKE_CURRENT_SOURCE_DIR} + ${tblgen_includes} + ${LLVM_TABLEGEN_FLAGS} + ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} + ${tblgen_change_flag} + ${additional_cmdline} + # The file in LLVM_TARGET_DEFINITIONS may be not in the current + # directory and local_tds may not contain it, so we must + # explicitly list it here: + DEPENDS ${ARG_DEPENDS} ${tablegen_depends} + ${local_tds} ${global_tds} + ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} + ${LLVM_TARGET_DEPENDS} + COMMENT "Building ${ofn}..." + ) + + # `make clean' must remove all those generated files: + set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn}) + + set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) + set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES + GENERATED 1) +endfunction() + # Declare a PDLL library in the current directory. function(add_mlir_pdll_library target inputFile ofn) set(LLVM_TARGET_DEFINITIONS ${inputFile}) - tablegen(MLIR_PDLL ${ofn} -x=cpp ${ARGN}) + _pdll_tablegen(MLIR_PDLL ${ofn} -x=cpp ${ARGN}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)