mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-22 00:37:49 +00:00
PR1255: case ranges.
IntegersSubsetGeneric, IntegersSubsetMapping: added IntTy template parameter, that allows use either APInt or IntItem. This change allows to write unittest for these classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157880 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
be4258adc5
commit
4319a552ac
include/llvm/Support
lib/CodeGen/SelectionDAG
@ -171,39 +171,40 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: it should be a class in next commit.
|
||||
template<class IntType>
|
||||
struct IntRange {
|
||||
|
||||
IntItem Low;
|
||||
IntItem High;
|
||||
typedef IntRange<IntType> self;
|
||||
IntType Low;
|
||||
IntType High;
|
||||
bool IsEmpty : 1;
|
||||
bool IsSingleNumber : 1;
|
||||
// TODO:
|
||||
// public:
|
||||
|
||||
typedef std::pair<IntRange, IntRange> SubRes;
|
||||
typedef std::pair<self, self> SubRes;
|
||||
|
||||
IntRange() : IsEmpty(true) {}
|
||||
IntRange(const IntRange &RHS) :
|
||||
IntRange(const self &RHS) :
|
||||
Low(RHS.Low), High(RHS.High), IsEmpty(false), IsSingleNumber(false) {}
|
||||
IntRange(const IntItem &C) :
|
||||
IntRange(const IntType &C) :
|
||||
Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
|
||||
IntRange(const IntItem &L, const IntItem &H) : Low(L), High(H),
|
||||
IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
|
||||
IsEmpty(false), IsSingleNumber(false) {}
|
||||
|
||||
bool isEmpty() const { return IsEmpty; }
|
||||
bool isSingleNumber() const { return IsSingleNumber; }
|
||||
|
||||
const IntItem& getLow() {
|
||||
const IntType& getLow() {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return Low;
|
||||
}
|
||||
const IntItem& getHigh() {
|
||||
const IntType& getHigh() {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return High;
|
||||
}
|
||||
|
||||
bool operator<(const IntRange &RHS) const {
|
||||
bool operator<(const self &RHS) const {
|
||||
assert(!IsEmpty && "Left range is empty.");
|
||||
assert(!RHS.IsEmpty && "Right range is empty.");
|
||||
if (Low == RHS.Low) {
|
||||
@ -216,26 +217,26 @@ struct IntRange {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const IntRange &RHS) const {
|
||||
bool operator==(const self &RHS) const {
|
||||
assert(!IsEmpty && "Left range is empty.");
|
||||
assert(!RHS.IsEmpty && "Right range is empty.");
|
||||
return Low == RHS.Low && High == RHS.High;
|
||||
}
|
||||
|
||||
bool operator!=(const IntRange &RHS) const {
|
||||
bool operator!=(const self &RHS) const {
|
||||
return !operator ==(RHS);
|
||||
}
|
||||
|
||||
static bool LessBySize(const IntRange &LHS, const IntRange &RHS) {
|
||||
static bool LessBySize(const self &LHS, const self &RHS) {
|
||||
return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
|
||||
}
|
||||
|
||||
bool isInRange(const IntItem &IntVal) const {
|
||||
bool isInRange(const IntType &IntVal) const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return IntVal >= Low && IntVal <= High;
|
||||
}
|
||||
|
||||
SubRes sub(const IntRange &RHS) const {
|
||||
SubRes sub(const self &RHS) const {
|
||||
SubRes Res;
|
||||
|
||||
// RHS is either more global and includes this range or
|
||||
@ -245,19 +246,19 @@ struct IntRange {
|
||||
// If RHS more global (it is enough to check
|
||||
// only one border in this case.
|
||||
if (RHS.isInRange(Low))
|
||||
return std::make_pair(IntRange(Low, High), IntRange());
|
||||
return std::make_pair(self(Low, High), self());
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
if (Low < RHS.Low) {
|
||||
Res.first.Low = Low;
|
||||
IntItem NewHigh = RHS.Low;
|
||||
IntType NewHigh = RHS.Low;
|
||||
--NewHigh;
|
||||
Res.first.High = NewHigh;
|
||||
}
|
||||
if (High > RHS.High) {
|
||||
IntItem NewLow = RHS.High;
|
||||
IntType NewLow = RHS.High;
|
||||
++NewLow;
|
||||
Res.second.Low = NewLow;
|
||||
Res.second.High = High;
|
||||
@ -269,6 +270,7 @@ struct IntRange {
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// IntegersSubsetGeneric - class that implements the subset of integers. It
|
||||
/// consists from ranges and single numbers.
|
||||
template <class IntTy>
|
||||
class IntegersSubsetGeneric {
|
||||
public:
|
||||
// Use Chris Lattner idea, that was initially described here:
|
||||
@ -276,10 +278,10 @@ public:
|
||||
// In short, for more compact memory consumption we can store flat
|
||||
// numbers collection, and define range as pair of indices.
|
||||
// In that case we can safe some memory on 32 bit machines.
|
||||
typedef std::list<IntItem> FlatCollectionTy;
|
||||
typedef std::pair<IntItem*, IntItem*> RangeLinkTy;
|
||||
typedef std::list<IntTy> FlatCollectionTy;
|
||||
typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
|
||||
typedef SmallVector<RangeLinkTy, 64> RangeLinksTy;
|
||||
typedef RangeLinksTy::iterator RangeLinksConstIt;
|
||||
typedef typename RangeLinksTy::iterator RangeLinksConstIt;
|
||||
|
||||
protected:
|
||||
|
||||
@ -303,12 +305,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
typedef IntRange Range;
|
||||
typedef IntRange<IntTy> Range;
|
||||
|
||||
/// Checks is the given constant satisfies this case. Returns
|
||||
/// true if it equals to one of contained values or belongs to the one of
|
||||
/// contained ranges.
|
||||
bool isSatisfies(const IntItem &CheckingVal) const {
|
||||
bool isSatisfies(const IntTy &CheckingVal) const {
|
||||
for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
|
||||
if (RangeLinks[i].first == RangeLinks[i].second) {
|
||||
if (*RangeLinks[i].first == CheckingVal)
|
||||
@ -381,9 +383,9 @@ public:
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// IntegersSubset - currenly is extension of IntegersSubsetGeneric
|
||||
/// IntegersSubset - currently is extension of IntegersSubsetGeneric
|
||||
/// that also supports conversion to/from Constant* object.
|
||||
class IntegersSubset : public IntegersSubsetGeneric {
|
||||
class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
|
||||
Constant *Holder;
|
||||
|
||||
static unsigned getNumItemsFromConstant(Constant *C) {
|
||||
|
@ -26,19 +26,20 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <class SuccessorClass, class IntegersSubsetTy>
|
||||
template <class SuccessorClass,
|
||||
class IntegersSubsetTy = IntegersSubset,
|
||||
class IntTy = IntItem>
|
||||
class IntegersSubsetMapping {
|
||||
public:
|
||||
|
||||
typedef IntRange RangeTy;
|
||||
typedef IntRange<IntTy> RangeTy;
|
||||
|
||||
struct RangeEx : public RangeTy {
|
||||
typedef IntRange RangeTy;
|
||||
RangeEx() : Weight(1) {}
|
||||
RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {}
|
||||
RangeEx(const IntItem &C) : RangeTy(C), Weight(1) {}
|
||||
RangeEx(const IntItem &L, const IntItem &H) : RangeTy(L, H), Weight(1) {}
|
||||
RangeEx(const IntItem &L, const IntItem &H, unsigned W) :
|
||||
RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
|
||||
RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
|
||||
RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
|
||||
RangeTy(L, H), Weight(W) {}
|
||||
unsigned Weight;
|
||||
};
|
||||
@ -125,14 +126,14 @@ public:
|
||||
sort();
|
||||
CaseItems OldItems = Items;
|
||||
Items.clear();
|
||||
IntItem *Low = &OldItems.begin()->first.Low;
|
||||
IntItem *High = &OldItems.begin()->first.High;
|
||||
IntTy *Low = &OldItems.begin()->first.Low;
|
||||
IntTy *High = &OldItems.begin()->first.High;
|
||||
unsigned Weight = 1;
|
||||
SuccessorClass *Successor = OldItems.begin()->second;
|
||||
for (CaseItemIt i = OldItems.begin(), j = i+1, e = OldItems.end();
|
||||
j != e; i = j++) {
|
||||
if (isJoinable(i, j)) {
|
||||
IntItem *CurHigh = &j->first.High;
|
||||
IntTy *CurHigh = &j->first.High;
|
||||
++Weight;
|
||||
if (*CurHigh > *High)
|
||||
High = CurHigh;
|
||||
@ -152,13 +153,13 @@ public:
|
||||
}
|
||||
|
||||
/// Adds a constant value.
|
||||
void add(const IntItem &C, SuccessorClass *S = 0) {
|
||||
void add(const IntTy &C, SuccessorClass *S = 0) {
|
||||
RangeTy R(C);
|
||||
add(R, S);
|
||||
}
|
||||
|
||||
/// Adds a range.
|
||||
void add(const IntItem &Low, const IntItem &High, SuccessorClass *S = 0) {
|
||||
void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
|
||||
RangeTy R(Low, High);
|
||||
add(R, S);
|
||||
}
|
||||
@ -209,7 +210,7 @@ public:
|
||||
};
|
||||
|
||||
class BasicBlock;
|
||||
typedef IntegersSubsetMapping<BasicBlock, IntegersSubset> IntegersSubsetToBB;
|
||||
typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
|
||||
|
||||
}
|
||||
|
||||
|
@ -2427,7 +2427,7 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
|
||||
|
||||
/// Use a shorter form of declaration, and also
|
||||
/// show the we want to use CRSBuilder as Clusterifier.
|
||||
typedef IntegersSubsetMapping<MachineBasicBlock, IntegersSubset> Clusterifier;
|
||||
typedef IntegersSubsetMapping<MachineBasicBlock> Clusterifier;
|
||||
|
||||
Clusterifier TheClusterifier;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user