Skip to content

[DebugInfo][RemoveDIs] Have getInsertionPtAfterDef return an iterator #73149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/include/llvm/IR/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ class IRBuilderBase {
SetCurrentDebugLocation(IP->getStableDebugLoc());
}

/// This specifies that created instructions should be inserted at
/// the specified point, but also requires that \p IP is dereferencable.
void SetInsertPoint(BasicBlock::iterator IP) {
BB = IP->getParent();
InsertPt = IP;
SetCurrentDebugLocation(IP->getStableDebugLoc());
}

/// This specifies that created instructions should inserted at the beginning
/// end of the specified function, but after already existing static alloca
/// instructions that are at the start.
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class Instruction : public User,
/// of cases, e.g. phi nodes or terminators that return values. This function
/// may return null if the insertion after the definition is not possible,
/// e.g. due to a catchswitch terminator.
Instruction *getInsertionPointAfterDef();
std::optional<InstListType::iterator> getInsertionPointAfterDef();

//===--------------------------------------------------------------------===//
// Subclass classification.
Expand Down
12 changes: 8 additions & 4 deletions llvm/lib/IR/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ bool Instruction::comesBefore(const Instruction *Other) const {
return Order < Other->Order;
}

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

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

bool Instruction::isOnlyUserOfAnyOperand() {
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Coroutines/CoroFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2886,13 +2886,13 @@ void coro::salvageDebugInfo(
// dbg.value since it does not have the same function wide guarantees that
// dbg.declare does.
if (isa<DbgDeclareInst>(DVI)) {
Instruction *InsertPt = nullptr;
std::optional<BasicBlock::iterator> InsertPt;
if (auto *I = dyn_cast<Instruction>(Storage))
InsertPt = I->getInsertionPointAfterDef();
else if (isa<Argument>(Storage))
InsertPt = &*F->getEntryBlock().begin();
InsertPt = F->getEntryBlock().begin();
if (InsertPt)
DVI->moveBefore(InsertPt);
DVI->moveBefore(*(*InsertPt)->getParent(), *InsertPt);
}
}

Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4130,7 +4130,7 @@ static bool canFreelyInvert(InstCombiner &IC, Value *Op,
static Value *freelyInvert(InstCombinerImpl &IC, Value *Op,
Instruction *IgnoredUser) {
auto *I = cast<Instruction>(Op);
IC.Builder.SetInsertPoint(&*I->getInsertionPointAfterDef());
IC.Builder.SetInsertPoint(*I->getInsertionPointAfterDef());
Value *NotOp = IC.Builder.CreateNot(Op, Op->getName() + ".not");
Op->replaceUsesWithIf(NotOp,
[NotOp](Use &U) { return U.getUser() != NotOp; });
Expand Down Expand Up @@ -4168,7 +4168,7 @@ bool InstCombinerImpl::sinkNotIntoLogicalOp(Instruction &I) {
Op0 = freelyInvert(*this, Op0, &I);
Op1 = freelyInvert(*this, Op1, &I);

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

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

Builder.SetInsertPoint(&*I.getInsertionPointAfterDef());
Builder.SetInsertPoint(*I.getInsertionPointAfterDef());
Value *NewBinOp;
if (IsBinaryOp)
NewBinOp = Builder.CreateBinOp(NewOpc, Op0, Op1, I.getName() + ".not");
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4017,9 +4017,9 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) {
NV = NC = CastInst::CreateBitOrPointerCast(NC, OldRetTy);
NC->setDebugLoc(Caller->getDebugLoc());

Instruction *InsertPt = NewCall->getInsertionPointAfterDef();
assert(InsertPt && "No place to insert cast");
InsertNewInstBefore(NC, InsertPt->getIterator());
auto OptInsertPt = NewCall->getInsertionPointAfterDef();
assert(OptInsertPt && "No place to insert cast");
InsertNewInstBefore(NC, *OptInsertPt);
Worklist.pushUsersToWorkList(*Caller);
} else {
NV = PoisonValue::get(Caller->getType());
Expand Down
20 changes: 14 additions & 6 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3807,19 +3807,27 @@ bool InstCombinerImpl::freezeOtherUses(FreezeInst &FI) {
// *all* uses if the operand is an invoke/callbr and the use is in a phi on
// the normal/default destination. This is why the domination check in the
// replacement below is still necessary.
Instruction *MoveBefore;
BasicBlock::iterator MoveBefore;
if (isa<Argument>(Op)) {
MoveBefore =
&*FI.getFunction()->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
FI.getFunction()->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
} else {
MoveBefore = cast<Instruction>(Op)->getInsertionPointAfterDef();
if (!MoveBefore)
auto MoveBeforeOpt = cast<Instruction>(Op)->getInsertionPointAfterDef();
if (!MoveBeforeOpt)
return false;
MoveBefore = *MoveBeforeOpt;
}

// Don't move to the position of a debug intrinsic.
if (isa<DbgInfoIntrinsic>(MoveBefore))
MoveBefore = MoveBefore->getNextNonDebugInstruction()->getIterator();
// Re-point iterator to come after any debug-info records, if we're
// running in "RemoveDIs" mode
MoveBefore.setHeadBit(false);

bool Changed = false;
if (&FI != MoveBefore) {
FI.moveBefore(*MoveBefore->getParent(), MoveBefore->getIterator());
if (&FI != &*MoveBefore) {
FI.moveBefore(*MoveBefore->getParent(), MoveBefore);
Changed = true;
}

Expand Down
49 changes: 32 additions & 17 deletions llvm/lib/Transforms/Scalar/GuardWidening.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,35 +596,47 @@ void GuardWideningImpl::makeAvailableAt(Value *V, Instruction *Loc) const {
}

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

auto *Res = I->getInsertionPointAfterDef();
std::optional<BasicBlock::iterator> Res = I->getInsertionPointAfterDef();
// If there is no place to add freeze - return nullptr.
if (!Res || !DT.dominates(I, Res))
return nullptr;
if (!Res || !DT.dominates(I, &**Res))
return std::nullopt;

Instruction *ResInst = &**Res;

// If there is a User dominated by original I, then it should be dominated
// by Freeze instruction as well.
if (any_of(I->users(), [&](User *U) {
Instruction *User = cast<Instruction>(U);
return Res != User && DT.dominates(I, User) && !DT.dominates(Res, User);
return ResInst != User && DT.dominates(I, User) &&
!DT.dominates(ResInst, User);
}))
return nullptr;
return std::nullopt;
return Res;
}

Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
if (isGuaranteedNotToBePoison(Orig, nullptr, InsertPt, &DT))
return Orig;
Instruction *InsertPtAtDef = getFreezeInsertPt(Orig, DT);
if (!InsertPtAtDef)
return new FreezeInst(Orig, "gw.freeze", InsertPt);
if (isa<Constant>(Orig) || isa<GlobalValue>(Orig))
return new FreezeInst(Orig, "gw.freeze", InsertPtAtDef);
std::optional<BasicBlock::iterator> InsertPtAtDef =
getFreezeInsertPt(Orig, DT);
if (!InsertPtAtDef) {
FreezeInst *FI = new FreezeInst(Orig, "gw.freeze");
FI->insertBefore(InsertPt);
return FI;
}
if (isa<Constant>(Orig) || isa<GlobalValue>(Orig)) {
BasicBlock::iterator InsertPt = *InsertPtAtDef;
FreezeInst *FI = new FreezeInst(Orig, "gw.freeze");
FI->insertBefore(*InsertPt->getParent(), InsertPt);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should insertBefore be using InsertPtAtDef here instead?

Suggested change
FI->insertBefore(*InsertPt->getParent(), InsertPt);
FI->insertBefore(*InsertPt->getParent(), *InsertPtAtDef);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could do -- the motivation of unwrapping into a local iterator variable was to avoid a double-deref for the first argument to insertBefore -- it always makes me feel like there's something wrong, so I figured the unwrapping would make it more legible + understandable. (YMMV).

return FI;
}

SmallSet<Value *, 16> Visited;
SmallVector<Value *, 16> Worklist;
Expand All @@ -643,8 +655,10 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig, Instruction *InsertPt) {
if (Visited.insert(Def).second) {
if (isGuaranteedNotToBePoison(Def, nullptr, InsertPt, &DT))
return true;
CacheOfFreezes[Def] = new FreezeInst(Def, Def->getName() + ".gw.fr",
getFreezeInsertPt(Def, DT));
BasicBlock::iterator InsertPt = *getFreezeInsertPt(Def, DT);
FreezeInst *FI = new FreezeInst(Def, Def->getName() + ".gw.fr");
FI->insertBefore(*InsertPt->getParent(), InsertPt);
CacheOfFreezes[Def] = FI;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a shame about the added verbosity. Is there anything we can do about that? (Update/add instruction ctors as we go along, etc).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can certainly restore this back to "insert in the constructor", I'm just shying away from landing that right now. IMO it's better to land as one-foul-swoop which breaks downstream builds, but only does it once.

}

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

Value *Result = Orig;
for (Value *V : NeedFreeze) {
auto *FreezeInsertPt = getFreezeInsertPt(V, DT);
FreezeInst *FI = new FreezeInst(V, V->getName() + ".gw.fr", FreezeInsertPt);
BasicBlock::iterator FreezeInsertPt = *getFreezeInsertPt(V, DT);
FreezeInst *FI = new FreezeInst(V, V->getName() + ".gw.fr");
FI->insertBefore(*FreezeInsertPt->getParent(), FreezeInsertPt);
++FreezeAdded;
if (V == Orig)
Result = FI;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2411,7 +2411,7 @@ bool LoopIdiomRecognize::recognizeShiftUntilBitTest() {
// it's use count.
Instruction *InsertPt = nullptr;
if (auto *BitPosI = dyn_cast<Instruction>(BitPos))
InsertPt = BitPosI->getInsertionPointAfterDef();
InsertPt = &**BitPosI->getInsertionPointAfterDef();
else
InsertPt = &*DT->getRoot()->getFirstNonPHIOrDbgOrAlloca();
if (!InsertPt)
Expand Down
14 changes: 9 additions & 5 deletions llvm/lib/Transforms/Scalar/Reassociate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -921,16 +921,20 @@ static Value *NegateValue(Value *V, Instruction *BI,
TheNeg->getParent()->getParent() != BI->getParent()->getParent())
continue;

Instruction *InsertPt;
BasicBlock::iterator InsertPt;
if (Instruction *InstInput = dyn_cast<Instruction>(V)) {
InsertPt = InstInput->getInsertionPointAfterDef();
if (!InsertPt)
auto InsertPtOpt = InstInput->getInsertionPointAfterDef();
if (!InsertPtOpt)
continue;
InsertPt = *InsertPtOpt;
} else {
InsertPt = &*TheNeg->getFunction()->getEntryBlock().begin();
InsertPt = TheNeg->getFunction()
->getEntryBlock()
.getFirstNonPHIOrDbg()
->getIterator();
}

TheNeg->moveBefore(InsertPt);
TheNeg->moveBefore(*InsertPt->getParent(), InsertPt);
if (TheNeg->getOpcode() == Instruction::Sub) {
TheNeg->setHasNoUnsignedWrap(false);
TheNeg->setHasNoSignedWrap(false);
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Transforms/Vectorize/VectorCombine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1810,16 +1810,16 @@ bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
return SSV->getOperand(Op);
return SV->getOperand(Op);
};
Builder.SetInsertPoint(SVI0A->getInsertionPointAfterDef());
Builder.SetInsertPoint(*SVI0A->getInsertionPointAfterDef());
Value *NSV0A = Builder.CreateShuffleVector(GetShuffleOperand(SVI0A, 0),
GetShuffleOperand(SVI0A, 1), V1A);
Builder.SetInsertPoint(SVI0B->getInsertionPointAfterDef());
Builder.SetInsertPoint(*SVI0B->getInsertionPointAfterDef());
Value *NSV0B = Builder.CreateShuffleVector(GetShuffleOperand(SVI0B, 0),
GetShuffleOperand(SVI0B, 1), V1B);
Builder.SetInsertPoint(SVI1A->getInsertionPointAfterDef());
Builder.SetInsertPoint(*SVI1A->getInsertionPointAfterDef());
Value *NSV1A = Builder.CreateShuffleVector(GetShuffleOperand(SVI1A, 0),
GetShuffleOperand(SVI1A, 1), V2A);
Builder.SetInsertPoint(SVI1B->getInsertionPointAfterDef());
Builder.SetInsertPoint(*SVI1B->getInsertionPointAfterDef());
Value *NSV1B = Builder.CreateShuffleVector(GetShuffleOperand(SVI1B, 0),
GetShuffleOperand(SVI1B, 1), V2B);
Builder.SetInsertPoint(Op0);
Expand Down