1f96ae684SJakob Stoklund Olesen //===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===//
2f96ae684SJakob Stoklund Olesen //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f96ae684SJakob Stoklund Olesen //
7f96ae684SJakob Stoklund Olesen //===----------------------------------------------------------------------===//
8f96ae684SJakob Stoklund Olesen //
9f96ae684SJakob Stoklund Olesen // This file provides the implementation of the EdgeBundles analysis.
10f96ae684SJakob Stoklund Olesen //
11f96ae684SJakob Stoklund Olesen //===----------------------------------------------------------------------===//
12f96ae684SJakob Stoklund Olesen
13f96ae684SJakob Stoklund Olesen #include "llvm/CodeGen/EdgeBundles.h"
1489f6ca05SSimon Pilgrim #include "llvm/ADT/Twine.h"
15f96ae684SJakob Stoklund Olesen #include "llvm/CodeGen/MachineBasicBlock.h"
16f96ae684SJakob Stoklund Olesen #include "llvm/CodeGen/MachineFunction.h"
17f96ae684SJakob Stoklund Olesen #include "llvm/CodeGen/Passes.h"
1805da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
19f3ac7336SJakob Stoklund Olesen #include "llvm/Support/CommandLine.h"
20f96ae684SJakob Stoklund Olesen #include "llvm/Support/GraphWriter.h"
211804a77bSEugene Zelenko #include "llvm/Support/raw_ostream.h"
22f96ae684SJakob Stoklund Olesen
23f96ae684SJakob Stoklund Olesen using namespace llvm;
24f96ae684SJakob Stoklund Olesen
25f3ac7336SJakob Stoklund Olesen static cl::opt<bool>
26f3ac7336SJakob Stoklund Olesen ViewEdgeBundles("view-edge-bundles", cl::Hidden,
27f3ac7336SJakob Stoklund Olesen cl::desc("Pop up a window to show edge bundle graphs"));
28f3ac7336SJakob Stoklund Olesen
29f96ae684SJakob Stoklund Olesen char EdgeBundles::ID = 0;
30f96ae684SJakob Stoklund Olesen
31f96ae684SJakob Stoklund Olesen INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges",
3249a3ad21SRui Ueyama /* cfg = */true, /* is_analysis = */ true)
33f96ae684SJakob Stoklund Olesen
34f96ae684SJakob Stoklund Olesen char &llvm::EdgeBundlesID = EdgeBundles::ID;
35f96ae684SJakob Stoklund Olesen
getAnalysisUsage(AnalysisUsage & AU) const36f96ae684SJakob Stoklund Olesen void EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const {
37f96ae684SJakob Stoklund Olesen AU.setPreservesAll();
38f96ae684SJakob Stoklund Olesen MachineFunctionPass::getAnalysisUsage(AU);
39f96ae684SJakob Stoklund Olesen }
40f96ae684SJakob Stoklund Olesen
runOnMachineFunction(MachineFunction & mf)41f96ae684SJakob Stoklund Olesen bool EdgeBundles::runOnMachineFunction(MachineFunction &mf) {
42f96ae684SJakob Stoklund Olesen MF = &mf;
43f96ae684SJakob Stoklund Olesen EC.clear();
442c2aa9a9SAnna Zaks EC.grow(2 * MF->getNumBlockIDs());
45f96ae684SJakob Stoklund Olesen
4641b977dfSAlexey Samsonov for (const auto &MBB : *MF) {
47f96ae684SJakob Stoklund Olesen unsigned OutE = 2 * MBB.getNumber() + 1;
48f96ae684SJakob Stoklund Olesen // Join the outgoing bundle with the ingoing bundles of all successors.
49905cf88dSKazu Hirata for (const MachineBasicBlock *Succ : MBB.successors())
50905cf88dSKazu Hirata EC.join(OutE, 2 * Succ->getNumber());
51f96ae684SJakob Stoklund Olesen }
52f96ae684SJakob Stoklund Olesen EC.compress();
53f3ac7336SJakob Stoklund Olesen if (ViewEdgeBundles)
54f3ac7336SJakob Stoklund Olesen view();
55ed47ed4eSJakob Stoklund Olesen
56ed47ed4eSJakob Stoklund Olesen // Compute the reverse mapping.
57ed47ed4eSJakob Stoklund Olesen Blocks.clear();
58ed47ed4eSJakob Stoklund Olesen Blocks.resize(getNumBundles());
59ed47ed4eSJakob Stoklund Olesen
60ed47ed4eSJakob Stoklund Olesen for (unsigned i = 0, e = MF->getNumBlockIDs(); i != e; ++i) {
611804a77bSEugene Zelenko unsigned b0 = getBundle(i, false);
621804a77bSEugene Zelenko unsigned b1 = getBundle(i, true);
63ed47ed4eSJakob Stoklund Olesen Blocks[b0].push_back(i);
64ed47ed4eSJakob Stoklund Olesen if (b1 != b0)
65ed47ed4eSJakob Stoklund Olesen Blocks[b1].push_back(i);
66ed47ed4eSJakob Stoklund Olesen }
67ed47ed4eSJakob Stoklund Olesen
68f96ae684SJakob Stoklund Olesen return false;
69f96ae684SJakob Stoklund Olesen }
70f96ae684SJakob Stoklund Olesen
71a4b7cfd6SRichard Smith namespace llvm {
721804a77bSEugene Zelenko
73*a1aada75SNicolás Alvarez /// Specialize WriteGraph, the standard implementation won't work.
740d9ec713SRichard Smith template<>
WriteGraph(raw_ostream & O,const EdgeBundles & G,bool ShortNames,const Twine & Title)75a4b7cfd6SRichard Smith raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G,
76f96ae684SJakob Stoklund Olesen bool ShortNames,
774c93d15fSBenjamin Kramer const Twine &Title) {
78f96ae684SJakob Stoklund Olesen const MachineFunction *MF = G.getMachineFunction();
79f96ae684SJakob Stoklund Olesen
80f96ae684SJakob Stoklund Olesen O << "digraph {\n";
8141b977dfSAlexey Samsonov for (const auto &MBB : *MF) {
8241b977dfSAlexey Samsonov unsigned BB = MBB.getNumber();
8325528d6dSFrancis Visoiu Mistrih O << "\t\"" << printMBBReference(MBB) << "\" [ shape=box ]\n"
8425528d6dSFrancis Visoiu Mistrih << '\t' << G.getBundle(BB, false) << " -> \"" << printMBBReference(MBB)
8525528d6dSFrancis Visoiu Mistrih << "\"\n"
8625528d6dSFrancis Visoiu Mistrih << "\t\"" << printMBBReference(MBB) << "\" -> " << G.getBundle(BB, true)
8725528d6dSFrancis Visoiu Mistrih << '\n';
88905cf88dSKazu Hirata for (const MachineBasicBlock *Succ : MBB.successors())
8925528d6dSFrancis Visoiu Mistrih O << "\t\"" << printMBBReference(MBB) << "\" -> \""
90905cf88dSKazu Hirata << printMBBReference(*Succ) << "\" [ color=lightgray ]\n";
91f96ae684SJakob Stoklund Olesen }
92f96ae684SJakob Stoklund Olesen O << "}\n";
93f96ae684SJakob Stoklund Olesen return O;
94f96ae684SJakob Stoklund Olesen }
951804a77bSEugene Zelenko
961804a77bSEugene Zelenko } // end namespace llvm
970d9ec713SRichard Smith
980d9ec713SRichard Smith /// view - Visualize the annotated bipartite CFG with Graphviz.
view() const990d9ec713SRichard Smith void EdgeBundles::view() const {
1000d9ec713SRichard Smith ViewGraph(*this, "EdgeBundles");
1010d9ec713SRichard Smith }
102