From 22b8e86371bf53fc9cfb73b39ac04c7e6f32b0ef Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 24 Aug 2016 18:29:49 +0000 Subject: [PATCH] DebugInfo: Add flag to CU to disable emission of inline debug info into the skeleton CU In cases where .dwo/.dwp files are guaranteed to be available, skipping the extra online (in the .o file) inline info can save a substantial amount of space - see the original r221306 for more details there. llvm-svn: 279650 --- include/llvm/IR/DIBuilder.h | 2 +- include/llvm/IR/DebugInfoMetadata.h | 50 ++++++++++++++--------- lib/AsmParser/LLParser.cpp | 6 ++- lib/Bitcode/Reader/BitcodeReader.cpp | 5 ++- lib/Bitcode/Writer/BitcodeWriter.cpp | 1 + lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 6 ++- lib/IR/AsmWriter.cpp | 8 +++- lib/IR/DIBuilder.cpp | 5 ++- lib/IR/DebugInfoMetadata.cpp | 10 +++-- test/Assembler/dicompileunit.ll | 6 +-- test/DebugInfo/X86/fission-no-inlining.ll | 41 +++++++++++++++++++ unittests/IR/MetadataTest.cpp | 7 ++-- 12 files changed, 105 insertions(+), 42 deletions(-) create mode 100644 test/DebugInfo/X86/fission-no-inlining.ll diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index 0f2f67f5fea..777d09620bb 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -101,7 +101,7 @@ namespace llvm { unsigned RV, StringRef SplitName = StringRef(), DICompileUnit::DebugEmissionKind Kind = DICompileUnit::DebugEmissionKind::FullDebug, - uint64_t DWOId = 0); + uint64_t DWOId = 0, bool SplitDebugInlining = true); /// Create a file descriptor to hold debugging information /// for a file. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 4046accb0d1..a9caf79656e 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -997,14 +997,16 @@ private: unsigned RuntimeVersion; unsigned EmissionKind; uint64_t DWOId; + bool SplitDebugInlining; DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage, bool IsOptimized, unsigned RuntimeVersion, - unsigned EmissionKind, uint64_t DWOId, ArrayRef Ops) + unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, + ArrayRef Ops) : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), - DWOId(DWOId) { + DWOId(DWOId), SplitDebugInlining(SplitDebugInlining) { assert(Storage != Uniqued); } ~DICompileUnit() = default; @@ -1016,13 +1018,15 @@ private: unsigned EmissionKind, DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, DIGlobalVariableArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, - uint64_t DWOId, StorageType Storage, bool ShouldCreate = true) { - return getImpl( - Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), - IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, - getCanonicalMDString(Context, SplitDebugFilename), EmissionKind, - EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(), - ImportedEntities.get(), Macros.get(), DWOId, Storage, ShouldCreate); + uint64_t DWOId, bool SplitDebugInlining, StorageType Storage, + bool ShouldCreate = true) { + return getImpl(Context, SourceLanguage, File, + getCanonicalMDString(Context, Producer), IsOptimized, + getCanonicalMDString(Context, Flags), RuntimeVersion, + getCanonicalMDString(Context, SplitDebugFilename), + EmissionKind, EnumTypes.get(), RetainedTypes.get(), + GlobalVariables.get(), ImportedEntities.get(), Macros.get(), + DWOId, SplitDebugInlining, Storage, ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -1030,15 +1034,16 @@ private: unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, - Metadata *Macros, uint64_t DWOId, StorageType Storage, - bool ShouldCreate = true); + Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, + StorageType Storage, bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { - return getTemporary( - getContext(), getSourceLanguage(), getFile(), getProducer(), - isOptimized(), getFlags(), getRuntimeVersion(), getSplitDebugFilename(), - getEmissionKind(), getEnumTypes(), getRetainedTypes(), - getGlobalVariables(), getImportedEntities(), getMacros(), DWOId); + return getTemporary(getContext(), getSourceLanguage(), getFile(), + getProducer(), isOptimized(), getFlags(), + getRuntimeVersion(), getSplitDebugFilename(), + getEmissionKind(), getEnumTypes(), getRetainedTypes(), + getGlobalVariables(), getImportedEntities(), + getMacros(), DWOId, getSplitDebugInlining()); } static void get() = delete; @@ -1053,20 +1058,21 @@ public: DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, DIGlobalVariableArray GlobalVariables, DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, - uint64_t DWOId), + uint64_t DWOId, bool SplitDebugInlining), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, - GlobalVariables, ImportedEntities, Macros, DWOId)) + GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, - Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId), + Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, + bool SplitDebugInlining), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, - GlobalVariables, ImportedEntities, Macros, DWOId)) + GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining)) TempDICompileUnit clone() const { return cloneImpl(); } @@ -1096,6 +1102,10 @@ public: } uint64_t getDWOId() const { return DWOId; } void setDWOId(uint64_t DwoId) { DWOId = DwoId; } + bool getSplitDebugInlining() const { return SplitDebugInlining; } + void setSplitDebugInlining(bool SplitDebugInlining) { + this->SplitDebugInlining = SplitDebugInlining; + } MDString *getRawProducer() const { return getOperandAs(1); } MDString *getRawFlags() const { return getOperandAs(2); } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index a2fcbf41204..e97202dd989 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -3969,14 +3969,16 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { OPTIONAL(globals, MDField, ); \ OPTIONAL(imports, MDField, ); \ OPTIONAL(macros, MDField, ); \ - OPTIONAL(dwoId, MDUnsignedField, ); + OPTIONAL(dwoId, MDUnsignedField, ); \ + OPTIONAL(splitDebugInlining, MDBoolField, = true); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS Result = DICompileUnit::getDistinct( Context, language.Val, file.Val, producer.Val, isOptimized.Val, flags.Val, runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, - retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val); + retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, + splitDebugInlining.Val); return false; } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e8ca7306f2b..0443a053894 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2452,7 +2452,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 16) + if (Record.size() < 14 || Record.size() > 17) return error("Invalid record"); // Ignore Record[0], which indicates whether this compile unit is @@ -2464,7 +2464,8 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { Record[8], getMDOrNull(Record[9]), getMDOrNull(Record[10]), getMDOrNull(Record[12]), getMDOrNull(Record[13]), Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]), - Record.size() <= 14 ? 0 : Record[14]); + Record.size() <= 14 ? 0 : Record[14], + Record.size() <= 16 ? true : Record[16]); MetadataList.assignValue(CU, NextMetadataNo++); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 428bb11a33d..391adeb47f0 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1564,6 +1564,7 @@ void ModuleBitcodeWriter::writeDICompileUnit(const DICompileUnit *N, Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get())); Record.push_back(N->getDWOId()); Record.push_back(VE.getMetadataOrNullID(N->getMacros().get())); + Record.push_back(N->getSplitDebugInlining()); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index f3c84a57f7e..d2fb6fe8e38 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -352,7 +352,8 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) { template static void forBothCUs(DwarfCompileUnit &CU, Func F) { F(CU); if (auto *SkelCU = CU.getSkeleton()) - F(*SkelCU); + if (CU.getCUNode()->getSplitDebugInlining()) + F(*SkelCU); } void DwarfDebug::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) { @@ -1155,7 +1156,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { TheCU.constructSubprogramScopeDIE(FnScope); if (auto *SkelCU = TheCU.getSkeleton()) - if (!LScopes.getAbstractScopesList().empty()) + if (!LScopes.getAbstractScopesList().empty() && + TheCU.getCUNode()->getSplitDebugInlining()) SkelCU->constructSubprogramScopeDIE(FnScope); // Clear debug info diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 26ca84b43f6..828767e0736 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1409,7 +1409,7 @@ struct MDFieldPrinter { bool ShouldSkipNull = true); template void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true); - void printBool(StringRef Name, bool Value); + void printBool(StringRef Name, bool Value, Optional Default = None); void printDIFlags(StringRef Name, unsigned Flags); template void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString, @@ -1472,7 +1472,10 @@ void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) { Out << FS << Name << ": " << Int; } -void MDFieldPrinter::printBool(StringRef Name, bool Value) { +void MDFieldPrinter::printBool(StringRef Name, bool Value, + Optional Default) { + if (Default && Value == *Default) + return; Out << FS << Name << ": " << (Value ? "true" : "false"); } @@ -1666,6 +1669,7 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, Printer.printMetadata("imports", N->getRawImportedEntities()); Printer.printMetadata("macros", N->getRawMacros()); Printer.printInt("dwoId", N->getDWOId()); + Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true); Out << ")"; } diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 01b47f386e1..29ccb92f84e 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -111,7 +111,8 @@ static DIScope *getNonCompileUnitScope(DIScope *N) { DICompileUnit *DIBuilder::createCompileUnit( unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName, - DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId) { + DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, + bool SplitDebugInlining) { assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && @@ -123,7 +124,7 @@ DICompileUnit *DIBuilder::createCompileUnit( CUNode = DICompileUnit::getDistinct( VMContext, Lang, DIFile::get(VMContext, Filename, Directory), Producer, isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr, nullptr, - nullptr, nullptr, nullptr, DWOId); + nullptr, nullptr, nullptr, DWOId, SplitDebugInlining); // Create a named metadata so that it is easier to find cu in a module. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp index c58e3685b3c..f4675387b66 100644 --- a/lib/IR/DebugInfoMetadata.cpp +++ b/lib/IR/DebugInfoMetadata.cpp @@ -361,7 +361,8 @@ DICompileUnit *DICompileUnit::getImpl( unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, - uint64_t DWOId, StorageType Storage, bool ShouldCreate) { + uint64_t DWOId, bool SplitDebugInlining, StorageType Storage, + bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -371,9 +372,10 @@ DICompileUnit *DICompileUnit::getImpl( File, Producer, Flags, SplitDebugFilename, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros}; - return storeImpl(new (array_lengthof(Ops)) DICompileUnit( - Context, Storage, SourceLanguage, IsOptimized, - RuntimeVersion, EmissionKind, DWOId, Ops), + return storeImpl(new (array_lengthof(Ops)) + DICompileUnit(Context, Storage, SourceLanguage, + IsOptimized, RuntimeVersion, EmissionKind, + DWOId, SplitDebugInlining, Ops), Storage); } diff --git a/test/Assembler/dicompileunit.ll b/test/Assembler/dicompileunit.ll index 994beff3b24..c1683e2d630 100644 --- a/test/Assembler/dicompileunit.ll +++ b/test/Assembler/dicompileunit.ll @@ -22,18 +22,18 @@ splitDebugFilename: "abc.debug", emissionKind: FullDebug, enums: !2, retainedTypes: !3, - globals: !5, imports: !6, macros: !7, dwoId: 42) + globals: !5, imports: !6, macros: !7, dwoId: 42, splitDebugInlining: true) ; CHECK: !9 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug) !9 = distinct !DICompileUnit(language: 12, file: !1, producer: "", isOptimized: false, flags: "", runtimeVersion: 0, splitDebugFilename: "", emissionKind: NoDebug) -; CHECK: !10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly) +; CHECK: !10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly, splitDebugInlining: false) !10 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 2, splitDebugFilename: "abc.debug", - emissionKind: LineTablesOnly) + emissionKind: LineTablesOnly, splitDebugInlining: false) !llvm.module.flags = !{!11} !11 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/test/DebugInfo/X86/fission-no-inlining.ll b/test/DebugInfo/X86/fission-no-inlining.ll new file mode 100644 index 00000000000..3f1e087f9ba --- /dev/null +++ b/test/DebugInfo/X86/fission-no-inlining.ll @@ -0,0 +1,41 @@ +; RUN: llc -split-dwarf=Enable -O0 < %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj | llvm-dwarfdump -debug-dump=info - | FileCheck %s + +; CHECK-NOT: DW_TAG_subprogram + +; IR generated from the following source: +; void f1(); +; inline __attribute__((always_inline)) void f2() { +; f1(); +; } +; void f3() { +; f2(); +; } + +; Function Attrs: uwtable +define void @_Z2f3v() #0 !dbg !5 { +entry: + call void @_Z2f1v(), !dbg !8 + ret void, !dbg !11 +} + +declare void @_Z2f1v() #1 + +attributes #0 = { uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3} +!llvm.ident = !{!4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (trunk 279571) (llvm/trunk 279602)", isOptimized: false, runtimeVersion: 0, splitDebugFilename: "fission-no-inlining.dwo", emissionKind: FullDebug, enums: !2, splitDebugInlining: false) +!1 = !DIFile(filename: "fission-no-inlining.cpp", directory: "/tmp/dbginfo") +!2 = !{} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{!"clang version 4.0.0 (trunk 279571) (llvm/trunk 279602)"} +!5 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !1, file: !1, line: 5, type: !6, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!6 = !DISubroutineType(types: !7) +!7 = !{null} +!8 = !DILocation(line: 3, column: 3, scope: !9, inlinedAt: !10) +!9 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!10 = distinct !DILocation(line: 6, column: 3, scope: !5) +!11 = !DILocation(line: 7, column: 1, scope: !5) diff --git a/unittests/IR/MetadataTest.cpp b/unittests/IR/MetadataTest.cpp index 15b03b3d572..01770ea8f8e 100644 --- a/unittests/IR/MetadataTest.cpp +++ b/unittests/IR/MetadataTest.cpp @@ -94,7 +94,7 @@ protected: return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false, "-g", 2, "", DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), - getTuple(), getTuple(), 0); + getTuple(), getTuple(), 0, true); } DIType *getBasicType(StringRef Name) { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); @@ -1391,8 +1391,7 @@ TEST_F(DICompileUnitTest, get) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, GlobalVariables, ImportedEntities, Macros, - DWOId); + RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -1449,7 +1448,7 @@ TEST_F(DICompileUnitTest, replaceArrays) { auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, - RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId); + RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get());