aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/VirtRegMap.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 /lib/CodeGen/VirtRegMap.h
parent87e3caf81939db20d2359bd38df2ed206040026d (diff)
downloadexternal_llvm-c781a243a3d17e7e763515794168d8fa6043f565.zip
external_llvm-c781a243a3d17e7e763515794168d8fa6043f565.tar.gz
external_llvm-c781a243a3d17e7e763515794168d8fa6043f565.tar.bz2
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 'lib/CodeGen/VirtRegMap.h')
-rw-r--r--lib/CodeGen/VirtRegMap.h55
1 files changed, 49 insertions, 6 deletions
diff --git a/lib/CodeGen/VirtRegMap.h b/lib/CodeGen/VirtRegMap.h
index 2e9c899..91c8322 100644
--- a/lib/CodeGen/VirtRegMap.h
+++ b/lib/CodeGen/VirtRegMap.h
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -27,6 +28,7 @@
#include <map>
namespace llvm {
+ class LiveIntervals;
class MachineInstr;
class MachineFunction;
class TargetInstrInfo;
@@ -122,6 +124,9 @@ namespace llvm {
/// the register is implicitly defined.
BitVector ImplicitDefed;
+ /// UnusedRegs - A list of physical registers that have not been used.
+ BitVector UnusedRegs;
+
VirtRegMap(const VirtRegMap&); // DO NOT IMPLEMENT
void operator=(const VirtRegMap&); // DO NOT IMPLEMENT
@@ -277,8 +282,10 @@ namespace llvm {
/// @brief records the specified MachineInstr as a spill point for virtReg.
void addSpillPoint(unsigned virtReg, bool isKill, MachineInstr *Pt) {
- if (SpillPt2VirtMap.find(Pt) != SpillPt2VirtMap.end())
- SpillPt2VirtMap[Pt].push_back(std::make_pair(virtReg, isKill));
+ std::map<MachineInstr*, std::vector<std::pair<unsigned,bool> > >::iterator
+ I = SpillPt2VirtMap.find(Pt);
+ if (I != SpillPt2VirtMap.end())
+ I->second.push_back(std::make_pair(virtReg, isKill));
else {
std::vector<std::pair<unsigned,bool> > Virts;
Virts.push_back(std::make_pair(virtReg, isKill));
@@ -289,7 +296,7 @@ namespace llvm {
/// @brief - transfer spill point information from one instruction to
/// another.
void transferSpillPts(MachineInstr *Old, MachineInstr *New) {
- std::map<MachineInstr*,std::vector<std::pair<unsigned,bool> > >::iterator
+ std::map<MachineInstr*, std::vector<std::pair<unsigned,bool> > >::iterator
I = SpillPt2VirtMap.find(Old);
if (I == SpillPt2VirtMap.end())
return;
@@ -315,8 +322,10 @@ namespace llvm {
/// @brief records the specified MachineInstr as a restore point for virtReg.
void addRestorePoint(unsigned virtReg, MachineInstr *Pt) {
- if (RestorePt2VirtMap.find(Pt) != RestorePt2VirtMap.end())
- RestorePt2VirtMap[Pt].push_back(virtReg);
+ std::map<MachineInstr*, std::vector<unsigned> >::iterator I =
+ RestorePt2VirtMap.find(Pt);
+ if (I != RestorePt2VirtMap.end())
+ I->second.push_back(virtReg);
else {
std::vector<unsigned> Virts;
Virts.push_back(virtReg);
@@ -327,7 +336,7 @@ namespace llvm {
/// @brief - transfer restore point information from one instruction to
/// another.
void transferRestorePts(MachineInstr *Old, MachineInstr *New) {
- std::map<MachineInstr*,std::vector<unsigned> >::iterator I =
+ std::map<MachineInstr*, std::vector<unsigned> >::iterator I =
RestorePt2VirtMap.find(Old);
if (I == RestorePt2VirtMap.end())
return;
@@ -430,6 +439,40 @@ namespace llvm {
/// the folded instruction map and spill point map.
void RemoveMachineInstrFromMaps(MachineInstr *MI);
+ /// FindUnusedRegisters - Gather a list of allocatable registers that
+ /// have not been allocated to any virtual register.
+ bool FindUnusedRegisters(const TargetRegisterInfo *TRI,
+ LiveIntervals* LIs);
+
+ /// HasUnusedRegisters - Return true if there are any allocatable registers
+ /// that have not been allocated to any virtual register.
+ bool HasUnusedRegisters() const {
+ return !UnusedRegs.none();
+ }
+
+ /// setRegisterUsed - Remember the physical register is now used.
+ void setRegisterUsed(unsigned Reg) {
+ UnusedRegs.reset(Reg);
+ }
+
+ /// isRegisterUnused - Return true if the physical register has not been
+ /// used.
+ bool isRegisterUnused(unsigned Reg) const {
+ return UnusedRegs[Reg];
+ }
+
+ /// getFirstUnusedRegister - Return the first physical register that has not
+ /// been used.
+ unsigned getFirstUnusedRegister(const TargetRegisterClass *RC) {
+ int Reg = UnusedRegs.find_first();
+ while (Reg != -1) {
+ if (RC->contains(Reg))
+ return (unsigned)Reg;
+ Reg = UnusedRegs.find_next(Reg);
+ }
+ return 0;
+ }
+
void print(std::ostream &OS, const Module* M = 0) const;
void print(std::ostream *OS) const { if (OS) print(*OS); }
void dump() const;