GraphWriter.cpp revision 1f6efa3996dd1929fbc129203ce5009b620e6969
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" 151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h" 161f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Program.h" 179d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#include "llvm/Config/config.h" 189d5b532de9bdca37810a59a93a69128441b02c55Reid Spencerusing namespace llvm; 199d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 20103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattnerstd::string llvm::DOT::EscapeString(const std::string &Label) { 21103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner std::string Str(Label); 22103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner for (unsigned i = 0; i != Str.length(); ++i) 23103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner switch (Str[i]) { 24103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '\n': 25103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str.insert(Str.begin()+i, '\\'); // Escape character... 26103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner ++i; 27103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str[i] = 'n'; 28103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner break; 29103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '\t': 30103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str.insert(Str.begin()+i, ' '); // Convert to two spaces 31103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner ++i; 32103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str[i] = ' '; 33103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner break; 34103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '\\': 35103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner if (i+1 != Str.length()) 36103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner switch (Str[i+1]) { 37103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case 'l': continue; // don't disturb \l 38103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '|': case '{': case '}': 39103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str.erase(Str.begin()+i); continue; 40103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner default: break; 41103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner } 42103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '{': case '}': 43103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '<': case '>': 44103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner case '|': case '"': 45103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner Str.insert(Str.begin()+i, '\\'); // Escape character... 46103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner ++i; // don't infinite loop 47103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner break; 48103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner } 49103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner return Str; 50103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner} 51103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner 52103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner 53103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner 5400ad26ff5760ff2d1b24acb18718e63541088923David Greenevoid llvm::DisplayGraph(const sys::Path &Filename, bool wait, 5500ad26ff5760ff2d1b24acb18718e63541088923David Greene GraphProgram::Name program) { 568ea5ecb0564b8822c70ad84202471f03e2690da7Reid Spencer std::string ErrMsg; 579d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#if HAVE_GRAPHVIZ 589d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer sys::Path Graphviz(LLVM_PATH_GRAPHVIZ); 599d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 609d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer std::vector<const char*> args; 619d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(Graphviz.c_str()); 629d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(Filename.c_str()); 639d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(0); 649d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 65103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner errs() << "Running 'Graphviz' program... "; 66644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman if (sys::Program::ExecuteAndWait(Graphviz, &args[0],0,0,0,0,&ErrMsg)) { 67c4633160465325ec001fe9beb97aac0a5e2a43f6Dan Gohman errs() << "Error: " << ErrMsg << "\n"; 68644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman return; 69644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman } 70644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman Filename.eraseFromDisk(); 71644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman errs() << " done. \n"; 7200ad26ff5760ff2d1b24acb18718e63541088923David Greene 7348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman#elif HAVE_XDOT_PY 7448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman std::vector<const char*> args; 7548fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman args.push_back(LLVM_PATH_XDOT_PY); 7648fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman args.push_back(Filename.c_str()); 7748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman 7848fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman switch (program) { 7948fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman case GraphProgram::DOT: args.push_back("-f"); args.push_back("dot"); break; 8048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman case GraphProgram::FDP: args.push_back("-f"); args.push_back("fdp"); break; 8148fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman case GraphProgram::NEATO: args.push_back("-f"); args.push_back("neato");break; 8248fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman case GraphProgram::TWOPI: args.push_back("-f"); args.push_back("twopi");break; 8348fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman case GraphProgram::CIRCO: args.push_back("-f"); args.push_back("circo");break; 8448fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman default: errs() << "Unknown graph layout name; using default.\n"; 8548fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman } 8648fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman 8748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman args.push_back(0); 8848fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman 8948fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman errs() << "Running 'xdot.py' program... "; 9048fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman if (sys::Program::ExecuteAndWait(sys::Path(LLVM_PATH_XDOT_PY), 91644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman &args[0],0,0,0,0,&ErrMsg)) { 92c4633160465325ec001fe9beb97aac0a5e2a43f6Dan Gohman errs() << "Error: " << ErrMsg << "\n"; 93644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman return; 94644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman } 95644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman Filename.eraseFromDisk(); 96644801a199794a74bdc4655f6af5bc05f8153dc8Dan Gohman errs() << " done. \n"; 9748fd5a79e023bf6a647dfabb2bbb4c2f98617b81Dan Gohman 9800ad26ff5760ff2d1b24acb18718e63541088923David Greene#elif (HAVE_GV && (HAVE_DOT || HAVE_FDP || HAVE_NEATO || \ 9900ad26ff5760ff2d1b24acb18718e63541088923David Greene HAVE_TWOPI || HAVE_CIRCO)) 1009d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer sys::Path PSFilename = Filename; 1019d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer PSFilename.appendSuffix("ps"); 102229509a8bc2390c4c9c1bd20f777acf29911d452David Greene 10300ad26ff5760ff2d1b24acb18718e63541088923David Greene sys::Path prog; 10400ad26ff5760ff2d1b24acb18718e63541088923David Greene 10500ad26ff5760ff2d1b24acb18718e63541088923David Greene // Set default grapher 10600ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_CIRCO 10700ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_CIRCO); 10800ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 10900ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_TWOPI 11000ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_TWOPI); 11100ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 11200ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_NEATO 11300ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_NEATO); 11400ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 115229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#if HAVE_FDP 11600ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_FDP); 11700ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 11800ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT 11900ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_DOT); 12000ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 12100ad26ff5760ff2d1b24acb18718e63541088923David Greene 12200ad26ff5760ff2d1b24acb18718e63541088923David Greene // Find which program the user wants 12300ad26ff5760ff2d1b24acb18718e63541088923David Greene#if HAVE_DOT 12440ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (program == GraphProgram::DOT) 12500ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_DOT); 12600ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 12700ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_FDP) 12840ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (program == GraphProgram::FDP) 12900ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_FDP); 13000ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 13100ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_NEATO) 13240ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (program == GraphProgram::NEATO) 13300ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_NEATO); 13400ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 13500ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_TWOPI) 13640ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (program == GraphProgram::TWOPI) 13700ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_TWOPI); 13800ad26ff5760ff2d1b24acb18718e63541088923David Greene#endif 13900ad26ff5760ff2d1b24acb18718e63541088923David Greene#if (HAVE_CIRCO) 14040ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (program == GraphProgram::CIRCO) 14100ad26ff5760ff2d1b24acb18718e63541088923David Greene prog = sys::Path(LLVM_PATH_CIRCO); 142229509a8bc2390c4c9c1bd20f777acf29911d452David Greene#endif 1439d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 1449d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer std::vector<const char*> args; 145229509a8bc2390c4c9c1bd20f777acf29911d452David Greene args.push_back(prog.c_str()); 1469d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back("-Tps"); 1479d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back("-Nfontname=Courier"); 1489d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back("-Gsize=7.5,10"); 1499d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(Filename.c_str()); 1509d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back("-o"); 1519d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(PSFilename.c_str()); 1529d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(0); 1539d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 1542d5e3acd2a69070c4e3550e014a54626e18bf12cDan Gohman errs() << "Running '" << prog.str() << "' program... "; 155229509a8bc2390c4c9c1bd20f777acf29911d452David Greene 15640ef79d5e24d0a66345b4c9a1b97952478850d42Chris Lattner if (sys::Program::ExecuteAndWait(prog, &args[0], 0, 0, 0, 0, &ErrMsg)) { 157c4633160465325ec001fe9beb97aac0a5e2a43f6Dan Gohman errs() << "Error: " << ErrMsg << "\n"; 158459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner return; 159459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner } 160459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner errs() << " done. \n"; 1619d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 162459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner sys::Path gv(LLVM_PATH_GV); 163459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner args.clear(); 164459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner args.push_back(gv.c_str()); 165459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner args.push_back(PSFilename.c_str()); 166459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner args.push_back("--spartan"); 167459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner args.push_back(0); 168459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner 169459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner ErrMsg.clear(); 170459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner if (wait) { 171459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner if (sys::Program::ExecuteAndWait(gv, &args[0],0,0,0,0,&ErrMsg)) 172c4633160465325ec001fe9beb97aac0a5e2a43f6Dan Gohman errs() << "Error: " << ErrMsg << "\n"; 173459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner Filename.eraseFromDisk(); 174459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner PSFilename.eraseFromDisk(); 175459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner } 176459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner else { 177459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner sys::Program::ExecuteNoWait(gv, &args[0],0,0,0,&ErrMsg); 178459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner errs() << "Remember to erase graph files: " << Filename.str() << " " 179459e13a9cef943c582f55d26ce03a0dc7409edffChris Lattner << PSFilename.str() << "\n"; 1809d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer } 1819d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#elif HAVE_DOTTY 1829d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer sys::Path dotty(LLVM_PATH_DOTTY); 1839d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 1849d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer std::vector<const char*> args; 18582493289e0234e0172313e845fb87306cf3687acChris Lattner args.push_back(dotty.c_str()); 1869d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(Filename.c_str()); 1879d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer args.push_back(0); 1889d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer 189103289e9383ad1eb66caf28c9b166aebce963a35Chris Lattner errs() << "Running 'dotty' program... "; 1909ba8a76f8baaa1092d60ccfbc04e7efdc207c98fAnton Korobeynikov if (sys::Program::ExecuteAndWait(dotty, &args[0],0,0,0,0,&ErrMsg)) { 191c4633160465325ec001fe9beb97aac0a5e2a43f6Dan Gohman errs() << "Error: " << ErrMsg << "\n"; 1929d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer } else { 1937c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner// Dotty spawns another app and doesn't wait until it returns 1947c57b7b80838eb48db03f4cfc7839864822c0112Chris Lattner#if defined (__MINGW32__) || defined (_WINDOWS) 1959d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer return; 1969d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif 197229509a8bc2390c4c9c1bd20f777acf29911d452David Greene Filename.eraseFromDisk(); 1989d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer } 1999d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer#endif 2009d5b532de9bdca37810a59a93a69128441b02c55Reid Spencer} 201