Go to the documentation of this file.
20 #include "llvm/Config/config.h"
34 #include <system_error>
41 struct CreateViewBackground {
44 cl::desc(
"Execute graph viewer in the background. "
45 "Creates tmp file litter."));
56 std::string Str(Label);
57 for (
unsigned i = 0;
i != Str.length(); ++
i)
60 Str.insert(Str.begin()+
i,
'\\');
65 Str.insert(Str.begin()+
i,
' ');
70 if (
i+1 != Str.length())
73 case '|':
case '{':
case '}':
74 Str.erase(Str.begin()+
i);
continue;
81 Str.insert(Str.begin()+
i,
'\\');
91 static const int NumColors = 20;
92 static const char* Colors[NumColors] = {
93 "aaaaaa",
"aa0000",
"00aa00",
"aa5500",
"0055ff",
"aa00aa",
"00aaaa",
94 "555555",
"ff5555",
"55ff55",
"ffff55",
"5555ff",
"ff55ff",
"55ffff",
95 "ffaaaa",
"aaffaa",
"ffffaa",
"aaaaff",
"ffaaff",
"aaffff"};
96 return Colors[ColorNumber % NumColors];
100 const char ReplacementChar) {
101 std::string IllegalChars =
104 for (
char IllegalChar : IllegalChars) {
105 std::replace(Filename.begin(), Filename.end(), IllegalChar,
117 std::string
N =
Name.str();
118 N =
N.substr(0, std::min<std::size_t>(
N.size(), 140));
126 errs() <<
"Error: " << EC.message() <<
"\n";
130 errs() <<
"Writing '" << Filename <<
"'... ";
131 return std::string(Filename.
str());
137 std::string &ErrMsg) {
140 errs() <<
"Error: " << ErrMsg <<
"\n";
144 errs() <<
" done. \n";
147 errs() <<
"Remember to erase graph file: " << Filename <<
"\n";
154 struct GraphSession {
155 std::string LogBuffer;
157 bool TryFindProgram(
StringRef Names, std::string &ProgramPath) {
160 Names.
split(parts,
'|');
161 for (
auto Name : parts) {
166 Log <<
" Tried '" <<
Name <<
"'\n";
192 std::string Filename = std::string(FilenameRef);
194 std::string ViewerPath;
198 wait &= !*ViewBackground;
199 if (
S.TryFindProgram(
"open", ViewerPath)) {
200 std::vector<StringRef> args;
201 args.push_back(ViewerPath);
203 args.push_back(
"-W");
204 args.push_back(Filename);
205 errs() <<
"Trying 'open' program... ";
210 if (
S.TryFindProgram(
"xdg-open", ViewerPath)) {
211 std::vector<StringRef> args;
212 args.push_back(ViewerPath);
213 args.push_back(Filename);
214 errs() <<
"Trying 'xdg-open' program... ";
220 if (
S.TryFindProgram(
"Graphviz", ViewerPath)) {
221 std::vector<StringRef> args;
222 args.push_back(ViewerPath);
223 args.push_back(Filename);
225 errs() <<
"Running 'Graphviz' program... ";
230 if (
S.TryFindProgram(
"xdot|xdot.py", ViewerPath)) {
231 std::vector<StringRef> args;
232 args.push_back(ViewerPath);
233 args.push_back(Filename);
235 args.push_back(
"-f");
238 errs() <<
"Running 'xdot.py' program... ";
249 ViewerKind Viewer = VK_None;
251 if (!Viewer &&
S.TryFindProgram(
"open", ViewerPath))
254 if (!Viewer &&
S.TryFindProgram(
"gv", ViewerPath))
255 Viewer = VK_Ghostview;
256 if (!Viewer &&
S.TryFindProgram(
"xdg-open", ViewerPath))
259 if (!Viewer &&
S.TryFindProgram(
"cmd", ViewerPath)) {
260 Viewer = VK_CmdStart;
265 std::string GeneratorPath;
268 S.TryFindProgram(
"dot|fdp|neato|twopi|circo", GeneratorPath))) {
270 Filename + (Viewer == VK_CmdStart ?
".pdf" :
".ps");
272 std::vector<StringRef> args;
273 args.push_back(GeneratorPath);
274 if (Viewer == VK_CmdStart)
275 args.push_back(
"-Tpdf");
277 args.push_back(
"-Tps");
278 args.push_back(
"-Nfontname=Courier");
279 args.push_back(
"-Gsize=7.5,10");
280 args.push_back(Filename);
281 args.push_back(
"-o");
284 errs() <<
"Running '" << GeneratorPath <<
"' program... ";
291 std::string StartArg;
294 args.push_back(ViewerPath);
297 args.push_back(
"-W");
305 args.push_back(
"--spartan");
309 args.push_back(
"/S");
310 args.push_back(
"/C");
313 args.push_back(StartArg);
324 if (
S.TryFindProgram(
"dotty", ViewerPath)) {
325 std::vector<StringRef> args;
326 args.push_back(ViewerPath);
327 args.push_back(Filename);
333 errs() <<
"Running 'dotty' program... ";
337 errs() <<
"Error: Couldn't find a usable graph viewer program:\n";
338 errs() <<
S.LogBuffer <<
"\n";
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
static bool ExecGraphViewer(StringRef ExecPath, std::vector< StringRef > &args, StringRef Filename, bool wait, std::string &ErrMsg)
This is an optimization pass for GlobalISel generic memory operations.
ProcessInfo ExecuteNoWait(StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env, ArrayRef< Optional< StringRef >> Redirects={}, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, BitVector *AffinityMask=nullptr)
Similar to ExecuteAndWait, but returns immediately.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
std::string createGraphFilename(const Twine &Name, int &FD)
static const char * getProgramName(GraphProgram::Name program)
A raw_ostream that writes to an std::string.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::string EscapeString(const std::string &Label)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void initGraphWriterOptions()
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
ManagedStatic - This transparently changes the behavior of global statics to be lazily constructed on...
bool DisplayGraph(StringRef Filename, bool wait=true, GraphProgram::Name program=GraphProgram::DOT)
S is passed via registers r2 But gcc stores them to the and then reload them to and r3 before issuing the call(r0 contains the address of the format string)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
static std::string replaceIllegalFilenameChars(std::string Filename, const char ReplacementChar)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef str() const
Explicit conversion to StringRef.
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
constexpr bool is_style_windows(Style S)
Check if S uses Windows path rules.
int ExecuteAndWait(StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env=None, ArrayRef< Optional< StringRef >> Redirects={}, unsigned SecondsToWait=0, unsigned MemoryLimit=0, std::string *ErrMsg=nullptr, bool *ExecutionFailed=nullptr, Optional< ProcessStatistics > *ProcStat=nullptr, BitVector *AffinityMask=nullptr)
This function executes the program using the arguments provided.
Represents either an error or a value T.