Radovan.Obradovic updated this revision to Diff 31807.
Radovan.Obradovic added a comment.

The patch is updated to be consistent with the patch for IC for LLVM.


http://reviews.llvm.org/D4724

Files:
  include/clang/Driver/Compilation.h
  include/clang/Driver/Driver.h
  include/clang/Driver/Options.td
  lib/CodeGen/BackendUtil.cpp
  lib/Driver/Driver.cpp
  lib/Driver/Tools.cpp
  tools/driver/driver.cpp

Index: tools/driver/driver.cpp
===================================================================
--- tools/driver/driver.cpp
+++ tools/driver/driver.cpp
@@ -50,6 +50,10 @@
 #include "llvm/Support/raw_ostream.h"
 #include <memory>
 #include <system_error>
+#include "llvm/Analysis/DecisionTree.h"
+#include "llvm/Support/Program.h"
+#include <string>
+#include <sstream>
 using namespace clang;
 using namespace clang::driver;
 using namespace llvm::opt;
@@ -470,6 +474,35 @@
         Diags.takeClient(), std::move(SerializedConsumer)));
   }
 
+  // Get number of iterations for iterative compilation.
+  int ICNumberOfIterations = 0;
+  std::string ICInputFile;
+  std::string ICInputFile2;
+  std::string ICResultsFile;
+  std::string ICResultsFile2;
+
+  std::unique_ptr<OptTable> CCopts(createDriverOptTable());
+  unsigned MissingArgIndex, MissingArgCount;
+  ArrayRef<const char*> argv_ref(argv);
+  InputArgList Args = CCopts->ParseArgs(argv_ref.slice(1),
+                                        MissingArgIndex, MissingArgCount);
+  if (Args.getLastArg(options::OPT_fiterative_comp_EQ)) {
+    std::string Val = Args.getLastArgValue(options::OPT_fiterative_comp_EQ, "1");
+    std::stringstream Convert(Val);
+    Convert >> ICNumberOfIterations;
+   }
+  if (!ICNumberOfIterations)
+    ICNumberOfIterations = 1; // Default value is 1.
+
+  llvm::ModuleDecisionTrees moduleDecisionTrees;
+
+  int CurrentIteration = 0;
+  int Res = 0;
+
+  llvm::FnNameAndPhase::ICPhase CurrICPhase = llvm::FnNameAndPhase::ModulePhase;
+
+  for (; CurrentIteration < ICNumberOfIterations; CurrentIteration++) {
+
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
@@ -480,12 +513,138 @@
 
   SetBackdoorDriverOutputsFromEnvVars(TheDriver);
 
+  std::stringstream filename;
+
+  if (ICNumberOfIterations > 1) {
+    std::string ErrMsg;
+    SmallString<128> InputPath;
+    filename << "ic-input-" << CurrentIteration;
+    if (llvm::sys::fs::createTemporaryFile(filename.str(), ".json", InputPath)) {
+      llvm::errs() << "Error creating temporary file: " << ErrMsg << "\n";
+      ICNumberOfIterations = 1;
+    }
+    ICInputFile = InputPath.c_str();
+
+    SmallString<128> InputPath2;
+
+    filename.str("");
+    filename << "ic-input2-" << CurrentIteration;
+    if (llvm::sys::fs::createTemporaryFile(filename.str(), ".json", InputPath2)) {
+      llvm::errs() << "Error creating temporary file: " << ErrMsg << "\n";
+      ICNumberOfIterations = 1;
+    }
+    ICInputFile2 = InputPath2.c_str();
+
+    SmallString<128> ResPath;
+    filename.str("");
+    filename << "ic-results-" << CurrentIteration;
+    if (llvm::sys::fs::createTemporaryFile(filename.str(), ".json", ResPath)) {
+      llvm::errs() << "Error creating temporary file: " << ErrMsg << "\n";
+      ICNumberOfIterations = 1;
+    }
+    ICResultsFile = ResPath.c_str();
+
+    SmallString<128> ResPath2;
+    filename.str("");
+    filename << "ic-results2-" << CurrentIteration;
+    if (llvm::sys::fs::createTemporaryFile(filename.str(), ".json", ResPath2)) {
+      llvm::errs() << "Error creating temporary file: " << ErrMsg << "\n";
+      ICNumberOfIterations = 1;
+    }
+    ICResultsFile2 = ResPath2.c_str();
+
+    moduleDecisionTrees.getICInputFile() = ICInputFile;
+    moduleDecisionTrees.getICInputFile2() = ICInputFile2;
+    moduleDecisionTrees.getICResultsFile() = ICResultsFile;
+    moduleDecisionTrees.getICResultsFile2() = ICResultsFile2;
+    TheDriver.setModuleDecisionTrees(&moduleDecisionTrees);
+
+    std::map<llvm::FnNameAndPhase, llvm::BitVector> paths;
+    std::map<llvm::FnNameAndPhase, llvm::BitVector> paths1;
+    std::map<llvm::FnNameAndPhase, llvm::BitVector> paths2;
+    moduleDecisionTrees.getPaths(paths);
+    moduleDecisionTrees.startNewIteration();
+    moduleDecisionTrees.splitPaths(paths, paths1, paths2);
+    std::string pathsStr =
+      llvm::ModuleDecisionTrees::generateMdtPathsString(paths1);
+    llvm::DecisionTree::writeToFile(ICInputFile, pathsStr);
+    std::string pathsStr2 =
+      llvm::ModuleDecisionTrees::generateMdtPathsString(paths2);
+    llvm::DecisionTree::writeToFile(ICInputFile2, pathsStr2);
+  }
+
   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
   int Res = 0;
   SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
   if (C.get())
     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
 
+  if (ICNumberOfIterations > 1) {
+    std::string ResultsStrJson = llvm::DecisionTree::readFromFile(ICResultsFile);
+    std::vector<llvm::MdtResults> ResultsJson;
+    std::string ErrorMsg;
+    if (!llvm::ModuleDecisionTrees::parseMdtResults(ResultsJson,
+      ResultsStrJson, ErrorMsg)) {
+      llvm::errs() << "ITERATIVE COMPILATION ERROR:" << ErrorMsg << "\n";
+      return 1;
+    }
+
+    std::string ResultsStr2Json = llvm::DecisionTree::readFromFile(ICResultsFile2);
+    std::vector<llvm::MdtResults> Results2Json;
+    if (!llvm::ModuleDecisionTrees::parseMdtResults(Results2Json,
+      ResultsStr2Json, ErrorMsg)) {
+      llvm::errs() << "ITERATIVE COMPILATION ERROR:" << ErrorMsg << "\n";
+      return 1;
+    }
+
+    llvm::sys::fs::remove(ICInputFile);
+    llvm::sys::fs::remove(ICInputFile2);
+    llvm::sys::fs::remove(ICResultsFile);
+    llvm::sys::fs::remove(ICResultsFile2);
+
+    std::vector<llvm::MdtResults> MergerdResults;
+    llvm::ModuleDecisionTrees::mergeMdtResults(MergerdResults,
+      ResultsJson, Results2Json);
+
+    std::string mergedResultsStr = llvm::ModuleDecisionTrees::generateMdtResultsString(
+                                            MergerdResults);
+
+    // Calculate the new decision three paths.
+    if (CurrICPhase == llvm::FnNameAndPhase::ModulePhase) {
+      int TotalFittness =
+        llvm::ModuleDecisionTrees::calculateTotalFitness(MergerdResults);
+      std::string ModuleNameId = "module-id";
+
+      llvm::MdtResults *ModuleResults = 0;
+      for (unsigned i = 0; i < MergerdResults.size(); i++) {
+        llvm::MdtResults &res = MergerdResults[i];
+        if (res.FunctionNameAndPhase.getName() == ModuleNameId)
+          ModuleResults = &res;
+      }
+
+      llvm::DecisionTree &dt =
+        moduleDecisionTrees.getDecisionTree(
+          llvm::FnNameAndPhase(ModuleNameId,
+                               llvm::FnNameAndPhase::ModulePhase));
+
+      if (ModuleResults)
+        dt.applyResults(*ModuleResults);
+
+      dt.setFunctionFitness(TotalFittness);
+      dt.updateBestFunctionFitness(CurrentIteration);
+
+
+      bool FinalIteration = false;
+      if (CurrentIteration >= ICNumberOfIterations - 2)
+        FinalIteration = true;
+      bool finished = dt.selectPath(FinalIteration);
+      if (finished && CurrentIteration < (ICNumberOfIterations - 2))
+        CurrentIteration = ICNumberOfIterations - 2;
+
+      dt.dumpToJSON(CurrentIteration);
+    }
+  }
+
   // Force a crash to test the diagnostics.
   if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
     Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
@@ -522,7 +681,7 @@
   // If any timers were active but haven't been destroyed yet, print their
   // results now.  This happens in -disable-free mode.
   llvm::TimerGroup::printAll(llvm::errs());
-
+  } // iterative compiler
   llvm::llvm_shutdown();
 
 #ifdef LLVM_ON_WIN32
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -41,6 +41,8 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Analysis/DecisionTree.h"
+#include <sstream>
 
 #ifdef LLVM_ON_UNIX
 #include <unistd.h> // For getuid().
