diff options
| author | Nico Weber <nicolasweber@gmx.de> | 2019-10-03 21:22:28 +0000 | 
|---|---|---|
| committer | Nico Weber <nicolasweber@gmx.de> | 2019-10-03 21:22:28 +0000 | 
| commit | 204623e05c12dd137c2ffdda4876afd4fb66309f (patch) | |
| tree | 1edc405a59f97b7a9d73f9d99d117718abd2dffa /llvm/lib/TableGen | |
| parent | 2ac586c58f1fade51b397e375b2cdcdbf33b40a8 (diff) | |
| download | bcm5719-llvm-204623e05c12dd137c2ffdda4876afd4fb66309f.tar.gz bcm5719-llvm-204623e05c12dd137c2ffdda4876afd4fb66309f.zip  | |
Reland r349624: Let TableGen write output only if it changed, instead of doing so in cmake
Move the write-if-changed logic behind a flag and don't pass it
with the MSVC generator. msbuild doesn't have a restat optimization,
so not doing write-if-change there doesn't have a cost, and it
should fix whatever causes PR43385.
llvm-svn: 373664
Diffstat (limited to 'llvm/lib/TableGen')
| -rw-r--r-- | llvm/lib/TableGen/Main.cpp | 37 | 
1 files changed, 29 insertions, 8 deletions
diff --git a/llvm/lib/TableGen/Main.cpp b/llvm/lib/TableGen/Main.cpp index bf97e37f324..48ded6c45a4 100644 --- a/llvm/lib/TableGen/Main.cpp +++ b/llvm/lib/TableGen/Main.cpp @@ -49,6 +49,9 @@ static cl::list<std::string>  MacroNames("D", cl::desc("Name of the macro to be defined"),              cl::value_desc("macro name"), cl::Prefix); +static cl::opt<bool> +WriteIfChanged("write-if-changed", cl::desc("Only write output if it changed")); +  static int reportError(const char *ProgName, Twine Msg) {    errs() << ProgName << ": " << Msg;    errs().flush(); @@ -99,23 +102,41 @@ int llvm::TableGenMain(char *argv0, TableGenMainFn *MainFn) {    if (Parser.ParseFile())      return 1; -  std::error_code EC; -  ToolOutputFile Out(OutputFilename, EC, sys::fs::OF_None); -  if (EC) -    return reportError(argv0, "error opening " + OutputFilename + ":" + -                                  EC.message() + "\n"); +  // Write output to memory. +  std::string OutString; +  raw_string_ostream Out(OutString); +  if (MainFn(Out, Records)) +    return 1; + +  // Always write the depfile, even if the main output hasn't changed. +  // If it's missing, Ninja considers the output dirty.  If this was below +  // the early exit below and someone deleted the .inc.d file but not the .inc +  // file, tablegen would never write the depfile.    if (!DependFilename.empty()) {      if (int Ret = createDependencyFile(Parser, argv0))        return Ret;    } -  if (MainFn(Out.os(), Records)) -    return 1; +  if (WriteIfChanged) { +    // Only updates the real output file if there are any differences. +    // This prevents recompilation of all the files depending on it if there +    // aren't any. +    if (auto ExistingOrErr = MemoryBuffer::getFile(OutputFilename)) +      if (std::move(ExistingOrErr.get())->getBuffer() == Out.str()) +        return 0; +  } + +  std::error_code EC; +  ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None); +  if (EC) +    return reportError(argv0, "error opening " + OutputFilename + ":" + +                                  EC.message() + "\n"); +  OutFile.os() << Out.str();    if (ErrorsPrinted > 0)      return reportError(argv0, Twine(ErrorsPrinted) + " errors.\n");    // Declare success. -  Out.keep(); +  OutFile.keep();    return 0;  }  | 

