LLVM API Documentation

RegisterCoalescer.h

Go to the documentation of this file.
00001 //===-- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===//
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 contains the abstract interface for register coalescers, 
00011 // allowing them to interact with and query register allocators.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/System/IncludeFile.h"
00016 #include "llvm/CodeGen/LiveInterval.h"
00017 #include "llvm/ADT/SmallPtrSet.h"
00018 
00019 #ifndef LLVM_CODEGEN_REGISTER_COALESCER_H
00020 #define LLVM_CODEGEN_REGISTER_COALESCER_H
00021 
00022 namespace llvm {
00023 
00024   class MachineFunction;
00025   class RegallocQuery;
00026   class AnalysisUsage;
00027   class MachineInstr;
00028 
00029   /// An abstract interface for register coalescers.  Coalescers must
00030   /// implement this interface to be part of the coalescer analysis
00031   /// group.
00032   class RegisterCoalescer {
00033   public:
00034     static char ID; // Class identification, replacement for typeinfo
00035     RegisterCoalescer() {}
00036     virtual ~RegisterCoalescer();  // We want to be subclassed
00037 
00038     /// Run the coalescer on this function, providing interference
00039     /// data to query.  Return whether we removed any copies.
00040     virtual bool coalesceFunction(MachineFunction &mf,
00041                                   RegallocQuery &ifd) = 0;
00042 
00043     /// Reset state.  Can be used to allow a coalescer run by
00044     /// PassManager to be run again by the register allocator.
00045     virtual void reset(MachineFunction &mf) {};
00046 
00047     /// Register allocators must call this from their own
00048     /// getAnalysisUsage to cover the case where the coalescer is not
00049     /// a Pass in the proper sense and isn't managed by PassManager.
00050     /// PassManager needs to know which analyses to make available and
00051     /// which to invalidate when running the register allocator or any
00052     /// pass that might call coalescing.  The long-term solution is to
00053     /// allow hierarchies of PassManagers.
00054     virtual void getAnalysisUsage(AnalysisUsage &AU) const {};
00055   }; 
00056 
00057   /// An abstract interface for register allocators to interact with
00058   /// coalescers
00059   ///
00060   /// Example:
00061   ///
00062   /// This is simply an example of how to use the RegallocQuery
00063   /// interface.  It is not meant to be used in production.
00064   ///
00065   ///   class LinearScanRegallocQuery : public RegallocQuery {
00066   ///   private:
00067   ///     const LiveIntervals &li;
00068   ///
00069   ///   public:
00070   ///     LinearScanRegallocQuery(LiveIntervals &intervals) 
00071   ///         : li(intervals) {};
00072   ///
00073   ///     /// This is pretty slow and conservative, but since linear scan
00074   ///     /// allocation doesn't pre-compute interference information it's
00075   ///     /// the best we can do.  Coalescers are always free to ignore this
00076   ///     /// and implement their own discovery strategy.  See
00077   ///     /// SimpleRegisterCoalescing for an example.
00078   ///     void getInterferences(IntervalSet &interferences,
00079   ///                           const LiveInterval &a) const {
00080   ///       for(LiveIntervals::const_iterator iv = li.begin(),
00081   ///             ivend = li.end();
00082   ///           iv != ivend;
00083   ///           ++iv) {
00084   ///         if (interfere(a, iv->second)) {
00085   ///           interferences.insert(&iv->second);
00086   ///         }
00087   ///       }
00088   ///     };
00089   ///
00090   ///     /// This is *really* slow and stupid.  See above.
00091   ///     int getNumberOfInterferences(const LiveInterval &a) const {
00092   ///       IntervalSet intervals;
00093   ///       getInterferences(intervals, a);
00094   ///       return intervals.size();
00095   ///     };
00096   ///   };  
00097   ///
00098   ///   In the allocator:
00099   ///
00100   ///   RegisterCoalescer &coalescer = getAnalysis<RegisterCoalescer>();
00101   ///
00102   ///   // We don't reset the coalescer so if it's already been run this
00103   ///   // takes almost no time.
00104   ///   LinearScanRegallocQuery ifd(*li_);
00105   ///   coalescer.coalesceFunction(fn, ifd);
00106   ///
00107   class RegallocQuery {
00108   public:
00109     typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet;
00110 
00111     virtual ~RegallocQuery() {};
00112     
00113     /// Return whether two live ranges interfere.
00114     virtual bool interfere(const LiveInterval &a,
00115                            const LiveInterval &b) const {
00116       // A naive test
00117       return a.overlaps(b);
00118     };
00119 
00120     /// Return the set of intervals that interfere with this one.
00121     virtual void getInterferences(IntervalSet &interferences,
00122                                   const LiveInterval &a) const = 0;
00123 
00124     /// This can often be cheaper than actually returning the
00125     /// interferences.
00126     virtual int getNumberOfInterferences(const LiveInterval &a) const = 0;
00127 
00128     /// Make any data structure updates necessary to reflect
00129     /// coalescing or other modifications.
00130     virtual void updateDataForMerge(const LiveInterval &a,
00131                                     const LiveInterval &b,
00132                                     const MachineInstr &copy) {};
00133 
00134     /// Allow the register allocator to communicate when it doesn't
00135     /// want a copy coalesced.  This may be due to assumptions made by
00136     /// the allocator about various invariants and so this question is
00137     /// a matter of legality, not performance.  Performance decisions
00138     /// about which copies to coalesce should be made by the
00139     /// coalescer.
00140     virtual bool isLegalToCoalesce(const MachineInstr &inst) const {
00141       return true;
00142     }
00143   };
00144 }
00145 
00146 // Because of the way .a files work, we must force the SimpleRC
00147 // implementation to be pulled in if the RegisterCoalescing header is
00148 // included.  Otherwise we run the risk of RegisterCoalescing being
00149 // used, but the default implementation not being linked into the tool
00150 // that uses it.
00151 FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer)
00152 FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing)
00153 
00154 #endif