Newer
Older
//===-- llvm/CodeGen/RenderMachineFunction.cpp - MF->HTML -----s-----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "rendermf"
#include "RenderMachineFunction.h"
#include "VirtRegMap.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <sstream>
using namespace llvm;
char RenderMachineFunction::ID = 0;
INITIALIZE_PASS(RenderMachineFunction, "rendermf",
"Render machine functions (and related info) to HTML pages",
false, false);
static cl::opt<std::string>
outputFileSuffix("rmf-file-suffix",
cl::desc("Appended to function name to get output file name "
"(default: \".html\")"),
cl::init(".html"), cl::Hidden);
static cl::opt<std::string>
machineFuncsToRender("rmf-funcs",
cl::desc("Coma seperated list of functions to render"
", or \"*\"."),
cl::init(""), cl::Hidden);
static cl::opt<std::string>
pressureClasses("rmf-classes",
cl::desc("Register classes to render pressure for."),
cl::init(""), cl::Hidden);
static cl::opt<std::string>
showIntervals("rmf-intervals",
cl::desc("Live intervals to show alongside code."),
cl::init(""), cl::Hidden);
static cl::opt<bool>
filterEmpty("rmf-filter-empty-intervals",
cl::desc("Don't display empty intervals."),
cl::init(true), cl::Hidden);
static cl::opt<bool>
showEmptyIndexes("rmf-empty-indexes",
cl::desc("Render indexes not associated with instructions or "
"MBB starts."),
cl::init(false), cl::Hidden);
static cl::opt<bool>
useFancyVerticals("rmf-fancy-verts",
cl::desc("Use SVG for vertical text."),
cl::init(true), cl::Hidden);
Lang Hames
committed
static cl::opt<bool>
prettyHTML("rmf-pretty-html",
cl::desc("Pretty print HTML. For debugging the renderer only.."),
cl::init(false), cl::Hidden);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
namespace llvm {
bool MFRenderingOptions::renderingOptionsProcessed;
std::set<std::string> MFRenderingOptions::mfNamesToRender;
bool MFRenderingOptions::renderAllMFs = false;
std::set<std::string> MFRenderingOptions::classNamesToRender;
bool MFRenderingOptions::renderAllClasses = false;
std::set<std::pair<unsigned, unsigned> >
MFRenderingOptions::intervalNumsToRender;
unsigned MFRenderingOptions::intervalTypesToRender = ExplicitOnly;
template <typename OutputItr>
void MFRenderingOptions::splitComaSeperatedList(const std::string &s,
OutputItr outItr) {
std::string::const_iterator curPos = s.begin();
std::string::const_iterator nextComa = std::find(curPos, s.end(), ',');
while (nextComa != s.end()) {
std::string elem;
std::copy(curPos, nextComa, std::back_inserter(elem));
*outItr = elem;
++outItr;
curPos = llvm::next(nextComa);
nextComa = std::find(curPos, s.end(), ',');
}
if (curPos != s.end()) {
std::string elem;
std::copy(curPos, s.end(), std::back_inserter(elem));
*outItr = elem;
++outItr;
}
}
void MFRenderingOptions::processOptions() {
if (!renderingOptionsProcessed) {
processFuncNames();
processRegClassNames();
processIntervalNumbers();
renderingOptionsProcessed = true;
}
}
void MFRenderingOptions::processFuncNames() {
if (machineFuncsToRender == "*") {
renderAllMFs = true;
} else {
splitComaSeperatedList(machineFuncsToRender,
std::inserter(mfNamesToRender,
mfNamesToRender.begin()));
}
}
void MFRenderingOptions::processRegClassNames() {
if (pressureClasses == "*") {
renderAllClasses = true;
} else {
splitComaSeperatedList(pressureClasses,
std::inserter(classNamesToRender,
classNamesToRender.begin()));
}
}
void MFRenderingOptions::processIntervalNumbers() {
std::set<std::string> intervalRanges;
splitComaSeperatedList(showIntervals,
std::inserter(intervalRanges,
intervalRanges.begin()));
std::for_each(intervalRanges.begin(), intervalRanges.end(),
processIntervalRange);
}
void MFRenderingOptions::processIntervalRange(
const std::string &intervalRangeStr) {
if (intervalRangeStr == "*") {
intervalTypesToRender |= All;
} else if (intervalRangeStr == "virt-nospills*") {
intervalTypesToRender |= VirtNoSpills;
} else if (intervalRangeStr == "spills*") {
intervalTypesToRender |= VirtSpills;
} else if (intervalRangeStr == "virt*") {
intervalTypesToRender |= AllVirt;
} else if (intervalRangeStr == "phys*") {
intervalTypesToRender |= AllPhys;
} else {
std::istringstream iss(intervalRangeStr);
unsigned reg1, reg2;
if ((iss >> reg1 >> std::ws)) {
if (iss.eof()) {
intervalNumsToRender.insert(std::make_pair(reg1, reg1 + 1));
} else {
char c;
iss >> c;
if (c == '-' && (iss >> reg2)) {
intervalNumsToRender.insert(std::make_pair(reg1, reg2 + 1));
} else {
dbgs() << "Warning: Invalid interval range \""
<< intervalRangeStr << "\" in -rmf-intervals. Skipping.\n";
}
}
} else {
dbgs() << "Warning: Invalid interval number \""
<< intervalRangeStr << "\" in -rmf-intervals. Skipping.\n";
}
}
}
void MFRenderingOptions::setup(MachineFunction *mf,
const TargetRegisterInfo *tri,
LiveIntervals *lis,
const RenderMachineFunction *rmf) {
this->mf = mf;
this->tri = tri;
this->lis = lis;
this->rmf = rmf;
clear();
}
Loading
Loading full blame...