1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

Turn the EdgeBundles class into a stand-alone machine CFG analysis pass.

The analysis will be needed by both the greedy register allocator and the
X86FloatingPoint pass. It only needs to be computed once when the CFG doesn't
change.

This pass is very fast, usually showing up as 0.0% wall time.

llvm-svn: 122832
This commit is contained in:
Jakob Stoklund Olesen 2011-01-04 21:10:05 +00:00
parent c7168aa6fe
commit abf8941a60
8 changed files with 147 additions and 88 deletions

View File

@ -0,0 +1,58 @@
//===-------- EdgeBundles.h - Bundles of CFG edges --------------*- c++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The EdgeBundles analysis forms equivalence classes of CFG edges such that all
// edges leaving a machine basic block are in the same bundle, and all edges
// leaving a basic block are in the same bundle.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_EDGEBUNDLES_H
#define LLVM_CODEGEN_EDGEBUNDLES_H
#include "llvm/ADT/IntEqClasses.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
class EdgeBundles : public MachineFunctionPass {
const MachineFunction *MF;
/// EC - Each edge bundle is an equivalence class. The keys are:
/// 2*BB->getNumber() -> Ingoing bundle.
/// 2*BB->getNumber()+1 -> Outgoing bundle.
IntEqClasses EC;
public:
static char ID;
EdgeBundles() : MachineFunctionPass(ID) {}
/// getBundle - Return the ingoing (Out = false) or outgoing (Out = true)
/// bundle number for basic block #N
unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; }
/// getMachineFunction - Return the last machine function computed.
const MachineFunction *getMachineFunction() const { return MF; }
/// view - Visualize the annotated bipartite CFG with Graphviz.
void view() const;
private:
virtual bool runOnMachineFunction(MachineFunction&);
virtual void getAnalysisUsage(AnalysisUsage&) const;
};
/// Specialize WriteGraph, the standard implementation won't work.
raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G,
bool ShortNames = false,
const std::string &Title = "");
} // end namespace llvm
#endif

View File

@ -54,6 +54,10 @@ namespace llvm {
/// ///
extern char &MachineDominatorsID; extern char &MachineDominatorsID;
/// EdgeBundles analysis - Bundle machine CFG edges.
///
extern char &EdgeBundlesID;
/// PHIElimination pass - This pass eliminates machine instruction PHI nodes /// PHIElimination pass - This pass eliminates machine instruction PHI nodes
/// by inserting copy instructions. This destroys SSA information, but is the /// by inserting copy instructions. This destroys SSA information, but is the
/// desired input for some register allocators. This pass is "required" by /// desired input for some register allocators. This pass is "required" by

View File

@ -91,6 +91,7 @@ void initializeDomPrinterPass(PassRegistry&);
void initializeDomViewerPass(PassRegistry&); void initializeDomViewerPass(PassRegistry&);
void initializeDominanceFrontierPass(PassRegistry&); void initializeDominanceFrontierPass(PassRegistry&);
void initializeDominatorTreePass(PassRegistry&); void initializeDominatorTreePass(PassRegistry&);
void initializeEdgeBundlesPass(PassRegistry&);
void initializeEdgeProfilerPass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&);
void initializeEarlyCSEPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&);
void initializeExpandISelPseudosPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&);

View File

@ -10,6 +10,7 @@ add_llvm_library(LLVMCodeGen
CriticalAntiDepBreaker.cpp CriticalAntiDepBreaker.cpp
DeadMachineInstructionElim.cpp DeadMachineInstructionElim.cpp
DwarfEHPrepare.cpp DwarfEHPrepare.cpp
EdgeBundles.cpp
ELFCodeEmitter.cpp ELFCodeEmitter.cpp
ELFWriter.cpp ELFWriter.cpp
ExpandISelPseudos.cpp ExpandISelPseudos.cpp

View File

@ -0,0 +1,79 @@
//===-------- 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/GraphWriter.h"
using namespace llvm;
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();
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;
}

View File

@ -24,7 +24,6 @@
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -35,56 +34,6 @@ static cl::opt<bool>
AllowSplit("spiller-splits-edges", AllowSplit("spiller-splits-edges",
cl::desc("Allow critical edge splitting during spilling")); cl::desc("Allow critical edge splitting during spilling"));
//===----------------------------------------------------------------------===//
// Edge Bundles
//===----------------------------------------------------------------------===//
/// compute - Compute the edge bundles for MF. Bundles depend only on the CFG.
void EdgeBundles::compute(const 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();
}
/// 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;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Split Analysis // Split Analysis
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -1,4 +1,4 @@
//===-------- SplitKit.cpp - Toolkit for splitting live ranges --*- C++ -*-===// //===-------- SplitKit.h - Toolkit for splitting live ranges ----*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,12 +13,9 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntEqClasses.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/SlotIndexes.h"
#include <string>
namespace llvm { namespace llvm {
class LiveInterval; class LiveInterval;
@ -40,39 +37,6 @@ template <class NodeT> class DomTreeNodeBase;
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode; typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
/// EdgeBundles - Group CFG edges into equivalence classes where registers must
/// be allocated identically. This annotates the CFG to form a bipartite graph
/// where each block is connected to an ingoing and an outgoing bundle.
/// Edge bundles are simply numbered, there is no object representation.
class EdgeBundles {
const MachineFunction *MF;
/// EC - Each edge bundle is an equivalence class. The keys are:
/// 2*BB->getNumber() -> Ingoing bundle.
/// 2*BB->getNumber()+1 -> Outgoing bundle.
IntEqClasses EC;
public:
/// compute - Compute the edge bundles for MF. Bundles depend only on the CFG.
void compute(const MachineFunction *MF);
/// getBundle - Return the ingoing (Out = false) or outgoing (Out = true)
/// bundle number for basic block #N
unsigned getBundle(unsigned N, bool Out) const { return EC[2 * N + Out]; }
/// getMachineFunction - Return the last machine function computed.
const MachineFunction *getMachineFunction() const { return MF; }
/// view - Visualize the annotated bipartite CFG with Graphviz.
void view() const;
};
/// Specialize WriteGraph, the standard implementation won't work.
raw_ostream &WriteGraph(raw_ostream &O, const EdgeBundles &G,
bool ShortNames = false,
const std::string &Title = "");
/// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting
/// opportunities. /// opportunities.
class SplitAnalysis { class SplitAnalysis {

View File

@ -32,6 +32,7 @@
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/EdgeBundles.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
@ -51,6 +52,7 @@ namespace {
struct FPS : public MachineFunctionPass { struct FPS : public MachineFunctionPass {
static char ID; static char ID;
FPS() : MachineFunctionPass(ID) { FPS() : MachineFunctionPass(ID) {
initializeEdgeBundlesPass(*PassRegistry::getPassRegistry());
// This is really only to keep valgrind quiet. // This is really only to keep valgrind quiet.
// The logic in isLive() is too much for it. // The logic in isLive() is too much for it.
memset(Stack, 0, sizeof(Stack)); memset(Stack, 0, sizeof(Stack));
@ -59,6 +61,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG(); AU.setPreservesCFG();
AU.addRequired<EdgeBundles>();
AU.addPreservedID(MachineLoopInfoID); AU.addPreservedID(MachineLoopInfoID);
AU.addPreservedID(MachineDominatorsID); AU.addPreservedID(MachineDominatorsID);
MachineFunctionPass::getAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU);