-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[DebugInfo][RemoveDIs] Support cloning and remapping DPValues #72546
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
Changes from 4 commits
070ca2c
07cd831
fc90371
3244823
68cf827
5876028
44c9c47
cd24fdf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1101,12 +1101,13 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( | |
// Note that there may be multiple predecessor blocks, so we cannot move | ||
// bonus instructions to a predecessor block. | ||
for (Instruction &BonusInst : *BB) { | ||
if (isa<DbgInfoIntrinsic>(BonusInst) || BonusInst.isTerminator()) | ||
if (BonusInst.isTerminator()) | ||
continue; | ||
|
||
Instruction *NewBonusInst = BonusInst.clone(); | ||
|
||
if (PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) { | ||
if (!isa<DbgInfoIntrinsic>(BonusInst) && | ||
PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) { | ||
// Unless the instruction has the same !dbg location as the original | ||
// branch, drop it. When we fold the bonus instructions we want to make | ||
// sure we reset their debug locations in order to avoid stepping on | ||
|
@@ -1116,7 +1117,6 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( | |
|
||
RemapInstruction(NewBonusInst, VMap, | ||
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); | ||
VMap[&BonusInst] = NewBonusInst; | ||
|
||
// If we speculated an instruction, we need to drop any metadata that may | ||
// result in undefined behavior, as the metadata might have been valid | ||
|
@@ -1126,8 +1126,17 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( | |
NewBonusInst->dropUBImplyingAttrsAndMetadata(); | ||
|
||
NewBonusInst->insertInto(PredBlock, PTI->getIterator()); | ||
NewBonusInst->cloneDebugInfoFrom(&BonusInst); | ||
|
||
for (DPValue &DPV : NewBonusInst->getDbgValueRange()) | ||
RemapDPValue(NewBonusInst->getModule(), &DPV, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); | ||
|
||
if (isa<DbgInfoIntrinsic>(BonusInst)) | ||
continue; | ||
|
||
NewBonusInst->takeName(&BonusInst); | ||
BonusInst.setName(NewBonusInst->getName() + ".old"); | ||
VMap[&BonusInst] = NewBonusInst; | ||
|
||
// Update (liveout) uses of bonus instructions, | ||
// now that the bonus instruction has been cloned into predecessor. | ||
|
@@ -3293,6 +3302,10 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, | |
BasicBlock::iterator InsertPt = EdgeBB->getFirstInsertionPt(); | ||
DenseMap<Value *, Value *> TranslateMap; // Track translated values. | ||
TranslateMap[Cond] = CB; | ||
|
||
// RemoveDIs: track instructions that we optimise away while folding, so | ||
// that we can copy DPValues from them later. | ||
BasicBlock::iterator DbgInfoCursor = BB->begin(); | ||
for (BasicBlock::iterator BBI = BB->begin(); &*BBI != BI; ++BBI) { | ||
if (PHINode *PN = dyn_cast<PHINode>(BBI)) { | ||
TranslateMap[PN] = PN->getIncomingValueForBlock(EdgeBB); | ||
|
@@ -3327,13 +3340,26 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, | |
TranslateMap[&*BBI] = N; | ||
} | ||
if (N) { | ||
// Copy all debug-info attached to instructions from the last we | ||
// successfully clone, up to this instruction (they might have been | ||
// folded away). | ||
for (; DbgInfoCursor != BBI; ++DbgInfoCursor) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hasn't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's iterating over the source block where things don't get erased, I think it's only the clones that can be simplified away in the blocks above that get deleted. This is a legitimate confusion though, perhaps renaming it to SrcDbgCursor makes it clearer? |
||
N->cloneDebugInfoFrom(&*DbgInfoCursor); | ||
DbgInfoCursor = std::next(BBI); | ||
// Clone debug-info on this instruction too. | ||
N->cloneDebugInfoFrom(&*BBI); | ||
|
||
// Register the new instruction with the assumption cache if necessary. | ||
if (auto *Assume = dyn_cast<AssumeInst>(N)) | ||
if (AC) | ||
AC->registerAssumption(Assume); | ||
} | ||
} | ||
|
||
for (; &*DbgInfoCursor != BI; ++DbgInfoCursor) | ||
InsertPt->cloneDebugInfoFrom(&*DbgInfoCursor); | ||
InsertPt->cloneDebugInfoFrom(BI); | ||
|
||
BB->removePredecessor(EdgeBB); | ||
BranchInst *EdgeBI = cast<BranchInst>(EdgeBB->getTerminator()); | ||
EdgeBI->setSuccessor(0, RealDest); | ||
|
@@ -3738,22 +3764,21 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, | |
ValueToValueMapTy VMap; // maps original values to cloned values | ||
CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(BB, PredBlock, VMap); | ||
|
||
Module *M = BB->getModule(); | ||
|
||
if (PredBlock->IsNewDbgInfoFormat) { | ||
PredBlock->getTerminator()->cloneDebugInfoFrom(BB->getTerminator()); | ||
for (DPValue &DPV : PredBlock->getTerminator()->getDbgValueRange()) { | ||
RemapDPValue(M, &DPV, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); | ||
} | ||
} | ||
|
||
// Now that the Cond was cloned into the predecessor basic block, | ||
// or/and the two conditions together. | ||
Value *BICond = VMap[BI->getCondition()]; | ||
PBI->setCondition( | ||
createLogicalOp(Builder, Opc, PBI->getCondition(), BICond, "or.cond")); | ||
|
||
// Copy any debug value intrinsics into the end of PredBlock. | ||
for (Instruction &I : *BB) { | ||
if (isa<DbgInfoIntrinsic>(I)) { | ||
Instruction *NewI = I.clone(); | ||
RemapInstruction(NewI, VMap, | ||
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); | ||
NewI->insertBefore(PBI); | ||
} | ||
} | ||
|
||
++NumFoldBranchToCommonDest; | ||
return true; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
#include "llvm/IR/InlineAsm.h" | ||
#include "llvm/IR/Instruction.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/IR/IntrinsicInst.h" | ||
#include "llvm/IR/Metadata.h" | ||
#include "llvm/IR/Operator.h" | ||
#include "llvm/IR/Type.h" | ||
|
@@ -145,6 +146,7 @@ class Mapper { | |
Value *mapValue(const Value *V); | ||
void remapInstruction(Instruction *I); | ||
void remapFunction(Function &F); | ||
void remapDPValue(DPValue &DPV); | ||
|
||
Constant *mapConstant(const Constant *C) { | ||
return cast_or_null<Constant>(mapValue(C)); | ||
|
@@ -535,6 +537,37 @@ Value *Mapper::mapValue(const Value *V) { | |
return getVM()[V] = ConstantPointerNull::get(cast<PointerType>(NewTy)); | ||
} | ||
|
||
void Mapper::remapDPValue(DPValue &V) { | ||
// Remap variables and DILocations. | ||
auto *MappedVar = mapMetadata(V.getVariable()); | ||
auto *MappedDILoc = mapMetadata(V.getDebugLoc()); | ||
V.setVariable(cast<DILocalVariable>(MappedVar)); | ||
V.setDebugLoc(DebugLoc(cast<DILocation>(MappedDILoc))); | ||
|
||
// Find Value operands and remap those. | ||
SmallVector<Value *, 4> Vals, NewVals; | ||
for (Value *Val: V.location_ops()) | ||
Vals.push_back(Val); | ||
for (Value *Val : Vals) | ||
NewVals.push_back(mapValue(Val)); | ||
|
||
// If there are no changes to the Value operands, finished. | ||
if (Vals == NewVals) | ||
return; | ||
|
||
bool IgnoreMissingLocals = Flags & RF_IgnoreMissingLocals; | ||
|
||
// Otherwise, do some replacement. | ||
if (!IgnoreMissingLocals && | ||
llvm::any_of(NewVals, [&](Value *V) { return V == nullptr;})) { | ||
V.setKillLocation(); | ||
} else { | ||
for (unsigned int I = 0; I < Vals.size(); ++I) | ||
if (NewVals[I] || !IgnoreMissingLocals) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch; I've just removed the check and added a comment, asserting something that's guaranteed three lines above seems like overkill. |
||
V.replaceVariableLocationOp(I, NewVals[I]); | ||
} | ||
} | ||
|
||
Value *Mapper::mapBlockAddress(const BlockAddress &BA) { | ||
Function *F = cast<Function>(mapValue(BA.getFunction())); | ||
|
||
|
@@ -1179,6 +1212,16 @@ void ValueMapper::remapInstruction(Instruction &I) { | |
FlushingMapper(pImpl)->remapInstruction(&I); | ||
} | ||
|
||
void ValueMapper::remapDPValue(Module *M, DPValue &V) { | ||
FlushingMapper(pImpl)->remapDPValue(V); | ||
} | ||
|
||
void ValueMapper::remapDPValueRange(Module *M, iterator_range<DPValue::self_iterator> Range) { | ||
for (DPValue &DPV : Range) { | ||
remapDPValue(M, DPV); | ||
} | ||
} | ||
|
||
void ValueMapper::remapFunction(Function &F) { | ||
FlushingMapper(pImpl)->remapFunction(F); | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.