EdgeBundles.cpp revision 218893
1169691Skan//===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===//
2169691Skan//
3169691Skan//                     The LLVM Compiler Infrastructure
4169691Skan//
5169691Skan// This file is distributed under the University of Illinois Open Source
6169691Skan// License. See LICENSE.TXT for details.
7169691Skan//
8169691Skan//===----------------------------------------------------------------------===//
9169691Skan//
10169691Skan// This file provides the implementation of the EdgeBundles analysis.
11169691Skan//
12169691Skan//===----------------------------------------------------------------------===//
13169691Skan
14169691Skan#include "llvm/CodeGen/EdgeBundles.h"
15169691Skan#include "llvm/CodeGen/MachineBasicBlock.h"
16169691Skan#include "llvm/CodeGen/MachineFunction.h"
17169691Skan#include "llvm/CodeGen/Passes.h"
18169691Skan#include "llvm/Support/CommandLine.h"
19169691Skan#include "llvm/Support/GraphWriter.h"
20169691Skan
21169691Skanusing namespace llvm;
22169691Skan
23169691Skanstatic cl::opt<bool>
24169691SkanViewEdgeBundles("view-edge-bundles", cl::Hidden,
25169691Skan                cl::desc("Pop up a window to show edge bundle graphs"));
26169691Skan
27169691Skanchar EdgeBundles::ID = 0;
28169691Skan
29169691SkanINITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges",
30169691Skan                /* cfg = */true, /* analysis = */ true)
31169691Skan
32169691Skanchar &llvm::EdgeBundlesID = EdgeBundles::ID;
33169691Skan
34169691Skanvoid EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const {
35169691Skan  AU.setPreservesAll();
36169691Skan  MachineFunctionPass::getAnalysisUsage(AU);
37169691Skan}
38169691Skan
39169691Skanbool EdgeBundles::runOnMachineFunction(MachineFunction &mf) {
40169691Skan  MF = &mf;
41169691Skan  EC.clear();
42169691Skan  EC.grow(2 * MF->size());
43169691Skan
44169691Skan  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
45169691Skan       ++I) {
46169691Skan    const MachineBasicBlock &MBB = *I;
47169691Skan    unsigned OutE = 2 * MBB.getNumber() + 1;
48169691Skan    // Join the outgoing bundle with the ingoing bundles of all successors.
49169691Skan    for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
50169691Skan           SE = MBB.succ_end(); SI != SE; ++SI)
51169691Skan      EC.join(OutE, 2 * (*SI)->getNumber());
52169691Skan  }
53169691Skan  EC.compress();
54169691Skan  if (ViewEdgeBundles)
55169691Skan    view();
56169691Skan  return false;
57}
58
59/// view - Visualize the annotated bipartite CFG with Graphviz.
60void EdgeBundles::view() const {
61  ViewGraph(*this, "EdgeBundles");
62}
63
64/// Specialize WriteGraph, the standard implementation won't work.
65raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G,
66                              bool ShortNames,
67                              const std::string &Title) {
68  const MachineFunction *MF = G.getMachineFunction();
69
70  O << "digraph {\n";
71  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
72       I != E; ++I) {
73    unsigned BB = I->getNumber();
74    O << "\t\"BB#" << BB << "\" [ shape=box ]\n"
75      << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n"
76      << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n';
77    for (MachineBasicBlock::const_succ_iterator SI = I->succ_begin(),
78           SE = I->succ_end(); SI != SE; ++SI)
79      O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber()
80        << "\" [ color=lightgray ]\n";
81  }
82  O << "}\n";
83  return O;
84}
85
86
87