From aa50fa7c2f6a22d97a11336d7281377dcfcafc9d Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Fri, 31 Jul 2015 17:55:53 +0000 Subject: [PATCH] DI: Rewrite the DIBuilder local variable API Replace the general `createLocalVariable()` with two more specific functions: `createParameterVariable()` and `createAutoVariable()`, and rewrite the documentation. Besides cleaning up the API, this avoids exposing the fake DWARF tags `DW_TAG_arg_variable` and `DW_TAG_auto_variable` to frontends, and is preparation for removing them completely. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243764 91177308-0d34-0410-b5e6-96231b3b80d8 --- bindings/go/llvm/DIBuilderBindings.cpp | 13 ++++--- docs/tutorial/LangImpl8.rst | 5 ++- examples/Kaleidoscope/Chapter8/toy.cpp | 5 ++- include/llvm/IR/DIBuilder.h | 48 ++++++++++++++++---------- lib/IR/DIBuilder.cpp | 26 ++++++++++++-- unittests/Transforms/Utils/Cloning.cpp | 4 +-- 6 files changed, 67 insertions(+), 34 deletions(-) diff --git a/bindings/go/llvm/DIBuilderBindings.cpp b/bindings/go/llvm/DIBuilderBindings.cpp index df5885de25c4..627c09131aa5 100644 --- a/bindings/go/llvm/DIBuilderBindings.cpp +++ b/bindings/go/llvm/DIBuilderBindings.cpp @@ -84,13 +84,18 @@ LLVMMetadataRef LLVMDIBuilderCreateFunction( } LLVMMetadataRef LLVMDIBuilderCreateLocalVariable( - LLVMDIBuilderRef Dref, unsigned Tag, LLVMMetadataRef Scope, + LLVMDIBuilderRef Dref, unsigned, LLVMMetadataRef Scope, const char *Name, LLVMMetadataRef File, unsigned Line, LLVMMetadataRef Ty, int AlwaysPreserve, unsigned Flags, unsigned ArgNo) { DIBuilder *D = unwrap(Dref); - return wrap(D->createLocalVariable( - Tag, unwrap(Scope), Name, unwrap(File), Line, - unwrap(Ty), AlwaysPreserve, Flags, ArgNo)); + // FIXME: Update the Go bindings to match the DIBuilder API. + if (ArgNo) + return wrap(D->createParameterVariable( + unwrap(Scope), Name, ArgNo, unwrap(File), Line, + unwrap(Ty), AlwaysPreserve, Flags)); + return wrap(D->createAutoVariable(unwrap(Scope), Name, + unwrap(File), Line, + unwrap(Ty), AlwaysPreserve, Flags)); } LLVMMetadataRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref, diff --git a/docs/tutorial/LangImpl8.rst b/docs/tutorial/LangImpl8.rst index 88224bb92f07..24c4d171f859 100644 --- a/docs/tutorial/LangImpl8.rst +++ b/docs/tutorial/LangImpl8.rst @@ -395,9 +395,8 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``. DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU.getFilename(), KSDbgInfo.TheCU.getDirectory()); - DILocalVariable D = DBuilder->createLocalVariable( - dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line, - KSDbgInfo.getDoubleTy(), true, 0, Idx + 1); + DILocalVariable D = DBuilder->createParameterVariable( + Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true); Instruction *Call = DBuilder->insertDeclare( Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock()); diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp index 72e5089177b7..f525ac7a1b0a 100644 --- a/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/examples/Kaleidoscope/Chapter8/toy.cpp @@ -1253,9 +1253,8 @@ void PrototypeAST::CreateArgumentAllocas(Function *F) { DIScope *Scope = KSDbgInfo.LexicalBlocks.back(); DIFile *Unit = DBuilder->createFile(KSDbgInfo.TheCU->getFilename(), KSDbgInfo.TheCU->getDirectory()); - DILocalVariable *D = DBuilder->createLocalVariable( - dwarf::DW_TAG_arg_variable, Scope, Args[Idx], Unit, Line, - KSDbgInfo.getDoubleTy(), true, 0, Idx + 1); + DILocalVariable *D = DBuilder->createParameterVariable( + Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true); DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), DebugLoc::get(Line, 0, Scope), diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 0137a096e970..8aca266ce77b 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -457,26 +457,36 @@ namespace llvm { unsigned LineNo, DIType *Ty, bool isLocalToUnit, llvm::Constant *Val, MDNode *Decl = nullptr); - /// Create a new descriptor for the specified - /// local variable. - /// \param Tag Dwarf TAG. Usually DW_TAG_auto_variable or - /// DW_TAG_arg_variable. - /// \param Scope Variable scope. - /// \param Name Variable name. - /// \param File File where this variable is defined. - /// \param LineNo Line number. - /// \param Ty Variable Type - /// \param AlwaysPreserve Boolean. Set to true if debug info for this - /// variable should be preserved in optimized build. - /// \param Flags Flags, e.g. artificial variable. - /// \param ArgNo If this variable is an argument then this argument's - /// number. 1 indicates 1st argument. - DILocalVariable *createLocalVariable(unsigned Tag, DIScope *Scope, - StringRef Name, DIFile *File, - unsigned LineNo, DIType *Ty, + /// Create a new descriptor for an auto variable. This is a local variable + /// that is not a subprogram parameter. + /// + /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually + /// leads to a \a DISubprogram. + /// + /// If \c AlwaysPreserve, this variable will be referenced from its + /// containing subprogram, and will survive some optimizations. + DILocalVariable *createAutoVariable(DIScope *Scope, StringRef Name, + DIFile *File, unsigned LineNo, + DIType *Ty, bool AlwaysPreserve = false, - unsigned Flags = 0, - unsigned ArgNo = 0); + unsigned Flags = 0); + + /// Create a new descriptor for a parameter variable. + /// + /// \c Scope must be a \a DILocalScope, and thus its scope chain eventually + /// leads to a \a DISubprogram. + /// + /// \c ArgNo is the index (starting from \c 1) of this variable in the + /// subprogram parameters. \c ArgNo should not conflict with other + /// parameters of the same subprogram. + /// + /// If \c AlwaysPreserve, this variable will be referenced from its + /// containing subprogram, and will survive some optimizations. + DILocalVariable *createParameterVariable(DIScope *Scope, StringRef Name, + unsigned ArgNo, DIFile *File, + unsigned LineNo, DIType *Ty, + bool AlwaysPreserve = false, + unsigned Flags = 0); /// Create a new descriptor for the specified /// variable which has a complex address expression for its address. diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 28a8d567c223..7a4c52039654 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -602,15 +602,18 @@ DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( .release(); } -DILocalVariable *DIBuilder::createLocalVariable( - unsigned Tag, DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo, - DIType *Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { +static DILocalVariable *createLocalVariable( + LLVMContext &VMContext, + DenseMap> &PreservedVariables, + DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File, + unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) { // FIXME: Why getNonCompileUnitScope()? // FIXME: Why is "!Context" okay here? // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT // the only valid scopes)? DIScope *Context = getNonCompileUnitScope(Scope); + dwarf::Tag Tag = ArgNo ? dwarf::DW_TAG_arg_variable : dwarf::DW_TAG_auto_variable; auto *Node = DILocalVariable::get( VMContext, Tag, cast_or_null(Context), Name, File, LineNo, DITypeRef::get(Ty), ArgNo, Flags); @@ -625,6 +628,23 @@ DILocalVariable *DIBuilder::createLocalVariable( return Node; } +DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name, + DIFile *File, unsigned LineNo, + DIType *Ty, bool AlwaysPreserve, + unsigned Flags) { + return createLocalVariable(VMContext, PreservedVariables, Scope, Name, + /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, + Flags); +} + +DILocalVariable *DIBuilder::createParameterVariable( + DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File, + unsigned LineNo, DIType *Ty, bool AlwaysPreserve, unsigned Flags) { + assert(ArgNo && "Expected non-zero argument number for parameter"); + return createLocalVariable(VMContext, PreservedVariables, Scope, Name, ArgNo, + File, LineNo, Ty, AlwaysPreserve, Flags); +} + DIExpression *DIBuilder::createExpression(ArrayRef Addr) { return DIExpression::get(VMContext, Addr); } diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index e2671499e812..3ceb84c42c7e 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -255,8 +255,8 @@ class CloneFunc : public ::testing::Test { auto *IntType = DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed); auto *E = DBuilder.createExpression(); - auto *Variable = DBuilder.createLocalVariable( - dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true); + auto *Variable = + DBuilder.createAutoVariable(Subprogram, "x", File, 5, IntType, true); auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram); DBuilder.insertDeclare(Alloca, Variable, E, DL, Store); DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,