mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-16 12:24:03 +00:00
Use IntEqClasses to compute connected components of live intervals.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122296 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -39,13 +39,20 @@ class IntEqClasses {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
|
/// IntEqClasses - Create an equivalence class mapping for 0 .. N-1.
|
||||||
IntEqClasses(unsigned N) : NumClasses(0) { grow(N); }
|
IntEqClasses(unsigned N = 0) : NumClasses(0) { grow(N); }
|
||||||
|
|
||||||
/// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
|
/// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
|
||||||
/// equivalence classes.
|
/// equivalence classes.
|
||||||
/// This requires an uncompressed map.
|
/// This requires an uncompressed map.
|
||||||
void grow(unsigned N);
|
void grow(unsigned N);
|
||||||
|
|
||||||
|
/// clear - Clear all classes so that grow() will assign a unique class to
|
||||||
|
/// every integer.
|
||||||
|
void clear() {
|
||||||
|
EC.clear();
|
||||||
|
NumClasses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// join - Join the equivalence classes of a and b. After joining classes,
|
/// join - Join the equivalence classes of a and b. After joining classes,
|
||||||
/// findLeader(a) == findLeader(b).
|
/// findLeader(a) == findLeader(b).
|
||||||
/// This requires an uncompressed map.
|
/// This requires an uncompressed map.
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
|
#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
|
||||||
#define LLVM_CODEGEN_LIVEINTERVAL_H
|
#define LLVM_CODEGEN_LIVEINTERVAL_H
|
||||||
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/IntEqClasses.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
#include "llvm/Support/AlignOf.h"
|
#include "llvm/Support/AlignOf.h"
|
||||||
#include "llvm/CodeGen/SlotIndexes.h"
|
#include "llvm/CodeGen/SlotIndexes.h"
|
||||||
@ -561,11 +561,7 @@ namespace llvm {
|
|||||||
|
|
||||||
class ConnectedVNInfoEqClasses {
|
class ConnectedVNInfoEqClasses {
|
||||||
LiveIntervals &lis_;
|
LiveIntervals &lis_;
|
||||||
|
IntEqClasses eqClass_;
|
||||||
// Map each value number to its equivalence class.
|
|
||||||
// The invariant is that EqClass[x] <= x.
|
|
||||||
// Two values are connected iff EqClass[x] == EqClass[b].
|
|
||||||
SmallVector<unsigned, 8> eqClass_;
|
|
||||||
|
|
||||||
// Note that values a and b are connected.
|
// Note that values a and b are connected.
|
||||||
void Connect(unsigned a, unsigned b);
|
void Connect(unsigned a, unsigned b);
|
||||||
|
@ -703,42 +703,10 @@ void LiveRange::print(raw_ostream &os) const {
|
|||||||
os << *this;
|
os << *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a
|
|
||||||
/// LiveInterval into equivalence clases of connected components. A
|
|
||||||
/// LiveInterval that has multiple connected components can be broken into
|
|
||||||
/// multiple LiveIntervals.
|
|
||||||
|
|
||||||
void ConnectedVNInfoEqClasses::Connect(unsigned a, unsigned b) {
|
|
||||||
while (eqClass_[a] != eqClass_[b]) {
|
|
||||||
if (eqClass_[a] > eqClass_[b])
|
|
||||||
std::swap(a, b);
|
|
||||||
unsigned t = eqClass_[b];
|
|
||||||
assert(t <= b && "Invariant broken");
|
|
||||||
eqClass_[b] = eqClass_[a];
|
|
||||||
b = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ConnectedVNInfoEqClasses::Renumber() {
|
|
||||||
// Assign final class numbers.
|
|
||||||
// We use the fact that eqClass_[i] == i for class leaders.
|
|
||||||
// For others, eqClass_[i] points to an earlier value in the same class.
|
|
||||||
unsigned count = 0;
|
|
||||||
for (unsigned i = 0, e = eqClass_.size(); i != e; ++i) {
|
|
||||||
unsigned q = eqClass_[i];
|
|
||||||
assert(q <= i && "Invariant broken");
|
|
||||||
eqClass_[i] = q == i ? count++ : eqClass_[q];
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
||||||
// Create initial equivalence classes.
|
// Create initial equivalence classes.
|
||||||
eqClass_.clear();
|
eqClass_.clear();
|
||||||
eqClass_.reserve(LI->getNumValNums());
|
eqClass_.grow(LI->getNumValNums());
|
||||||
for (unsigned i = 0, e = LI->getNumValNums(); i != e; ++i)
|
|
||||||
eqClass_.push_back(i);
|
|
||||||
|
|
||||||
const VNInfo *used = 0, *unused = 0;
|
const VNInfo *used = 0, *unused = 0;
|
||||||
|
|
||||||
@ -749,7 +717,7 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
|||||||
// Group all unused values into one class.
|
// Group all unused values into one class.
|
||||||
if (VNI->isUnused()) {
|
if (VNI->isUnused()) {
|
||||||
if (unused)
|
if (unused)
|
||||||
Connect(unused->id, VNI->id);
|
eqClass_.join(unused->id, VNI->id);
|
||||||
unused = VNI;
|
unused = VNI;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -762,36 +730,28 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
|||||||
PE = MBB->pred_end(); PI != PE; ++PI)
|
PE = MBB->pred_end(); PI != PE; ++PI)
|
||||||
if (const VNInfo *PVNI =
|
if (const VNInfo *PVNI =
|
||||||
LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot()))
|
LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot()))
|
||||||
Connect(VNI->id, PVNI->id);
|
eqClass_.join(VNI->id, PVNI->id);
|
||||||
} else {
|
} else {
|
||||||
// Normal value defined by an instruction. Check for two-addr redef.
|
// Normal value defined by an instruction. Check for two-addr redef.
|
||||||
// FIXME: This could be coincidental. Should we really check for a tied
|
// FIXME: This could be coincidental. Should we really check for a tied
|
||||||
// operand constraint?
|
// operand constraint?
|
||||||
if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getUseIndex()))
|
// Note that VNI->def may be a use slot for an early clobber def.
|
||||||
Connect(VNI->id, UVNI->id);
|
if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot()))
|
||||||
|
eqClass_.join(VNI->id, UVNI->id);
|
||||||
// Check for a tied operand constraint involving an early clobber def,
|
|
||||||
// where one VN ends right before the use index and the next VN is defined
|
|
||||||
// at the same use index.
|
|
||||||
if (VNI->def.isUse()) {
|
|
||||||
if (const VNInfo *PVNI = LI->getVNInfoAt(VNI->def.getLoadIndex()))
|
|
||||||
Connect(PVNI->id, VNI->id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lump all the unused values in with the last used value.
|
// Lump all the unused values in with the last used value.
|
||||||
if (used && unused)
|
if (used && unused)
|
||||||
Connect(used->id, unused->id);
|
eqClass_.join(used->id, unused->id);
|
||||||
|
|
||||||
return Renumber();
|
eqClass_.compress();
|
||||||
|
return eqClass_.getNumClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) {
|
void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) {
|
||||||
assert(LIV[0] && "LIV[0] must be set");
|
assert(LIV[0] && "LIV[0] must be set");
|
||||||
LiveInterval &LI = *LIV[0];
|
LiveInterval &LI = *LIV[0];
|
||||||
// Check that they likely ran Classify() on LIV[0] first.
|
|
||||||
assert(eqClass_.size() == LI.getNumValNums() && "Bad classification data");
|
|
||||||
|
|
||||||
// First move runs to new intervals.
|
// First move runs to new intervals.
|
||||||
LiveInterval::iterator J = LI.begin(), E = LI.end();
|
LiveInterval::iterator J = LI.begin(), E = LI.end();
|
||||||
|
@ -24,6 +24,7 @@ using namespace llvm;
|
|||||||
|
|
||||||
void IntEqClasses::grow(unsigned N) {
|
void IntEqClasses::grow(unsigned N) {
|
||||||
assert(NumClasses == 0 && "grow() called after compress().");
|
assert(NumClasses == 0 && "grow() called after compress().");
|
||||||
|
EC.reserve(N);
|
||||||
while (EC.size() < N)
|
while (EC.size() < N)
|
||||||
EC.push_back(EC.size());
|
EC.push_back(EC.size());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user