Skip to content

Commit 2425e29

Browse files
authored
[DebugInfo][RemoveDIs] Have getInsertionPtAfterDef return an iterator (#73149)
Part of the "RemoveDIs" project to remove debug intrinsics requires passing block-positions around in iterators rather than as instruction pointers, allowing some debug-info to reside in BasicBlock::iterator. This means getInsertionPointAfterDef has to return an iterator, and as it can return no-instruction that means returning an optional iterator. This patch changes the signature for getInsertionPtAfterDef and then patches up the various places that use it to handle the different type. This would overall be an NFC patch, however in InstCombinerImpl::freezeOtherUses I've started skipping any debug intrinsics at the returned insert-position. This should not have any _meaningful_ effect on the compiler output: at worst it means variable assignments that are skipped will now cover the freeze instruction and anything inserted before it, which should be inconsequential. Sadly: this makes the function signature ugly. This is probably the ugliest piece of fallout for the "RemoveDIs" work, but it serves the overall purpose of improving compile times and not allowing `-g` to affect compiler output, so should be worthwhile in the end.
1 parent 269e304 commit 2425e29

File tree

11 files changed

+86
-47
lines changed

11 files changed

+86
-47
lines changed

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ class IRBuilderBase {
200200
SetCurrentDebugLocation(IP->getStableDebugLoc());
201201
}
202202

203+
/// This specifies that created instructions should be inserted at
204+
/// the specified point, but also requires that \p IP is dereferencable.
205+
void SetInsertPoint(BasicBlock::iterator IP) {
206+
BB = IP->getParent();
207+
InsertPt = IP;
208+
SetCurrentDebugLocation(IP->getStableDebugLoc());
209+
}
210+
203211
/// This specifies that created instructions should inserted at the beginning
204212
/// end of the specified function, but after already existing static alloca
205213
/// instructions that are at the start.

llvm/include/llvm/IR/Instruction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ class Instruction : public User,
224224
/// of cases, e.g. phi nodes or terminators that return values. This function
225225
/// may return null if the insertion after the definition is not possible,
226226
/// e.g. due to a catchswitch terminator.
227-
Instruction *getInsertionPointAfterDef();
227+
std::optional<InstListType::iterator> getInsertionPointAfterDef();
228228

229229
//===--------------------------------------------------------------------===//
230230
// Subclass classification.

llvm/lib/IR/Instruction.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ bool Instruction::comesBefore(const Instruction *Other) const {
274274
return Order < Other->Order;
275275
}
276276

277-
Instruction *Instruction::getInsertionPointAfterDef() {
277+
std::optional<BasicBlock::iterator> Instruction::getInsertionPointAfterDef() {
278278
assert(!getType()->isVoidTy() && "Instruction must define result");
279279
BasicBlock *InsertBB;
280280
BasicBlock::iterator InsertPt;
@@ -287,18 +287,22 @@ Instruction *Instruction::getInsertionPointAfterDef() {
287287
} else if (isa<CallBrInst>(this)) {
288288
// Def is available in multiple successors, there's no single dominating
289289
// insertion point.
290-
return nullptr;
290+
return std::nullopt;
291291
} else {
292292
assert(!isTerminator() && "Only invoke/callbr terminators return value");
293293
InsertBB = getParent();
294294
InsertPt = std::next(getIterator());
295+
// Any instruction inserted immediately after "this" will come before any
296+
// debug-info records take effect -- thus, set the head bit indicating that
297+
// to debug-info-transfer code.
298+
InsertPt.setHeadBit(true);
295299
}
296300

297301
// catchswitch blocks don't have any legal insertion point (because they
298302
// are both an exception pad and a terminator).
299303
if (InsertPt == InsertBB->end())
300-
return nullptr;
301-
return &*InsertPt;
304+
return std::nullopt;
305+
return InsertPt;
302306
}
303307

304308
bool Instruction::isOnlyUserOfAnyOperand() {

llvm/lib/Transforms/Coroutines/CoroFrame.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2886,13 +2886,13 @@ void coro::salvageDebugInfo(
28862886
// dbg.value since it does not have the same function wide guarantees that
28872887
// dbg.declare does.
28882888
if (isa<DbgDeclareInst>(DVI)) {
2889-
Instruction *InsertPt = nullptr;
2889+
std::optional<BasicBlock::iterator> InsertPt;
28902890
if (auto *I = dyn_cast<Instruction>(Storage))
28912891
InsertPt = I->getInsertionPointAfterDef();
28922892
else if (isa<Argument>(Storage))
2893-
InsertPt = &*F->getEntryBlock().begin();
2893+
InsertPt = F->getEntryBlock().begin();
28942894
if (InsertPt)
2895-
DVI->moveBefore(InsertPt);
2895+
DVI->moveBefore(*(*InsertPt)->getParent(), *InsertPt);
28962896
}
28972897
}
28982898

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4130,7 +4130,7 @@ static bool canFreelyInvert(InstCombiner &IC, Value *Op,
41304130
static Value *freelyInvert(InstCombinerImpl &IC, Value *Op,
41314131
Instruction *IgnoredUser) {
41324132
auto *I = cast<Instruction>(Op);
4133-
IC.Builder.SetInsertPoint(&*I->getInsertionPointAfterDef());
4133+
IC.Builder.SetInsertPoint(*I->getInsertionPointAfterDef());
41344134
Value *NotOp = IC.Builder.CreateNot(Op, Op->getName() + ".not");
41354135
Op->replaceUsesWithIf(NotOp,
41364136
[NotOp](Use &U) { return U.getUser() != NotOp; });
@@ -4168,7 +4168,7 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
41684168
Op0 = freelyInvert(*this, Op0, &I);
41694169
Op1 = freelyInvert(*this, Op1, &I);
41704170

4171-
Builder.SetInsertPoint(I.getInsertionPointAfterDef());
4171+
Builder.SetInsertPoint(*I.getInsertionPointAfterDef());
41724172
Value *NewLogicOp;
41734173
if (IsBinaryOp)
41744174
NewLogicOp = Builder.CreateBinOp(NewOpc, Op0, Op1, I.getName() + ".not");
@@ -4216,7 +4216,7 @@ bool InstCombinerImpl::sinkNotIntoOtherHandOfLogicalOp(Instruction &I) {
42164216

42174217
*OpToInvert = freelyInvert(*this, *OpToInvert, &I);
42184218

4219-
Builder.SetInsertPoint(&*I.getInsertionPointAfterDef());
4219+
Builder.SetInsertPoint(*I.getInsertionPointAfterDef());
42204220
Value *NewBinOp;
42214221
if (IsBinaryOp)
42224222
NewBinOp = Builder.CreateBinOp(NewOpc, Op0, Op1, I.getName() + ".not");

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4017,9 +4017,9 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
40174017
NV = NC = CastInst::CreateBitOrPointerCast(NC, OldRetTy);
40184018
NC->setDebugLoc(Caller->getDebugLoc());
40194019

4020-
Instruction *InsertPt = NewCall->getInsertionPointAfterDef();
4021-
assert(InsertPt && "No place to insert cast");
4022-
InsertNewInstBefore(NC, InsertPt->getIterator());
4020+
auto OptInsertPt = NewCall->getInsertionPointAfterDef();
4021+
assert(OptInsertPt && "No place to insert cast");
4022+
InsertNewInstBefore(NC, *OptInsertPt);
40234023
Worklist.pushUsersToWorkList(*Caller);
40244024
} else {
40254025
NV = PoisonValue::get(Caller->getType());

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,19 +3823,27 @@ bool InstCombinerImpl::freezeOtherUses(FreezeInst &FI) {
38233823
// *all* uses if the operand is an invoke/callbr and the use is in a phi on
38243824
// the normal/default destination. This is why the domination check in the
38253825
// replacement below is still necessary.
3826-
Instruction *MoveBefore;
3826+
BasicBlock::iterator MoveBefore;
38273827
if (isa<Argument>(Op)) {
38283828
MoveBefore =
3829-
&*FI.getFunction()->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
3829+
FI.getFunction()->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
38303830
} else {
3831-
MoveBefore = cast<Instruction>(Op)->getInsertionPointAfterDef();
3832-
if (!MoveBefore)
3831+
auto MoveBeforeOpt = cast<Instruction>(Op)->getInsertionPointAfterDef();
3832+
if (!MoveBeforeOpt)
38333833
return false;
3834+
MoveBefore = *MoveBeforeOpt;
38343835
}
38353836

3837+
// Don't move to the position of a debug intrinsic.
3838+
if (isa<DbgInfoIntrinsic>(MoveBefore))
3839+
MoveBefore = MoveBefore->getNextNonDebugInstruction()->getIterator();
3840+
// Re-point iterator to come after any debug-info records, if we're
3841+
// running in "RemoveDIs" mode
3842+
MoveBefore.setHeadBit(false);
3843+
38363844
bool Changed = false;
3837-
if (&FI != MoveBefore) {
3838-
FI.moveBefore(*MoveBefore->getParent(), MoveBefore->getIterator());
3845+
if (&FI != &*MoveBefore) {
3846+
FI.moveBefore(*MoveBefore->getParent(), MoveBefore);
38393847
Changed = true;
38403848
}
38413849

llvm/lib/Transforms/Scalar/GuardWidening.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -596,35 +596,47 @@ void GuardWideningImpl::makeAvailableAt(Value *V, Instruction *Loc) const {
596596
}
597597

598598
// Return Instruction before which we can insert freeze for the value V as close
599-
// to def as possible. If there is no place to add freeze, return nullptr.
600-
static Instruction *getFreezeInsertPt(Value *V, const DominatorTree &DT) {
599+
// to def as possible. If there is no place to add freeze, return empty.
600+
static std::optional<BasicBlock::iterator>
601+
getFreezeInsertPt(Value *V, const DominatorTree &DT) {
601602
auto *I = dyn_cast<Instruction>(V);
602603
if (!I)
603-
return &*DT.getRoot()->getFirstNonPHIOrDbgOrAlloca();
604+
return DT.getRoot()->getFirstNonPHIOrDbgOrAlloca()->getIterator();
604605

605-
auto *Res = I->getInsertionPointAfterDef();
606+
std::optional<BasicBlock::iterator> Res = I->getInsertionPointAfterDef();
606607
// If there is no place to add freeze - return nullptr.
607-
if (!Res || !DT.dominates(I, Res))
608-
return nullptr;
608+
if (!Res || !DT.dominates(I, &**Res))
609+
return std::nullopt;
610+
611+
Instruction *ResInst = &**Res;
609612

610613
// If there is a User dominated by original I, then it should be dominated
611614
// by Freeze instruction as well.
612615
if (any_of(I->users(), [&](User *U) {
613616
Instruction *User = cast<Instruction>(U);
614-
return Res != User && DT.dominates(I, User) && !DT.dominates(Res, User);
617+
return ResInst != User && DT.dominates(I, User) &&
618+
!DT.dominates(ResInst, User);
615619
}))
616-
return nullptr;
620+
return std::nullopt;
617621
return Res;
618622
}
619623

620624
Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
621625
if (isGuaranteedNotToBePoison(Orig, nullptr, InsertPt, &DT))
622626
return Orig;
623-
Instruction *InsertPtAtDef = getFreezeInsertPt(Orig, DT);
624-
if (!InsertPtAtDef)
625-
return new FreezeInst(Orig, "gw.freeze", InsertPt);
626-
if (isa<Constant>(Orig) || isa<GlobalValue>(Orig))
627-
return new FreezeInst(Orig, "gw.freeze", InsertPtAtDef);
627+
std::optional<BasicBlock::iterator> InsertPtAtDef =
628+
getFreezeInsertPt(Orig, DT);
629+
if (!InsertPtAtDef) {
630+
FreezeInst *FI = new FreezeInst(Orig, "gw.freeze");
631+
FI->insertBefore(InsertPt);
632+
return FI;
633+
}
634+
if (isa<Constant>(Orig) || isa<GlobalValue>(Orig)) {
635+
BasicBlock::iterator InsertPt = *InsertPtAtDef;
636+
FreezeInst *FI = new FreezeInst(Orig, "gw.freeze");
637+
FI->insertBefore(*InsertPt->getParent(), InsertPt);
638+
return FI;
639+
}
628640

629641
SmallSet<Value *, 16> Visited;
630642
SmallVector<Value *, 16> Worklist;
@@ -643,8 +655,10 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
643655
if (Visited.insert(Def).second) {
644656
if (isGuaranteedNotToBePoison(Def, nullptr, InsertPt, &DT))
645657
return true;
646-
CacheOfFreezes[Def] = new FreezeInst(Def, Def->getName() + ".gw.fr",
647-
getFreezeInsertPt(Def, DT));
658+
BasicBlock::iterator InsertPt = *getFreezeInsertPt(Def, DT);
659+
FreezeInst *FI = new FreezeInst(Def, Def->getName() + ".gw.fr");
660+
FI->insertBefore(*InsertPt->getParent(), InsertPt);
661+
CacheOfFreezes[Def] = FI;
648662
}
649663

650664
if (CacheOfFreezes.count(Def))
@@ -685,8 +699,9 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
685699

686700
Value *Result = Orig;
687701
for (Value *V : NeedFreeze) {
688-
auto *FreezeInsertPt = getFreezeInsertPt(V, DT);
689-
FreezeInst *FI = new FreezeInst(V, V->getName() + ".gw.fr", FreezeInsertPt);
702+
BasicBlock::iterator FreezeInsertPt = *getFreezeInsertPt(V, DT);
703+
FreezeInst *FI = new FreezeInst(V, V->getName() + ".gw.fr");
704+
FI->insertBefore(*FreezeInsertPt->getParent(), FreezeInsertPt);
690705
++FreezeAdded;
691706
if (V == Orig)
692707
Result = FI;

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2411,7 +2411,7 @@ bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
24112411
// it's use count.
24122412
Instruction *InsertPt = nullptr;
24132413
if (auto *BitPosI = dyn_cast<Instruction>(BitPos))
2414-
InsertPt = BitPosI->getInsertionPointAfterDef();
2414+
InsertPt = &**BitPosI->getInsertionPointAfterDef();
24152415
else
24162416
InsertPt = &*DT->getRoot()->getFirstNonPHIOrDbgOrAlloca();
24172417
if (!InsertPt)

llvm/lib/Transforms/Scalar/Reassociate.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,16 +921,20 @@ static Value *NegateValue(Value *V, Instruction *BI,
921921
TheNeg->getParent()->getParent() != BI->getParent()->getParent())
922922
continue;
923923

924-
Instruction *InsertPt;
924+
BasicBlock::iterator InsertPt;
925925
if (Instruction *InstInput = dyn_cast<Instruction>(V)) {
926-
InsertPt = InstInput->getInsertionPointAfterDef();
927-
if (!InsertPt)
926+
auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
927+
if (!InsertPtOpt)
928928
continue;
929+
InsertPt = *InsertPtOpt;
929930
} else {
930-
InsertPt = &*TheNeg->getFunction()->getEntryBlock().begin();
931+
InsertPt = TheNeg->getFunction()
932+
->getEntryBlock()
933+
.getFirstNonPHIOrDbg()
934+
->getIterator();
931935
}
932936

933-
TheNeg->moveBefore(InsertPt);
937+
TheNeg->moveBefore(*InsertPt->getParent(), InsertPt);
934938
if (TheNeg->getOpcode() == Instruction::Sub) {
935939
TheNeg->setHasNoUnsignedWrap(false);
936940
TheNeg->setHasNoSignedWrap(false);

llvm/lib/Transforms/Vectorize/VectorCombine.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,16 +1810,16 @@ bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
18101810
return SSV->getOperand(Op);
18111811
return SV->getOperand(Op);
18121812
};
1813-
Builder.SetInsertPoint(SVI0A->getInsertionPointAfterDef());
1813+
Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
18141814
Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
18151815
GetShuffleOperand(SVI0A, 1), V1A);
1816-
Builder.SetInsertPoint(SVI0B->getInsertionPointAfterDef());
1816+
Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
18171817
Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
18181818
GetShuffleOperand(SVI0B, 1), V1B);
1819-
Builder.SetInsertPoint(SVI1A->getInsertionPointAfterDef());
1819+
Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
18201820
Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
18211821
GetShuffleOperand(SVI1A, 1), V2A);
1822-
Builder.SetInsertPoint(SVI1B->getInsertionPointAfterDef());
1822+
Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
18231823
Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
18241824
GetShuffleOperand(SVI1B, 1), V2B);
18251825
Builder.SetInsertPoint(Op0);

0 commit comments

Comments
 (0)