267 lines · plain
1# LLVM_TARGET_DEFINITIONS must contain the name of the .td file to process,2# while LLVM_TARGET_DEPENDS may contain additional file dependencies.3# Extra parameters for `tblgen' may come after `ofn' parameter.4# Adds the name of the generated file to TABLEGEN_OUTPUT.5include(LLVMDistributionSupport)6 7function(tablegen project ofn)8 cmake_parse_arguments(ARG "" "" "DEPENDS;EXTRA_INCLUDES" ${ARGN})9 10 # Override ${project} with ${project}_TABLEGEN_PROJECT11 if(NOT "${${project}_TABLEGEN_PROJECT}" STREQUAL "")12 set(project ${${project}_TABLEGEN_PROJECT})13 endif()14 15 # Validate calling context.16 if(NOT ${project}_TABLEGEN_EXE)17 message(FATAL_ERROR "${project}_TABLEGEN_EXE not set")18 endif()19 20 # Set the include directories21 get_directory_property(tblgen_includes INCLUDE_DIRECTORIES)22 list(PREPEND tblgen_includes ${ARG_EXTRA_INCLUDES})23 list(PREPEND tblgen_includes ${CMAKE_CURRENT_SOURCE_DIR})24 # Filter out any empty include items.25 list(REMOVE_ITEM tblgen_includes "")26 27 # Use depfile instead of globbing arbitrary *.td(s) for Ninja. We force28 # CMake versions older than v3.30 on Windows to use the fallback behavior29 # due to a depfile parsing bug on Windows paths in versions prior to 3.30.30 # https://gitlab.kitware.com/cmake/cmake/-/issues/2594331 # CMake versions older than v3.23 on other platforms use the fallback32 # behavior as v3.22 and earlier fail to parse some depfiles that get33 # generated, and this behavior was fixed in CMake commit34 # e04a352cca523eba2ac0d60063a3799f5bb1c69e.35 cmake_policy(GET CMP0116 cmp0116_state)36 if(CMAKE_GENERATOR MATCHES "Ninja" AND cmp0116_state STREQUAL NEW37 AND NOT (CMAKE_HOST_WIN32 AND CMAKE_VERSION VERSION_LESS 3.30)38 AND NOT (CMAKE_VERSION VERSION_LESS 3.23))39 # CMake emits build targets as relative paths but Ninja doesn't identify40 # absolute path (in *.d) as relative path (in build.ninja). Post CMP0116,41 # CMake handles this discrepancy for us, otherwise we use the fallback42 # logic.43 set(additional_cmdline44 -o ${ofn}45 -d ${ofn}.d46 DEPFILE ${ofn}.d47 )48 set(global_tds)49 else()50 set(include_td_dirs "${tblgen_includes}")51 list(TRANSFORM include_td_dirs APPEND "/*.td")52 file(GLOB global_tds ${include_td_dirs})53 set(additional_cmdline54 -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}55 )56 endif()57 58 if (LLVM_ENABLE_DAGISEL_COV AND "-gen-dag-isel" IN_LIST ARGN)59 list(APPEND LLVM_TABLEGEN_FLAGS "-instrument-coverage")60 endif()61 if (LLVM_ENABLE_GISEL_COV AND "-gen-global-isel" IN_LIST ARGN)62 list(APPEND LLVM_TABLEGEN_FLAGS "-instrument-gisel-coverage")63 list(APPEND LLVM_TABLEGEN_FLAGS "-gisel-coverage-file=${LLVM_GISEL_COV_PREFIX}all")64 endif()65 if (LLVM_OMIT_DAGISEL_COMMENTS AND "-gen-dag-isel" IN_LIST ARGN)66 list(APPEND LLVM_TABLEGEN_FLAGS "-omit-comments")67 endif()68 69 set(EXTRA_OUTPUTS)70 if("-gen-register-info" IN_LIST ARGN)71 cmake_path(GET ofn STEM OUTPUT_BASENAME)72 list(APPEND EXTRA_OUTPUTS73 ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_BASENAME}Enums.inc74 ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_BASENAME}Header.inc75 ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_BASENAME}MCDesc.inc76 ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_BASENAME}TargetDesc.inc)77 endif()78 79 # MSVC can't support long string literals ("long" > 65534 bytes)[1], so if there's80 # a possibility of generated tables being consumed by MSVC, generate arrays of81 # char literals, instead. If we're cross-compiling, then conservatively assume82 # that the source might be consumed by MSVC.83 # [1] https://docs.microsoft.com/en-us/cpp/cpp/compiler-limits?view=vs-201784 # Don't pass this flag to mlir-src-sharder, since it doesn't support the85 # flag, and it doesn't need it.86 if (MSVC AND NOT "${project}" STREQUAL "MLIR_SRC_SHARDER")87 list(APPEND LLVM_TABLEGEN_FLAGS "--long-string-literals=0")88 endif()89 if (CMAKE_GENERATOR MATCHES "Visual Studio")90 # Visual Studio has problems with llvm-tblgen's native --write-if-changed91 # behavior. Since it doesn't do restat optimizations anyway, just don't92 # pass --write-if-changed there.93 set(tblgen_change_flag)94 else()95 set(tblgen_change_flag "--write-if-changed")96 endif()97 98 if (NOT LLVM_ENABLE_WARNINGS)99 list(APPEND LLVM_TABLEGEN_FLAGS "-no-warn-on-unused-template-args")100 endif()101 102 # Build the absolute path for the current input file.103 if (IS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})104 set(LLVM_TARGET_DEFINITIONS_ABSOLUTE ${LLVM_TARGET_DEFINITIONS})105 else()106 set(LLVM_TARGET_DEFINITIONS_ABSOLUTE107 ${CMAKE_CURRENT_SOURCE_DIR}/${LLVM_TARGET_DEFINITIONS})108 endif()109 110 # Append this file and its includes to the compile commands file.111 # This file is used by the TableGen LSP Language Server (tblgen-lsp-server).112 file(APPEND ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml113 "--- !FileInfo:\n"114 " filepath: \"${LLVM_TARGET_DEFINITIONS_ABSOLUTE}\"\n"115 " includes: \"${tblgen_includes}\"\n"116 )117 118 # Prepend each include entry with -I for arguments.119 list(TRANSFORM tblgen_includes PREPEND -I)120 121 # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list122 # (both the target and the file) to have .inc files rebuilt on123 # a tablegen change, as cmake does not propagate file-level dependencies124 # of custom targets. See the following ticket for more information:125 # https://cmake.org/Bug/view.php?id=15858126 # The dependency on both, the target and the file, produces the same127 # dependency twice in the result file when128 # ("${${project}_TABLEGEN_TARGET}" STREQUAL "${${project}_TABLEGEN_EXE}")129 # but lets us having smaller and cleaner code here.130 set(tablegen_exe ${${project}_TABLEGEN_EXE})131 set(tablegen_depends ${${project}_TABLEGEN_TARGET} ${tablegen_exe})132 133 if(LLVM_PARALLEL_TABLEGEN_JOBS)134 set(LLVM_TABLEGEN_JOB_POOL JOB_POOL tablegen_job_pool)135 else()136 set(LLVM_TABLEGEN_JOB_POOL "")137 endif()138 139 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} ${EXTRA_OUTPUTS}140 COMMAND ${tablegen_exe} ${ARG_UNPARSED_ARGUMENTS}141 ${tblgen_includes}142 ${LLVM_TABLEGEN_FLAGS}143 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}144 ${tblgen_change_flag}145 ${additional_cmdline}146 # The file in LLVM_TARGET_DEFINITIONS may be not in the current147 # directory and local_tds may not contain it, so we must148 # explicitly list it here:149 DEPENDS ${ARG_DEPENDS} ${tablegen_depends}150 ${global_tds}151 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}152 ${LLVM_TARGET_DEPENDS}153 ${LLVM_TABLEGEN_JOB_POOL}154 COMMENT "Building ${ofn}..."155 )156 157 # `make clean' must remove all those generated files:158 set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn})159 160 set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)161 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES162 GENERATED 1)163endfunction()164 165# Creates a target for publicly exporting tablegen dependencies.166function(add_public_tablegen_target target)167 if(NOT TABLEGEN_OUTPUT)168 message(FATAL_ERROR "Requires tablegen() definitions as TABLEGEN_OUTPUT.")169 endif()170 add_custom_target(${target}171 DEPENDS ${TABLEGEN_OUTPUT})172 if(LLVM_COMMON_DEPENDS)173 add_dependencies(${target} ${LLVM_COMMON_DEPENDS})174 endif()175 get_subproject_title(subproject_title)176 set_target_properties(${target} PROPERTIES FOLDER "${subproject_title}/Tablegenning")177 set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} ${target} PARENT_SCOPE)178endfunction()179 180macro(add_tablegen target project)181 cmake_parse_arguments(ADD_TABLEGEN "" "DESTINATION;EXPORT" "" ${ARGN})182 183 set(${target}_OLD_LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS})184 set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} TableGen)185 186 add_llvm_executable(${target} DISABLE_LLVM_LINK_LLVM_DYLIB187 ${ADD_TABLEGEN_UNPARSED_ARGUMENTS})188 set(LLVM_LINK_COMPONENTS ${${target}_OLD_LLVM_LINK_COMPONENTS})189 190 set(${project}_TABLEGEN_DEFAULT "${target}")191 if (LLVM_NATIVE_TOOL_DIR)192 if (EXISTS "${LLVM_NATIVE_TOOL_DIR}/${target}${LLVM_HOST_EXECUTABLE_SUFFIX}")193 set(${project}_TABLEGEN_DEFAULT "${LLVM_NATIVE_TOOL_DIR}/${target}${LLVM_HOST_EXECUTABLE_SUFFIX}")194 endif()195 endif()196 197 # FIXME: Quick fix to reflect LLVM_TABLEGEN to llvm-min-tblgen198 if("${target}" STREQUAL "llvm-min-tblgen"199 AND NOT "${LLVM_TABLEGEN}" STREQUAL ""200 AND NOT "${LLVM_TABLEGEN}" STREQUAL "llvm-tblgen")201 set(${project}_TABLEGEN_DEFAULT "${LLVM_TABLEGEN}")202 endif()203 204 if(ADD_TABLEGEN_EXPORT)205 set(${project}_TABLEGEN "${${project}_TABLEGEN_DEFAULT}" CACHE206 STRING "Native TableGen executable. Saves building one when cross-compiling.")207 else()208 # Internal tablegen209 set(${project}_TABLEGEN "${${project}_TABLEGEN_DEFAULT}")210 set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL ON)211 endif()212 213 # Effective tblgen executable to be used:214 set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN} PARENT_SCOPE)215 set(${project}_TABLEGEN_TARGET ${${project}_TABLEGEN} PARENT_SCOPE)216 217 if(LLVM_USE_HOST_TOOLS)218 if( ${${project}_TABLEGEN} STREQUAL "${target}" )219 # The NATIVE tablegen executable *must* depend on the current target one220 # otherwise the native one won't get rebuilt when the tablgen sources221 # change, and we end up with incorrect builds.222 build_native_tool(${target} ${project}_TABLEGEN_EXE DEPENDS ${target})223 set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE)224 225 add_custom_target(${target}-host DEPENDS ${${project}_TABLEGEN_EXE})226 get_subproject_title(subproject_title)227 set_target_properties(${target}-host PROPERTIES FOLDER "${subproject_title}/Native")228 set(${project}_TABLEGEN_TARGET ${target}-host PARENT_SCOPE)229 230 # If we're using the host tablegen, and utils were not requested, we have no231 # need to build this tablegen.232 if ( NOT LLVM_BUILD_UTILS )233 set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL ON)234 endif()235 endif()236 endif()237 238 if (ADD_TABLEGEN_DESTINATION AND NOT LLVM_INSTALL_TOOLCHAIN_ONLY AND239 (LLVM_BUILD_UTILS OR ${target} IN_LIST LLVM_DISTRIBUTION_COMPONENTS))240 set(export_arg)241 if(ADD_TABLEGEN_EXPORT)242 get_target_export_arg(${target} ${ADD_TABLEGEN_EXPORT} export_arg)243 endif()244 install(TARGETS ${target}245 ${export_arg}246 COMPONENT ${target}247 RUNTIME DESTINATION "${ADD_TABLEGEN_DESTINATION}")248 if(NOT LLVM_ENABLE_IDE)249 add_llvm_install_targets("install-${target}"250 DEPENDS ${target}251 COMPONENT ${target})252 endif()253 endif()254 if(ADD_TABLEGEN_EXPORT)255 string(TOUPPER ${ADD_TABLEGEN_EXPORT} export_upper)256 set_property(GLOBAL APPEND PROPERTY ${export_upper}_EXPORTS ${target})257 endif()258endmacro()259 260# Make sure 'tablegen_compile_commands.yml' is only deleted once the very261# first time this file is included.262include_guard(GLOBAL)263 264# Clear out any pre-existing compile_commands file before processing. This265# allows for generating a clean compile_commands on each configure.266file(REMOVE ${CMAKE_BINARY_DIR}/tablegen_compile_commands.yml)267