Skip to content

Commit b002b38

Browse files
committed
[DebugInfo][RemoveDIs] Add new behind-the-scenes plumbing for debug-info
This is the "central" patch to the removing-debug-intrinsics project: it changes the instruction movement APIs (insert, move, splice) to interpret the "Head" bits we're attaching to BasicBlock::iterators, and updates debug-info records in the background to preserve the ordering of debug-info (which is in DPValue objects instead of dbg.values). The cost is the complexity of this patch, plus memory. The benefit is that LLVM developers can cease thinking about whether they're moving debug-info or not, because it'll happen behind the scenes. All that complexity appears in BasicBlock::spliceDebugInfo, see the diagram there for how we now manually shuffle debug-info around. Each potential splice configuration gets tested in the added unit tests. The rest of this patch applies the same reasoning in a variety of scenarios. When moveBefore (and it's siblings) are used to move instructions around, the caller has to indicate whether they intend for debug-info to move too (is it a "Preserving" call or not), and then the "Head" bits used to determine where debug-info moves to. Similar reasoning is needed for insertBefore. Differential Revision: https://reviews.llvm.org/D154353
1 parent b371ea3 commit b002b38

File tree

7 files changed

+1628
-41
lines changed

7 files changed

+1628
-41
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/ilist_node.h"
2020
#include "llvm/ADT/iterator.h"
2121
#include "llvm/ADT/iterator_range.h"
22+
#include "llvm/IR/DebugProgramInstruction.h"
2223
#include "llvm/IR/Instruction.h"
2324
#include "llvm/IR/DebugProgramInstruction.h"
2425
#include "llvm/IR/SymbolTableListTraits.h"
@@ -118,6 +119,28 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
118119

119120
void dumpDbgValues() const;
120121

122+
/// Return the DPMarker for the position given by \p It, so that DPValues can
123+
/// be inserted there. This will either be nullptr if not present, a DPMarker,
124+
/// or TrailingDPValues if It is end().
125+
DPMarker *getMarker(InstListType::iterator It);
126+
127+
/// Return the DPMarker for the position that comes after \p I. \see
128+
/// BasicBlock::getMarker, this can be nullptr, a DPMarker, or
129+
/// TrailingDPValues if there is no next instruction.
130+
DPMarker *getNextMarker(Instruction *I);
131+
132+
/// Insert a DPValue into a block at the position given by \p I.
133+
void insertDPValueAfter(DPValue *DPV, Instruction *I);
134+
135+
/// Insert a DPValue into a block at the position given by \p Here.
136+
void insertDPValueBefore(DPValue *DPV, InstListType::iterator Here);
137+
138+
/// Eject any debug-info trailing at the end of a block. DPValues can
139+
/// transiently be located "off the end" of a block if the blocks terminator
140+
/// is temporarily removed. Once a terminator is re-inserted this method will
141+
/// move such DPValues back to the right place (ahead of the terminator).
142+
void flushTerminatorDbgValues();
143+
121144
private:
122145
void setParent(Function *parent);
123146

@@ -154,6 +177,19 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
154177
friend class llvm::ilist_node_with_parent<llvm::Instruction, llvm::BasicBlock,
155178
ilist_iterator_bits<true>>;
156179

180+
// Friendly methods that need to access us for the maintenence of
181+
// debug-info attachments.
182+
friend void Instruction::insertBefore(BasicBlock::iterator InsertPos);
183+
friend void Instruction::insertAfter(Instruction *InsertPos);
184+
friend void Instruction::insertBefore(BasicBlock &BB,
185+
InstListType::iterator InsertPos);
186+
friend void Instruction::moveBeforeImpl(BasicBlock &BB,
187+
InstListType::iterator I,
188+
bool Preserve);
189+
friend iterator_range<DPValue::self_iterator> Instruction::cloneDebugInfoFrom(
190+
const Instruction *From, std::optional<DPValue::self_iterator> FromHere,
191+
bool InsertAtHead);
192+
157193
/// Creates a new BasicBlock.
158194
///
159195
/// If the Parent parameter is specified, the basic block is automatically
@@ -478,6 +514,21 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
478514
return &BasicBlock::InstList;
479515
}
480516

517+
/// Dedicated function for splicing debug-info: when we have an empty
518+
/// splice (i.e. zero instructions), the caller may still intend any
519+
/// debug-info in between the two "positions" to be spliced.
520+
void spliceDebugInfoEmptyBlock(BasicBlock::iterator ToIt, BasicBlock *FromBB,
521+
BasicBlock::iterator FromBeginIt,
522+
BasicBlock::iterator FromEndIt);
523+
524+
/// Perform any debug-info specific maintenence for the given splice
525+
/// activity. In the DPValue debug-info representation, debug-info is not
526+
/// in instructions, and so it does not automatically move from one block
527+
/// to another.
528+
void spliceDebugInfo(BasicBlock::iterator ToIt, BasicBlock *FromBB,
529+
BasicBlock::iterator FromBeginIt,
530+
BasicBlock::iterator FromEndIt);
531+
481532
public:
482533
/// Returns a pointer to the symbol table if one exists.
483534
ValueSymbolTable *getValueSymbolTable();

