[llvm-commits] [llvm] r41743 - in /llvm/trunk: include/llvm/CodeGen/LinkAllCodegenComponents.h include/llvm/CodeGen/Passes.h include/llvm/CodeGen/RegisterCoalescer.h include/llvm/CodeGen/SimpleRegisterCoalescing.h lib/CodeGen/RegAllocLinearScan.cpp lib/CodeGen/RegisterCoalescer.cpp lib/CodeGen/SimpleRegisterCoalescing.cpp
David Greene
greened at obbligato.org
Thu Sep 6 09:18:45 PDT 2007
Author: greened
Date: Thu Sep 6 11:18:45 2007
New Revision: 41743
URL: http://llvm.org/viewvc/llvm-project?rev=41743&view=rev
Log:
Pluggable coalescers inplementation.
Added:
llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h (with props)
llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (with props)
Modified:
llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h
llvm/trunk/include/llvm/CodeGen/Passes.h
llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=41743&r1=41742&r2=41743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Thu Sep 6 11:18:45 2007
@@ -32,6 +32,8 @@
(void) llvm::createLocalRegisterAllocator();
(void) llvm::createBigBlockRegisterAllocator();
(void) llvm::createLinearScanRegisterAllocator();
+
+ (void) llvm::createSimpleRegisterCoalescer();
(void) llvm::createBFS_DAGScheduler(NULL, NULL, NULL);
(void) llvm::createSimpleDAGScheduler(NULL, NULL, NULL);
Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=41743&r1=41742&r2=41743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu Sep 6 11:18:45 2007
@@ -23,6 +23,7 @@
class FunctionPass;
class PassInfo;
class TargetMachine;
+ class RegisterCoalescer;
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
@@ -84,6 +85,11 @@
///
FunctionPass *createLinearScanRegisterAllocator();
+ /// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
+ /// independently of the register allocator.
+ ///
+ RegisterCoalescer *createSimpleRegisterCoalescer();
+
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
/// and eliminates abstract frame references.
///
Added: llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h?rev=41743&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h (added)
+++ llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h Thu Sep 6 11:18:45 2007
@@ -0,0 +1,159 @@
+//===-- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the abstract interface for register coalescers,
+// allowing them to interact with and query register allocators.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/IncludeFile.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+#ifndef LLVM_CODEGEN_REGISTER_COALESCER_H
+#define LLVM_CODEGEN_REGISTER_COALESCER_H
+
+namespace llvm
+{
+ class MachineFunction;
+ class RegallocQuery;
+ class AnalysisUsage;
+ class LiveIntervals;
+ class MachineInstr;
+ class MRegisterInfo;
+
+ /// An abstract interface for register coalescers. Coalescers must
+ /// implement this interface to be part of the coalescer analysis
+ /// group.
+ class RegisterCoalescer {
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ RegisterCoalescer() {}
+ virtual ~RegisterCoalescer(); // We want to be subclassed
+
+ /// Run the coalescer on this function, providing interference
+ /// data to query. Return whether we removed any copies.
+ virtual bool coalesceFunction(MachineFunction &mf,
+ RegallocQuery &ifd) = 0;
+
+ /// Reset state. Can be used to allow a coalescer run by
+ /// PassManager to be run again by the register allocator.
+ virtual void reset(MachineFunction &mf) {};
+
+ /// Register allocators must call this from their own
+ /// getAnalysisUsage to cover the case where the coalescer is not
+ /// a Pass in the proper sense and isn't managed by PassManager.
+ /// PassManager needs to know which analyses to make available and
+ /// which to invalidate when running the register allocator or any
+ /// pass that might call coalescing. The long-term solution is to
+ /// allow hierarchies of PassManagers.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {};
+ };
+
+ /// An abstract interface for register allocators to interact with
+ /// coalescers
+ ///
+ /// Example:
+ ///
+ /// This is simply an example of how to use the RegallocQuery
+ /// interface. It is not meant to be used in production.
+ ///
+ /// class LinearScanRegallocQuery : public RegallocQuery {
+ /// private:
+ /// const LiveIntervals &li;
+ ///
+ /// public:
+ /// LinearScanRegallocQuery(LiveIntervals &intervals)
+ /// : li(intervals) {};
+ ///
+ /// /// This is pretty slow and conservative, but since linear scan
+ /// /// allocation doesn't pre-compute interference information it's
+ /// /// the best we can do. Coalescers are always free to ignore this
+ /// /// and implement their own discovery strategy. See
+ /// /// SimpleRegisterCoalescing for an example.
+ /// void getInterferences(IntervalSet &interferences,
+ /// const LiveInterval &a) const {
+ /// for(LiveIntervals::const_iterator iv = li.begin(),
+ /// ivend = li.end();
+ /// iv != ivend;
+ /// ++iv) {
+ /// if (interfere(a, iv->second)) {
+ /// interferences.insert(&iv->second);
+ /// }
+ /// }
+ /// };
+ ///
+ /// /// This is *really* slow and stupid. See above.
+ /// int getNumberOfInterferences(const LiveInterval &a) const {
+ /// IntervalSet intervals;
+ /// getInterferences(intervals, a);
+ /// return(intervals.size());
+ /// };
+ /// };
+ ///
+ /// In the allocator:
+ ///
+ /// RegisterCoalescer &coalescer = getAnalysis<RegisterCoalescer>();
+ ///
+ /// // We don't reset the coalescer so if it's already been run this
+ /// // takes almost no time.
+ /// LinearScanRegallocQuery ifd(*li_);
+ /// coalescer.coalesceFunction(fn, ifd);
+ ///
+ class RegallocQuery {
+ public:
+ typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet;
+
+ virtual ~RegallocQuery() {};
+
+ /// Return whether two live ranges interfere.
+ virtual bool interfere(const LiveInterval &a,
+ const LiveInterval &b) const {
+ // A naive test
+ return(a.overlaps(b));
+ };
+
+ /// Return the set of intervals that interfere with this one.
+ virtual void getInterferences(IntervalSet &interferences,
+ const LiveInterval &a) const = 0;
+
+ /// This can often be cheaper than actually returning the
+ /// interferences.
+ virtual int getNumberOfInterferences(const LiveInterval &a) const = 0;
+
+ /// Make any data structure updates necessary to reflect
+ /// coalescing or other modifications.
+ virtual void updateDataForMerge(const LiveInterval &a,
+ const LiveInterval &b,
+ const MachineInstr ©) {};
+
+ /// Allow the register allocator to communicate when it doesn't
+ /// want a copy coalesced. This may be due to assumptions made by
+ /// the allocator about various invariants and so this question is
+ /// a matter of legality, not performance. Performance decisions
+ /// about which copies to coalesce should be made by the
+ /// coalescer.
+ virtual bool isLegalToCoalesce(const MachineInstr &inst) const {
+ return(true);
+ }
+ };
+}
+
+// Because of the way .a files work, we must force the SimpleRC
+// implementation to be pulled in if the RegisterCoalescing header is
+// included. Otherwise we run the risk of RegisterCoalescing being
+// used, but the default implementation not being linked into the tool
+// that uses it.
+FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer)
+FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing)
+
+#endif
Propchange: llvm/trunk/include/llvm/CodeGen/RegisterCoalescer.h
------------------------------------------------------------------------------
svn:eol-style = LF
Modified: llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h?rev=41743&r1=41742&r2=41743&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SimpleRegisterCoalescing.h Thu Sep 6 11:18:45 2007
@@ -17,6 +17,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/IndexedMap.h"
@@ -27,7 +28,8 @@
class TargetInstrInfo;
class VirtRegMap;
- class SimpleRegisterCoalescing : public MachineFunctionPass {
+ class SimpleRegisterCoalescing : public MachineFunctionPass,
+ public RegisterCoalescer {
MachineFunction* mf_;
const TargetMachine* tm_;
const MRegisterInfo* mri_;
@@ -76,6 +78,11 @@
/// runOnMachineFunction - pass entry point
virtual bool runOnMachineFunction(MachineFunction&);
+ bool coalesceFunction(MachineFunction &mf, RegallocQuery &) {
+ // This runs as an independent pass, so don't do anything.
+ return(false);
+ };
+
/// print - Implement the dump method.
virtual void print(std::ostream &O, const Module* = 0) const;
void print(std::ostream *O, const Module* M = 0) const {
Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=41743&r1=41742&r2=41743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Thu Sep 6 11:18:45 2007
@@ -21,6 +21,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -96,7 +97,9 @@
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LiveIntervals>();
- AU.addRequiredID(SimpleRegisterCoalescingID);
+ // Make sure PassManager knows which analyses to make available
+ // to coalescing and which analyses coalescing invalidates.
+ AU.addRequiredTransitive<RegisterCoalescer>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -194,6 +197,11 @@
mri_ = tm_->getRegisterInfo();
li_ = &getAnalysis<LiveIntervals>();
+ // We don't run the coalescer here because we have no reason to
+ // interact with it. If the coalescer requires interaction, it
+ // won't do anything. If it doesn't require interaction, we assume
+ // it was run as a separate pass.
+
// If this is the first function compiled, compute the related reg classes.
if (RelatedRegClasses.empty())
ComputeRelatedRegClasses();
Added: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=41743&view=auto
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (added)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Thu Sep 6 11:18:45 2007
@@ -0,0 +1,43 @@
+//===- RegisterCoalescer.cpp - Generic Register Coalescing Interface -------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the generic RegisterCoalescer interface which
+// is used as the common interface used by all clients and
+// implementations of register coalescing.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/RegisterCoalescer.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Pass.h"
+
+using namespace llvm;
+
+// Register the RegisterCoalescer interface, providing a nice name to refer to.
+namespace {
+ RegisterAnalysisGroup<RegisterCoalescer> Z("Register Coalescer");
+}
+char RegisterCoalescer::ID = 0;
+
+// RegisterCoalescer destructor: DO NOT move this to the header file
+// for RegisterCoalescer or else clients of the RegisterCoalescer
+// class may not depend on the RegisterCoalescer.o file in the current
+// .a file, causing alias analysis support to not be included in the
+// tool correctly!
+//
+RegisterCoalescer::~RegisterCoalescer() {}
+
+// Because of the way .a files work, we must force the SimpleRC
+// implementation to be pulled in if the RegisterCoalescer classes are
+// pulled in. Otherwise we run the risk of RegisterCoalescer being
+// used, but the default implementation not being linked into the tool
+// that uses it.
+DEFINING_FILE_FOR(RegisterCoalescer)
Propchange: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
------------------------------------------------------------------------------
svn:eol-style = LF
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=41743&r1=41742&r2=41743&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Thu Sep 6 11:18:45 2007
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/CodeGen/RegisterCoalescer.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -48,6 +49,9 @@
RegisterPass<SimpleRegisterCoalescing>
X("simple-register-coalescing", "Simple Register Coalescing");
+
+ // Declare that we implement the RegisterCoalescer interface
+ RegisterAnalysisGroup<RegisterCoalescer, true/*The Default*/> V(X);
}
const PassInfo *llvm::SimpleRegisterCoalescingID = X.getPassInfo();
@@ -1191,3 +1195,10 @@
void SimpleRegisterCoalescing::print(std::ostream &O, const Module* m) const {
li_->print(O, m);
}
+
+RegisterCoalescer* llvm::createSimpleRegisterCoalescer() {
+ return new SimpleRegisterCoalescing();
+}
+
+// Make sure that anything that uses RegisterCoalescer pulls in this file...
+DEFINING_FILE_FOR(SimpleRegisterCoalescing)
More information about the llvm-commits
mailing list