Add an option, -view-sunit-dags, for viewing the actual SUnit DAGs used by

scheduling.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41556 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2007-08-28 20:32:58 +00:00
parent f5a69fe81f
commit 3e1a7aef17
3 changed files with 145 additions and 1 deletions

View File

@ -17,6 +17,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallSet.h"
namespace llvm {
@ -191,6 +192,11 @@ namespace llvm {
virtual ~ScheduleDAG() {}
/// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
/// using 'dot'.
///
void viewGraph();
/// Run - perform scheduling.
///
MachineBasicBlock *Run();
@ -315,6 +321,68 @@ namespace llvm {
ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
SelectionDAG *DAG,
MachineBasicBlock *BB);
class SUnitIterator : public forward_iterator<SUnit, ptrdiff_t> {
SUnit *Node;
unsigned Operand;
SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
public:
bool operator==(const SUnitIterator& x) const {
return Operand == x.Operand;
}
bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
const SUnitIterator &operator=(const SUnitIterator &I) {
assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
Operand = I.Operand;
return *this;
}
pointer operator*() const {
return Node->Preds[Operand].first;
}
pointer operator->() const { return operator*(); }
SUnitIterator& operator++() { // Preincrement
++Operand;
return *this;
}
SUnitIterator operator++(int) { // Postincrement
SUnitIterator tmp = *this; ++*this; return tmp;
}
static SUnitIterator begin(SUnit *N) { return SUnitIterator(N, 0); }
static SUnitIterator end (SUnit *N) {
return SUnitIterator(N, N->Preds.size());
}
unsigned getOperand() const { return Operand; }
const SUnit *getNode() const { return Node; }
bool isChain() const { return Node->Preds[Operand].second; }
};
template <> struct GraphTraits<SUnit*> {
typedef SUnit NodeType;
typedef SUnitIterator ChildIteratorType;
static inline NodeType *getEntryNode(SUnit *N) { return N; }
static inline ChildIteratorType child_begin(NodeType *N) {
return SUnitIterator::begin(N);
}
static inline ChildIteratorType child_end(NodeType *N) {
return SUnitIterator::end(N);
}
};
template <> struct GraphTraits<ScheduleDAG*> : public GraphTraits<SUnit*> {
typedef std::vector<SUnit>::iterator nodes_iterator;
static nodes_iterator nodes_begin(ScheduleDAG *G) {
return G->SUnits.begin();
}
static nodes_iterator nodes_end(ScheduleDAG *G) {
return G->SUnits.end();
}
};
}
#endif

View File

@ -54,8 +54,11 @@ ViewISelDAGs("view-isel-dags", cl::Hidden,
static cl::opt<bool>
ViewSchedDAGs("view-sched-dags", cl::Hidden,
cl::desc("Pop up a window to show sched dags as they are processed"));
static cl::opt<bool>
ViewSUnitDAGs("view-sunit-dags", cl::Hidden,
cl::desc("Pop up a window to show SUnit dags after they are processed"));
#else
static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0;
static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0, ViewSUnitDAGs = 0;
#endif
//===---------------------------------------------------------------------===//
@ -4842,6 +4845,9 @@ void SelectionDAGISel::ScheduleAndEmitDAG(SelectionDAG &DAG) {
ScheduleDAG *SL = Ctor(this, &DAG, BB);
BB = SL->Run();
if (ViewSUnitDAGs) SL->viewGraph();
delete SL;
}

View File

@ -15,6 +15,7 @@
#include "llvm/Function.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/MRegisterInfo.h"
@ -243,3 +244,72 @@ void SelectionDAG::setGraphColor(const SDNode *N, const char *Color) {
#endif
}
namespace llvm {
template<>
struct DOTGraphTraits<ScheduleDAG*> : public DefaultDOTGraphTraits {
static std::string getGraphName(const ScheduleDAG *G) {
return DOTGraphTraits<SelectionDAG*>::getGraphName(&G->DAG);
}
static bool renderGraphFromBottomUp() {
return true;
}
static bool hasNodeAddressLabel(const SUnit *Node,
const ScheduleDAG *Graph) {
return true;
}
/// If you want to override the dot attributes printed for a particular
/// edge, override this method.
template<typename EdgeIter>
static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
if (EI.isChain())
return "color=blue,style=dashed";
return "";
}
static std::string getNodeLabel(const SUnit *Node,
const ScheduleDAG *Graph);
static std::string getNodeAttributes(const SUnit *N,
const ScheduleDAG *Graph) {
return "shape=Mrecord";
}
static void addCustomGraphFeatures(ScheduleDAG *G,
GraphWriter<ScheduleDAG*> &GW) {
GW.emitSimpleNode(0, "plaintext=circle", "GraphRoot");
if (G->DAG.getRoot().Val)
GW.emitEdge(0, -1, G->SUnitMap[G->DAG.getRoot().Val], -1, "");
}
};
}
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
const ScheduleDAG *G) {
std::string Op;
for (unsigned i = 0; i < SU->FlaggedNodes.size(); ++i) {
Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->FlaggedNodes[i],
&G->DAG) + "\n";
}
Op += DOTGraphTraits<SelectionDAG*>::getNodeLabel(SU->Node, &G->DAG);
return Op;
}
/// viewGraph - Pop up a ghostview window with the reachable parts of the DAG
/// rendered using 'dot'.
///
void ScheduleDAG::viewGraph() {
// This code is only for debugging!
#ifndef NDEBUG
ViewGraph(this, "dag." + DAG.getMachineFunction().getFunction()->getName());
#else
cerr << "ScheduleDAG::viewGraph is only available in debug builds on "
<< "systems with Graphviz or gv!\n";
#endif // NDEBUG
}