Line data Source code
1 : //===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file provides the implementation of the EdgeBundles analysis.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "llvm/CodeGen/EdgeBundles.h"
15 : #include "llvm/CodeGen/MachineBasicBlock.h"
16 : #include "llvm/CodeGen/MachineFunction.h"
17 : #include "llvm/CodeGen/Passes.h"
18 : #include "llvm/Support/CommandLine.h"
19 : #include "llvm/Support/GraphWriter.h"
20 : #include "llvm/Support/raw_ostream.h"
21 :
22 : using namespace llvm;
23 :
24 : static cl::opt<bool>
25 : ViewEdgeBundles("view-edge-bundles", cl::Hidden,
26 : cl::desc("Pop up a window to show edge bundle graphs"));
27 :
28 : char EdgeBundles::ID = 0;
29 :
30 110115 : INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges",
31 : /* cfg = */true, /* analysis = */ true)
32 :
33 : char &llvm::EdgeBundlesID = EdgeBundles::ID;
34 :
35 34220 : void EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const {
36 : AU.setPreservesAll();
37 34220 : MachineFunctionPass::getAnalysisUsage(AU);
38 34220 : }
39 :
40 507610 : bool EdgeBundles::runOnMachineFunction(MachineFunction &mf) {
41 507610 : MF = &mf;
42 507610 : EC.clear();
43 507610 : EC.grow(2 * MF->getNumBlockIDs());
44 :
45 4132380 : for (const auto &MBB : *MF) {
46 3624770 : unsigned OutE = 2 * MBB.getNumber() + 1;
47 : // Join the outgoing bundle with the ingoing bundles of all successors.
48 : for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
49 7706082 : SE = MBB.succ_end(); SI != SE; ++SI)
50 4081312 : EC.join(OutE, 2 * (*SI)->getNumber());
51 : }
52 507610 : EC.compress();
53 507610 : if (ViewEdgeBundles)
54 0 : view();
55 :
56 : // Compute the reverse mapping.
57 507610 : Blocks.clear();
58 507610 : Blocks.resize(getNumBundles());
59 :
60 4132384 : for (unsigned i = 0, e = MF->getNumBlockIDs(); i != e; ++i) {
61 : unsigned b0 = getBundle(i, false);
62 : unsigned b1 = getBundle(i, true);
63 7249548 : Blocks[b0].push_back(i);
64 3624774 : if (b1 != b0)
65 6855406 : Blocks[b1].push_back(i);
66 : }
67 :
68 507610 : return false;
69 : }
70 :
71 : /// Specialize WriteGraph, the standard implementation won't work.
72 : namespace llvm {
73 :
74 : template<>
75 0 : raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
76 : bool ShortNames,
77 : const Twine &Title) {
78 0 : const MachineFunction *MF = G.getMachineFunction();
79 :
80 0 : O << "digraph {\n";
81 0 : for (const auto &MBB : *MF) {
82 0 : unsigned BB = MBB.getNumber();
83 0 : O << "\t\"" << printMBBReference(MBB) << "\" [ shape=box ]\n"
84 0 : << '\t' << G.getBundle(BB, false) << " -> \"" << printMBBReference(MBB)
85 0 : << "\"\n"
86 0 : << "\t\"" << printMBBReference(MBB) << "\" -> " << G.getBundle(BB, true)
87 : << '\n';
88 : for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
89 0 : SE = MBB.succ_end(); SI != SE; ++SI)
90 0 : O << "\t\"" << printMBBReference(MBB) << "\" -> \""
91 0 : << printMBBReference(**SI) << "\" [ color=lightgray ]\n";
92 : }
93 0 : O << "}\n";
94 0 : return O;
95 : }
96 :
97 : } // end namespace llvm
98 :
99 : /// view - Visualize the annotated bipartite CFG with Graphviz.
100 0 : void EdgeBundles::view() const {
101 0 : ViewGraph(*this, "EdgeBundles");
102 0 : }
|