mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 14:40:25 +00:00
Introduce a typing refinenement on tagged data
using the 'volatile' qualifier. This should not have any operational consequences on code, because tags should always be stripped off (giving a non-volatile pointer) before dereferencing. The new qualification is there to catch some attempts to use tagged pointers in a context where an untagged pointer is appropriate. Notably this approach does not catch dereferencing of tagged pointers, but helps in separating the two concepts a bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57641 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cc30d9caa5
commit
023f84ecaf
@ -34,27 +34,27 @@ enum Tag { noTag, tagOne, tagTwo, tagThree };
|
||||
|
||||
/// addTag - insert tag bits into an (untagged) pointer
|
||||
template <typename T, typename TAG>
|
||||
inline T *addTag(const T *P, TAG Tag) {
|
||||
inline volatile T *addTag(const T *P, TAG Tag) {
|
||||
return reinterpret_cast<T*>(ptrdiff_t(P) | Tag);
|
||||
}
|
||||
|
||||
/// stripTag - remove tag bits from a pointer,
|
||||
/// making it dereferencable
|
||||
template <ptrdiff_t MASK, typename T>
|
||||
inline T *stripTag(const T *P) {
|
||||
inline T *stripTag(const volatile T *P) {
|
||||
return reinterpret_cast<T*>(ptrdiff_t(P) & ~MASK);
|
||||
}
|
||||
|
||||
/// extractTag - extract tag bits from a pointer
|
||||
template <typename TAG, TAG MASK, typename T>
|
||||
inline TAG extractTag(const T *P) {
|
||||
inline TAG extractTag(const volatile T *P) {
|
||||
return TAG(ptrdiff_t(P) & MASK);
|
||||
}
|
||||
|
||||
/// transferTag - transfer tag bits from a pointer,
|
||||
/// to an untagged pointer
|
||||
template <ptrdiff_t MASK, typename T>
|
||||
inline T *transferTag(const T *From, const T *To) {
|
||||
inline volatile T *transferTag(const volatile T *From, const T *To) {
|
||||
return reinterpret_cast<T*>((ptrdiff_t(From) & MASK) | ptrdiff_t(To));
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ private:
|
||||
static Use *initTags(Use *Start, Use *Stop, ptrdiff_t Done = 0);
|
||||
|
||||
Value *Val;
|
||||
Use *Next, **Prev;
|
||||
Use *Next, *volatile*Prev;
|
||||
|
||||
void setPrev(Use **NewPrev) {
|
||||
Prev = transferTag<fullStopTag>(Prev, NewPrev);
|
||||
|
@ -127,7 +127,7 @@ void Use::zap(Use *Start, const Use *Stop, bool del) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
struct AugmentedUse : Use {
|
||||
User *ref;
|
||||
volatile User *ref;
|
||||
AugmentedUse(); // not implemented
|
||||
};
|
||||
|
||||
@ -138,12 +138,10 @@ struct AugmentedUse : Use {
|
||||
|
||||
User *Use::getUser() const {
|
||||
const Use *End = getImpliedUser();
|
||||
User *She = static_cast<const AugmentedUse*>(End - 1)->ref;
|
||||
She = extractTag<Tag, tagOne>(She)
|
||||
volatile User *She = static_cast<const AugmentedUse*>(End - 1)->ref;
|
||||
return extractTag<Tag, tagOne>(She)
|
||||
? llvm::stripTag<tagOne>(She)
|
||||
: reinterpret_cast<User*>(const_cast<Use*>(End));
|
||||
|
||||
return She;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user