llvm.org GIT mirror llvm / 0bc70d3
Let TableGen write output only if it changed, instead of doing so in cmake, attempt 2 This relands r330742: """ Let TableGen write output only if it changed, instead of doing so in cmake. Removes one subprocess and one temp file from the build for each tablegen invocation. No intended behavior change. """ In particular, if you see rebuilds after this change that you didn't see before this change, that's unintended and it's fine to revert this change again (but let me know). r330742 got reverted because some people reported that llvm-tblgen ran on every build after it. This could happen if the depfile output got deleted without deleting the main .inc output. To fix, make TableGen always write the depfile, but keep writing the main .inc output only if it has changed. This matches what we did in cmake before. Differential Revision: https://reviews.llvm.org/D55842 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@349624 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber 9 months ago
3 changed file(s) with 28 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
2424 file(RELATIVE_PATH ofn_rel
2525 ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/${ofn})
2626 set(additional_cmdline
27 -o ${ofn_rel}.tmp
27 -o ${ofn_rel}
2828 -d ${ofn_rel}.d
2929 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
3030 DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.d
3535 file(GLOB local_tds "*.td")
3636 file(GLOB_RECURSE global_tds "${LLVM_MAIN_INCLUDE_DIR}/llvm/*.td")
3737 set(additional_cmdline
38 -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
38 -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
3939 )
4040 endif()
4141
6868 # dependency twice in the result file when
6969 # ("${${project}_TABLEGEN_TARGET}" STREQUAL "${${project}_TABLEGEN_EXE}")
7070 # but lets us having smaller and cleaner code here.
71 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
72 # Generate tablegen output in a temporary file.
71 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
7372 COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR}
7473 ${LLVM_TABLEGEN_FLAGS}
7574 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
8281 ${LLVM_TARGET_DEFINITIONS_ABSOLUTE}
8382 COMMENT "Building ${ofn}..."
8483 )
85 add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
86 # Only update the real output file if there are any differences.
87 # This prevents recompilation of all the files depending on it if there
88 # aren't any.
89 COMMAND ${CMAKE_COMMAND} -E copy_if_different
90 ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
91 ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
92 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp
93 COMMENT "Updating ${ofn}..."
94 )
9584
9685 # `make clean' must remove all those generated files:
97 set_property(DIRECTORY APPEND
98 PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn}.tmp ${ofn})
86 set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${ofn})
9987
10088 set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE)
10189 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES
9999 if (Parser.ParseFile())
100100 return 1;
101101
102 std::error_code EC;
103 ToolOutputFile Out(OutputFilename, EC, sys::fs::F_Text);
104 if (EC)
105 return reportError(argv0, "error opening " + OutputFilename + ":" +
106 EC.message() + "\n");
102 // Write output to memory.
103 std::string OutString;
104 raw_string_ostream Out(OutString);
105 if (MainFn(Out, Records))
106 return 1;
107
108 // Always write the depfile, even if the main output hasn't changed.
109 // If it's missing, Ninja considers the output dirty. If this was below
110 // the early exit below and someone deleted the .inc.d file but not the .inc
111 // file, tablegen would never write the depfile.
107112 if (!DependFilename.empty()) {
108113 if (int Ret = createDependencyFile(Parser, argv0))
109114 return Ret;
110115 }
111116
112 if (MainFn(Out.os(), Records))
113 return 1;
117 // Only updates the real output file if there are any differences.
118 // This prevents recompilation of all the files depending on it if there
119 // aren't any.
120 if (auto ExistingOrErr = MemoryBuffer::getFile(OutputFilename))
121 if (std::move(ExistingOrErr.get())->getBuffer() == Out.str())
122 return 0;
123
124 std::error_code EC;
125 ToolOutputFile OutFile(OutputFilename, EC, sys::fs::F_Text);
126 if (EC)
127 return reportError(argv0, "error opening " + OutputFilename + ":" +
128 EC.message() + "\n");
129 OutFile.os() << Out.str();
114130
115131 if (ErrorsPrinted > 0)
116132 return reportError(argv0, Twine(ErrorsPrinted) + " errors.\n");
117133
118134 // Declare success.
119 Out.keep();
135 OutFile.keep();
120136 return 0;
121137 }
5959 depfile = "$gen_output.d"
6060 td_file = rebase_path(td_file, root_build_dir)
6161
62 # FIXME: The cmake build lets tablegen write to a temp file and then copies
63 # it over the final output only if it has changed, for ninja's restat
64 # optimization. Instead of doing that in cmake, llvm-tblgen should do this
65 # itself. r330742 tried this, but it caused problems. Fix those and reland,
66 # so that the gn build has the optimization too.
6762 args = [
6863 rebase_path(tblgen_executable, root_build_dir),
6964 "-I",