GraphWriter.cpp revision aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91
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
684d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindolastd::string llvm::createGraphFilename(const Twine &Name) {
694d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  std::string ErrMsg;
704d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
714d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  if (Filename.isEmpty()) {
724d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    errs() << "Error: " << ErrMsg << "\n";
734d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    return "";
744d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  }
754d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  Filename.appendComponent((Name + ".dot").str());
764d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  if (Filename.makeUnique(true,&ErrMsg)) {
774d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    errs() << "Error: " << ErrMsg << "\n";
784d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    return "";
794d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  }
804d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  return Filename.str();
814d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola}
824d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola
83255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick// Execute the graph viewer. Return true if successful.
84cdaedf9f4acc60f8a7a1042af4be04291465e213Benjamin Kramerstatic bool LLVM_ATTRIBUTE_UNUSED
854d39727eaee3e7cb5c72dba469855cb538110782Rafael EspindolaExecGraphViewer(StringRef ExecPath, std::vector<const char*> &args,
864d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola                StringRef Filename, bool wait, std::string &ErrMsg) {
87255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (wait) {
884d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    if (sys::ExecuteAndWait(sys::Path(ExecPath), &args[0],0,0,0,0,&ErrMsg)) {
89255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick      errs() << "Error: " << ErrMsg << "\n";
90255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick      return false;
91255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    }
924d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    bool Existed;
934d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    sys::fs::remove(Filename, Existed);
94255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    errs() << " done. \n";
95255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  }
96255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  else {
974d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    sys::ExecuteNoWait(sys::Path(ExecPath), &args[0],0,0,0,&ErrMsg);
98255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    errs() << "Remember to erase graph file: " << Filename.str() << "\n";
99255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  }
100255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  return true;
101255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick}
102103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner
103aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindolavoid llvm::DisplayGraph(StringRef FilenameRef, bool wait,
10400ad26ff5760ff2d1b24acb18718e63541088923David Greene                        GraphProgram::Name program) {
105aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindola  std::string Filename = FilenameRef;
106255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  wait &= !ViewBackground;
1078ea5ecb0564b8822c70ad84202471f03e2690da7Reid Spencer  std::string ErrMsg;
1089d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#if HAVE_GRAPHVIZ
1099d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  sys::Path Graphviz(LLVM_PATH_GRAPHVIZ);
1109d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1119d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
1129d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Graphviz.c_str());
1139d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Filename.c_str());
1149d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
115255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
116103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner  errs() << "Running 'Graphviz' program... ";
117255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(Graphviz, args, Filename, wait, ErrMsg))
118644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman    return;
11900ad26ff5760ff2d1b24acb18718e63541088923David Greene
12048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman#elif HAVE_XDOT_PY
12148fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  std::vector<const char*> args;
12248fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(LLVM_PATH_XDOT_PY);
12348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(Filename.c_str());
12448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
12548fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  switch (program) {
12648fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::DOT:   args.push_back("-f"); args.push_back("dot"); break;
12748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::FDP:   args.push_back("-f"); args.push_back("fdp"); break;
12848fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::NEATO: args.push_back("-f"); args.push_back("neato");break;
12948fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::TWOPI: args.push_back("-f"); args.push_back("twopi");break;
13048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  case GraphProgram::CIRCO: args.push_back("-f"); args.push_back("circo");break;
13148fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  }
132255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
13348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  args.push_back(0);
13448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
13548fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman  errs() << "Running 'xdot.py' program... ";
136255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(sys::Path(LLVM_PATH_XDOT_PY), args, Filename, wait, ErrMsg))
137644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman    return;
13848fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman
13900ad26ff5760ff2d1b24acb18718e63541088923David Greene#elif (HAVE_GV && (HAVE_DOT || HAVE_FDP || HAVE_NEATO || \
14000ad26ff5760ff2d1b24acb18718e63541088923David Greene                   HAVE_TWOPI || HAVE_CIRCO))
1414d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  sys::Path PSFilename = sys::Path(Filename);
1429d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  PSFilename.appendSuffix("ps");
143229509a8bc2390c4c9c1bd20f777acf29911d452David Greene
1444d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  std::string prog;
14500ad26ff5760ff2d1b24acb18718e63541088923David Greene
14600ad26ff5760ff2d1b24acb18718e63541088923David Greene  // Set default grapher
14700ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_CIRCO
1484d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_CIRCO;
14900ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15000ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_TWOPI
1514d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_TWOPI;
15200ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15300ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_NEATO
1544d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_NEATO;
15500ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
156229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#if HAVE_FDP
1574d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_FDP;
15800ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
15900ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT
1604d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  prog = LLVM_PATH_DOT;
16100ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
16200ad26ff5760ff2d1b24acb18718e63541088923David Greene
16300ad26ff5760ff2d1b24acb18718e63541088923David Greene  // Find which program the user wants
16400ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT
16540ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::DOT)
1664d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_DOT;
16700ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
16800ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_FDP)
16940ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::FDP)
1704d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_FDP;
17100ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
17200ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_NEATO)
17340ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::NEATO)
1744d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_NEATO;
17500ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
17600ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_TWOPI)
17740ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::TWOPI)
1784d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_TWOPI;
17900ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif
18000ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_CIRCO)
18140ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner  if (program == GraphProgram::CIRCO)
1824d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola    prog = LLVM_PATH_CIRCO;
183229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#endif
1849d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
1859d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
186229509a8bc2390c4c9c1bd20f777acf29911d452David Greene  args.push_back(prog.c_str());
1879d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Tps");
1889d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Nfontname=Courier");
1899d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-Gsize=7.5,10");
190aaf4c1e2ee0887e5e8cb9768186ff5e72e8a3e91Rafael Espindola  args.push_back(Filename.c_str());
1919d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back("-o");
1929d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(PSFilename.c_str());
1939d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
194255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
1954d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  errs() << "Running '" << prog << "' program... ";
196229509a8bc2390c4c9c1bd20f777acf29911d452David Greene
197255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(prog, args, Filename, wait, ErrMsg))
198459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner    return;
1999d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
2004d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  std::string gv(LLVM_PATH_GV);
201459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.clear();
202459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(gv.c_str());
203459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(PSFilename.c_str());
204459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back("--spartan");
205459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  args.push_back(0);
206255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
207459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner  ErrMsg.clear();
2084d39727eaee3e7cb5c72dba469855cb538110782Rafael Espindola  if (!ExecGraphViewer(gv, args, PSFilename.str(), wait, ErrMsg))
209255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    return;
210255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
2119d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#elif HAVE_DOTTY
2129d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  sys::Path dotty(LLVM_PATH_DOTTY);
2139d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer
2149d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  std::vector<const char*> args;
21582493289e0234e0172313e845fb87306cf3687acChris Lattner  args.push_back(dotty.c_str());
2169d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(Filename.c_str());
2179d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer  args.push_back(0);
218255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick
2197c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner// Dotty spawns another app and doesn't wait until it returns
2207c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner#if defined (__MINGW32__) || defined (_WINDOWS)
221255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  wait = false;
2229d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif
223255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  errs() << "Running 'dotty' program... ";
224255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick  if (!ExecGraphViewer(dotty, args, Filename, wait, ErrMsg))
225255cd51fbd771c0131a74eaf4385f1ea703a3c68Andrew Trick    return;
2269d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif
2279d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer}
228