mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// User is preceded in memory by all the Uses corresponding to its
|
||||
// operands, and the low bits of one of the fields (Prev) of the Use
|
||||
// class are used to encode offsets to be able to find that User given
|
||||
// a pointer to any Use. For details, see:
|
||||
//
|
||||
// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
||||
//
|
||||
/// \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
|
||||
/// 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 User is preceded in
|
||||
/// memory by all the Uses corresponding to its operands, and the low bits of
|
||||
/// one of the fields (Prev) of the Use class are used to encode offsets to be
|
||||
/// able to find that User given a pointer to any Use. For details, see:
|
||||
///
|
||||
/// http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_IR_USE_H
|
||||
@ -51,15 +51,26 @@ public:
|
||||
enum { NumLowBitsAvailable = 2 };
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Use Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Use is here to make keeping the "use" list of a Value up-to-date really
|
||||
/// easy.
|
||||
/// \brief A Use represents the edge between a Value definition and its users.
|
||||
///
|
||||
/// This is notionally a two-dimensional linked list. It supports traversing
|
||||
/// all of the uses for a particular value definition. It also supports jumping
|
||||
/// directly to the used value when we arrive from the User's operands, and
|
||||
/// 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 {
|
||||
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
|
||||
void swap(Use &RHS);
|
||||
|
||||
@ -86,15 +97,13 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
/// Normally Use will just implicitly convert to a Value* that it holds.
|
||||
operator Value*() const { return Val; }
|
||||
|
||||
/// If implicit conversion to Value* doesn't work, the get() method returns
|
||||
/// the Value*.
|
||||
Value *get() const { return Val; }
|
||||
|
||||
/// getUser - This returns the User that contains this Use. For an
|
||||
/// instruction operand, for example, this will return the instruction.
|
||||
|
||||
/// \brief Returns the User that contains this Use.
|
||||
///
|
||||
/// For an instruction operand, for example, this will return the
|
||||
/// instruction.
|
||||
User *getUser() const;
|
||||
|
||||
inline void set(Value *Val);
|
||||
@ -113,18 +122,19 @@ public:
|
||||
|
||||
Use *getNext() const { return Next; }
|
||||
|
||||
|
||||
/// initTags - initialize the waymarking tags on an array of Uses, so that
|
||||
/// getUser() can find the User from any of those Uses.
|
||||
/// \brief Initializes the waymarking tags on an array of 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);
|
||||
|
||||
/// 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.
|
||||
static void zap(Use *Start, const Use *Stop, bool del = false);
|
||||
|
||||
private:
|
||||
const Use* getImpliedUser() const;
|
||||
|
||||
|
||||
Value *Val;
|
||||
Use *Next;
|
||||
PointerIntPair<Use**, 2, PrevPtrTag> Prev;
|
||||
@ -147,8 +157,8 @@ private:
|
||||
friend class Value;
|
||||
};
|
||||
|
||||
// simplify_type - Allow clients to treat uses just like values when using
|
||||
// casting operators.
|
||||
/// \brief Allow clients to treat uses just like values when using
|
||||
/// casting operators.
|
||||
template<> struct simplify_type<Use> {
|
||||
typedef Value* SimpleType;
|
||||
static SimpleType getSimplifiedValue(Use &Val) {
|
||||
@ -186,7 +196,7 @@ public:
|
||||
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; }
|
||||
|
||||
// Iterator traversal: forward iteration only
|
||||
@ -208,16 +218,16 @@ public:
|
||||
UserTy *operator->() const { return operator*(); }
|
||||
|
||||
Use &getUse() const { return *U; }
|
||||
|
||||
/// getOperandNo - Return the operand # of this use in its User. Defined in
|
||||
/// User.h
|
||||
|
||||
/// \brief Return the operand # of this use in its User.
|
||||
///
|
||||
/// Defined in User.h
|
||||
unsigned getOperandNo() const;
|
||||
};
|
||||
|
||||
// Create wrappers for C Binding types (see CBindingWrapping.h).
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
|
||||
|
||||
} // End llvm namespace
|
||||
}
|
||||
|
||||
#endif
|
||||
|
124
lib/IR/Use.cpp
124
lib/IR/Use.cpp
@ -6,20 +6,13 @@
|
||||
// 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 <new>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Use swap Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void Use::swap(Use &RHS) {
|
||||
Value *V1(Val);
|
||||
Value *V2(RHS.Val);
|
||||
@ -45,9 +38,58 @@ void Use::swap(Use &RHS) {
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Use getImpliedUser 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));
|
||||
}
|
||||
|
||||
// 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 *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
|
||||
|
Loading…
Reference in New Issue
Block a user