[llvm] [LLVM] Add option to store Parent-pointer in ilist_node_base (PR #94224)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 3 07:01:04 PDT 2024
https://github.com/SLTozer created https://github.com/llvm/llvm-project/pull/94224
This patch adds a new option for `ilist`, `ilist_parent<ParentTy>`, that enables storing an additional pointer in the `ilist_node_base` type to a specified "parent" type, and uses that option for `Instruction`.
This is distinct from the `ilist_node_with_parent` class, despite their apparent similarities. The `ilist_node_with_parent` class is a subclass of `ilist_node` that requires its own subclasses to define a `getParent` method, which is then used by the owning `ilist` for some of its operations; it is purely an interface declaration. The `ilist_parent` option on the other hand is concerned with data; it is declared as a property of the list itself, and causes every node of that list to own a pointer to the list owner; it has no effect on node access and adds no new methods. Not all `ilist_node_with_parent`s should be in lists with `ilist_parent`; all lists with `ilist_parent` currently contain `ilist_node_with_parent`s, but there's no real advantage to enforcing this relationship at compile time.
Currently, we can use `BasicBlock::iterator` to insert instructions, _except_ when either the iterator is invalid (`NodePtr=0x0`), or when the iterator points to a sentinel value (`BasicBlock::end()`). The former can be easily verified from the iterator object itself, but the latter is currently not detectable (as we do not enable explicit sentinel tracking), and even if we know it we have no clean way to get the correct `BasicBlock*` value from the sentinel node (technically it should exist at a fixed offset from the start of the owning `BasicBlock` object, but using that fact is tricky without reinterpret_cast and funky pointer arithmetic). Moving the `BasicBlock *Parent` field from `Instruction` to `ilist_node_base` means that we can fetch the owning BB from the `end()` iterator, which allows us to use iterators for all insertions, without needing to store or pass an extra `BasicBlock *BB` argument alongside it.
The motivation for this is to move smoothly towards the [proposed rewrite of the instruction insertion interface](https://discourse.llvm.org/t/rfc-rewriting-the-instruction-insertion-interface/78494/1), which itself is needed to reduce the potential for errors to sneak in to the compiler from the use of insertion patterns that behave incorrectly with respect to debug records. This also allows us to greatly deduplicate the code for creating new instructions; in a followup commit (opening shortly), this behaviour is used to define a simple `InsertPosition` class that replaces the "insertBefore/insertAtEnd" arguments for all instruction creation/constructor methods, resulting in a significant reduction in the size of that file with [almost neutral performance impact](http://llvm-compile-time-tracker.com/compare.php?from=b2bd024384b484647da9fd9863bf6f77b5731949&to=3e5b1785fafacea2d3302d4ca9a4f85cb4cd808c&stat=instructions%3Au).
The performance impact of this patch can be seen on the compile time tracker [here](http://llvm-compile-time-tracker.com/compare.php?from=b2bd024384b484647da9fd9863bf6f77b5731949&to=f50c98bee78cec619e8e79f6386b70af5994abe2&stat=instructions:u). The results are basically neutral, except for a very slight increase in compile time (0.04%) and file size (0.01%) of stage 2 clang; the followup commit that exploits this change causes a larger reduction in both of these statistics.
>From 537c8f80bfed595ca3f061a2d53b5a8f5ce7802e Mon Sep 17 00:00:00 2001
From: Stephen Tozer <stephen.tozer at sony.com>
Date: Fri, 31 May 2024 18:14:06 +0100
Subject: [PATCH] Add option to store Parent-pointer in ilist_node_base
---
llvm/include/llvm/ADT/ilist_base.h | 4 +-
llvm/include/llvm/ADT/ilist_iterator.h | 10 +++++
llvm/include/llvm/ADT/ilist_node.h | 11 +++++
llvm/include/llvm/ADT/ilist_node_base.h | 51 ++++++++++++++++++++--
llvm/include/llvm/ADT/ilist_node_options.h | 43 +++++++++++++++---
llvm/include/llvm/IR/BasicBlock.h | 10 +++--
llvm/include/llvm/IR/Instruction.h | 15 ++++---
llvm/include/llvm/IR/ValueSymbolTable.h | 4 +-
llvm/lib/IR/BasicBlock.cpp | 5 ++-
llvm/lib/IR/Instruction.cpp | 25 +++++------
10 files changed, 140 insertions(+), 38 deletions(-)
diff --git a/llvm/include/llvm/ADT/ilist_base.h b/llvm/include/llvm/ADT/ilist_base.h
index b8c098b951ade..000253a26012b 100644
--- a/llvm/include/llvm/ADT/ilist_base.h
+++ b/llvm/include/llvm/ADT/ilist_base.h
@@ -15,9 +15,9 @@
namespace llvm {
/// Implementations of list algorithms using ilist_node_base.
-template <bool EnableSentinelTracking> class ilist_base {
+template <bool EnableSentinelTracking, class ParentPtrTy> class ilist_base {
public:
- using node_base_type = ilist_node_base<EnableSentinelTracking>;
+ using node_base_type = ilist_node_base<EnableSentinelTracking, ParentPtrTy>;
static void insertBeforeImpl(node_base_type &Next, node_base_type &N) {
node_base_type &Prev = *Next.getPrev();
diff --git a/llvm/include/llvm/ADT/ilist_iterator.h b/llvm/include/llvm/ADT/ilist_iterator.h
index 2393c4d2c403c..635e050e0d09a 100644
--- a/llvm/include/llvm/ADT/ilist_iterator.h
+++ b/llvm/include/llvm/ADT/ilist_iterator.h
@@ -70,6 +70,7 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
using iterator_category = std::bidirectional_iterator_tag;
using const_pointer = typename OptionsT::const_pointer;
using const_reference = typename OptionsT::const_reference;
+ using parent_ptr_ty = typename OptionsT::parent_ptr_ty;
private:
using node_pointer = typename Traits::node_pointer;
@@ -101,6 +102,8 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
return *this;
}
+ parent_ptr_ty getNodeParent() { return NodePtr->getNodeBaseParent(); }
+
/// Explicit conversion between forward/reverse iterators.
///
/// Translate between forward and reverse iterators without changing range
@@ -168,6 +171,8 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
return tmp;
}
+ bool isValid() const { return NodePtr; }
+
/// Get the underlying ilist_node.
node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
@@ -195,6 +200,7 @@ class ilist_iterator_w_bits : ilist_detail::SpecificNodeAccess<OptionsT> {
using iterator_category = std::bidirectional_iterator_tag;
using const_pointer = typename OptionsT::const_pointer;
using const_reference = typename OptionsT::const_reference;
+ using parent_ptr_ty = typename OptionsT::parent_ptr_ty;
private:
using node_pointer = typename Traits::node_pointer;
@@ -319,6 +325,10 @@ class ilist_iterator_w_bits : ilist_detail::SpecificNodeAccess<OptionsT> {
return tmp;
}
+ parent_ptr_ty getNodeParent() { return NodePtr->getNodeBaseParent(); }
+
+ bool isValid() const { return NodePtr; }
+
/// Get the underlying ilist_node.
node_pointer getNodePtr() const { return static_cast<node_pointer>(NodePtr); }
diff --git a/llvm/include/llvm/ADT/ilist_node.h b/llvm/include/llvm/ADT/ilist_node.h
index 3b6f0dcc7b5e9..ec615497abee1 100644
--- a/llvm/include/llvm/ADT/ilist_node.h
+++ b/llvm/include/llvm/ADT/ilist_node.h
@@ -118,7 +118,9 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
}
// Under-approximation, but always available for assertions.
+ using node_base_type::getNodeBaseParent;
using node_base_type::isKnownSentinel;
+ using node_base_type::setNodeBaseParent;
/// Check whether this is the sentinel node.
///
@@ -171,6 +173,15 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
/// }
/// \endexample
///
+/// When the \a ilist_parent<ParentTy> option is passed to an ilist_node and the
+/// owning ilist, each node contains a pointer to the ilist's owner. This
+/// pointer does not have any automatic behaviour; set it manually, including
+/// for the sentinel node when the list is created. The primary benefit of this
+/// over declaring and using this pointer in the final node class is that the
+/// pointer will be added in the sentinel, meaning that you can safely use \a
+/// ilist_iterator::getNodeParent() to get the node parent from any valid (i.e.
+/// non-null) iterator, even a sentinel value.
+///
/// See \a is_valid_option for steps on adding a new option.
template <class T, class... Options>
class ilist_node
diff --git a/llvm/include/llvm/ADT/ilist_node_base.h b/llvm/include/llvm/ADT/ilist_node_base.h
index f6c518e6eed7a..e396bb22fca02 100644
--- a/llvm/include/llvm/ADT/ilist_node_base.h
+++ b/llvm/include/llvm/ADT/ilist_node_base.h
@@ -16,9 +16,9 @@ namespace llvm {
/// Base class for ilist nodes.
///
/// Optionally tracks whether this node is the sentinel.
-template <bool EnableSentinelTracking> class ilist_node_base;
+template <bool EnableSentinelTracking, class ParentPtrTy> class ilist_node_base;
-template <> class ilist_node_base<false> {
+template <> class ilist_node_base<false, void> {
ilist_node_base *Prev = nullptr;
ilist_node_base *Next = nullptr;
@@ -28,11 +28,14 @@ template <> class ilist_node_base<false> {
ilist_node_base *getPrev() const { return Prev; }
ilist_node_base *getNext() const { return Next; }
+ void setNodeBaseParent(void) {}
+ inline void getNodeBaseParent() const {}
+
bool isKnownSentinel() const { return false; }
void initializeSentinel() {}
};
-template <> class ilist_node_base<true> {
+template <> class ilist_node_base<true, void> {
PointerIntPair<ilist_node_base *, 1> PrevAndSentinel;
ilist_node_base *Next = nullptr;
@@ -42,6 +45,48 @@ template <> class ilist_node_base<true> {
ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }
ilist_node_base *getNext() const { return Next; }
+ void setNodeBaseParent(void) {}
+ inline void getNodeBaseParent() const {}
+
+ bool isSentinel() const { return PrevAndSentinel.getInt(); }
+ bool isKnownSentinel() const { return isSentinel(); }
+ void initializeSentinel() { PrevAndSentinel.setInt(true); }
+};
+
+template <class ParentPtrTy> class ilist_node_base<false, ParentPtrTy> {
+ ilist_node_base *Prev = nullptr;
+ ilist_node_base *Next = nullptr;
+ ParentPtrTy Parent = nullptr;
+
+public:
+ void setPrev(ilist_node_base *Prev) { this->Prev = Prev; }
+ void setNext(ilist_node_base *Next) { this->Next = Next; }
+ ilist_node_base *getPrev() const { return Prev; }
+ ilist_node_base *getNext() const { return Next; }
+
+ void setNodeBaseParent(ParentPtrTy Parent) { this->Parent = Parent; }
+ inline const ParentPtrTy getNodeBaseParent() const { return Parent; }
+ inline ParentPtrTy getNodeBaseParent() { return Parent; }
+
+ bool isKnownSentinel() const { return false; }
+ void initializeSentinel() {}
+};
+
+template <class ParentPtrTy> class ilist_node_base<true, ParentPtrTy> {
+ PointerIntPair<ilist_node_base *, 1> PrevAndSentinel;
+ ilist_node_base *Next = nullptr;
+ ParentPtrTy Parent = nullptr;
+
+public:
+ void setPrev(ilist_node_base *Prev) { PrevAndSentinel.setPointer(Prev); }
+ void setNext(ilist_node_base *Next) { this->Next = Next; }
+ ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }
+ ilist_node_base *getNext() const { return Next; }
+
+ void setNodeBaseParent(ParentPtrTy Parent) { this->Parent = Parent; }
+ inline const ParentPtrTy getNodeBaseParent() const { return Parent; }
+ inline ParentPtrTy getNodeBaseParent() { return Parent; }
+
bool isSentinel() const { return PrevAndSentinel.getInt(); }
bool isKnownSentinel() const { return isSentinel(); }
void initializeSentinel() { PrevAndSentinel.setInt(true); }
diff --git a/llvm/include/llvm/ADT/ilist_node_options.h b/llvm/include/llvm/ADT/ilist_node_options.h
index e6e1068953e36..aa32162cd51e4 100644
--- a/llvm/include/llvm/ADT/ilist_node_options.h
+++ b/llvm/include/llvm/ADT/ilist_node_options.h
@@ -15,8 +15,8 @@
namespace llvm {
-template <bool EnableSentinelTracking> class ilist_node_base;
-template <bool EnableSentinelTracking> class ilist_base;
+template <bool EnableSentinelTracking, class ParentPtrTy> class ilist_node_base;
+template <bool EnableSentinelTracking, class ParentPtrTy> class ilist_base;
/// Option to choose whether to track sentinels.
///
@@ -39,6 +39,19 @@ template <class Tag> struct ilist_tag {};
/// iterator class to store that information.
template <bool ExtraIteratorBits> struct ilist_iterator_bits {};
+/// Option to add a pointer to this list's owner in every node.
+///
+/// This option causes the \a ilist_base_node for this list to contain a pointer
+/// ParentTy *Parent, returned by \a ilist_base_node::getNodeBaseParent() and
+/// set by \a ilist_base_node::setNodeBaseParent(ParentTy *Parent). The parent
+/// value is not set automatically; the ilist owner should set itself as the
+/// parent of the list sentinel, and the parent should be set on each node
+/// inserted into the list. This value is also not used by
+/// \a ilist_node_with_parent::getNodeParent(), but is used by \a
+/// ilist_iterator::getNodeParent(), which allows the parent to be fetched from
+/// any valid (non-null) iterator to this list, including the sentinel.
+template <class ParentTy> struct ilist_parent {};
+
namespace ilist_detail {
/// Helper trait for recording whether an option is specified explicitly.
@@ -114,6 +127,21 @@ template <> struct extract_iterator_bits<> : std::false_type, is_implicit {};
template <bool IteratorBits>
struct is_valid_option<ilist_iterator_bits<IteratorBits>> : std::true_type {};
+/// Extract node parent option.
+///
+/// Look through \p Options for the \a ilist_parent option, pulling out the
+/// custom parent type, using void as a default.
+template <class... Options> struct extract_parent;
+template <class ParentTy, class... Options>
+struct extract_parent<ilist_parent<ParentTy>, Options...> {
+ typedef ParentTy *type;
+};
+template <class Option1, class... Options>
+struct extract_parent<Option1, Options...> : extract_parent<Options...> {};
+template <> struct extract_parent<> { typedef void type; };
+template <class ParentTy>
+struct is_valid_option<ilist_parent<ParentTy>> : std::true_type {};
+
/// Check whether options are valid.
///
/// The conjunction of \a is_valid_option on each individual option.
@@ -128,7 +156,7 @@ struct check_options<Option1, Options...>
///
/// This is usually computed via \a compute_node_options.
template <class T, bool EnableSentinelTracking, bool IsSentinelTrackingExplicit,
- class TagT, bool HasIteratorBits>
+ class TagT, bool HasIteratorBits, class ParentPtrTy>
struct node_options {
typedef T value_type;
typedef T *pointer;
@@ -140,15 +168,18 @@ struct node_options {
static const bool is_sentinel_tracking_explicit = IsSentinelTrackingExplicit;
static const bool has_iterator_bits = HasIteratorBits;
typedef TagT tag;
- typedef ilist_node_base<enable_sentinel_tracking> node_base_type;
- typedef ilist_base<enable_sentinel_tracking> list_base_type;
+ typedef ParentPtrTy parent_ptr_ty;
+ typedef ilist_node_base<enable_sentinel_tracking, parent_ptr_ty>
+ node_base_type;
+ typedef ilist_base<enable_sentinel_tracking, parent_ptr_ty> list_base_type;
};
template <class T, class... Options> struct compute_node_options {
typedef node_options<T, extract_sentinel_tracking<Options...>::value,
extract_sentinel_tracking<Options...>::is_explicit,
typename extract_tag<Options...>::type,
- extract_iterator_bits<Options...>::value>
+ extract_iterator_bits<Options...>::value,
+ typename extract_parent<Options...>::type>
type;
};
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index e1220966e7e6e..80067f2652a2b 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -59,7 +59,8 @@ class DbgMarker;
class BasicBlock final : public Value, // Basic blocks are data objects also
public ilist_node_with_parent<BasicBlock, Function> {
public:
- using InstListType = SymbolTableList<Instruction, ilist_iterator_bits<true>>;
+ using InstListType = SymbolTableList<Instruction, ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>>;
/// Flag recording whether or not this block stores debug-info in the form
/// of intrinsic instructions (false) or non-instruction records (true).
bool IsNewDbgInfoFormat;
@@ -172,10 +173,11 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
friend BasicBlock::iterator Instruction::eraseFromParent();
friend BasicBlock::iterator Instruction::insertInto(BasicBlock *BB,
BasicBlock::iterator It);
- friend class llvm::SymbolTableListTraits<llvm::Instruction,
- ilist_iterator_bits<true>>;
+ friend class llvm::SymbolTableListTraits<
+ llvm::Instruction, ilist_iterator_bits<true>, ilist_parent<BasicBlock>>;
friend class llvm::ilist_node_with_parent<llvm::Instruction, llvm::BasicBlock,
- ilist_iterator_bits<true>>;
+ ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>>;
// Friendly methods that need to access us for the maintenence of
// debug-info attachments.
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 249be2799fa93..e1cb362ad20d0 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -46,11 +46,13 @@ getDbgRecordRange(DbgMarker *);
class Instruction : public User,
public ilist_node_with_parent<Instruction, BasicBlock,
- ilist_iterator_bits<true>> {
+ ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>> {
public:
- using InstListType = SymbolTableList<Instruction, ilist_iterator_bits<true>>;
+ using InstListType = SymbolTableList<Instruction, ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>>;
+
private:
- BasicBlock *Parent;
DebugLoc DbgLoc; // 'dbg' Metadata cache.
/// Relative order of this instruction in its parent basic block. Used for
@@ -149,8 +151,8 @@ class Instruction : public User,
Instruction *user_back() { return cast<Instruction>(*user_begin());}
const Instruction *user_back() const { return cast<Instruction>(*user_begin());}
- inline const BasicBlock *getParent() const { return Parent; }
- inline BasicBlock *getParent() { return Parent; }
+ inline const BasicBlock *getParent() const { return getNodeBaseParent(); }
+ inline BasicBlock *getParent() { return getNodeBaseParent(); }
/// Return the module owning the function this instruction belongs to
/// or nullptr it the function does not have a module.
@@ -980,7 +982,8 @@ class Instruction : public User,
};
private:
- friend class SymbolTableListTraits<Instruction, ilist_iterator_bits<true>>;
+ friend class SymbolTableListTraits<Instruction, ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>>;
friend class BasicBlock; // For renumbering.
// Shadow Value::setValueSubclassData with a private forwarding method so that
diff --git a/llvm/include/llvm/IR/ValueSymbolTable.h b/llvm/include/llvm/IR/ValueSymbolTable.h
index 6350f6a2435e4..cd1dbbe1688a1 100644
--- a/llvm/include/llvm/IR/ValueSymbolTable.h
+++ b/llvm/include/llvm/IR/ValueSymbolTable.h
@@ -28,6 +28,7 @@ class GlobalIFunc;
class GlobalVariable;
class Instruction;
template <bool ExtraIteratorBits> struct ilist_iterator_bits;
+template <class ParentTy> struct ilist_parent;
template <unsigned InternalLen> class SmallString;
template <typename ValueSubClass, typename ... Args> class SymbolTableListTraits;
@@ -42,7 +43,8 @@ class ValueSymbolTable {
friend class SymbolTableListTraits<GlobalAlias>;
friend class SymbolTableListTraits<GlobalIFunc>;
friend class SymbolTableListTraits<GlobalVariable>;
- friend class SymbolTableListTraits<Instruction, ilist_iterator_bits<true>>;
+ friend class SymbolTableListTraits<Instruction, ilist_iterator_bits<true>,
+ ilist_parent<BasicBlock>>;
friend class Value;
/// @name Types
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index 29f2cbf611fa3..a5199f36c1cb5 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -175,8 +175,8 @@ template <> void llvm::invalidateParentIListOrdering(BasicBlock *BB) {
// Explicit instantiation of SymbolTableListTraits since some of the methods
// are not in the public header file...
-template class llvm::SymbolTableListTraits<Instruction,
- ilist_iterator_bits<true>>;
+template class llvm::SymbolTableListTraits<
+ Instruction, ilist_iterator_bits<true>, ilist_parent<BasicBlock>>;
BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
BasicBlock *InsertBefore)
@@ -189,6 +189,7 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
assert(!InsertBefore &&
"Cannot insert block before another block with no function!");
+ end().getNodePtr()->setNodeBaseParent(this);
setName(Name);
if (NewParent)
setIsNewDbgInfoFormat(NewParent->IsNewDbgInfoFormat);
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 29272e627a1d1..8e8131113a230 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -27,8 +27,7 @@ using namespace llvm;
Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
InstListType::iterator InsertBefore)
- : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
-
+ : User(ty, Value::InstructionVal + it, Ops, NumOps) {
// When called with an iterator, there must be a block to insert into.
BasicBlock *BB = InsertBefore->getParent();
assert(BB && "Instruction to insert before is not in a basic block!");
@@ -37,7 +36,7 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction *InsertBefore)
- : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
+ : User(ty, Value::InstructionVal + it, Ops, NumOps) {
// If requested, insert this instruction into a basic block...
if (InsertBefore) {
@@ -49,15 +48,14 @@ Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
Instruction::Instruction(Type *ty, unsigned it, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd)
- : User(ty, Value::InstructionVal + it, Ops, NumOps), Parent(nullptr) {
-
+ : User(ty, Value::InstructionVal + it, Ops, NumOps) {
// If requested, append this instruction into the basic block.
if (InsertAtEnd)
insertInto(InsertAtEnd, InsertAtEnd->end());
}
Instruction::~Instruction() {
- assert(!Parent && "Instruction still linked in the program!");
+ assert(!getParent() && "Instruction still linked in the program!");
// Replace any extant metadata uses of this instruction with undef to
// preserve debug info accuracy. Some alternatives include:
@@ -76,9 +74,7 @@ Instruction::~Instruction() {
setMetadata(LLVMContext::MD_DIAssignID, nullptr);
}
-void Instruction::setParent(BasicBlock *P) {
- Parent = P;
-}
+void Instruction::setParent(BasicBlock *P) { setNodeBaseParent(P); }
const Module *Instruction::getModule() const {
return getParent()->getModule();
@@ -96,7 +92,7 @@ void Instruction::removeFromParent() {
}
void Instruction::handleMarkerRemoval() {
- if (!Parent->IsNewDbgInfoFormat || !DebugMarker)
+ if (!getParent()->IsNewDbgInfoFormat || !DebugMarker)
return;
DebugMarker->removeMarker();
@@ -329,11 +325,12 @@ void Instruction::dropOneDbgRecord(DbgRecord *DVR) {
}
bool Instruction::comesBefore(const Instruction *Other) const {
- assert(Parent && Other->Parent &&
+ assert(getParent() && Other->getParent() &&
"instructions without BB parents have no order");
- assert(Parent == Other->Parent && "cross-BB instruction order comparison");
- if (!Parent->isInstrOrderValid())
- Parent->renumberInstructions();
+ assert(getParent() == Other->getParent() &&
+ "cross-BB instruction order comparison");
+ if (!getParent()->isInstrOrderValid())
+ const_cast<BasicBlock *>(getParent())->renumberInstructions();
return Order < Other->Order;
}
More information about the llvm-commits
mailing list