mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
Recommited r156374 with critical fixes in BitcodeReader/Writer:
Ordinary patch for PR1255. Added new case-ranges orientated methods for adding/removing cases in SwitchInst. After this patch cases will internally representated as ConstantArray-s instead of ConstantInt, externally cases wrapped within the ConstantRangesSet object. Old methods of SwitchInst are also works well, but marked as deprecated. So on this stage we have no side effects except that I added support for case ranges in BitcodeReader/Writer, of course test for Bitcode is also added. Old "switch" format is also supported. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156704 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -20,6 +20,8 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/Support/ConstantRangesSet.h"
|
||||
#include "llvm/Support/CRSBuilder.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@@ -2500,9 +2502,19 @@ public:
|
||||
}
|
||||
|
||||
/// Resolves case value for current case.
|
||||
/// @Deprecated
|
||||
ConstantIntTy *getCaseValue() {
|
||||
assert(Index < SI->getNumCases() && "Index out the number of cases.");
|
||||
return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
|
||||
ConstantRangesSet CRS =
|
||||
reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
|
||||
ConstantRangesSet::Range R = CRS.getItem(0);
|
||||
return R.Low;
|
||||
}
|
||||
|
||||
/// Resolves case value for current case.
|
||||
ConstantRangesSet getCaseValueEx() {
|
||||
assert(Index < SI->getNumCases() && "Index out the number of cases.");
|
||||
return reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
|
||||
}
|
||||
|
||||
/// Resolves successor for current case.
|
||||
@@ -2572,9 +2584,19 @@ public:
|
||||
CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
|
||||
|
||||
/// Sets the new value for current case.
|
||||
/// @Deprecated.
|
||||
void setValue(ConstantInt *V) {
|
||||
assert(Index < SI->getNumCases() && "Index out the number of cases.");
|
||||
SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
|
||||
CRSBuilder CB;
|
||||
CB.add(V);
|
||||
SI->setOperand(2 + Index*2,
|
||||
reinterpret_cast<Value*>((Constant*)CB.getCase()));
|
||||
}
|
||||
|
||||
/// Sets the new value for current case.
|
||||
void setValueEx(ConstantRangesSet& V) {
|
||||
assert(Index < SI->getNumCases() && "Index out the number of cases.");
|
||||
SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V));
|
||||
}
|
||||
|
||||
/// Sets the new successor for current case.
|
||||
@@ -2654,13 +2676,13 @@ public:
|
||||
/// that it is handled by the default handler.
|
||||
CaseIt findCaseValue(const ConstantInt *C) {
|
||||
for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
|
||||
if (i.getCaseValue() == C)
|
||||
if (i.getCaseValueEx().isSatisfies(C))
|
||||
return i;
|
||||
return case_default();
|
||||
}
|
||||
ConstCaseIt findCaseValue(const ConstantInt *C) const {
|
||||
for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
|
||||
if (i.getCaseValue() == C)
|
||||
if (i.getCaseValueEx().isSatisfies(C))
|
||||
return i;
|
||||
return case_default();
|
||||
}
|
||||
@@ -2681,10 +2703,17 @@ public:
|
||||
}
|
||||
|
||||
/// addCase - Add an entry to the switch instruction...
|
||||
/// @Deprecated
|
||||
/// Note:
|
||||
/// This action invalidates case_end(). Old case_end() iterator will
|
||||
/// point to the added case.
|
||||
void addCase(ConstantInt *OnVal, BasicBlock *Dest);
|
||||
|
||||
/// addCase - Add an entry to the switch instruction.
|
||||
/// Note:
|
||||
/// This action invalidates case_end(). Old case_end() iterator will
|
||||
/// point to the added case.
|
||||
void addCase(ConstantRangesSet& OnVal, BasicBlock *Dest);
|
||||
|
||||
/// removeCase - This method removes the specified case and its successor
|
||||
/// from the switch instruction. Note that this operation may reorder the
|
||||
@@ -2703,6 +2732,17 @@ public:
|
||||
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
|
||||
setOperand(idx*2+1, (Value*)NewSucc);
|
||||
}
|
||||
|
||||
uint16_t Hash() const {
|
||||
uint32_t NumberOfCases = (uint32_t)getNumCases();
|
||||
uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
|
||||
for (ConstCaseIt i = case_begin(), e = case_end();
|
||||
i != e; ++i) {
|
||||
uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
|
||||
Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
|
||||
}
|
||||
return Hash;
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SwitchInst *) { return true; }
|
||||
|
||||
@@ -48,8 +48,15 @@ class ConstantRangesSet {
|
||||
Constant *Array;
|
||||
public:
|
||||
|
||||
bool IsWide;
|
||||
|
||||
// implicit
|
||||
ConstantRangesSet(Constant *V) : Array(V) {}
|
||||
ConstantRangesSet(Constant *V) : Array(V) {
|
||||
ArrayType *ArrTy = cast<ArrayType>(Array->getType());
|
||||
VectorType *VecTy = cast<VectorType>(ArrTy->getElementType());
|
||||
IntegerType *IntTy = cast<IntegerType>(VecTy->getElementType());
|
||||
IsWide = IntTy->getBitWidth() > 64;
|
||||
}
|
||||
|
||||
operator Constant*() { return Array; }
|
||||
operator const Constant*() const { return Array; }
|
||||
@@ -230,6 +237,13 @@ public:
|
||||
return cast<ArrayType>(Array->getType())->getNumElements();
|
||||
}
|
||||
|
||||
bool isWideNumberFormat() const { return IsWide; }
|
||||
|
||||
bool isSingleNumber(unsigned idx) const {
|
||||
Constant *CV = Array->getAggregateElement(idx);
|
||||
return cast<VectorType>(CV->getType())->getNumElements() == 1;
|
||||
}
|
||||
|
||||
/// Returns set the size, that equals number of all values + sizes of all
|
||||
/// ranges.
|
||||
/// Ranges set is considered as flat numbers collection.
|
||||
|
||||
Reference in New Issue
Block a user