From 070ca2ca3aa09fa22755bac7ec0edf27299a9b3e Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 16 Nov 2023 15:41:52 +0000 Subject: [PATCH 1/8] [DebugInfo] Clone dbg.values in SimplifyCFG like normal instructions The code in the CloneInstructionsIntoPredec... function modified by this patch has a long history that dates back to 2011, see d715ec82b4ad12c59. There, when folding branches, all dbg.value intrinsics seen when folding would be saved and then re-inserted at the end of whatever was folded. Over the last 12 years this behaviour has been preserved. However, IMO it's bad behaviour. If we have: inst1 dbg.value1 inst2 dbg.value2 And we fold that sequence into a different block, then we would want the instructions and variable assignments to appear in the same order. However because of this old behaviour, the dbg.values are sunk, and we get: inst1 inst2 dbg.value1 dbg.value2 This clustering of dbg.values can make assignments to the same variable invisible, as well as reducing the coverage of other assignments. This patch relaxes the CloneInstructions... function and allows it to clone and update dbg.values in-place, causing them to appear in the original order in the destination block. I've added some extra dbg.values to the updated test: without the changes to the pass, the dbg.values sink into a blob ahead of the select. (Metadata changes to make the LLVM-IR parser not drop the debug-info for it being out of date. The RemoveDIs related RUN line has been removed because it was spuriously passing due to the debug-info being dropped). Don't add dbg.values to the remap-map (it's wasteful), clang-format --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 21 +++++------- .../Transforms/SimplifyCFG/branch-fold-dbg.ll | 34 ++++++++++++------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 4dae52a8ecffd..9f4f0f2512904 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -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(BonusInst) || BonusInst.isTerminator()) + if (BonusInst.isTerminator()) continue; Instruction *NewBonusInst = BonusInst.clone(); - if (PTI->getDebugLoc() != NewBonusInst->getDebugLoc()) { + if (!isa(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,13 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( NewBonusInst->dropUBImplyingAttrsAndMetadata(); NewBonusInst->insertInto(PredBlock, PTI->getIterator()); + + if (isa(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. @@ -3744,16 +3749,6 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, 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(I)) { - Instruction *NewI = I.clone(); - RemapInstruction(NewI, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - NewI->insertBefore(PBI); - } - } - ++NumFoldBranchToCommonDest; return true; } diff --git a/llvm/test/Transforms/SimplifyCFG/branch-fold-dbg.ll b/llvm/test/Transforms/SimplifyCFG/branch-fold-dbg.ll index 41486c5935a39..e8b8cc6edafe0 100644 --- a/llvm/test/Transforms/SimplifyCFG/branch-fold-dbg.ll +++ b/llvm/test/Transforms/SimplifyCFG/branch-fold-dbg.ll @@ -8,23 +8,26 @@ define i1 @foo(i32) nounwind ssp !dbg !0 { ; CHECK-LABEL: @foo( ; CHECK-NEXT: Entry: -; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0:%.*]], 0 -; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 4 -; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TMP1]], [[TMP2]] -; CHECK-NEXT: br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[BB2:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[TMP0:%.*]], 0, !dbg [[DBG7:![0-9]+]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP0]], 4, !dbg [[DBG7]] +; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[TMP1]], [[TMP2]], !dbg [[DBG7]] +; CHECK-NEXT: br i1 [[OR_COND]], label [[COMMON_RET:%.*]], label [[BB2:%.*]], !dbg [[DBG7]] ; CHECK: BB2: -; CHECK-NEXT: [[TMP3:%.*]] = shl i32 1, [[TMP0]] -; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 31 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0 +; CHECK-NEXT: [[TMP3:%.*]] = shl i32 1, [[TMP0]], !dbg [[DBG7]] +; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 31, !dbg [[DBG7]] +; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP4]], 0, !dbg [[DBG7]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr null, metadata [[META8:![0-9]+]], metadata !DIExpression()), !dbg [[DBG13:![0-9]+]] ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [5 x %0], ptr @[[GLOB0:[0-9]+]], i32 0, i32 [[TMP0]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr [[TMP6]], metadata [[META8]], metadata !DIExpression()), !dbg [[DBG13]] ; CHECK-NEXT: [[TMP7:%.*]] = icmp eq ptr [[TMP6]], null -; CHECK-NEXT: [[OR_COND2:%.*]] = select i1 [[TMP5]], i1 true, i1 [[TMP7]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr [[TMP6]], metadata [[META8]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: [[OR_COND2:%.*]] = select i1 [[TMP5]], i1 true, i1 [[TMP7]], !dbg [[DBG7]] ; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i32 [[TMP0]], 0 -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[OR_COND2]], i1 false, i1 [[TMP8]] -; CHECK-NEXT: br label [[COMMON_RET]] +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[OR_COND2]], i1 false, i1 [[TMP8]], !dbg [[DBG7]] +; CHECK-NEXT: br label [[COMMON_RET]], !dbg [[DBG7]] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[SPEC_SELECT]], [[BB2]] ] -; CHECK-NEXT: ret i1 [[COMMON_RET_OP]] +; CHECK-NEXT: ret i1 [[COMMON_RET_OP]], !dbg [[DBG14:![0-9]+]] ; Entry: %1 = icmp slt i32 %0, 0, !dbg !5 @@ -42,9 +45,11 @@ BB2: ; preds = %BB1 BB3: ; preds = %BB2 + call void @llvm.dbg.value(metadata ptr null, metadata !7, metadata !DIExpression()), !dbg !12 %6 = getelementptr inbounds [5 x %0], ptr @0, i32 0, i32 %0, !dbg !6 - call void @llvm.dbg.value(metadata ptr %6, metadata !7, metadata !{}), !dbg !12 + call void @llvm.dbg.value(metadata ptr %6, metadata !7, metadata !DIExpression()), !dbg !12 %7 = icmp eq ptr %6, null, !dbg !13 + call void @llvm.dbg.value(metadata ptr %6, metadata !7, metadata !DIExpression()), !dbg !12 br i1 %7, label %BB5, label %BB4, !dbg !13 BB4: ; preds = %BB3 @@ -58,12 +63,13 @@ BB5: ; preds = %BB3, %BB2, %BB1, %E declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone !llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!16, !17} !0 = distinct !DISubprogram(name: "foo", line: 231, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !15, scope: !1, type: !3) !1 = !DIFile(filename: "a.c", directory: "/private/tmp") !2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang (trunk 129006)", isOptimized: true, emissionKind: FullDebug, file: !15, enums: !4, retainedTypes: !4) !3 = !DISubroutineType(types: !4) -!4 = !{null} +!4 = !{} !5 = !DILocation(line: 131, column: 2, scope: !0) !6 = !DILocation(line: 134, column: 2, scope: !0) !7 = !DILocalVariable(name: "bar", line: 232, scope: !8, file: !1, type: !9) @@ -75,3 +81,5 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) nounwind readnone !13 = !DILocation(line: 234, column: 2, scope: !8) !14 = !DILocation(line: 274, column: 1, scope: !8) !15 = !DIFile(filename: "a.c", directory: "/private/tmp") +!16 = !{i32 1, !"Debug Info Version", i32 3} +!17 = !{i32 2, !"Dwarf Version", i32 4} From 07cd831607725bda5e69277c4e0ed61b403bd221 Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Wed, 15 Nov 2023 16:39:11 +0000 Subject: [PATCH 2/8] [DebugInfo][RemoveDIs] Allow speculative-DPMarker creation There's good justification for having a function specifying "I need there to be a marker here, so return the marker there or create a new one". This was going to come later in the series, but it's starting to become necessary much eariler alas. Make use of it in spliceDebugInfo, where we can occasionally splice DPValues onto the end() iterator of a block while it's been edited. --- llvm/lib/IR/BasicBlock.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp index a41bcff58e529..ed00f3f247e3a 100644 --- a/llvm/lib/IR/BasicBlock.cpp +++ b/llvm/lib/IR/BasicBlock.cpp @@ -39,8 +39,8 @@ cl::opt DPMarker *BasicBlock::createMarker(Instruction *I) { assert(IsNewDbgInfoFormat && "Tried to create a marker in a non new debug-info block!"); - assert(I->DbgMarker == nullptr && - "Tried to create marker for instuction that already has one!"); + if (I->DbgMarker) + return I->DbgMarker; DPMarker *Marker = new DPMarker(); Marker->MarkedInstr = I; I->DbgMarker = Marker; @@ -918,8 +918,8 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src, // move their markers onto Last. They remain in the Src block. No action // needed. if (!ReadFromHead) { - DPMarker *OntoLast = Src->getMarker(Last); - DPMarker *FromFirst = Src->getMarker(First); + DPMarker *OntoLast = Src->createMarker(Last); + DPMarker *FromFirst = Src->createMarker(First); OntoLast->absorbDebugValues(*FromFirst, true); // Always insert at head of it. } From fc90371e43e58497da4e2b31addb4ceb02be58be Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Wed, 7 Jun 2023 16:00:15 +0100 Subject: [PATCH 3/8] [DebugInfo][RemoveDIs] Support cloning and remapping DPValues This patch adds support for CloneBasicBlock duplicating the DPValues attached to instructions, and adds facilities to remap them into their new context. The plumbing to achieve this is fairly straightforwards and mechanical. I've also added illustrative uses to LoopUnrollRuntime, SimpleLoopUnswitch and SimplifyCFG. The former only updates for the epilogue right now so I've added CHECK lines just for the end of an unrolled loop (further updates coming later). SimpleLoopUnswitch had no debug-info tests so I've added a new one. The two modified parts of SimplifyCFG are covered by the two modified SimplifyCFG tests. These are scenarios where we have to do extra cloning for copying of DPValues because they're no longer instructions, and remap them too. --- .../llvm/Transforms/Utils/ValueMapper.h | 22 ++++ .../Transforms/Scalar/SimpleLoopUnswitch.cpp | 2 + llvm/lib/Transforms/Utils/CloneFunction.cpp | 5 +- .../Transforms/Utils/LoopUnrollRuntime.cpp | 5 + llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 30 +++++ llvm/lib/Transforms/Utils/ValueMapper.cpp | 43 +++++++ .../LoopUnroll/runtime-epilog-debuginfo.ll | 13 +++ .../SimpleLoopUnswitch/debuginfo.ll | 108 ++++++++++++++++++ .../SimplifyCFG/jump-threading-debuginfo.ll | 95 +++++++++++++++ 9 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll create mode 100644 llvm/test/Transforms/SimplifyCFG/jump-threading-debuginfo.ll diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index e80951d50d56e..82f0f99ee14ca 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -15,17 +15,21 @@ #define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/simple_ilist.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" namespace llvm { class Constant; +class DIBuilder; +class DPValue; class Function; class GlobalVariable; class Instruction; class MDNode; class Metadata; +class Module; class Type; class Value; @@ -175,6 +179,8 @@ class ValueMapper { Constant *mapConstant(const Constant &C); void remapInstruction(Instruction &I); + void remapDPValue(Module *M, DPValue &V); + void remapDPValueRange(Module *M, iterator_range::iterator> Range); void remapFunction(Function &F); void remapGlobalObjectMetadata(GlobalObject &GO); @@ -260,6 +266,22 @@ inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I); } +/// Remap the Values used in the DPValue \a V using the value map \a VM. +inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { + ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValue(M, *V); +} + +/// Remap the Values used in the DPValue \a V using the value map \a VM. +inline void RemapDPValueRange(Module *M, iterator_range::iterator> Range, ValueToValueMapTy &VM, + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { + ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValueRange(M, Range); +} + /// Remap the operands, metadata, arguments, and instructions of a function. /// /// Calls \a MapValue() on prefix data, prologue data, and personality diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index e9e6ead9ccb74..72465d0a1db09 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -1260,8 +1260,10 @@ static BasicBlock *buildClonedLoopBlocks( // everything available. Also, we have inserted new instructions which may // include assume intrinsics, so we update the assumption cache while // processing this. + Module *M = ClonedPH->getParent()->getParent(); for (auto *ClonedBB : NewBlocks) for (Instruction &I : *ClonedBB) { + RemapDPValueRange(M, I.getDbgValueRange(), VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); if (auto *II = dyn_cast(&I)) diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index 94c6abcf7b4e1..9ff4f01a9809e 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -59,7 +59,10 @@ BasicBlock *llvm::CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, Instruction *NewInst = I.clone(); if (I.hasName()) NewInst->setName(I.getName() + NameSuffix); - NewInst->insertInto(NewBB, NewBB->end()); + + NewInst->insertBefore(*NewBB, NewBB->end()); + NewInst->cloneDebugInfoFrom(&I); + VMap[&I] = NewInst; // Add instruction map to value. if (isa(I) && !I.isDebugOrPseudoInst()) { diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 1c8850048f6ab..bed9dc6d22e5f 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -913,9 +913,14 @@ bool llvm::UnrollRuntimeLoopRemainder( // Rewrite the cloned instruction operands to use the values created when the // clone is created. for (BasicBlock *BB : NewBlocks) { + Module *M = BB->getModule(); for (Instruction &I : *BB) { RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + for (DPValue &DPV : I.getDbgValueRange()) { + RemapDPValue(M, &DPV, VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + } } } diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 9f4f0f2512904..fda5d6a7f92e3 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1126,6 +1126,10 @@ 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(BonusInst)) continue; @@ -3298,6 +3302,10 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, BasicBlock::iterator InsertPt = EdgeBB->getFirstInsertionPt(); DenseMap 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(BBI)) { TranslateMap[PN] = PN->getIncomingValueForBlock(EdgeBB); @@ -3332,6 +3340,15 @@ 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) + 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(N)) if (AC) @@ -3339,6 +3356,10 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, } } + for (; &*DbgInfoCursor != BI; ++DbgInfoCursor) + InsertPt->cloneDebugInfoFrom(&*DbgInfoCursor); + InsertPt->cloneDebugInfoFrom(BI); + BB->removePredecessor(EdgeBB); BranchInst *EdgeBI = cast(EdgeBB->getTerminator()); EdgeBI->setSuccessor(0, RealDest); @@ -3743,6 +3764,15 @@ 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()]; diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 3446e31cc2ef1..70dfffc5d1dce 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -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(mapValue(C)); @@ -535,6 +537,37 @@ Value *Mapper::mapValue(const Value *V) { return getVM()[V] = ConstantPointerNull::get(cast(NewTy)); } +void Mapper::remapDPValue(DPValue &V) { + // Remap variables and DILocations. + auto *MappedVar = mapMetadata(V.getVariable()); + auto *MappedDILoc = mapMetadata(V.getDebugLoc()); + V.setVariable(cast(MappedVar)); + V.setDebugLoc(DebugLoc(cast(MappedDILoc))); + + // Find Value operands and remap those. + SmallVector 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) + V.replaceVariableLocationOp(I, NewVals[I]); + } +} + Value *Mapper::mapBlockAddress(const BlockAddress &BA) { Function *F = cast(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 Range) { + for (DPValue &DPV : Range) { + remapDPValue(M, DPV); + } +} + void ValueMapper::remapFunction(Function &F) { FlushingMapper(pImpl)->remapFunction(F); } diff --git a/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll b/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll index bd5d68c5b9af3..3622374661185 100644 --- a/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll @@ -1,4 +1,5 @@ ; RUN: opt -passes=loop-unroll -unroll-runtime -unroll-runtime-epilog -S %s | FileCheck %s +; RUN: opt -passes=loop-unroll -unroll-runtime -unroll-runtime-epilog -S %s --try-experimental-debuginfo-iterators | FileCheck %s ; Test that epilogue is tagged with the same debug information as original loop body rather than original loop exit. @@ -11,6 +12,18 @@ ; CHECK: br i1 %lcmp.mod, label %for.body.i.epil.preheader, label %lee1.exit.loopexit, !dbg ![[LOOP_LOC]] ; CHECK: for.body.i.epil.preheader: ; CHECK: br label %for.body.i.epil, !dbg ![[LOOP_LOC]] +; CHECK: for.body.i.epil: +;; Ensure that when we clone the div/add/add and it's following dbg.values, +;; those dbg.values are remapped to the duplicated adds, not the originals. +; CHECK: %div.i.epil = sdiv i32 %t.08.i.epil, 2, +; CHECK-NEXT: %add.i.epil = add i32 %t.08.i.epil, %a, +; CHECK-NEXT: %add1.i.epil = add i32 %add.i.epil, %div.i.epil, +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %add1.i.epil, +; CHECK-NEXT: %inc.i.epil = add nuw i32 %i.09.i.epil, 1, !dbg !36 +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %inc.i.epil, +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %inc.i.epil, +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 %add1.i.epil, + ; CHECK: lee1.exit.loopexit: ; CHECK: br label %lee1.exit, !dbg ![[EXIT_LOC:[0-9]+]] diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll b/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll new file mode 100644 index 0000000000000..e821fd48a92fc --- /dev/null +++ b/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll @@ -0,0 +1,108 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -passes='loop-mssa(simple-loop-unswitch),verify' -S < %s | FileCheck %s +; RUN: opt -passes='loop-mssa(simple-loop-unswitch),verify' -S < %s --try-experimental-debuginfo-iterators | FileCheck %s +; +;; Check that when we duplicate the load in the loop header, we also duplicate +;; the corresponding dbg.value. +;; FIXME: the hoisted load dominates the duplicated dbg.value, however as it's +;; not subsequently used in the loop, so it doesn't get remapped into the +;; debug user and we get a undef/poison dbg.value. This is suboptimal, but it's +;; important that it gets duplicated nonetheless. + +declare void @clobber() +declare void @llvm.dbg.value(metadata, metadata, metadata) + +define i32 @partial_unswitch_true_successor(ptr %ptr, i32 %N) { +; CHECK-LABEL: @partial_unswitch_true_successor( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[PTR:%.*]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 100 +; CHECK-NEXT: br i1 [[TMP1]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] +; CHECK: entry.split.us: +; CHECK-NEXT: br label [[LOOP_HEADER_US:%.*]] +; CHECK: loop.header.us: +; CHECK-NEXT: [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ], [ [[IV_NEXT_US:%.*]], [[LOOP_LATCH_US:%.*]] ] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 poison, metadata [[META3:![0-9]+]], metadata !DIExpression()), !dbg [[DBG8:![0-9]+]] +; CHECK-NEXT: br label [[NOCLOBBER_US:%.*]] +; CHECK: noclobber.us: +; CHECK-NEXT: br label [[LOOP_LATCH_US]] +; CHECK: loop.latch.us: +; CHECK-NEXT: [[C_US:%.*]] = icmp ult i32 [[IV_US]], [[N:%.*]] +; CHECK-NEXT: [[IV_NEXT_US]] = add i32 [[IV_US]], 1 +; CHECK-NEXT: br i1 [[C_US]], label [[LOOP_HEADER_US]], label [[EXIT_SPLIT_US:%.*]] +; CHECK: exit.split.us: +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: entry.split: +; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] +; CHECK: loop.header: +; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] +; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[PTR]], align 4 +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[LV]], metadata [[META3]], metadata !DIExpression()), !dbg [[DBG8]] +; CHECK-NEXT: [[SC:%.*]] = icmp eq i32 [[LV]], 100 +; CHECK-NEXT: br i1 [[SC]], label [[NOCLOBBER:%.*]], label [[CLOBBER:%.*]] +; CHECK: noclobber: +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: clobber: +; CHECK-NEXT: call void @clobber() +; CHECK-NEXT: br label [[LOOP_LATCH]] +; CHECK: loop.latch: +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[IV]], [[N]] +; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 +; CHECK-NEXT: br i1 [[C]], label [[LOOP_HEADER]], label [[EXIT_SPLIT:%.*]], !llvm.loop [[LOOP9:![0-9]+]] +; CHECK: exit.split: +; CHECK-NEXT: br label [[EXIT]] +; CHECK: exit: +; CHECK-NEXT: ret i32 10 +; +entry: + br label %loop.header + +loop.header: + %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] + %lv = load i32, ptr %ptr + call void @llvm.dbg.value(metadata i32 %lv, metadata !6, metadata !DIExpression()), !dbg !7 + %sc = icmp eq i32 %lv, 100 + br i1 %sc, label %noclobber, label %clobber + +noclobber: + br label %loop.latch + +clobber: + call void @clobber() + br label %loop.latch + +loop.latch: + %c = icmp ult i32 %iv, %N + %iv.next = add i32 %iv, 1 + br i1 %c, label %loop.header, label %exit + +exit: + ret i32 10 +} + +!llvm.module.flags = !{!21} +!llvm.dbg.cu = !{!2} + +!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !20, scope: !1, type: !3) +!1 = !DIFile(filename: "b.c", directory: "/private/tmp") +!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", isOptimized: true, emissionKind: FullDebug, file: !20) +!3 = !DISubroutineType(types: !4) +!4 = !{!5} +!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) +!6 = !DILocalVariable(name: "i", line: 2, arg: 1, scope: !0, file: !1, type: !5) +!7 = !DILocation(line: 2, column: 13, scope: !0) +!9 = !DILocalVariable(name: "k", line: 3, scope: !10, file: !1, type: !5) +!10 = distinct !DILexicalBlock(line: 2, column: 16, file: !20, scope: !0) +!11 = !DILocation(line: 3, column: 12, scope: !10) +!12 = !DILocation(line: 4, column: 3, scope: !10) +!13 = !DILocation(line: 5, column: 5, scope: !14) +!14 = distinct !DILexicalBlock(line: 4, column: 10, file: !20, scope: !10) +!15 = !DILocation(line: 6, column: 3, scope: !14) +!16 = !DILocation(line: 7, column: 5, scope: !17) +!17 = distinct !DILexicalBlock(line: 6, column: 10, file: !20, scope: !10) +!18 = !DILocation(line: 8, column: 3, scope: !17) +!19 = !DILocation(line: 9, column: 3, scope: !10) +!20 = !DIFile(filename: "b.c", directory: "/private/tmp") +!21 = !{i32 1, !"Debug Info Version", i32 3} + + diff --git a/llvm/test/Transforms/SimplifyCFG/jump-threading-debuginfo.ll b/llvm/test/Transforms/SimplifyCFG/jump-threading-debuginfo.ll new file mode 100644 index 0000000000000..ad88d23706c99 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/jump-threading-debuginfo.ll @@ -0,0 +1,95 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s +;; Test that we correct clone debug-info when folding in +;; FoldCondBranchOnValueKnownInPredecessorImpl. There should be two paths +;; through this program, assigning [0 1 2 3 4 5 6 7] to the variable down +;; one path, and [0 1 2 3 6 7] down the other. + +declare void @foo() +declare void @bar() +declare void @use.i1(i1) +declare void @use.i32(i32) +declare void @llvm.dbg.value(metadata, metadata, metadata) + +define void @test_phi_extra_use(i1 %c) { +; CHECK-LABEL: @test_phi_extra_use( +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] +; CHECK: if: +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 0, metadata [[META7:![0-9]+]], metadata !DIExpression()), !dbg [[DBG13:![0-9]+]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 1, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @use.i1(i1 true) +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 2, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 3, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: br label [[JOIN2:%.*]] +; CHECK: else: +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 0, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 1, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @use.i1(i1 false) +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 2, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 3, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 4, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 5, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: br label [[JOIN2]] +; CHECK: join2: +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 6, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 7, metadata [[META7]], metadata !DIExpression()), !dbg [[DBG13]] +; CHECK-NEXT: ret void, !dbg [[DBG13]] +; + br i1 %c, label %if, label %else + +if: + call void @foo() + br label %join + +else: + call void @bar() + br label %join + +join: + %c2 = phi i1 [ true, %if ], [ false, %else ] + call void @llvm.dbg.value(metadata i32 0, metadata !12, metadata !DIExpression()), !dbg !15 + call void @llvm.dbg.value(metadata i32 1, metadata !12, metadata !DIExpression()), !dbg !15 + call void @use.i1(i1 %c2) + call void @llvm.dbg.value(metadata i32 2, metadata !12, metadata !DIExpression()), !dbg !15 + call void @llvm.dbg.value(metadata i32 3, metadata !12, metadata !DIExpression()), !dbg !15 + br i1 %c2, label %if2, label %else2 + +if2: + call void @foo() + br label %join2 + +else2: + call void @llvm.dbg.value(metadata i32 4, metadata !12, metadata !DIExpression()), !dbg !15 + call void @llvm.dbg.value(metadata i32 5, metadata !12, metadata !DIExpression()), !dbg !15 + call void @bar() + br label %join2 + +join2: + call void @llvm.dbg.value(metadata i32 6, metadata !12, metadata !DIExpression()), !dbg !15 + call void @llvm.dbg.value(metadata i32 7, metadata !12, metadata !DIExpression()), !dbg !15 + ret void, !dbg !15 +} + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: ".", directory: "/foo") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang"} +!7 = distinct !DISubprogram(name: "test1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "getdirt", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!15 = !DILocation(line: 1, column: 15, scope: !7) + From 3244823210a72b72dc855bbd87c771b169d2da00 Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 23 Nov 2023 16:53:37 +0000 Subject: [PATCH 4/8] Address review comments --- llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 3 +-- llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll | 2 +- llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index bed9dc6d22e5f..e360502433e5c 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -917,8 +917,7 @@ bool llvm::UnrollRuntimeLoopRemainder( for (Instruction &I : *BB) { RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - for (DPValue &DPV : I.getDbgValueRange()) { - RemapDPValue(M, &DPV, VMap, + RemapDPValueRange(M, I.getDbgValueRange(), VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } } diff --git a/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll b/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll index 3622374661185..4de90c3a00a69 100644 --- a/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll +++ b/llvm/test/Transforms/LoopUnroll/runtime-epilog-debuginfo.ll @@ -13,7 +13,7 @@ ; CHECK: for.body.i.epil.preheader: ; CHECK: br label %for.body.i.epil, !dbg ![[LOOP_LOC]] ; CHECK: for.body.i.epil: -;; Ensure that when we clone the div/add/add and it's following dbg.values, +;; Ensure that when we clone the div/add/add and its following dbg.values, ;; those dbg.values are remapped to the duplicated adds, not the originals. ; CHECK: %div.i.epil = sdiv i32 %t.08.i.epil, 2, ; CHECK-NEXT: %add.i.epil = add i32 %t.08.i.epil, %a, diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll b/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll index e821fd48a92fc..ca3691dff9d18 100644 --- a/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/debuginfo.ll @@ -7,7 +7,7 @@ ;; FIXME: the hoisted load dominates the duplicated dbg.value, however as it's ;; not subsequently used in the loop, so it doesn't get remapped into the ;; debug user and we get a undef/poison dbg.value. This is suboptimal, but it's -;; important that it gets duplicated nonetheless. +;; important that the dbg.value gets duplicated nonetheless. declare void @clobber() declare void @llvm.dbg.value(metadata, metadata, metadata) From 68cf827a0cbee2823a83ec6433a9e0f8923d702f Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 23 Nov 2023 17:10:43 +0000 Subject: [PATCH 5/8] Downgrade a test-strength after review feedback --- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 70dfffc5d1dce..0eb6ea7728f91 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -562,8 +562,10 @@ void Mapper::remapDPValue(DPValue &V) { llvm::any_of(NewVals, [&](Value *V) { return V == nullptr;})) { V.setKillLocation(); } else { + // Either we have all non-empty NewVals, or we're permitted to ignore + // missing locals. for (unsigned int I = 0; I < Vals.size(); ++I) - if (NewVals[I] || !IgnoreMissingLocals) + if (NewVals[I]) V.replaceVariableLocationOp(I, NewVals[I]); } } From 5876028372f5542b55e1862f7878be76947a5f67 Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 23 Nov 2023 17:11:45 +0000 Subject: [PATCH 6/8] I don't always build my code, but when I do, I like it to compile --- llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index e360502433e5c..ac8aff15c313c 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -919,7 +919,6 @@ bool llvm::UnrollRuntimeLoopRemainder( RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapDPValueRange(M, I.getDbgValueRange(), VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - } } } From 44c9c47828ed61acba4a5175347e6ec697fa439b Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 23 Nov 2023 17:18:31 +0000 Subject: [PATCH 7/8] Rename an iterator to be clearer, add alias for DPValue iterator type --- llvm/include/llvm/Transforms/Utils/ValueMapper.h | 5 +++-- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index 82f0f99ee14ca..5a59da29bcaf3 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -34,6 +34,7 @@ class Type; class Value; using ValueToValueMapTy = ValueMap; +using DPValueIterator = simple_ilist::iterator; /// This is a class that can be implemented by clients to remap types when /// cloning constants and instructions. @@ -180,7 +181,7 @@ class ValueMapper { void remapInstruction(Instruction &I); void remapDPValue(Module *M, DPValue &V); - void remapDPValueRange(Module *M, iterator_range::iterator> Range); + void remapDPValueRange(Module *M, iterator_range Range); void remapFunction(Function &F); void remapGlobalObjectMetadata(GlobalObject &GO); @@ -275,7 +276,7 @@ inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM, } /// Remap the Values used in the DPValue \a V using the value map \a VM. -inline void RemapDPValueRange(Module *M, iterator_range::iterator> Range, ValueToValueMapTy &VM, +inline void RemapDPValueRange(Module *M, iterator_range Range, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = nullptr, ValueMaterializer *Materializer = nullptr) { diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index fda5d6a7f92e3..355d5f86c1bbb 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3305,7 +3305,7 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, // RemoveDIs: track instructions that we optimise away while folding, so // that we can copy DPValues from them later. - BasicBlock::iterator DbgInfoCursor = BB->begin(); + BasicBlock::iterator SrcDbgCursor = BB->begin(); for (BasicBlock::iterator BBI = BB->begin(); &*BBI != BI; ++BBI) { if (PHINode *PN = dyn_cast(BBI)) { TranslateMap[PN] = PN->getIncomingValueForBlock(EdgeBB); @@ -3343,9 +3343,9 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, // 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) - N->cloneDebugInfoFrom(&*DbgInfoCursor); - DbgInfoCursor = std::next(BBI); + for (; SrcDbgCursor != BBI; ++SrcDbgCursor) + N->cloneDebugInfoFrom(&*SrcDbgCursor); + SrcDbgCursor = std::next(BBI); // Clone debug-info on this instruction too. N->cloneDebugInfoFrom(&*BBI); @@ -3356,8 +3356,8 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, } } - for (; &*DbgInfoCursor != BI; ++DbgInfoCursor) - InsertPt->cloneDebugInfoFrom(&*DbgInfoCursor); + for (; &*SrcDbgCursor != BI; ++SrcDbgCursor) + InsertPt->cloneDebugInfoFrom(&*SrcDbgCursor); InsertPt->cloneDebugInfoFrom(BI); BB->removePredecessor(EdgeBB); From cd24fdfae794aad3e2d7acb6a159140703d42f8a Mon Sep 17 00:00:00 2001 From: Jeremy Morse Date: Thu, 23 Nov 2023 17:19:52 +0000 Subject: [PATCH 8/8] Appease clang-format --- llvm/include/llvm/Transforms/Utils/ValueMapper.h | 14 +++++++------- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | 3 ++- llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 2 +- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 6 ++++-- llvm/lib/Transforms/Utils/ValueMapper.cpp | 7 ++++--- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index 5a59da29bcaf3..eedd25f898c01 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -269,17 +269,17 @@ inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, /// Remap the Values used in the DPValue \a V using the value map \a VM. inline void RemapDPValue(Module *M, DPValue *V, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None, - ValueMapTypeRemapper *TypeMapper = nullptr, - ValueMaterializer *Materializer = nullptr) { + RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValue(M, *V); } /// Remap the Values used in the DPValue \a V using the value map \a VM. -inline void RemapDPValueRange(Module *M, iterator_range Range, ValueToValueMapTy &VM, - RemapFlags Flags = RF_None, - ValueMapTypeRemapper *TypeMapper = nullptr, - ValueMaterializer *Materializer = nullptr) { +inline void RemapDPValueRange(Module *M, iterator_range Range, + ValueToValueMapTy &VM, RemapFlags Flags = RF_None, + ValueMapTypeRemapper *TypeMapper = nullptr, + ValueMaterializer *Materializer = nullptr) { ValueMapper(VM, Flags, TypeMapper, Materializer).remapDPValueRange(M, Range); } diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index 72465d0a1db09..63f6367f3b7f0 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -1263,7 +1263,8 @@ static BasicBlock *buildClonedLoopBlocks( Module *M = ClonedPH->getParent()->getParent(); for (auto *ClonedBB : NewBlocks) for (Instruction &I : *ClonedBB) { - RemapDPValueRange(M, I.getDbgValueRange(), VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDPValueRange(M, I.getDbgValueRange(), VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); if (auto *II = dyn_cast(&I)) diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index ac8aff15c313c..612f699708814 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -918,7 +918,7 @@ bool llvm::UnrollRuntimeLoopRemainder( RemapInstruction(&I, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); RemapDPValueRange(M, I.getDbgValueRange(), VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } } diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 355d5f86c1bbb..2537a2bb9c4df 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -1129,7 +1129,8 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses( NewBonusInst->cloneDebugInfoFrom(&BonusInst); for (DPValue &DPV : NewBonusInst->getDbgValueRange()) - RemapDPValue(NewBonusInst->getModule(), &DPV, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDPValue(NewBonusInst->getModule(), &DPV, VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); if (isa(BonusInst)) continue; @@ -3769,7 +3770,8 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, if (PredBlock->IsNewDbgInfoFormat) { PredBlock->getTerminator()->cloneDebugInfoFrom(BB->getTerminator()); for (DPValue &DPV : PredBlock->getTerminator()->getDbgValueRange()) { - RemapDPValue(M, &DPV, VMap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); + RemapDPValue(M, &DPV, VMap, + RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); } } diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 0eb6ea7728f91..71d0f09e47713 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -546,7 +546,7 @@ void Mapper::remapDPValue(DPValue &V) { // Find Value operands and remap those. SmallVector Vals, NewVals; - for (Value *Val: V.location_ops()) + for (Value *Val : V.location_ops()) Vals.push_back(Val); for (Value *Val : Vals) NewVals.push_back(mapValue(Val)); @@ -559,7 +559,7 @@ void Mapper::remapDPValue(DPValue &V) { // Otherwise, do some replacement. if (!IgnoreMissingLocals && - llvm::any_of(NewVals, [&](Value *V) { return V == nullptr;})) { + llvm::any_of(NewVals, [&](Value *V) { return V == nullptr; })) { V.setKillLocation(); } else { // Either we have all non-empty NewVals, or we're permitted to ignore @@ -1218,7 +1218,8 @@ void ValueMapper::remapDPValue(Module *M, DPValue &V) { FlushingMapper(pImpl)->remapDPValue(V); } -void ValueMapper::remapDPValueRange(Module *M, iterator_range Range) { +void ValueMapper::remapDPValueRange( + Module *M, iterator_range Range) { for (DPValue &DPV : Range) { remapDPValue(M, DPV); }