GraphWriter.cpp revision 2ebb97792dceb9729df690ec53cea1a592edfe52
19d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//===-- GraphWriter.cpp - Implements GraphWriter support routines ---------===//
29d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//
39d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//                     The LLVM Compiler Infrastructure
49d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
79d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//
89d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//===----------------------------------------------------------------------===//
99d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//
109d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer// This file implements misc. GraphWriter support routines.
119d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//
129d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer//===----------------------------------------------------------------------===//
139d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1465a392ebeae214ccb25f4d5ec856688e4e690e0dChris Lattner#include "llvm/Support/GraphWriter.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Config/config.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/CommandLine.h"
174d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola#include "llvm/Support/FileSystem.h"
181f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h"
191f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Program.h"
209d5b532de9bdca37810a59a93a69128441b02c55Reid Spencerusing namespace llvm;
219d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
22255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trickstatic cl::opt<bool> ViewBackground("view-background", cl::Hidden,
23255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  cl::desc("Execute graph viewer in the background. Creates tmp file litter."));
24255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
25103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattnerstd::string llvm::DOT::EscapeString(const std::string &Label) {
26103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  std::string Str(Label);
27103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  for (unsigned i = 0; i != Str.length(); ++i)
28103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  switch (Str[i]) {
29103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '\n':
30103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      Str.insert(Str.begin()+i, '\\');  // Escape character...
31103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      ++i;
32103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      Str[i] = 'n';
33103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      break;
34103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '\t':
35103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      Str.insert(Str.begin()+i, ' ');  // Convert to two spaces
36103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      ++i;
37103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      Str[i] = ' ';
38103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      break;
39103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '\\':
40103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      if (i+1 != Str.length())
41103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner        switch (Str[i+1]) {
42103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner          case 'l': continue; // don't disturb \l
43103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner          case '|': case '{': case '}':
44103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner            Str.erase(Str.begin()+i); continue;
45103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner          default: break;
46103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner        }
47103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '{': case '}':
48103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '<': case '>':
49103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner    case '|': case '"':
50103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      Str.insert(Str.begin()+i, '\\');  // Escape character...
51103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      ++i;  // don't infinite loop
52103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner      break;
53103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  }
54103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  return Str;
55103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner}
56103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner
57c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick/// \brief Get a color string for this node number. Simply round-robin selects
58c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick/// from a reasonable number of colors.
59c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew TrickStringRef llvm::DOT::getColorString(unsigned ColorNumber) {
60c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick  static const int NumColors = 20;
61c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick  static const char* Colors[NumColors] = {
62c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick    "aaaaaa", "aa0000", "00aa00", "aa5500", "0055ff", "aa00aa", "00aaaa",
63c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick    "555555", "ff5555", "55ff55", "ffff55", "5555ff", "ff55ff", "55ffff",
64c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick    "ffaaaa", "aaffaa", "ffffaa", "aaaaff", "ffaaff", "aaffff"};
65c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick  return Colors[ColorNumber % NumColors];
66c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick}
67c6ada8e5f38168f13830e448f2b9e2d8e3eac72bAndrew Trick
68a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindolastd::string llvm::createGraphFilename(const Twine &Name, int &FD) {
69a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola  FD = -1;
70a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola  SmallString<128> Filename;
71a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola  error_code EC = sys::fs::unique_file(Twine(Name) + "-%%%%%%%.dot",
72a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola                                       FD, Filename);
73a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola  if (EC) {
74a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola    errs() << "Error: " << EC.message() << "\n";
754d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    return "";
764d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  }
77a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola
78a54ba12ae7a8cf826b65d2e4a882258e952c35b1Rafael Espindola  errs() << "Writing '" << Filename << "'... ";
794d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  return Filename.str();
804d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola}
814d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola
82255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick// Execute the graph viewer. Return true if successful.
83cdaedf9f4acc60f8a7a1042af4be04291465e213Benjamin Kramerstatic bool LLVM_ATTRIBUTE_UNUSED
844d39727eaee3e7cb5c72dba469855cb538110782Rafael EspindolaExecGraphViewer(StringRef ExecPath, std::vector<const char*> &args,
854d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola                StringRef Filename, bool wait, std::string &ErrMsg) {
86255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (wait) {
87675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola    if (sys::ExecuteAndWait(ExecPath, &args[0],0,0,0,0,&ErrMsg)) {
88255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick      errs() << "Error: " << ErrMsg << "\n";
89255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick      return false;
90255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    }
914d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    bool Existed;
924d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    sys::fs::remove(Filename, Existed);
93255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    errs() << " done. \n";
94255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  }
95255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  else {
96675e0ac0bfd6fb78423d9fbee9f50c1dec62c111Rafael Espindola    sys::ExecuteNoWait(ExecPath, &args[0],0,0,0,&ErrMsg);
97255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    errs() << "Remember to erase graph file: " << Filename.str() << "\n";
98255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  }
99255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  return true;
100255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick}
101103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner
102aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindolavoid llvm::DisplayGraph(StringRef FilenameRef, bool wait,
10300ad26ff5760ff2d1b24acb18718e63541088923David Greene                        GraphProgram::Name program) {
104aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindola  std::string Filename = FilenameRef;
105255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  wait &= !ViewBackground;
1068ea5ecb0564b8822c70ad84202471f03e2690da7Reid Spencer  std::string ErrMsg;
1079d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#if HAVE_GRAPHVIZ
108a65ee83ea96f367eff8d00b86c44b38d04819d1aRafael Espindola  std::string Graphviz(LLVM_PATH_GRAPHVIZ);
1099d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1109d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
1119d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Graphviz.c_str());
1129d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Filename.c_str());
1139d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
114255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
115103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  errs() << "Running 'Graphviz' program... ";
116255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(Graphviz, args, Filename, wait, ErrMsg))
117644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman    return;
11800ad26ff5760ff2d1b24acb18718e63541088923David Greene
11948fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman#elif HAVE_XDOT_PY
12048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  std::vector<const char*> args;
12148fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(LLVM_PATH_XDOT_PY);
12248fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(Filename.c_str());
12348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
12448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  switch (program) {
12548fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::DOT:   args.push_back("-f"); args.push_back("dot"); break;
12648fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::FDP:   args.push_back("-f"); args.push_back("fdp"); break;
12748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::NEATO: args.push_back("-f"); args.push_back("neato");break;
12848fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::TWOPI: args.push_back("-f"); args.push_back("twopi");break;
12948fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::CIRCO: args.push_back("-f"); args.push_back("circo");break;
13048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  }
131255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
13248fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(0);
13348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
13448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  errs() << "Running 'xdot.py' program... ";
135a65ee83ea96f367eff8d00b86c44b38d04819d1aRafael Espindola  if (!ExecGraphViewer(LLVM_PATH_XDOT_PY, args, Filename, wait, ErrMsg))
136644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman    return;
13748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
13800ad26ff5760ff2d1b24acb18718e63541088923David Greene#elif (HAVE_GV && (HAVE_DOT || HAVE_FDP || HAVE_NEATO || \
13900ad26ff5760ff2d1b24acb18718e63541088923David Greene                   HAVE_TWOPI || HAVE_CIRCO))
1402ebb97792dceb9729df690ec53cea1a592edfe52Rafael Espindola  std::string PSFilename = Filename + ".ps";
1414d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  std::string prog;
14200ad26ff5760ff2d1b24acb18718e63541088923David Greene
14300ad26ff5760ff2d1b24acb18718e63541088923David Greene  // Set default grapher
14400ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_CIRCO
1454d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_CIRCO;
14600ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
14700ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_TWOPI
1484d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_TWOPI;
14900ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15000ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_NEATO
1514d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_NEATO;
15200ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
153229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#if HAVE_FDP
1544d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_FDP;
15500ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15600ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT
1574d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_DOT;
15800ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15900ad26ff5760ff2d1b24acb18718e63541088923David Greene
16000ad26ff5760ff2d1b24acb18718e63541088923David Greene  // Find which program the user wants
16100ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT
16240ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::DOT)
1634d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_DOT;
16400ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
16500ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_FDP)
16640ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::FDP)
1674d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_FDP;
16800ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
16900ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_NEATO)
17040ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::NEATO)
1714d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_NEATO;
17200ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
17300ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_TWOPI)
17440ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::TWOPI)
1754d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_TWOPI;
17600ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
17700ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_CIRCO)
17840ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::CIRCO)
1794d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_CIRCO;
180229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#endif
1819d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1829d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
183229509a8bc2390c4c9c1bd20f777acf29911d452David Greene  args.push_back(prog.c_str());
1849d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Tps");
1859d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Nfontname=Courier");
1869d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Gsize=7.5,10");
187aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindola  args.push_back(Filename.c_str());
1889d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-o");
1899d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(PSFilename.c_str());
1909d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
191255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
1924d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  errs() << "Running '" << prog << "' program... ";
193229509a8bc2390c4c9c1bd20f777acf29911d452David Greene
194255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(prog, args, Filename, wait, ErrMsg))
195459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner    return;
1969d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1974d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  std::string gv(LLVM_PATH_GV);
198459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.clear();
199459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(gv.c_str());
200459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(PSFilename.c_str());
201459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back("--spartan");
202459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(0);
203255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
204459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  ErrMsg.clear();
2052ebb97792dceb9729df690ec53cea1a592edfe52Rafael Espindola  if (!ExecGraphViewer(gv, args, PSFilename, wait, ErrMsg))
206255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    return;
207255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
2089d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#elif HAVE_DOTTY
209a65ee83ea96f367eff8d00b86c44b38d04819d1aRafael Espindola  std::string dotty(LLVM_PATH_DOTTY);
2109d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
2119d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
21282493289e0234e0172313e845fb87306cf3687acChris Lattner  args.push_back(dotty.c_str());
2139d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Filename.c_str());
2149d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
215255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
2167c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner// Dotty spawns another app and doesn't wait until it returns
2177c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner#if defined (__MINGW32__) || defined (_WINDOWS)
218255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  wait = false;
2199d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif
220255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  errs() << "Running 'dotty' program... ";
221255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(dotty, args, Filename, wait, ErrMsg))
222255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    return;
2239d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif
2249d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer}
225