LLVM API Documentation
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 ©) {}; 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