LLVM API Documentation
00001 //===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides the implementation of the EdgeBundles analysis. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/EdgeBundles.h" 00015 #include "llvm/CodeGen/MachineBasicBlock.h" 00016 #include "llvm/CodeGen/MachineFunction.h" 00017 #include "llvm/CodeGen/Passes.h" 00018 #include "llvm/Support/CommandLine.h" 00019 #include "llvm/Support/GraphWriter.h" 00020 00021 using namespace llvm; 00022 00023 static cl::opt<bool> 00024 ViewEdgeBundles("view-edge-bundles", cl::Hidden, 00025 cl::desc("Pop up a window to show edge bundle graphs")); 00026 00027 char EdgeBundles::ID = 0; 00028 00029 INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges", 00030 /* cfg = */true, /* analysis = */ true) 00031 00032 char &llvm::EdgeBundlesID = EdgeBundles::ID; 00033 00034 void EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const { 00035 AU.setPreservesAll(); 00036 MachineFunctionPass::getAnalysisUsage(AU); 00037 } 00038 00039 bool EdgeBundles::runOnMachineFunction(MachineFunction &mf) { 00040 MF = &mf; 00041 EC.clear(); 00042 EC.grow(2 * MF->getNumBlockIDs()); 00043 00044 for (const auto &MBB : *MF) { 00045 unsigned OutE = 2 * MBB.getNumber() + 1; 00046 // Join the outgoing bundle with the ingoing bundles of all successors. 00047 for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), 00048 SE = MBB.succ_end(); SI != SE; ++SI) 00049 EC.join(OutE, 2 * (*SI)->getNumber()); 00050 } 00051 EC.compress(); 00052 if (ViewEdgeBundles) 00053 view(); 00054 00055 // Compute the reverse mapping. 00056 Blocks.clear(); 00057 Blocks.resize(getNumBundles()); 00058 00059 for (unsigned i = 0, e = MF->getNumBlockIDs(); i != e; ++i) { 00060 unsigned b0 = getBundle(i, 0); 00061 unsigned b1 = getBundle(i, 1); 00062 Blocks[b0].push_back(i); 00063 if (b1 != b0) 00064 Blocks[b1].push_back(i); 00065 } 00066 00067 return false; 00068 } 00069 00070 /// Specialize WriteGraph, the standard implementation won't work. 00071 namespace llvm { 00072 template<> 00073 raw_ostream &WriteGraph<>(raw_ostream &O, const EdgeBundles &G, 00074 bool ShortNames, 00075 const Twine &Title) { 00076 const MachineFunction *MF = G.getMachineFunction(); 00077 00078 O << "digraph {\n"; 00079 for (const auto &MBB : *MF) { 00080 unsigned BB = MBB.getNumber(); 00081 O << "\t\"BB#" << BB << "\" [ shape=box ]\n" 00082 << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n" 00083 << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n'; 00084 for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), 00085 SE = MBB.succ_end(); SI != SE; ++SI) 00086 O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber() 00087 << "\" [ color=lightgray ]\n"; 00088 } 00089 O << "}\n"; 00090 return O; 00091 } 00092 } 00093 00094 /// view - Visualize the annotated bipartite CFG with Graphviz. 00095 void EdgeBundles::view() const { 00096 ViewGraph(*this, "EdgeBundles"); 00097 }