mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-11 21:38:19 +00:00
Represent sentinel slot indexes with a null pointer.
This is much faster than using a pointer to a ManagedStatic object accessed with a function call. The greedy register allocator is 5% faster overall just from the SlotIndex default constructor savings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126925 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -34,77 +34,35 @@ namespace llvm {
|
|||||||
/// SlotIndex & SlotIndexes classes for the public interface to this
|
/// SlotIndex & SlotIndexes classes for the public interface to this
|
||||||
/// information.
|
/// information.
|
||||||
class IndexListEntry {
|
class IndexListEntry {
|
||||||
static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U,
|
|
||||||
TOMBSTONE_KEY_INDEX = ~0U & ~7U;
|
|
||||||
|
|
||||||
IndexListEntry *next, *prev;
|
IndexListEntry *next, *prev;
|
||||||
MachineInstr *mi;
|
MachineInstr *mi;
|
||||||
unsigned index;
|
unsigned index;
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType;
|
|
||||||
|
|
||||||
// This constructor is only to be used by getEmptyKeyEntry
|
|
||||||
// & getTombstoneKeyEntry. It sets index to the given
|
|
||||||
// value and mi to zero.
|
|
||||||
IndexListEntry(ReservedEntryType r) : mi(0) {
|
|
||||||
switch(r) {
|
|
||||||
case EMPTY_KEY: index = EMPTY_KEY_INDEX; break;
|
|
||||||
case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break;
|
|
||||||
default: assert(false && "Invalid value for constructor.");
|
|
||||||
}
|
|
||||||
next = this;
|
|
||||||
prev = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {
|
IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
|
||||||
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
|
|
||||||
"Attempt to create invalid index. "
|
|
||||||
"Available indexes may have been exhausted?.");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid() const {
|
|
||||||
return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
MachineInstr* getInstr() const { return mi; }
|
MachineInstr* getInstr() const { return mi; }
|
||||||
void setInstr(MachineInstr *mi) {
|
void setInstr(MachineInstr *mi) {
|
||||||
assert(isValid() && "Attempt to modify reserved index.");
|
|
||||||
this->mi = mi;
|
this->mi = mi;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getIndex() const { return index; }
|
unsigned getIndex() const { return index; }
|
||||||
void setIndex(unsigned index) {
|
void setIndex(unsigned index) {
|
||||||
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
|
|
||||||
"Attempt to set index to invalid value.");
|
|
||||||
assert(isValid() && "Attempt to reset reserved index value.");
|
|
||||||
this->index = index;
|
this->index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexListEntry* getNext() { return next; }
|
IndexListEntry* getNext() { return next; }
|
||||||
const IndexListEntry* getNext() const { return next; }
|
const IndexListEntry* getNext() const { return next; }
|
||||||
void setNext(IndexListEntry *next) {
|
void setNext(IndexListEntry *next) {
|
||||||
assert(isValid() && "Attempt to modify reserved index.");
|
|
||||||
this->next = next;
|
this->next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexListEntry* getPrev() { return prev; }
|
IndexListEntry* getPrev() { return prev; }
|
||||||
const IndexListEntry* getPrev() const { return prev; }
|
const IndexListEntry* getPrev() const { return prev; }
|
||||||
void setPrev(IndexListEntry *prev) {
|
void setPrev(IndexListEntry *prev) {
|
||||||
assert(isValid() && "Attempt to modify reserved index.");
|
|
||||||
this->prev = prev;
|
this->prev = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function returns the index list entry that is to be used for empty
|
|
||||||
// SlotIndex keys.
|
|
||||||
static IndexListEntry* getEmptyKeyEntry();
|
|
||||||
|
|
||||||
// This function returns the index list entry that is to be used for
|
|
||||||
// tombstone SlotIndex keys.
|
|
||||||
static IndexListEntry* getTombstoneKeyEntry();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialize PointerLikeTypeTraits for IndexListEntry.
|
// Specialize PointerLikeTypeTraits for IndexListEntry.
|
||||||
@ -130,9 +88,7 @@ namespace llvm {
|
|||||||
PointerIntPair<IndexListEntry*, 2, unsigned> lie;
|
PointerIntPair<IndexListEntry*, 2, unsigned> lie;
|
||||||
|
|
||||||
SlotIndex(IndexListEntry *entry, unsigned slot)
|
SlotIndex(IndexListEntry *entry, unsigned slot)
|
||||||
: lie(entry, slot) {
|
: lie(entry, slot) {}
|
||||||
assert(entry != 0 && "Attempt to construct index with 0 pointer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexListEntry& entry() const {
|
IndexListEntry& entry() const {
|
||||||
assert(isValid() && "Attempt to compare reserved index.");
|
assert(isValid() && "Attempt to compare reserved index.");
|
||||||
@ -149,22 +105,21 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned getHashValue(const SlotIndex &v) {
|
static inline unsigned getHashValue(const SlotIndex &v) {
|
||||||
IndexListEntry *ptrVal = &v.entry();
|
void *ptrVal = v.lie.getOpaqueValue();
|
||||||
return (unsigned((intptr_t)ptrVal) >> 4) ^
|
return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9);
|
||||||
(unsigned((intptr_t)ptrVal) >> 9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static inline SlotIndex getEmptyKey() {
|
static inline SlotIndex getEmptyKey() {
|
||||||
return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0);
|
return SlotIndex(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline SlotIndex getTombstoneKey() {
|
static inline SlotIndex getTombstoneKey() {
|
||||||
return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0);
|
return SlotIndex(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an invalid index.
|
/// Construct an invalid index.
|
||||||
SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {}
|
SlotIndex() : lie(0, 0) {}
|
||||||
|
|
||||||
// Construct a new slot index from the given one, and set the slot.
|
// Construct a new slot index from the given one, and set the slot.
|
||||||
SlotIndex(const SlotIndex &li, Slot s)
|
SlotIndex(const SlotIndex &li, Slot s)
|
||||||
@ -176,8 +131,7 @@ namespace llvm {
|
|||||||
/// Returns true if this is a valid index. Invalid indicies do
|
/// Returns true if this is a valid index. Invalid indicies do
|
||||||
/// not point into an index table, and cannot be compared.
|
/// not point into an index table, and cannot be compared.
|
||||||
bool isValid() const {
|
bool isValid() const {
|
||||||
IndexListEntry *entry = lie.getPointer();
|
return lie.getPointer();
|
||||||
return ((entry!= 0) && (entry->isValid()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print this index to the given raw_ostream.
|
/// Print this index to the given raw_ostream.
|
||||||
|
@ -13,45 +13,14 @@
|
|||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
|
||||||
// Yep - these are thread safe. See the header for details.
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyIndexListEntry : public IndexListEntry {
|
|
||||||
public:
|
|
||||||
EmptyIndexListEntry() : IndexListEntry(EMPTY_KEY) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TombstoneIndexListEntry : public IndexListEntry {
|
|
||||||
public:
|
|
||||||
TombstoneIndexListEntry() : IndexListEntry(TOMBSTONE_KEY) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The following statics are thread safe. They're read only, and you
|
|
||||||
// can't step from them to any other list entries.
|
|
||||||
ManagedStatic<EmptyIndexListEntry> IndexListEntryEmptyKey;
|
|
||||||
ManagedStatic<TombstoneIndexListEntry> IndexListEntryTombstoneKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
char SlotIndexes::ID = 0;
|
char SlotIndexes::ID = 0;
|
||||||
INITIALIZE_PASS(SlotIndexes, "slotindexes",
|
INITIALIZE_PASS(SlotIndexes, "slotindexes",
|
||||||
"Slot index numbering", false, false)
|
"Slot index numbering", false, false)
|
||||||
|
|
||||||
IndexListEntry* IndexListEntry::getEmptyKeyEntry() {
|
|
||||||
return &*IndexListEntryEmptyKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexListEntry* IndexListEntry::getTombstoneKeyEntry() {
|
|
||||||
return &*IndexListEntryTombstoneKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const {
|
void SlotIndexes::getAnalysisUsage(AnalysisUsage &au) const {
|
||||||
au.setPreservesAll();
|
au.setPreservesAll();
|
||||||
MachineFunctionPass::getAnalysisUsage(au);
|
MachineFunctionPass::getAnalysisUsage(au);
|
||||||
|
Reference in New Issue
Block a user