mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 21:34:23 +00:00
[cleanup] Tidy up and modernize comments and the definition order for
the Use class. More cleanups to come here. This class just needs some TLC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202798 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d186c936bb
commit
0a6057117e
@ -6,20 +6,20 @@
|
|||||||
// License. See LICENSE.TXT for details.
|
// License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
/// \file
|
||||||
// This defines the Use class. The Use class represents the operand of an
|
///
|
||||||
// instruction or some other User instance which refers to a Value. The Use
|
/// This defines the Use class. The Use class represents the operand of an
|
||||||
// class keeps the "use list" of the referenced value up to date.
|
/// instruction or some other User instance which refers to a Value. The Use
|
||||||
//
|
/// class keeps the "use list" of the referenced value up to date.
|
||||||
// Pointer tagging is used to efficiently find the User corresponding
|
///
|
||||||
// to a Use without having to store a User pointer in every Use. A
|
/// Pointer tagging is used to efficiently find the User corresponding to a Use
|
||||||
// User is preceded in memory by all the Uses corresponding to its
|
/// without having to store a User pointer in every Use. A User is preceded in
|
||||||
// operands, and the low bits of one of the fields (Prev) of the Use
|
/// memory by all the Uses corresponding to its operands, and the low bits of
|
||||||
// class are used to encode offsets to be able to find that User given
|
/// one of the fields (Prev) of the Use class are used to encode offsets to be
|
||||||
// a pointer to any Use. For details, see:
|
/// able to find that User given a pointer to any Use. For details, see:
|
||||||
//
|
///
|
||||||
// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
/// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
||||||
//
|
///
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_IR_USE_H
|
#ifndef LLVM_IR_USE_H
|
||||||
@ -51,15 +51,26 @@ public:
|
|||||||
enum { NumLowBitsAvailable = 2 };
|
enum { NumLowBitsAvailable = 2 };
|
||||||
};
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
/// \brief A Use represents the edge between a Value definition and its users.
|
||||||
// Use Class
|
///
|
||||||
//===----------------------------------------------------------------------===//
|
/// This is notionally a two-dimensional linked list. It supports traversing
|
||||||
|
/// all of the uses for a particular value definition. It also supports jumping
|
||||||
/// Use is here to make keeping the "use" list of a Value up-to-date really
|
/// directly to the used value when we arrive from the User's operands, and
|
||||||
/// easy.
|
/// jumping directly to the User when we arrive from the Value's uses.
|
||||||
|
///
|
||||||
|
/// The pointer to the used Value is explicit, and the pointer to the User is
|
||||||
|
/// implicit. The implicit pointer is found via a waymarking algorithm
|
||||||
|
/// described in the programmer's manual:
|
||||||
|
///
|
||||||
|
/// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
||||||
|
///
|
||||||
|
/// This is essentially the single most memory intensive object in LLVM because
|
||||||
|
/// of the number of uses in the system. At the same time, the constant time
|
||||||
|
/// operations it allows are essential to many optimizations having reasonable
|
||||||
|
/// time complexity.
|
||||||
class Use {
|
class Use {
|
||||||
public:
|
public:
|
||||||
/// swap - provide a fast substitute to std::swap<Use>
|
/// \brief Provide a fast substitute to std::swap<Use>
|
||||||
/// that also works with less standard-compliant compilers
|
/// that also works with less standard-compliant compilers
|
||||||
void swap(Use &RHS);
|
void swap(Use &RHS);
|
||||||
|
|
||||||
@ -86,15 +97,13 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Normally Use will just implicitly convert to a Value* that it holds.
|
|
||||||
operator Value*() const { return Val; }
|
operator Value*() const { return Val; }
|
||||||
|
|
||||||
/// If implicit conversion to Value* doesn't work, the get() method returns
|
|
||||||
/// the Value*.
|
|
||||||
Value *get() const { return Val; }
|
Value *get() const { return Val; }
|
||||||
|
|
||||||
/// getUser - This returns the User that contains this Use. For an
|
/// \brief Returns the User that contains this Use.
|
||||||
/// instruction operand, for example, this will return the instruction.
|
///
|
||||||
|
/// For an instruction operand, for example, this will return the
|
||||||
|
/// instruction.
|
||||||
User *getUser() const;
|
User *getUser() const;
|
||||||
|
|
||||||
inline void set(Value *Val);
|
inline void set(Value *Val);
|
||||||
@ -113,18 +122,19 @@ public:
|
|||||||
|
|
||||||
Use *getNext() const { return Next; }
|
Use *getNext() const { return Next; }
|
||||||
|
|
||||||
|
/// \brief Initializes the waymarking tags on an array of Uses.
|
||||||
/// initTags - initialize the waymarking tags on an array of Uses, so that
|
///
|
||||||
/// getUser() can find the User from any of those Uses.
|
/// This sets up the array of Uses such that getUser() can find the User from
|
||||||
|
/// any of those Uses.
|
||||||
static Use *initTags(Use *Start, Use *Stop);
|
static Use *initTags(Use *Start, Use *Stop);
|
||||||
|
|
||||||
/// zap - This is used to destroy Use operands when the number of operands of
|
/// \brief Destroys Use operands when the number of operands of
|
||||||
/// a User changes.
|
/// a User changes.
|
||||||
static void zap(Use *Start, const Use *Stop, bool del = false);
|
static void zap(Use *Start, const Use *Stop, bool del = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Use* getImpliedUser() const;
|
const Use* getImpliedUser() const;
|
||||||
|
|
||||||
Value *Val;
|
Value *Val;
|
||||||
Use *Next;
|
Use *Next;
|
||||||
PointerIntPair<Use**, 2, PrevPtrTag> Prev;
|
PointerIntPair<Use**, 2, PrevPtrTag> Prev;
|
||||||
@ -147,8 +157,8 @@ private:
|
|||||||
friend class Value;
|
friend class Value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// simplify_type - Allow clients to treat uses just like values when using
|
/// \brief Allow clients to treat uses just like values when using
|
||||||
// casting operators.
|
/// casting operators.
|
||||||
template<> struct simplify_type<Use> {
|
template<> struct simplify_type<Use> {
|
||||||
typedef Value* SimpleType;
|
typedef Value* SimpleType;
|
||||||
static SimpleType getSimplifiedValue(Use &Val) {
|
static SimpleType getSimplifiedValue(Use &Val) {
|
||||||
@ -186,7 +196,7 @@ public:
|
|||||||
return !operator==(x);
|
return !operator==(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// atEnd - return true if this iterator is equal to use_end() on the value.
|
/// \brief Returns true if this iterator is equal to use_end() on the value.
|
||||||
bool atEnd() const { return U == 0; }
|
bool atEnd() const { return U == 0; }
|
||||||
|
|
||||||
// Iterator traversal: forward iteration only
|
// Iterator traversal: forward iteration only
|
||||||
@ -208,16 +218,16 @@ public:
|
|||||||
UserTy *operator->() const { return operator*(); }
|
UserTy *operator->() const { return operator*(); }
|
||||||
|
|
||||||
Use &getUse() const { return *U; }
|
Use &getUse() const { return *U; }
|
||||||
|
|
||||||
/// getOperandNo - Return the operand # of this use in its User. Defined in
|
/// \brief Return the operand # of this use in its User.
|
||||||
/// User.h
|
|
||||||
///
|
///
|
||||||
|
/// Defined in User.h
|
||||||
unsigned getOperandNo() const;
|
unsigned getOperandNo() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
|
||||||
|
|
||||||
} // End llvm namespace
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
124
lib/IR/Use.cpp
124
lib/IR/Use.cpp
@ -6,20 +6,13 @@
|
|||||||
// License. See LICENSE.TXT for details.
|
// License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
|
||||||
// This file implements the algorithm for finding the User of a Use.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
|
#include "llvm/IR/Use.h"
|
||||||
#include "llvm/IR/Value.h"
|
#include "llvm/IR/Value.h"
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Use swap Implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
void Use::swap(Use &RHS) {
|
void Use::swap(Use &RHS) {
|
||||||
Value *V1(Val);
|
Value *V1(Val);
|
||||||
Value *V2(RHS.Val);
|
Value *V2(RHS.Val);
|
||||||
@ -45,9 +38,58 @@ void Use::swap(Use &RHS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
User *Use::getUser() const {
|
||||||
// Use getImpliedUser Implementation
|
const Use *End = getImpliedUser();
|
||||||
//===----------------------------------------------------------------------===//
|
const UserRef *ref = reinterpret_cast<const UserRef*>(End);
|
||||||
|
return ref->getInt()
|
||||||
|
? ref->getPointer()
|
||||||
|
: reinterpret_cast<User*>(const_cast<Use*>(End));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets up the waymarking algoritm's tags for a series of Uses. See the
|
||||||
|
// algorithm details here:
|
||||||
|
//
|
||||||
|
// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
||||||
|
//
|
||||||
|
Use *Use::initTags(Use * const Start, Use *Stop) {
|
||||||
|
ptrdiff_t Done = 0;
|
||||||
|
while (Done < 20) {
|
||||||
|
if (Start == Stop--)
|
||||||
|
return Start;
|
||||||
|
static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag,
|
||||||
|
oneDigitTag, oneDigitTag, stopTag,
|
||||||
|
zeroDigitTag, oneDigitTag, oneDigitTag,
|
||||||
|
stopTag, zeroDigitTag, oneDigitTag,
|
||||||
|
zeroDigitTag, oneDigitTag, stopTag,
|
||||||
|
oneDigitTag, oneDigitTag, oneDigitTag,
|
||||||
|
oneDigitTag, stopTag
|
||||||
|
};
|
||||||
|
new(Stop) Use(tags[Done++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrdiff_t Count = Done;
|
||||||
|
while (Start != Stop) {
|
||||||
|
--Stop;
|
||||||
|
if (!Count) {
|
||||||
|
new(Stop) Use(stopTag);
|
||||||
|
++Done;
|
||||||
|
Count = Done;
|
||||||
|
} else {
|
||||||
|
new(Stop) Use(PrevPtrTag(Count & 1));
|
||||||
|
Count >>= 1;
|
||||||
|
++Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Use::zap(Use *Start, const Use *Stop, bool del) {
|
||||||
|
while (Start != Stop)
|
||||||
|
(--Stop)->~Use();
|
||||||
|
if (del)
|
||||||
|
::operator delete(Start);
|
||||||
|
}
|
||||||
|
|
||||||
const Use *Use::getImpliedUser() const {
|
const Use *Use::getImpliedUser() const {
|
||||||
const Use *Current = this;
|
const Use *Current = this;
|
||||||
@ -82,64 +124,4 @@ const Use *Use::getImpliedUser() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Use initTags Implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
Use *Use::initTags(Use * const Start, Use *Stop) {
|
|
||||||
ptrdiff_t Done = 0;
|
|
||||||
while (Done < 20) {
|
|
||||||
if (Start == Stop--)
|
|
||||||
return Start;
|
|
||||||
static const PrevPtrTag tags[20] = { fullStopTag, oneDigitTag, stopTag,
|
|
||||||
oneDigitTag, oneDigitTag, stopTag,
|
|
||||||
zeroDigitTag, oneDigitTag, oneDigitTag,
|
|
||||||
stopTag, zeroDigitTag, oneDigitTag,
|
|
||||||
zeroDigitTag, oneDigitTag, stopTag,
|
|
||||||
oneDigitTag, oneDigitTag, oneDigitTag,
|
|
||||||
oneDigitTag, stopTag
|
|
||||||
};
|
|
||||||
new(Stop) Use(tags[Done++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptrdiff_t Count = Done;
|
|
||||||
while (Start != Stop) {
|
|
||||||
--Stop;
|
|
||||||
if (!Count) {
|
|
||||||
new(Stop) Use(stopTag);
|
|
||||||
++Done;
|
|
||||||
Count = Done;
|
|
||||||
} else {
|
|
||||||
new(Stop) Use(PrevPtrTag(Count & 1));
|
|
||||||
Count >>= 1;
|
|
||||||
++Done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Start;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Use zap Implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
void Use::zap(Use *Start, const Use *Stop, bool del) {
|
|
||||||
while (Start != Stop)
|
|
||||||
(--Stop)->~Use();
|
|
||||||
if (del)
|
|
||||||
::operator delete(Start);
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Use getUser Implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
User *Use::getUser() const {
|
|
||||||
const Use *End = getImpliedUser();
|
|
||||||
const UserRef *ref = reinterpret_cast<const UserRef*>(End);
|
|
||||||
return ref->getInt()
|
|
||||||
? ref->getPointer()
|
|
||||||
: reinterpret_cast<User*>(const_cast<Use*>(End));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user