Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -44,6 +44,10 @@ ``llvm::sys::ExecuteNoWait`` was changed to an ``ArrayRef`` of optional ``StringRef``'s to make it safer and more convenient to use. +* The ``SetInsertPoint`` APIs in ``IRBuilderBase`` have been deprecated in + favor of APIs which explicitly set the current debug location along with the + insert point. These APIs will be removed in LLVM 7.0. + * Note.. .. NOTE Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -2833,6 +2833,17 @@ LLVMValueRef Instr); void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr); void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block); +void LLVMPositionBuilderWithLoc(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Instr, LLVMValueRef Loc); +void LLVMPositionBuilderBeforeWithLoc(LLVMBuilderRef Builder, + LLVMValueRef Instr, LLVMValueRef Loc); +void LLVMPositionBuilderAtEndWithLoc(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, LLVMValueRef Loc); +LLVMValueRef LLVMGetUnknownDebugLocation(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, + LLVMValueRef Instr); +LLVMValueRef LLVMGetUnknownDebugLocationBefore(LLVMBuilderRef Builder, + LLVMValueRef Instr); LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder); void LLVMClearInsertionPosition(LLVMBuilderRef Builder); void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr); Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -125,13 +125,29 @@ /// \brief This specifies that created instructions should be appended to the /// end of the specified block. + /// + /// \deprecated{Please use: + /// setInsertPoint(BasicBlock *, DebugLoc) + /// } void SetInsertPoint(BasicBlock *TheBB) { BB = TheBB; InsertPt = BB->end(); } + /// This specifies that created instructions should be appended to the end + /// of the specified block, and should have the given debug location. + void setInsertPoint(BasicBlock *TheBB, DebugLoc Loc) { + BB = TheBB; + InsertPt = BB->end(); + SetCurrentDebugLocation(Loc); + } + /// \brief This specifies that created instructions should be inserted before /// the specified instruction. + /// + /// \deprecated{Please use: + /// setInsertPoint(Instruction *, DebugLoc) + /// } void SetInsertPoint(Instruction *I) { BB = I->getParent(); InsertPt = I->getIterator(); @@ -139,8 +155,20 @@ SetCurrentDebugLocation(I->getDebugLoc()); } + /// This specifies that created instructions should be inserted before the + /// specified instruction, and should have the given debug location. + void setInsertPoint(Instruction *I, DebugLoc Loc) { + BB = I->getParent(); + InsertPt = I->getIterator(); + SetCurrentDebugLocation(Loc); + } + /// \brief This specifies that created instructions should be inserted at the /// specified point. + /// + /// \deprecated{Please use: + /// setInsertPoint(BasicBlock *, BasicBlock::iterator, DebugLoc) + /// } void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) { BB = TheBB; InsertPt = IP; @@ -148,6 +176,26 @@ SetCurrentDebugLocation(IP->getDebugLoc()); } + /// This specifies that created instructions should be inserted at the + /// specified point, and should have the given debug location. + void setInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP, + DebugLoc Loc) { + BB = TheBB; + InsertPt = IP; + SetCurrentDebugLocation(Loc); + } + + /// Get the debug location which should be used for instructions without + /// a clear correspondence to a source location. This returns an empty debug + /// location when the specified insertion point is null or has no debug info + /// attached to it. Otherwise, this returns a :0:0 location with the + /// DIScope set to the current inline scope. + /// @{ + static DebugLoc getUnknownDebugLocation(Instruction *InsertPt = nullptr); + static DebugLoc getUnknownDebugLocation(BasicBlock *ForBB, + BasicBlock::iterator IP); + /// @} + /// \brief Set location information used by debugging information. void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -706,6 +706,12 @@ return MDNode::get(MAV->getContext(), MD); } +/// Convert an LLVMValueRef to a DebugLoc. +static DebugLoc getValueRefAsDebugLoc(LLVMValueRef L) { + return DebugLoc(L ? cast(unwrap(L)->getMetadata()) + : nullptr); +} + void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { MDNode *N = Val ? extractMDNode(unwrap(Val)) : nullptr; @@ -2367,21 +2373,75 @@ return LLVMCreateBuilderInContext(LLVMGetGlobalContext()); } +/// Set the insert point of the builder before \p IP. Apply a new debug +/// location if one is available, and the current one if not. +static void positionBuilderBefore(IRBuilderBase *IRB, BasicBlock *BB, + BasicBlock::iterator IP) { + if (IP == BB->end()) + IRB->setInsertPoint(BB, IP, IRB->getCurrentDebugLocation()); + else + IRB->setInsertPoint(BB, IP, IP->getDebugLoc()); +} + void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr) { BasicBlock *BB = unwrap(Block); auto I = Instr ? unwrap(Instr)->getIterator() : BB->end(); - unwrap(Builder)->SetInsertPoint(BB, I); + positionBuilderBefore(unwrap(Builder), BB, I); } void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) { Instruction *I = unwrap(Instr); - unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator()); + positionBuilderBefore(unwrap(Builder), I->getParent(), I->getIterator()); } void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) { BasicBlock *BB = unwrap(Block); - unwrap(Builder)->SetInsertPoint(BB); + auto *IRB = unwrap(Builder); + IRB->setInsertPoint(BB, IRB->getCurrentDebugLocation()); +} + +void LLVMPositionBuilderWithLoc(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Instr, LLVMValueRef Loc) { + BasicBlock *BB = unwrap(Block); + auto I = Instr ? unwrap(Instr)->getIterator() : BB->end(); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(BB, I, DL); +} + +void LLVMPositionBuilderBeforeWithLoc(LLVMBuilderRef Builder, + LLVMValueRef Instr, LLVMValueRef Loc) { + Instruction *I = unwrap(Instr); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(I->getParent(), I->getIterator(), DL); +} + +void LLVMPositionBuilderAtEndWithLoc(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, + LLVMValueRef Loc) { + BasicBlock *BB = unwrap(Block); + DebugLoc DL = getValueRefAsDebugLoc(Loc); + unwrap(Builder)->setInsertPoint(BB, DL); +} + +LLVMValueRef LLVMGetUnknownDebugLocation(LLVMBuilderRef Builder, + LLVMBasicBlockRef Block, + LLVMValueRef Instr) { + auto *IRB = unwrap(Builder); + DebugLoc DL = IRB->getUnknownDebugLocation( + unwrap(Block), ((Instruction *)unwrap(Instr))->getIterator()); + if (DL) + return wrap(MetadataAsValue::get(IRB->getContext(), DL.getAsMDNode())); + return nullptr; +} + +LLVMValueRef LLVMGetUnknownDebugLocationBefore(LLVMBuilderRef Builder, + LLVMValueRef Instr) { + auto *IRB = unwrap(Builder); + DebugLoc DL = IRB->getUnknownDebugLocation((Instruction *)unwrap(Instr)); + if (DL) + return wrap(MetadataAsValue::get(IRB->getContext(), DL.getAsMDNode())); + return nullptr; } LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) { @@ -2408,9 +2468,7 @@ /*--.. Metadata builders ...................................................--*/ void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { - MDNode *Loc = - L ? cast(unwrap(L)->getMetadata()) : nullptr; - unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc)); + unwrap(Builder)->SetCurrentDebugLocation(getValueRefAsDebugLoc(L)); } LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { Index: lib/IR/IRBuilder.cpp =================================================================== --- lib/IR/IRBuilder.cpp +++ lib/IR/IRBuilder.cpp @@ -20,6 +20,27 @@ #include "llvm/IR/Statepoint.h" using namespace llvm; +DebugLoc IRBuilderBase::getUnknownDebugLocation(Instruction *InsertPt) { + if (InsertPt) { + DebugLoc CurrentLoc = InsertPt->getDebugLoc(); + + // If the function has debug info, create a zero location in the closest + // scope we can find. + if (CurrentLoc) + return DebugLoc::get(0, 0, CurrentLoc.getInlinedAtScope()); + } + + // Use an empty location. + return DebugLoc(); +} + +DebugLoc IRBuilderBase::getUnknownDebugLocation(BasicBlock *ForBB, + BasicBlock::iterator IP) { + if (IP != ForBB->end()) + return getUnknownDebugLocation(&*IP); + return getUnknownDebugLocation((Instruction *)nullptr); +} + /// CreateGlobalString - Make a new global variable with an initializer that /// has array of i8 type filled in with the nul terminated string value /// specified. If Name is specified, it is the name of the global variable Index: tools/llvm-c-test/calc.c =================================================================== --- tools/llvm-c-test/calc.c +++ tools/llvm-c-test/calc.c @@ -122,7 +122,9 @@ LLVMValueRef F = LLVMAddFunction(M, name, Fty); LLVMBuilderRef builder = LLVMCreateBuilder(); - LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry")); + LLVMPositionBuilderAtEndWithLoc( + builder, LLVMAppendBasicBlock(F, "entry"), + LLVMGetUnknownDebugLocationBefore(builder, NULL)); LLVMGetParams(F, ¶m); LLVMSetValueName(param, "in"); Index: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ tools/llvm-c-test/echo.cpp @@ -369,7 +369,8 @@ auto Ctx = LLVMGetModuleContext(M); auto Builder = LLVMCreateBuilderInContext(Ctx); auto BB = DeclareBB(LLVMGetInstructionParent(Src)); - LLVMPositionBuilderAtEnd(Builder, BB); + LLVMPositionBuilderAtEndWithLoc( + Builder, BB, LLVMGetUnknownDebugLocationBefore(Builder, nullptr)); auto Dst = CloneInstruction(Src, Builder); LLVMDisposeBuilder(Builder); return Dst; @@ -701,7 +702,8 @@ auto Ctx = LLVMGetModuleContext(M); LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx); - LLVMPositionBuilderAtEnd(Builder, BB); + LLVMPositionBuilderAtEndWithLoc( + Builder, BB, LLVMGetUnknownDebugLocationBefore(Builder, nullptr)); LLVMValueRef Cur = First; LLVMValueRef Next = nullptr; Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -483,6 +483,7 @@ DIB.createFunction(CU, "foo", "foo", File, 1, SPType, false, true, 1); DebugLoc DL1 = DILocation::get(Ctx, 2, 0, SP); DebugLoc DL2 = DILocation::get(Ctx, 3, 0, SP); + DebugLoc DLZero = DILocation::get(Ctx, 0, 0, SP); auto BB2 = BasicBlock::Create(Ctx, "bb2", F); auto Br = BranchInst::Create(BB2, BB); @@ -500,6 +501,34 @@ auto Call2 = Builder.CreateCall(Callee, None); EXPECT_EQ(DL2, Call2->getDebugLoc()); + // Test the new setInsertPoint() API's. + IRBuilder<> Builder2(Ctx); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DebugLoc()); + + Builder2.setInsertPoint(BB, DL1); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL1); + + // Even if there is a current debug location set, getUnknownDebugLocation() + // must return an empty location if no insertion point is specified. + EXPECT_EQ(Builder2.getUnknownDebugLocation(), DebugLoc()); + + Builder2.setInsertPoint(Br, DL2); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL2); + + Builder2.setInsertPoint(BB, BB->begin(), DL1); + EXPECT_EQ(Builder2.getCurrentDebugLocation(), DL1); + + // If the insertion point has debug info, the unknown location should be + // :0:0. + EXPECT_EQ(Builder2.getUnknownDebugLocation(Br), DLZero); + EXPECT_EQ(Builder2.getUnknownDebugLocation(BB, Br->getIterator()), DLZero); + + // If the insertion point has no known debug info, or if the insertion point + // is not specified, the unknown location should be empty. + Br->setDebugLoc(DebugLoc()); + EXPECT_EQ(Builder2.getUnknownDebugLocation(), DebugLoc()); + EXPECT_EQ(Builder2.getUnknownDebugLocation(Br), DebugLoc()); + DIB.finalize(); }