@@ -3996,6 +3998,34 @@
     CmdArgs.push_back(A->getValue());
   else
     CmdArgs.push_back("19");
+  if (Arg *A = Args.getLastArg(options::OPT_fiterative_comp_EQ)) {
+    std::string Val = A->getValue();
+    int IterNo;
+    std::stringstream Convert(Val);
+    Convert >> IterNo;
+    if (IterNo > 1) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-fiterative-comp");
+      llvm::ModuleDecisionTrees *ModDecisionTrees =
+        C.getModuleDecisionTrees();
+      CmdArgs.push_back("-mllvm");
+      std::string &OptIF = ModDecisionTrees->getICInputFileOpt();
+      OptIF = "-fic-input-file=" + ModDecisionTrees->getICInputFile();
+      CmdArgs.push_back(OptIF.c_str());
+      CmdArgs.push_back("-mllvm");
+      std::string &OptIF2 = ModDecisionTrees->getICInputFile2Opt();
+      OptIF2 = "-fic-input2-file=" + ModDecisionTrees->getICInputFile2();
+      CmdArgs.push_back(OptIF2.c_str());
+      CmdArgs.push_back("-mllvm");
+      std::string &OptRF = ModDecisionTrees->getICResultsFileOpt();
+      OptRF = "-fic-results-file=" + ModDecisionTrees->getICResultsFile();
+      CmdArgs.push_back(OptRF.c_str());
+      CmdArgs.push_back("-mllvm");
+      std::string &OptRF2 = ModDecisionTrees->getICResultsFile2Opt();
+      OptRF2 = "-fic-results2-file=" + ModDecisionTrees->getICResultsFile2();
+      CmdArgs.push_back(OptRF2.c_str());
+    }
+  }
 
   if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
     CmdArgs.push_back("-fmacro-backtrace-limit");
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -55,7 +55,8 @@
       CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr),
       CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
       CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
