mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 02:33:33 +00:00
PR1255: case ranges.
IntRange converted from struct to class. So main change everywhere is replacement of ".Low/High" with ".getLow/getHigh()" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0fa2b7b90d
commit
43eb31bfae
@ -2660,7 +2660,7 @@ public:
|
||||
|
||||
// FIXME: Currently we work with ConstantInt based cases.
|
||||
// So return CaseValue as ConstantInt.
|
||||
return R.Low.toConstantInt();
|
||||
return R.getLow().toConstantInt();
|
||||
}
|
||||
|
||||
/// Resolves case value for current case.
|
||||
|
@ -172,34 +172,33 @@ public:
|
||||
};
|
||||
|
||||
template<class IntType>
|
||||
struct IntRange {
|
||||
|
||||
typedef IntRange<IntType> self;
|
||||
class IntRange {
|
||||
protected:
|
||||
IntType Low;
|
||||
IntType High;
|
||||
bool IsEmpty : 1;
|
||||
bool IsSingleNumber : 1;
|
||||
// TODO:
|
||||
// public:
|
||||
|
||||
|
||||
public:
|
||||
typedef IntRange<IntType> self;
|
||||
typedef std::pair<self, self> SubRes;
|
||||
|
||||
IntRange() : IsEmpty(true) {}
|
||||
IntRange(const self &RHS) :
|
||||
Low(RHS.Low), High(RHS.High), IsEmpty(false), IsSingleNumber(false) {}
|
||||
|
||||
IntRange(const IntType &C) :
|
||||
Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
|
||||
|
||||
IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
|
||||
IsEmpty(false), IsSingleNumber(false) {}
|
||||
IsEmpty(false), IsSingleNumber(Low == High) {}
|
||||
|
||||
bool isEmpty() const { return IsEmpty; }
|
||||
bool isSingleNumber() const { return IsSingleNumber; }
|
||||
|
||||
const IntType& getLow() {
|
||||
const IntType& getLow() const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return Low;
|
||||
}
|
||||
const IntType& getHigh() {
|
||||
const IntType& getHigh() const {
|
||||
assert(!IsEmpty && "Range is empty.");
|
||||
return High;
|
||||
}
|
||||
@ -296,10 +295,10 @@ public:
|
||||
for (typename RangesCollectionTy::const_iterator i = Links.begin(),
|
||||
e = Links.end(); i != e; ++i) {
|
||||
RangeLinkTy RangeLink;
|
||||
FlatCollection.push_back(i->Low);
|
||||
FlatCollection.push_back(i->getLow());
|
||||
RangeLink.first = &FlatCollection.back();
|
||||
if (i->Low != i->High)
|
||||
FlatCollection.push_back(i->High);
|
||||
if (i->getLow() != i->getHigh())
|
||||
FlatCollection.push_back(i->getHigh());
|
||||
RangeLink.second = &FlatCollection.back();
|
||||
RangeLinks.push_back(RangeLink);
|
||||
}
|
||||
@ -336,10 +335,17 @@ public:
|
||||
return RangeLinks.size();
|
||||
}
|
||||
|
||||
bool isSingleNumber(unsigned idx) const {
|
||||
/// Returns true if whole subset contains single element.
|
||||
bool isSingleNumber() const {
|
||||
return RangeLinks.size() == 1 &&
|
||||
RangeLinks[0].first == RangeLinks[0].second;
|
||||
}
|
||||
|
||||
/// Does the same like getItem(idx).isSingleNumber(), but
|
||||
/// works faster, since we avoid creation of temporary range object.
|
||||
bool isSingleNumber(unsigned idx) const {
|
||||
return RangeLinks[idx].first == RangeLinks[idx].second;
|
||||
}
|
||||
|
||||
/// Returns set the size, that equals number of all values + sizes of all
|
||||
/// ranges.
|
||||
@ -347,10 +353,10 @@ public:
|
||||
/// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
|
||||
/// for range [<0>, <1>, <5>] the size will 3
|
||||
unsigned getSize() const {
|
||||
APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0);
|
||||
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
|
||||
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
|
||||
const APInt &Low = getItem(i).Low;
|
||||
const APInt &High = getItem(i).High;
|
||||
const APInt &Low = getItem(i).getLow();
|
||||
const APInt &High = getItem(i).getHigh();
|
||||
const APInt &S = High - Low;
|
||||
sz += S;
|
||||
}
|
||||
@ -362,10 +368,10 @@ public:
|
||||
/// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
|
||||
/// For range [<1>, <4,8>] getSingleValue(3) returns 6.
|
||||
APInt getSingleValue(unsigned idx) const {
|
||||
APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0);
|
||||
APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
|
||||
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
|
||||
const APInt &Low = getItem(i).Low;
|
||||
const APInt &High = getItem(i).High;
|
||||
const APInt &Low = getItem(i).getLow();
|
||||
const APInt &High = getItem(i).getHigh();
|
||||
const APInt& S = High - Low;
|
||||
APInt oldSz = sz;
|
||||
sz += S;
|
||||
@ -439,15 +445,15 @@ public:
|
||||
e = Src.end(); i != e; ++i) {
|
||||
const Range &R = *i;
|
||||
std::vector<Constant*> r;
|
||||
if (R.Low != R.High) {
|
||||
if (R.isSingleNumber()) {
|
||||
r.reserve(2);
|
||||
// FIXME: Since currently we have ConstantInt based numbers
|
||||
// use hack-conversion of IntItem to ConstantInt
|
||||
r.push_back(R.Low.toConstantInt());
|
||||
r.push_back(R.High.toConstantInt());
|
||||
r.push_back(R.getLow().toConstantInt());
|
||||
r.push_back(R.getHigh().toConstantInt());
|
||||
} else {
|
||||
r.reserve(1);
|
||||
r.push_back(R.Low.toConstantInt());
|
||||
r.push_back(R.getLow().toConstantInt());
|
||||
}
|
||||
Constant *CV = ConstantVector::get(r);
|
||||
Elts.push_back(CV);
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
struct RangeEx : public RangeTy {
|
||||
RangeEx() : Weight(1) {}
|
||||
RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {}
|
||||
RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
|
||||
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) :
|
||||
@ -68,7 +68,7 @@ protected:
|
||||
bool Sorted;
|
||||
|
||||
bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
|
||||
return LItem->first.High >= RItem->first.Low;
|
||||
return LItem->first.getHigh() >= RItem->first.getLow();
|
||||
}
|
||||
|
||||
bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
|
||||
@ -77,10 +77,10 @@ protected:
|
||||
"Intersected items with different successors!");
|
||||
return false;
|
||||
}
|
||||
APInt RLow = RItem->first.Low;
|
||||
APInt RLow = RItem->first.getLow();
|
||||
if (RLow != APInt::getNullValue(RLow.getBitWidth()))
|
||||
--RLow;
|
||||
return LItem->first.High >= RLow;
|
||||
return LItem->first.getHigh() >= RLow;
|
||||
}
|
||||
|
||||
void sort() {
|
||||
@ -126,22 +126,22 @@ public:
|
||||
sort();
|
||||
CaseItems OldItems = Items;
|
||||
Items.clear();
|
||||
IntTy *Low = &OldItems.begin()->first.Low;
|
||||
IntTy *High = &OldItems.begin()->first.High;
|
||||
const IntTy *Low = &OldItems.begin()->first.getLow();
|
||||
const IntTy *High = &OldItems.begin()->first.getHigh();
|
||||
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)) {
|
||||
IntTy *CurHigh = &j->first.High;
|
||||
const IntTy *CurHigh = &j->first.getHigh();
|
||||
++Weight;
|
||||
if (*CurHigh > *High)
|
||||
High = CurHigh;
|
||||
} else {
|
||||
RangeEx R(*Low, *High, Weight);
|
||||
add(R, Successor);
|
||||
Low = &j->first.Low;
|
||||
High = &j->first.High;
|
||||
Low = &j->first.getLow();
|
||||
High = &j->first.getHigh();
|
||||
Weight = 1;
|
||||
Successor = j->second;
|
||||
}
|
||||
|
@ -1161,16 +1161,15 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||
Vals64.push_back(CaseRanges.getNumItems());
|
||||
for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
|
||||
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
||||
bool IsSingleNumber = r.isSingleNumber();
|
||||
|
||||
Vals64.push_back(CaseRanges.isSingleNumber(ri));
|
||||
Vals64.push_back(IsSingleNumber);
|
||||
|
||||
const APInt &Low = r.Low;
|
||||
const APInt &High = r.High;
|
||||
unsigned Code, Abbrev; // will unused.
|
||||
|
||||
EmitAPInt(Vals64, Code, Abbrev, Low, true);
|
||||
if (r.Low != r.High)
|
||||
EmitAPInt(Vals64, Code, Abbrev, High, true);
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
|
||||
if (!IsSingleNumber)
|
||||
EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
|
||||
}
|
||||
Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
|
||||
}
|
||||
|
@ -2458,10 +2458,10 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
|
||||
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
// Changing it to APInt based is a pretty heavy for this commit.
|
||||
Cases.push_back(Case(C.first.Low.toConstantInt(),
|
||||
C.first.High.toConstantInt(), C.second, W));
|
||||
Cases.push_back(Case(C.first.getLow().toConstantInt(),
|
||||
C.first.getHigh().toConstantInt(), C.second, W));
|
||||
|
||||
if (C.first.Low != C.first.High)
|
||||
if (C.first.getLow() != C.first.getHigh())
|
||||
// A range counts double, since it requires two compares.
|
||||
++numCmps;
|
||||
}
|
||||
|
@ -655,8 +655,8 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
|
||||
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
|
||||
IntegersSubset::Range r = Case.getItem(n);
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
const ConstantInt *LowCI = r.Low.toConstantInt();
|
||||
const ConstantInt *HighCI = r.High.toConstantInt();
|
||||
const ConstantInt *LowCI = r.getLow().toConstantInt();
|
||||
const ConstantInt *HighCI = r.getHigh().toConstantInt();
|
||||
GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
|
||||
GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
|
||||
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
|
||||
|
@ -173,7 +173,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
|
||||
if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) {
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
|
||||
CaseRanges.getItem(0).Low.toConstantInt(),
|
||||
CaseRanges.getItem(0).getLow().toConstantInt(),
|
||||
"cond");
|
||||
|
||||
// Insert the new branch.
|
||||
|
@ -242,9 +242,9 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
|
||||
|
||||
// FIXME: Currently work with ConstantInt based numbers.
|
||||
// Changing it to APInt based is a pretty heavy for this commit.
|
||||
Cases.push_back(CaseRange(C.first.Low.toConstantInt(),
|
||||
C.first.High.toConstantInt(), C.second));
|
||||
if (C.first.Low != C.first.High)
|
||||
Cases.push_back(CaseRange(C.first.getLow().toConstantInt(),
|
||||
C.first.getHigh().toConstantInt(), C.second));
|
||||
if (C.first.isSingleNumber())
|
||||
// A range counts double, since it requires two compares.
|
||||
++numCmps;
|
||||
}
|
||||
|
@ -813,9 +813,9 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
|
||||
IntegersSubset CaseRanges = i.getCaseValueEx();
|
||||
for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) {
|
||||
IntegersSubset::Range r = CaseRanges.getItem(ri);
|
||||
Assert1(((const APInt&)r.Low).getBitWidth() == IntTy->getBitWidth(),
|
||||
Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(),
|
||||
"Switch constants must all be same type as switch value!", &SI);
|
||||
Assert1(((const APInt&)r.High).getBitWidth() == IntTy->getBitWidth(),
|
||||
Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(),
|
||||
"Switch constants must all be same type as switch value!", &SI);
|
||||
Mapping.add(r);
|
||||
RangeSetMap[r] = i.getCaseIndex();
|
||||
|
Loading…
x
Reference in New Issue
Block a user