llvm/lib/CodeGen/EdgeBundles.cpp
Jakob Stoklund Olesen f4afdfc501 Build the Hopfield network incrementally when splitting global live ranges.
It is common for large live ranges to have few basic blocks with register uses
and many live-through blocks without any uses. This approach grows the Hopfield
network incrementally around the use blocks, completely avoiding checking
interference for some through blocks.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129188 91177308-0d34-0410-b5e6-96231b3b80d8
2011-04-09 02:59:09 +00:00

98 lines
3.1 KiB
C++

//===-------- EdgeBundles.cpp - Bundles of CFG edges ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides the implementation of the EdgeBundles analysis.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/EdgeBundles.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GraphWriter.h"
using namespace llvm;
static cl::opt<bool>
ViewEdgeBundles("view-edge-bundles", cl::Hidden,
cl::desc("Pop up a window to show edge bundle graphs"));
char EdgeBundles::ID = 0;
INITIALIZE_PASS(EdgeBundles, "edge-bundles", "Bundle Machine CFG Edges",
/* cfg = */true, /* analysis = */ true)
char &llvm::EdgeBundlesID = EdgeBundles::ID;
void EdgeBundles::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool EdgeBundles::runOnMachineFunction(MachineFunction &mf) {
MF = &mf;
EC.clear();
EC.grow(2 * MF->size());
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
++I) {
const MachineBasicBlock &MBB = *I;
unsigned OutE = 2 * MBB.getNumber() + 1;
// Join the outgoing bundle with the ingoing bundles of all successors.
for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
SE = MBB.succ_end(); SI != SE; ++SI)
EC.join(OutE, 2 * (*SI)->getNumber());
}
EC.compress();
if (ViewEdgeBundles)
view();
// Compute the reverse mapping.
Blocks.clear();
Blocks.resize(getNumBundles());
for (unsigned i = 0, e = MF->getNumBlockIDs(); i != e; ++i) {
unsigned b0 = getBundle(i, 0);
unsigned b1 = getBundle(i, 1);
Blocks[b0].push_back(i);
if (b1 != b0)
Blocks[b1].push_back(i);
}
return false;
}
/// view - Visualize the annotated bipartite CFG with Graphviz.
void EdgeBundles::view() const {
ViewGraph(*this, "EdgeBundles");
}
/// Specialize WriteGraph, the standard implementation won't work.
raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G,
bool ShortNames,
const std::string &Title) {
const MachineFunction *MF = G.getMachineFunction();
O << "digraph {\n";
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I) {
unsigned BB = I->getNumber();
O << "\t\"BB#" << BB << "\" [ shape=box ]\n"
<< '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n"
<< "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n';
for (MachineBasicBlock::const_succ_iterator SI = I->succ_begin(),
SE = I->succ_end(); SI != SE; ++SI)
O << "\t\"BB#" << BB << "\" -> \"BB#" << (*SI)->getNumber()
<< "\" [ color=lightgray ]\n";
}
O << "}\n";
return O;
}