-      CCCUsePCH(true), SuppressMissingInputWarning(false) {
+      CCCUsePCH(true), SuppressMissingInputWarning(false),
+      moduleDecisionTrees(0) {
 
   Name = llvm::sys::path::filename(ClangExecutable);
   Dir = llvm::sys::path::parent_path(ClangExecutable);
@@ -453,6 +454,8 @@
   // The compilation takes ownership of Args.
   Compilation *C = new Compilation(*this, TC, UArgs.release(), TranslatedArgs);
 
+  C->setModuleDecisionTrees(moduleDecisionTrees);
+
   if (!HandleImmediateArgs(*C))
     return C;
 
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -40,6 +40,7 @@
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/SymbolRewriter.h"
+#include "llvm/Analysis/Passes.h"
 #include <memory>
 using namespace clang;
 using namespace llvm;
@@ -224,6 +225,7 @@
   if (Builder.OptLevel > 0) {
     PM.add(createEarlyCSEPass());
     PM.add(createReassociatePass());
+    PM.add(createICSetCurrentFuncPass());
     PM.add(createLICMPass());
     PM.add(createGVNPass());
     PM.add(createInstructionCombiningPass());
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -515,6 +515,8 @@
 def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>;
 def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
 def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
+def fiterative_comp_EQ : Joined<["-"], "fiterative-comp=">, Group<f_Group>,
+  HelpText<"Number of iterations for iterative compilation">;
 def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable support for exception handling">;
 def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">,
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Analysis/DecisionTree.h"
 #include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo
 #include <memory>
                               // lands.
@@ -157,6 +158,9 @@
   /// Whether the driver is generating diagnostics for debugging purposes.
   unsigned CCGenDiagnostics : 1;
 
+  /// Module decision trees for iterative compilation.
+  llvm::ModuleDecisionTrees *moduleDecisionTrees;
+
 private:
   /// Name to use when invoking gcc/g++.
   std::string CCCGenericGCCName;
@@ -209,6 +213,9 @@
   /// @name Accessors
   /// @{
 
+  llvm::ModuleDecisionTrees *getModuleDecisionTrees() const { return moduleDecisionTrees; }
+  void setModuleDecisionTrees(llvm::ModuleDecisionTrees *x) { moduleDecisionTrees = x; }
+
   /// Name to use when invoking gcc/g++.
   const std::string &getCCCGenericGCCName() const { return CCCGenericGCCName; }
 
Index: include/clang/Driver/Compilation.h
===================================================================
--- include/clang/Driver/Compilation.h
+++ include/clang/Driver/Compilation.h
@@ -14,6 +14,7 @@
 #include "clang/Driver/Util.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Analysis/DecisionTree.h"
 
 namespace llvm {
 namespace opt {
@@ -69,6 +70,8 @@
   /// Redirection for stdout, stderr, etc.
   const StringRef **Redirects;
 
+  llvm::ModuleDecisionTrees *moduleDecisionTrees;
+
   /// Whether we're compiling for diagnostic purposes.
   bool ForDiagnostics;
 
@@ -107,6 +110,10 @@
   /// Returns the sysroot path.
   StringRef getSysRoot() const;
 
+  llvm::ModuleDecisionTrees *getModuleDecisionTrees() const { return moduleDecisionTrees; }
+
+  void setModuleDecisionTrees(llvm::ModuleDecisionTrees *x) { moduleDecisionTrees = x; }
+
   /// getArgsForToolChain - Return the derived argument list for the
   /// tool chain \p TC (or the default tool chain, if TC is not specified).
   ///
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to