Index: llvm/utils/gn/build/run_tablegen.py =================================================================== --- /dev/null +++ llvm/utils/gn/build/run_tablegen.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +"""Runs tablegen.""" + +# This makes llvm-tblgen write the output to a temp file and only copies +# it to the final location if the output is different from last run. +# FIXME: llvm-tblgen should do this itself. r330742 tried this, but it caused +# problems. Fix those and reland, then rename this script to run_host_binary.py +# and make it only do +# `sys.exit(subprocess.call(['./' + sys.argv[1]] + sys.argv[2:]))` + +from __future__ import print_function + +import os +import subprocess +import sys +import tempfile + + +def main(): + output = None + for i in range(1, len(sys.argv)): + if sys.argv[i] == '-o': + output_index = i + 1 + output = sys.argv[i + 1] + break + if not output: + print('failed to find -o argument', file=sys.stderr) + return 1 + + # Run tablegen, but write to a temp file. + temp_file = tempfile.NamedTemporaryFile(delete=False) + temp_file.close() # So that llvm-tblgen can write to it on Windows. + + # Prefix with ./ to run built binary, not arbitrary stuff from PATH. + cmd = ['./' + sys.argv[1]] + sys.argv[2:] + cmd[output_index - 1] = temp_file.name + subprocess.check_call(cmd) + + # Open new output, and overwrite if it's different from old output. + with open(temp_file.name, 'rb') as temp_file_handle: + new_output = temp_file_handle.read() + os.remove(temp_file.name) + + try: + with open(output, 'rb') as output_handle: + should_write = output_handle.read() != new_output + except IOError as e: + if error.errno != errno.ENOENT: + raise + should_write = True + + if should_write: + with open(output, 'wb') as output_handle: + output_handle.write(new_output) + + +if __name__ == '__main__': + sys.exit(main()) Index: llvm/utils/gn/secondary/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/BUILD.gn +++ llvm/utils/gn/secondary/BUILD.gn @@ -1,5 +1,6 @@ group("default") { deps = [ + "//llvm/lib/IR", "//llvm/utils/TableGen:llvm-tblgen", "//llvm/tools/llvm-undname", ] Index: llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn =================================================================== --- /dev/null +++ llvm/utils/gn/secondary/llvm/include/llvm/IR/BUILD.gn @@ -0,0 +1,18 @@ +import("//llvm/utils/TableGen/tablegen.gni") + +tablegen("IntrinsicEnums") { + visibility = [ "//llvm/lib/IR" ] + args = [ "-gen-intrinsic-enums" ] + td_file = "Intrinsics.td" +} + +tablegen("IntrinsicImpl") { + visibility = [ "//llvm/lib/IR" ] + args = [ "-gen-intrinsic-impl" ] + td_file = "Intrinsics.td" +} + +tablegen("Attributes") { + visibility = [ "//llvm/lib/IR" ] + args = [ "-gen-attrs" ] +} Index: llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn =================================================================== --- /dev/null +++ llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn @@ -0,0 +1,13 @@ +static_library("BinaryFormat") { + output_name = "LLVMBinaryFormat" + deps = [ + "//llvm/lib/Support", + ] + sources = [ + "Dwarf.cpp", + "Magic.cpp", + "MsgPackReader.cpp", + "MsgPackWriter.cpp", + "Wasm.cpp", + ] +} Index: llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn =================================================================== --- /dev/null +++ llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -0,0 +1,79 @@ +import("//llvm/utils/TableGen/tablegen.gni") + +tablegen("AttributesCompatFunc") { + visibility = [ ":IR" ] + args = [ "-gen-attrs" ] +} + +static_library("IR") { + output_name = "LLVMCore" + public_deps = [ + # Must be public_dep because IR's public headers include llvm-config.h. + "//llvm/include/llvm/Config:llvm-config", + # Must be public_dep because IR's public headers include Attributes.inc. + "//llvm/include/llvm/IR:Attributes", + # Must be public_dep because IR's public headers include IntrinsicEnums.inc. + "//llvm/include/llvm/IR:IntrinsicEnums", + ] + deps = [ + ":AttributesCompatFunc", + "//llvm/include/llvm/IR:IntrinsicImpl", + "//llvm/lib/BinaryFormat", + "//llvm/lib/Support", + ] + sources = [ + "AsmWriter.cpp", + "Attributes.cpp", + "AutoUpgrade.cpp", + "BasicBlock.cpp", + "Comdat.cpp", + "ConstantFold.cpp", + "ConstantRange.cpp", + "Constants.cpp", + "Core.cpp", + "DIBuilder.cpp", + "DataLayout.cpp", + "DebugInfo.cpp", + "DebugInfoMetadata.cpp", + "DebugLoc.cpp", + "DiagnosticHandler.cpp", + "DiagnosticInfo.cpp", + "DiagnosticPrinter.cpp", + "DomTreeUpdater.cpp", + "Dominators.cpp", + "Function.cpp", + "GVMaterializer.cpp", + "Globals.cpp", + "IRBuilder.cpp", + "IRPrintingPasses.cpp", + "InlineAsm.cpp", + "Instruction.cpp", + "Instructions.cpp", + "IntrinsicInst.cpp", + "LLVMContext.cpp", + "LLVMContextImpl.cpp", + "LegacyPassManager.cpp", + "MDBuilder.cpp", + "Mangler.cpp", + "Metadata.cpp", + "Module.cpp", + "ModuleSummaryIndex.cpp", + "Operator.cpp", + "OptBisect.cpp", + "Pass.cpp", + "PassInstrumentation.cpp", + "PassManager.cpp", + "PassRegistry.cpp", + "PassTimingInfo.cpp", + "ProfileSummary.cpp", + "SafepointIRVerifier.cpp", + "Statepoint.cpp", + "Type.cpp", + "TypeFinder.cpp", + "Use.cpp", + "User.cpp", + "Value.cpp", + "ValueSymbolTable.cpp", + "Verifier.cpp", + ] +} Index: llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni =================================================================== --- /dev/null +++ llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni @@ -0,0 +1,85 @@ +# This file defines a template for running llvm-tblgen. +# +# Parameters: +# +# args (required) +# [list of strings] Flags to pass to llvm-tblgen. +# +# output_name (optional) +# Basename of the generated output file. +# Defaults to target name with ".inc" appended. +# +# td_file (roptional) +# The .td file to pass to llvm-tblgen. +# Defaults to target name with ".td" appended. +# +# visibility (optional) +# GN's regular visibility attribute, see `gn help visibility`. +# +# Example use: +# +# tablegen("attributes_compat_func_gen") { +# visibility = [ ":IR" ] +# args = [ "-gen-attrs" ] +# td_file = "AttributesCompatFunc.td" +# } + +template("tablegen") { + assert(defined(invoker.args), "args must be defined for $target_name") + + config_name = "${target_name}_config" + config(config_name) { + visibility = [ ":$target_name" ] + include_dirs = [ target_gen_dir ] + } + + action(target_name) { + forward_variables_from(invoker, [ "visibility" ]) + + # FIXME: In cross builds, this should depend on the host binary. + tblgen_target = "//llvm/utils/TableGen:llvm-tblgen" + tblgen_executable = get_label_info(tblgen_target, "root_out_dir") + + "/bin/" + get_label_info(tblgen_target, "name") + deps = [ + tblgen_target, + ] + if (defined(invoker.td_file)) { + td_file = invoker.td_file + } else { + td_file = "$target_name.td" + } + sources = [ + td_file, + ] + script = "//llvm/utils/gn/build/run_tablegen.py" + if (defined(invoker.output_name)) { + gen_output = "$target_gen_dir/" + invoker.output_name + } else { + gen_output = "$target_gen_dir/$target_name.inc" + } + depfile = "$gen_output.d" + td_file = rebase_path(td_file, root_build_dir) + args = [ + rebase_path(tblgen_executable, root_build_dir), + "-I", + rebase_path("//llvm/include", root_build_dir), + + # FIXME: Rather than duplicating this -I flag in both the CMake and + # the gn build, let tablegen add input dir to include search path + # instead? + "-I", + get_path_info(td_file, "dir"), + "-d", + rebase_path(depfile, root_build_dir), + "-o", + rebase_path(gen_output, root_build_dir), + td_file, + ] + invoker.args + outputs = [ + gen_output, + ] + + # Let targets depending on this find the generated file. + public_configs = [ ":$config_name" ] + } +}