summaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/LiveStackAnalysis.h
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-05-03 18:32:42 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-05-03 18:32:42 +0000
commitc781a243a3d17e7e763515794168d8fa6043f565 (patch)
treedcaf1b9201cdb221cb2206858891575d2b241bbb /include/llvm/CodeGen/LiveStackAnalysis.h
parent87e3caf81939db20d2359bd38df2ed206040026d (diff)
downloadllvm-c781a243a3d17e7e763515794168d8fa6043f565.tar.gz
llvm-c781a243a3d17e7e763515794168d8fa6043f565.tar.bz2
llvm-c781a243a3d17e7e763515794168d8fa6043f565.tar.xz
In some rare cases, the register allocator can spill registers but end up not utilizing registers at all. The fundamental problem is linearscan's backtracking can end up freeing more than one allocated registers. However, reloads and restores might be folded into uses / defs and freed registers might not be used at all.
VirtRegMap keeps track of allocations so it knows what's not used. As a horrible hack, the stack coloring can color spill slots with *free* registers. That is, it replace reload and spills with copies from and to the free register. It unfold instructions that load and store the spill slot and replace them with register using variants. Not yet enabled. This is part 1. More coming. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70787 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/CodeGen/LiveStackAnalysis.h')
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h59
1 files changed, 41 insertions, 18 deletions
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index 7cb4151e87..a2a2f93df3 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -18,6 +18,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Allocator.h"
#include <map>
@@ -28,44 +29,66 @@ namespace llvm {
///
BumpPtrAllocator VNInfoAllocator;
- /// s2iMap - Stack slot indices to live interval mapping.
+ /// S2IMap - Stack slot indices to live interval mapping.
///
typedef std::map<int, LiveInterval> SS2IntervalMap;
- SS2IntervalMap s2iMap;
+ SS2IntervalMap S2IMap;
+ /// S2RCMap - Stack slot indices to register class mapping.
+ std::map<int, const TargetRegisterClass*> S2RCMap;
+
public:
static char ID; // Pass identification, replacement for typeid
LiveStacks() : MachineFunctionPass(&ID) {}
typedef SS2IntervalMap::iterator iterator;
typedef SS2IntervalMap::const_iterator const_iterator;
- const_iterator begin() const { return s2iMap.begin(); }
- const_iterator end() const { return s2iMap.end(); }
- iterator begin() { return s2iMap.begin(); }
- iterator end() { return s2iMap.end(); }
- unsigned getNumIntervals() const { return (unsigned)s2iMap.size(); }
-
- LiveInterval &getOrCreateInterval(int Slot) {
- SS2IntervalMap::iterator I = s2iMap.find(Slot);
- if (I == s2iMap.end())
- I = s2iMap.insert(I,std::make_pair(Slot,LiveInterval(Slot,0.0F,true)));
+ const_iterator begin() const { return S2IMap.begin(); }
+ const_iterator end() const { return S2IMap.end(); }
+ iterator begin() { return S2IMap.begin(); }
+ iterator end() { return S2IMap.end(); }
+
+ unsigned getNumIntervals() const { return (unsigned)S2IMap.size(); }
+
+ LiveInterval &getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ SS2IntervalMap::iterator I = S2IMap.find(Slot);
+ if (I == S2IMap.end()) {
+ I = S2IMap.insert(I,std::make_pair(Slot, LiveInterval(Slot,0.0F,true)));
+ S2RCMap.insert(std::make_pair(Slot, RC));
+ } else {
+ // Use the largest common subclass register class.
+ const TargetRegisterClass *OldRC = S2RCMap[Slot];
+ S2RCMap[Slot] = getCommonSubClass(OldRC, RC);
+ }
return I->second;
}
LiveInterval &getInterval(int Slot) {
- SS2IntervalMap::iterator I = s2iMap.find(Slot);
- assert(I != s2iMap.end() && "Interval does not exist for stack slot");
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ SS2IntervalMap::iterator I = S2IMap.find(Slot);
+ assert(I != S2IMap.end() && "Interval does not exist for stack slot");
return I->second;
}
const LiveInterval &getInterval(int Slot) const {
- SS2IntervalMap::const_iterator I = s2iMap.find(Slot);
- assert(I != s2iMap.end() && "Interval does not exist for stack slot");
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ SS2IntervalMap::const_iterator I = S2IMap.find(Slot);
+ assert(I != S2IMap.end() && "Interval does not exist for stack slot");
return I->second;
}
- bool hasInterval(unsigned Slot) const {
- return s2iMap.count(Slot);
+ bool hasInterval(int Slot) const {
+ return S2IMap.count(Slot);
+ }
+
+ const TargetRegisterClass *getIntervalRegClass(int Slot) const {
+ assert(Slot >= 0 && "Spill slot indice must be >= 0");
+ std::map<int, const TargetRegisterClass*>::const_iterator
+ I = S2RCMap.find(Slot);
+ assert(I != S2RCMap.end() &&
+ "Register class info does not exist for stack slot");
+ return I->second;
}
BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; }