Index: include/llvm/IR/DebugInfoMetadata.h =================================================================== --- include/llvm/IR/DebugInfoMetadata.h +++ include/llvm/IR/DebugInfoMetadata.h @@ -1320,27 +1320,6 @@ /// Returns a new DILocation with updated \p Discriminator. inline DILocation *cloneWithDiscriminator(unsigned Discriminator) const; - /// When two instructions are combined into a single instruction we also - /// need to combine the original locations into a single location. - /// - /// When the locations are the same we can use either location. When they - /// differ, we need a third location which is distinct from either. If - /// they have the same file/line but have a different discriminator we - /// could create a location with a new discriminator. If they are from - /// different files/lines the location is ambiguous and can't be - /// represented in a single line entry. In this case, no location - /// should be set. - /// - /// Currently the function does not create a new location. If the locations - /// are the same, or cannot be discriminated, the first location is returned. - /// Otherwise an empty location will be used. - static const DILocation *getMergedLocation(const DILocation *LocA, - const DILocation *LocB) { - if (LocA && LocB && (LocA == LocB || !LocA->canDiscriminate(*LocB))) - return LocA; - return nullptr; - } - Metadata *getRawScope() const { return getOperand(0); } Metadata *getRawInlinedAt() const { if (getNumOperands() == 2) Index: include/llvm/IR/Instruction.h =================================================================== --- include/llvm/IR/Instruction.h +++ include/llvm/IR/Instruction.h @@ -258,6 +258,22 @@ /// Return the debug location for this node as a DebugLoc. const DebugLoc &getDebugLoc() const { return DbgLoc; } + /// When two instructions are combined into a single instruction we also + /// need to combine the original locations into a single location. + /// + /// When the locations are the same we can use either location. When they + /// differ, we need a third location which is distinct from either. If + /// they have the same file/line but have a different discriminator we + /// could create a location with a new discriminator. If they are from + /// different files/lines the location is ambiguous and can't be + /// represented in a single line entry. In this case, no location + /// should be set. + /// + /// Currently the function does not create a new location. If the locations + /// are the same, or cannot be discriminated, the first location is returned. + /// Otherwise an empty location will be used. + void mergeDebugLocWith(const DILocation *Other); + /// Set or clear the nsw flag on this instruction, which must be an operator /// which supports this flag. See LangRef.html for the meaning of this flag. void setHasNoUnsignedWrap(bool b = true); Index: lib/IR/Instruction.cpp =================================================================== --- lib/IR/Instruction.cpp +++ lib/IR/Instruction.cpp @@ -15,6 +15,7 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" @@ -651,3 +652,21 @@ New->copyMetadata(*this); return New; } + +void Instruction::mergeDebugLocWith(const DILocation *Other) { + // If they are equivalent, keep the current location. + DILocation *Loc = DbgLoc.get(); + if (Loc && Other && (Loc == Other || !Loc->canDiscriminate(*Other))) + return; + + // If this is a call instruction, replace it with a line 0 location in the + // correct scope. + if (Loc && isa(this)) { + DbgLoc = DILocation::get(Loc->getContext(), 0, 0, Loc->getScope(), + Loc->getInlinedAt()); + return; + } + + // Else delete it. + DbgLoc = {}; +} Index: lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- lib/Transforms/InstCombine/InstCombineInternal.h +++ lib/Transforms/InstCombine/InstCombineInternal.h @@ -571,10 +571,6 @@ Instruction *FoldPHIArgLoadIntoPHI(PHINode &PN); Instruction *FoldPHIArgZextsIntoPHI(PHINode &PN); - /// Helper function for FoldPHIArgXIntoPHI() to get debug location for the - /// folded operation. - DebugLoc PHIArgMergedDebugLoc(PHINode &PN); - Instruction *foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I); Instruction *foldAllocaCmp(ICmpInst &ICI, const AllocaInst *Alloca, Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -1427,8 +1427,8 @@ SI.getSynchScope()); InsertNewInstBefore(NewSI, *BBI); // The debug locations of the original instructions might differ; merge them. - NewSI->setDebugLoc(DILocation::getMergedLocation(SI.getDebugLoc(), - OtherStore->getDebugLoc())); + NewSI->setDebugLoc(SI.getDebugLoc()); + NewSI->mergeDebugLocWith(OtherStore->getDebugLoc()); // If the two stores had AA tags, merge them. AAMDNodes AATags; Index: lib/Transforms/InstCombine/InstCombinePHI.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombinePHI.cpp +++ lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -27,16 +27,11 @@ /// The PHI arguments will be folded into a single operation with a PHI node /// as input. The debug location of the single operation will be the merged /// locations of the original PHI node arguments. -DebugLoc InstCombiner::PHIArgMergedDebugLoc(PHINode &PN) { - auto *FirstInst = cast(PN.getIncomingValue(0)); - const DILocation *Loc = FirstInst->getDebugLoc(); - - for (unsigned i = 1; i != PN.getNumIncomingValues(); ++i) { +static void setPHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) { + for (unsigned i = 0; i != PN.getNumIncomingValues(); ++i) { auto *I = cast(PN.getIncomingValue(i)); - Loc = DILocation::getMergedLocation(Loc, I->getDebugLoc()); + Inst->mergeDebugLocWith(I->getDebugLoc()); } - - return Loc; } /// If we have something like phi [add (a,b), add(a,c)] and if a/b/c and the @@ -117,7 +112,7 @@ if (CmpInst *CIOp = dyn_cast(FirstInst)) { CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), LHSVal, RHSVal); - NewCI->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(NewCI, PN); return NewCI; } @@ -130,7 +125,7 @@ for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) NewBinOp->andIRFlags(PN.getIncomingValue(i)); - NewBinOp->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(NewBinOp, PN); return NewBinOp; } @@ -238,8 +233,9 @@ GetElementPtrInst *NewGEP = GetElementPtrInst::Create(FirstInst->getSourceElementType(), Base, makeArrayRef(FixedOperands).slice(1)); - if (AllInBounds) NewGEP->setIsInBounds(); - NewGEP->setDebugLoc(PHIArgMergedDebugLoc(PN)); + if (AllInBounds) + NewGEP->setIsInBounds(); + setPHIArgMergedDebugLoc(NewGEP, PN); return NewGEP; } @@ -399,7 +395,7 @@ for (Value *IncValue : PN.incoming_values()) cast(IncValue)->setVolatile(false); - NewLI->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(NewLI, PN); return NewLI; } @@ -565,7 +561,7 @@ if (CastInst *FirstCI = dyn_cast(FirstInst)) { CastInst *NewCI = CastInst::Create(FirstCI->getOpcode(), PhiVal, PN.getType()); - NewCI->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(NewCI, PN); return NewCI; } @@ -576,14 +572,14 @@ for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) BinOp->andIRFlags(PN.getIncomingValue(i)); - BinOp->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(BinOp, PN); return BinOp; } CmpInst *CIOp = cast(FirstInst); CmpInst *NewCI = CmpInst::Create(CIOp->getOpcode(), CIOp->getPredicate(), PhiVal, ConstantOp); - NewCI->setDebugLoc(PHIArgMergedDebugLoc(PN)); + setPHIArgMergedDebugLoc(NewCI, PN); return NewCI; } Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -1277,9 +1277,7 @@ // I1 and I2 are being combined into a single instruction. Its debug // location is the merged locations of the original instructions. - if (!isa(I1)) - I1->setDebugLoc( - DILocation::getMergedLocation(I1->getDebugLoc(), I2->getDebugLoc())); + I1->mergeDebugLocWith(I2->getDebugLoc()); I2->eraseFromParent(); Changed = true; @@ -1584,17 +1582,14 @@ // The debug location for the "common" instruction is the merged locations of // all the commoned instructions. We start with the original location of the // "common" instruction and iteratively merge each location in the loop below. - const DILocation *Loc = I0->getDebugLoc(); // Update metadata and IR flags, and merge debug locations. for (auto *I : Insts) if (I != I0) { - Loc = DILocation::getMergedLocation(Loc, I->getDebugLoc()); + I0->mergeDebugLocWith(I->getDebugLoc()); combineMetadataForCSE(I0, I); I0->andIRFlags(I); } - if (!isa(I0)) - I0->setDebugLoc(Loc); if (!isa(I0)) { // canSinkLastInstruction checked that all instructions were used by @@ -2078,9 +2073,7 @@ Value *S = Builder.CreateSelect( BrCond, TrueV, FalseV, TrueV->getName() + "." + FalseV->getName(), BI); SpeculatedStore->setOperand(0, S); - SpeculatedStore->setDebugLoc( - DILocation::getMergedLocation( - BI->getDebugLoc(), SpeculatedStore->getDebugLoc())); + SpeculatedStore->mergeDebugLocWith(BI->getDebugLoc()); } // Metadata can be dependent on the condition we are hoisting above.