llvm/include/llvm/IR/Instruction.h

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,38 @@ class Instruction : public User,
5959
/// debugging information present.
6060
DPMarker *DbgMarker = nullptr;
6161

62+
/// Clone any debug-info attached to \p From onto this instruction. Used to
63+
/// copy debugging information from one block to another, when copying entire
64+
/// blocks. \see DebugProgramInstruction.h , because the ordering of DPValues
65+
/// is still important, fine grain control of which instructions are moved and
66+
/// where they go is necessary.
67+
/// \p From The instruction to clone debug-info from.
68+
/// \p from_here Optional iterator to limit DPValues cloned to be a range from
69+
/// from_here to end().
70+
/// \p InsertAtHead Whether the cloned DPValues should be placed at the end
71+
/// or the beginning of existing DPValues attached to this.
72+
/// \returns A range over the newly cloned DPValues.
73+
iterator_range<simple_ilist<DPValue>::iterator> cloneDebugInfoFrom(
74+
const Instruction *From,
75+
std::optional<simple_ilist<DPValue>::iterator> FromHere = std::nullopt,
76+
bool InsertAtHead = false);
77+
78+
/// Return a range over the DPValues attached to this instruction.
79+
iterator_range<simple_ilist<DPValue>::iterator> getDbgValueRange() const;
80+
81+
/// Returns true if any DPValues are attached to this instruction.
82+
bool hasDbgValues() const;
83+
84+
/// Erase any DPValues attached to this instruction.
85+
void dropDbgValues();
86+
87+
/// Erase a single DPValue \p I that is attached to this instruction.
88+
void dropOneDbgValue(DPValue *I);
89+
90+
/// Handle the debug-info implications of this instruction being removed. Any
91+
/// attached DPValues need to "fall" down onto the next instruction.
92+
void handleMarkerRemoval();
93+
6294
protected:
6395
// The 15 first bits of `Value::SubclassData` are available for subclasses of
6496
// `Instruction` to use.
@@ -135,9 +167,7 @@ class Instruction : public User,
135167
/// Insert an unlinked instruction into a basic block immediately before
136168
/// the specified instruction.
137169
void insertBefore(Instruction *InsertPos);
138-
void insertBefore(InstListType::iterator InsertPos) {
139-
insertBefore(&*InsertPos);
140-
}
170+
void insertBefore(InstListType::iterator InsertPos);
141171

142172
/// Insert an unlinked instruction into a basic block immediately after the
143173
/// specified instruction.
@@ -148,9 +178,7 @@ class Instruction : public User,
148178
InstListType::iterator insertInto(BasicBlock *ParentBB,
149179
InstListType::iterator It);
150180

151-
void insertBefore(BasicBlock &BB, InstListType::iterator InsertPos) {
152-
insertInto(&BB, InsertPos);
153-
}
181+
void insertBefore(BasicBlock &BB, InstListType::iterator InsertPos);
154182

155183
/// Unlink this instruction from its current basic block and insert it into
156184
/// the basic block that MovePos lives in, right before MovePos.
@@ -161,28 +189,28 @@ class Instruction : public User,
161189
/// means that any adjacent debug-info should move with this instruction.
162190
/// This method is currently a no-op placeholder, but it will become meaningful
163191
/// when the "RemoveDIs" project is enabled.
164-
void moveBeforePreserving(Instruction *MovePos) {
165-
moveBefore(MovePos);
166-
}
192+
void moveBeforePreserving(Instruction *MovePos);
167193

194+
private:
195+
/// RemoveDIs project: all other moves implemented with this method,
196+
/// centralising debug-info updates into one place.
197+
void moveBeforeImpl(BasicBlock &BB, InstListType::iterator I, bool Preserve);
198+
199+
public:
168200
/// Unlink this instruction and insert into BB before I.
169201
///
170202
/// \pre I is a valid iterator into BB.
171203
void moveBefore(BasicBlock &BB, InstListType::iterator I);
172204

173205
/// (See other overload for moveBeforePreserving).
174-
void moveBeforePreserving(BasicBlock &BB, InstListType::iterator I) {
175-
moveBefore(BB, I);
176-
}
206+
void moveBeforePreserving(BasicBlock &BB, InstListType::iterator I);
177207

178208
/// Unlink this instruction from its current basic block and insert it into
179209
/// the basic block that MovePos lives in, right after MovePos.
180210
void moveAfter(Instruction *MovePos);
181211

182212
/// See \ref moveBeforePreserving .
183-
void moveAfterPreserving(Instruction *MovePos) {
184-
moveAfter(MovePos);
185-
}
213+
void moveAfterPreserving(Instruction *MovePos);
186214

187215
/// Given an instruction Other in the same basic block as this instruction,
188216
/// return true if this instruction comes before Other. In this worst case,

0 commit comments

Comments
 (0)