r289701 - [DebugInfo] Changed DIBuilder::createCompileUnit() to take DIFile instead of FileName and Directory.
Author: aaboud Date: Wed Dec 14 14:24:40 2016 New Revision: 289701 URL: http://llvm.org/viewvc/llvm-project?rev=289701&view=rev Log: [DebugInfo] Changed DIBuilder::createCompileUnit() to take DIFile instead of FileName and Directory. This way it will be easier to expand DIFile (e.g., to contain checksum) without the need to modify the createCompileUnit() API. Reviewers: cfe-commits, rnk Differential Revision: https://reviews.llvm.org/D27763 Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=289701&r1=289700&r2=289701&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Dec 14 14:24:40 2016 @@ -466,7 +466,8 @@ void CGDebugInfo::CreateCompileUnit() { // Create new compile unit. // FIXME - Eliminate TheCU. TheCU = DBuilder.createCompileUnit( - LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()), + LangTag, DBuilder.createFile(remapDIPath(MainFileName), +remapDIPath(getCurrentDirname())), Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */, CGM.getCodeGenOpts().SplitDwarfInlining); @@ -1977,10 +1978,11 @@ CGDebugInfo::getOrCreateModuleRef(Extern // but LLVM detects skeleton CUs by looking for a non-zero DWO id. uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL; llvm::DIBuilder DIB(CGM.getModule()); -DIB.createCompileUnit(TheCU->getSourceLanguage(), Mod.getModuleName(), - Mod.getPath(), TheCU->getProducer(), true, - StringRef(), 0, Mod.getASTFile(), - llvm::DICompileUnit::FullDebug, Signature); +DIB.createCompileUnit(TheCU->getSourceLanguage(), + DIB.createFile(Mod.getModuleName(), Mod.getPath()), + TheCU->getProducer(), true, StringRef(), 0, + Mod.getASTFile(), llvm::DICompileUnit::FullDebug, + Signature); DIB.finalize(); } llvm::DIModule *Parent = ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r290515 - [DebugInfo] Added support for Checksum debug info feature.
Author: aaboud Date: Sun Dec 25 04:12:27 2016 New Revision: 290515 URL: http://llvm.org/viewvc/llvm-project?rev=290515&view=rev Log: [DebugInfo] Added support for Checksum debug info feature. Differential Revision: https://reviews.llvm.org/D27641 Added: cfe/trunk/test/CodeGen/Inputs/debug-info-file-checksum.c cfe/trunk/test/CodeGen/debug-info-file-checksum.c Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=290515&r1=290514&r2=290515&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sun Dec 25 04:12:27 2016 @@ -41,6 +41,7 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" using namespace clang; using namespace clang::CodeGen; @@ -320,11 +321,36 @@ StringRef CGDebugInfo::getClassName(cons return StringRef(); } +llvm::DIFile::ChecksumKind +CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const { + Checksum.clear(); + + if (!CGM.getCodeGenOpts().EmitCodeView) +return llvm::DIFile::CSK_None; + + SourceManager &SM = CGM.getContext().getSourceManager(); + bool Invalid; + llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid); + if (Invalid) +return llvm::DIFile::CSK_None; + + llvm::MD5 Hash; + llvm::MD5::MD5Result Result; + + Hash.update(MemBuffer->getBuffer()); + Hash.final(Result); + + Hash.stringifyResult(Result, Checksum); + return llvm::DIFile::CSK_MD5; +} + llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) { if (!Loc.isValid()) // If Location is not valid then use main input file. return DBuilder.createFile(remapDIPath(TheCU->getFilename()), - remapDIPath(TheCU->getDirectory())); + remapDIPath(TheCU->getDirectory()), + TheCU->getFile()->getChecksumKind(), + TheCU->getFile()->getChecksum()); SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(Loc); @@ -332,7 +358,9 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty()) // If the location is not valid then use main input file. return DBuilder.createFile(remapDIPath(TheCU->getFilename()), - remapDIPath(TheCU->getDirectory())); + remapDIPath(TheCU->getDirectory()), + TheCU->getFile()->getChecksumKind(), + TheCU->getFile()->getChecksum()); // Cache the results. const char *fname = PLoc.getFilename(); @@ -344,8 +372,13 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi return cast(V); } + SmallString<32> Checksum; + llvm::DIFile::ChecksumKind CSKind = + computeChecksum(SM.getFileID(Loc), Checksum); + llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.getFilename()), -remapDIPath(getCurrentDirname())); +remapDIPath(getCurrentDirname()), +CSKind, Checksum); DIFileCache[fname].reset(F); return F; @@ -353,7 +386,9 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi llvm::DIFile *CGDebugInfo::getOrCreateMainFile() { return DBuilder.createFile(remapDIPath(TheCU->getFilename()), - remapDIPath(TheCU->getDirectory())); + remapDIPath(TheCU->getDirectory()), + TheCU->getFile()->getChecksumKind(), + TheCU->getFile()->getChecksum()); } std::string CGDebugInfo::remapDIPath(StringRef Path) const { @@ -396,6 +431,8 @@ StringRef CGDebugInfo::getCurrentDirname } void CGDebugInfo::CreateCompileUnit() { + SmallString<32> Checksum; + llvm::DIFile::ChecksumKind CSKind = llvm::DIFile::CSK_None; // Should we be asking the SourceManager for the main file name, instead of // accepting it as an argument? This just causes the main file name to @@ -422,6 +459,7 @@ void CGDebugInfo::CreateCompileUnit() { llvm::sys::path::append(MainFileDirSS, MainFileName); MainFileName = MainFileDirSS.str(); } +CSKind = computeChecksum(SM.getMainFileID(), Checksum); } llvm::dwarf::SourceLanguage LangTag; @@ -467,7 +505,8 @@ void CGDebugInfo::CreateCompileUnit() { // FIXME - Eliminate TheCU. TheCU = DBuilder.createCompileUnit( LangTag, DBuilder.createFile(remapDIPath(MainFileName), -remapDIPath(getCurrentDirname())), + remapDIPath(getCurrentDirname()), CSKind, +
r294637 - [DebugInfo] Added support to Clang FE for generating debug info for preprocessor macros.
Author: aaboud Date: Thu Feb 9 16:07:24 2017 New Revision: 294637 URL: http://llvm.org/viewvc/llvm-project?rev=294637&view=rev Log: [DebugInfo] Added support to Clang FE for generating debug info for preprocessor macros. Added "-fdebug-macro" flag (and "-fno-debug-macro" flag) to enable (and to disable) emitting macro debug info. Added CC1 "-debug-info-macro" flag that enables emitting macro debug info. Differential Revision: https://reviews.llvm.org/D16135 Added: cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp cfe/trunk/lib/CodeGen/MacroPPCallbacks.h cfe/trunk/test/CodeGen/debug-info-macro.c cfe/trunk/test/CodeGen/include/debug-info-macro.h Modified: cfe/trunk/docs/UsersManual.rst cfe/trunk/include/clang/CodeGen/ModuleBuilder.h cfe/trunk/include/clang/Driver/CC1Options.td cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.def cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CMakeLists.txt cfe/trunk/lib/CodeGen/CodeGenAction.cpp cfe/trunk/lib/CodeGen/ModuleBuilder.cpp cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/Driver/debug-options.c Modified: cfe/trunk/docs/UsersManual.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=294637&r1=294636&r2=294637&view=diff == --- cfe/trunk/docs/UsersManual.rst (original) +++ cfe/trunk/docs/UsersManual.rst Thu Feb 9 16:07:24 2017 @@ -1696,6 +1696,22 @@ below. If multiple flags are present, th Generate complete debug info. +Controlling Macro Debug Info Generation +^^^ + +Debug info for C preprocessor macros increases the size of debug information in +the binary. Macro debug info generated by Clang can be controlled by the flags +listed below. + +.. option:: -fdebug-macro + + Generate debug info for preprocessor macros. This flag is discarded when + **-g0** is enabled. + +.. option:: -fno-debug-macro + + Do not generate debug info for preprocessor macros (default). + Controlling Debugger "Tuning" ^ Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=294637&r1=294636&r2=294637&view=diff == --- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original) +++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Thu Feb 9 16:07:24 2017 @@ -35,6 +35,7 @@ namespace clang { namespace CodeGen { class CodeGenModule; + class CGDebugInfo; } /// The primary public interface to the Clang code generator. @@ -65,6 +66,9 @@ public: /// CodeGenerator after releasing its module. llvm::Module *ReleaseModule(); + /// Return debug info code generator. + CodeGen::CGDebugInfo *getCGDebugInfo(); + /// Given a mangled name, return a declaration which mangles that way /// which has been added to this code generator via a Handle method. /// Modified: cfe/trunk/include/clang/Driver/CC1Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=294637&r1=294636&r2=294637&view=diff == --- cfe/trunk/include/clang/Driver/CC1Options.td (original) +++ cfe/trunk/include/clang/Driver/CC1Options.td Thu Feb 9 16:07:24 2017 @@ -136,6 +136,8 @@ def migrator_no_finalize_removal : Flag< let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; +def debug_info_macro : Flag<["-"], "debug-info-macro">, + HelpText<"Emit macro debug information">; def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=294637&r1=294636&r2=294637&view=diff == --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Thu Feb 9 16:07:24 2017 @@ -1322,6 +1322,10 @@ def fno_standalone_debug : Flag<["-"], " HelpText<"Limit debug information produced to reduce size of debug binary">; def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, Alias; def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Flags<[CoreOption]>, Alias; +def fdebug_macro : Flag<["-"], "fdebug-macro">, Group, Flags<[CoreOption]>, + HelpText<"Emit macro debug information">; +def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group, Flags<[CoreOption]>, + HelpText<"Do not emit m
[PATCH] D16135: Macro Debug Info support in Clang
aaboud added a comment. Thanks Richard for reviewing the patch and for the comments. Please, see answers below. Regards, Amjad Comment at: include/clang/AST/ASTConsumer.h:163 + /// The caller takes ownership on the returned pointer. + virtual std::unique_ptr CreatePreprocessorCallbacks(Preprocessor &PP); }; rsmith wrote: > aaboud wrote: > > Richard, > > I know that you suggested not to introduce the Preprocessor in anyway to > > the ASTConsumer. > > However, as I could not understand the other way to support macros in Clang > > without applying a huge redesign, I decided to upload the code I suggested > > in the proposal. > > http://lists.llvm.org/pipermail/llvm-dev/2015-November/092449.html > > > > If you still think that this approach is not the right one, I would > > appreciate it if you can explain again how to implement the macro support > > differently. > Don't add this to `ASTConsumer`; an AST consumer and a PP consumer are two > largely separate ideas. Instead, you could create and register a > `PPCallbacks` object directly from `CodeGenAction::CreateASTConsumer`. In > fact, if you look there, a `PPCallbacks` subclass is already registered (for > code coverage); you can do something similar to register your > `MacroPPCallbacks` object. Thanks, I will try this approach, it is indeed cleaner. Comment at: lib/CodeGen/CMakeLists.txt:76 ItaniumCXXABI.cpp + MacroPPCallbacks.cpp MicrosoftCXXABI.cpp rsmith wrote: > This file is missing from the diff. Sorry about that, it seems when I updated the code these files were removed from the patch. Also, I need to improve the implementation in these two files. By the way, you can find an old version of them in the previous diff. I will update them and upload them to the review together with the above suggestion of yours. https://reviews.llvm.org/D16135 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)
aaboud created this revision. aaboud added reviewers: mkuper, delena, craig.topper. aaboud added a subscriber: cfe-commits. aaboud set the repository for this revision to rL LLVM. Add intrinsics for the XSAVE instructions: XSAVE, XSAVE64 XRSTOR, XRSTOR64 XSAVEOPT, XSAVEOPT64 XRSTORS, XRSTORS64 XSAVEC, XSAVEC64 XSAVES, XSAVES64 These were previously declared in Intrin.h for MSVC compatibility, but now that we have them implemented, these declarations can be removed. Repository: rL LLVM http://reviews.llvm.org/D13014 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/CMakeLists.txt lib/Headers/Intrin.h lib/Headers/immintrin.h lib/Headers/xsavecintrin.h lib/Headers/xsaveintrin.h lib/Headers/xsaveoptintrin.h lib/Headers/xsavesintrin.h test/CodeGen/builtins-x86.c Index: lib/Headers/xsaveintrin.h === --- lib/Headers/xsaveintrin.h +++ lib/Headers/xsaveintrin.h @@ -0,0 +1,58 @@ +/*=== xsaveintrin.h - XSAVE intrinsic === + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===---=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVEINTRIN_H +#define __XSAVEINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsave"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsave(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xsave64(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave64(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor64(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif Index: lib/Headers/CMakeLists.txt === --- lib/Headers/CMakeLists.txt +++ lib/Headers/CMakeLists.txt @@ -66,6 +66,10 @@ x86intrin.h xmmintrin.h xopintrin.h + xsaveintrin.h + xsaveoptintrin.h + xsavecintrin.h + xsavesintrin.h xtestintrin.h ) Index: lib/Headers/immintrin.h === --- lib/Headers/immintrin.h +++ lib/Headers/immintrin.h @@ -144,6 +144,14 @@ #include +#include + +#include + +#include + +#include + /* Some intrinsics inside adxintrin.h are available only on processors with ADX, * whereas others are also available at all times. */ #include Index: lib/Headers/xsavesintrin.h === --- lib/Headers/xsavesintrin.h +++ lib/Headers/xsavesintrin.h @@ -0,0 +1,58 @@ +/*=== xsavesintrin.h - XSAVES intrinsic === + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO E
Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)
aaboud added a comment. In http://reviews.llvm.org/D13014#264638, @delena wrote: > Do you need to add some tests for clang? I thought I did (see "builtins-x86.c"). This is how other intrinsic instructions are tested by clang, am I missing something? Repository: rL LLVM http://reviews.llvm.org/D13014 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)
aaboud updated this revision to Diff 37108. aaboud added a comment. Added two LIT tests to check the xsave intrinsic instructions. Repository: rL LLVM http://reviews.llvm.org/D13014 Files: include/clang/Basic/BuiltinsX86.def lib/CodeGen/CGBuiltin.cpp lib/Headers/CMakeLists.txt lib/Headers/Intrin.h lib/Headers/immintrin.h lib/Headers/xsavecintrin.h lib/Headers/xsaveintrin.h lib/Headers/xsaveoptintrin.h lib/Headers/xsavesintrin.h test/CodeGen/builtins-x86.c test/CodeGen/x86_32-xsave.c test/CodeGen/x86_64-xsave.c Index: lib/Headers/xsaveintrin.h === --- lib/Headers/xsaveintrin.h +++ lib/Headers/xsaveintrin.h @@ -0,0 +1,58 @@ +/*=== xsaveintrin.h - XSAVE intrinsic === + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===---=== + */ + +#ifndef __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __XSAVEINTRIN_H +#define __XSAVEINTRIN_H + +/* Define the default attributes for the functions in this file. */ +#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("xsave"))) + +static __inline__ void __DEFAULT_FN_ATTRS +_xsave(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor(__p, __m); +} + +#ifdef __x86_64__ +static __inline__ void __DEFAULT_FN_ATTRS +_xsave64(void *__p, unsigned long long __m) { + return __builtin_ia32_xsave64(__p, __m); +} + +static __inline__ void __DEFAULT_FN_ATTRS +_xrstor64(void *__p, unsigned long long __m) { + return __builtin_ia32_xrstor64(__p, __m); +} +#endif + +#undef __DEFAULT_FN_ATTRS + +#endif Index: lib/Headers/CMakeLists.txt === --- lib/Headers/CMakeLists.txt +++ lib/Headers/CMakeLists.txt @@ -66,6 +66,10 @@ x86intrin.h xmmintrin.h xopintrin.h + xsaveintrin.h + xsaveoptintrin.h + xsavecintrin.h + xsavesintrin.h xtestintrin.h ) Index: lib/Headers/immintrin.h === --- lib/Headers/immintrin.h +++ lib/Headers/immintrin.h @@ -144,6 +144,14 @@ #include +#include + +#include + +#include + +#include + /* Some intrinsics inside adxintrin.h are available only on processors with ADX, * whereas others are also available at all times. */ #include Index: lib/Headers/xsavesintrin.h === --- lib/Headers/xsavesintrin.h +++ lib/Headers/xsavesintrin.h @@ -0,0 +1,58 @@ +/*=== xsavesintrin.h - XSAVES intrinsic === + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *===-
r250158 - [X86] Add XSAVE intrinsic family
Author: aaboud Date: Tue Oct 13 07:29:35 2015 New Revision: 250158 URL: http://llvm.org/viewvc/llvm-project?rev=250158&view=rev Log: [X86] Add XSAVE intrinsic family Add intrinsics for the XSAVE instructions (XSAVE/XSAVE64/XRSTOR/XRSTOR64) XSAVEOPT instructions (XSAVEOPT/XSAVEOPT64) XSAVEC instructions (XSAVEC/XSAVEC64) XSAVES instructions (XSAVES/XSAVES64/XRSTORS/XRSTORS64) Differential Revision: http://reviews.llvm.org/D13014 Added: cfe/trunk/lib/Headers/xsavecintrin.h cfe/trunk/lib/Headers/xsaveintrin.h cfe/trunk/lib/Headers/xsaveoptintrin.h cfe/trunk/lib/Headers/xsavesintrin.h cfe/trunk/test/CodeGen/x86_32-xsave.c cfe/trunk/test/CodeGen/x86_64-xsave.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/CMakeLists.txt cfe/trunk/lib/Headers/Intrin.h cfe/trunk/lib/Headers/immintrin.h cfe/trunk/test/CodeGen/builtins-x86.c Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=250158&r1=250157&r2=250158&view=diff == --- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original) +++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Tue Oct 13 07:29:35 2015 @@ -665,6 +665,20 @@ BUILTIN(__builtin_ia32_fxrstor64, "vv*", BUILTIN(__builtin_ia32_fxsave, "vv*", "") BUILTIN(__builtin_ia32_fxsave64, "vv*", "") +// XSAVE +BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "") +BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "") + // ADX TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx") TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx") Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=250158&r1=250157&r2=250158&view=diff == --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Oct 13 07:29:35 2015 @@ -6083,6 +6083,46 @@ Value *CodeGenFunction::EmitX86BuiltinEx Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); return Builder.CreateLoad(Tmp, "stmxcsr"); } + case X86::BI__builtin_ia32_xsave: + case X86::BI__builtin_ia32_xsave64: + case X86::BI__builtin_ia32_xrstor: + case X86::BI__builtin_ia32_xrstor64: + case X86::BI__builtin_ia32_xsaveopt: + case X86::BI__builtin_ia32_xsaveopt64: + case X86::BI__builtin_ia32_xrstors: + case X86::BI__builtin_ia32_xrstors64: + case X86::BI__builtin_ia32_xsavec: + case X86::BI__builtin_ia32_xsavec64: + case X86::BI__builtin_ia32_xsaves: + case X86::BI__builtin_ia32_xsaves64: { +Intrinsic::ID ID; +#define INTRINSIC_X86_XSAVE_ID(NAME) \ +case X86::BI__builtin_ia32_##NAME: \ + ID = Intrinsic::x86_##NAME; \ + break +switch (BuiltinID) { +default: llvm_unreachable("Unsupported intrinsic!"); +INTRINSIC_X86_XSAVE_ID(xsave); +INTRINSIC_X86_XSAVE_ID(xsave64); +INTRINSIC_X86_XSAVE_ID(xrstor); +INTRINSIC_X86_XSAVE_ID(xrstor64); +INTRINSIC_X86_XSAVE_ID(xsaveopt); +INTRINSIC_X86_XSAVE_ID(xsaveopt64); +INTRINSIC_X86_XSAVE_ID(xrstors); +INTRINSIC_X86_XSAVE_ID(xrstors64); +INTRINSIC_X86_XSAVE_ID(xsavec); +INTRINSIC_X86_XSAVE_ID(xsavec64); +INTRINSIC_X86_XSAVE_ID(xsaves); +INTRINSIC_X86_XSAVE_ID(xsaves64); +} +#undef INTRINSIC_X86_XSAVE_ID +Value *Mhi = Builder.CreateTrunc( + Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); +Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); +Ops[1] = Mhi; +Ops.push_back(Mlo); +return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); + } case X86::BI__builtin_ia32_storehps: case X86::BI__builtin_ia32_storelps: { llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); Modified: cfe/trunk/lib/Headers/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/CMakeLists.txt?rev=250158&r1=250157&r2=250158&view=diff == --- cfe/trunk/lib/Headers/CMakeLists.txt (original) +++ cfe/trunk/lib/Headers/CMakeLists.txt Tue Oct 13 07:29:35 2015 @@ -66,6 +66,10 @@ set(files x86intrin.h xmmintrin.h xopintrin.h + xsaveintrin.h + xsaveoptintrin.h + xsavecintrin.h + xsavesintrin.h xtestintrin.h ) Modified: cf
Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)
This revision was automatically updated to reflect the committed changes. Closed by commit rL250158: [X86] Add XSAVE intrinsic family (authored by aaboud). Changed prior to commit: http://reviews.llvm.org/D13014?vs=37108&id=37238#toc Repository: rL LLVM http://reviews.llvm.org/D13014 Files: cfe/trunk/include/clang/Basic/BuiltinsX86.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/Headers/CMakeLists.txt cfe/trunk/lib/Headers/Intrin.h cfe/trunk/lib/Headers/immintrin.h cfe/trunk/lib/Headers/xsavecintrin.h cfe/trunk/lib/Headers/xsaveintrin.h cfe/trunk/lib/Headers/xsaveoptintrin.h cfe/trunk/lib/Headers/xsavesintrin.h cfe/trunk/test/CodeGen/builtins-x86.c cfe/trunk/test/CodeGen/x86_32-xsave.c cfe/trunk/test/CodeGen/x86_64-xsave.c Index: cfe/trunk/test/CodeGen/x86_32-xsave.c === --- cfe/trunk/test/CodeGen/x86_32-xsave.c +++ cfe/trunk/test/CodeGen/x86_32-xsave.c @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVE +// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVE + +// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaveopt -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEOPT +// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaveopt -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEOPT + +// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsavec -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEC +// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsavec -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEC + +// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaves -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVES +// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaves -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVES + +void test() { + unsigned long long tmp_ULLi; + void* tmp_vp; + +#ifdef TEST_XSAVE +// XSAVE: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4 +// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8 +// XSAVE: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32 +// XSAVE: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32 +// XSAVE: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32 +// XSAVE: call void @llvm.x86.xsave(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]]) + (void)__builtin_ia32_xsave(tmp_vp, tmp_ULLi); + +// XSAVE: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4 +// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8 +// XSAVE: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32 +// XSAVE: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32 +// XSAVE: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32 +// XSAVE: call void @llvm.x86.xrstor(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]]) + (void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi); +#endif + +#ifdef TEST_XSAVEOPT +// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4 +// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8 +// XSAVEOPT: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32 +// XSAVEOPT: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32 +// XSAVEOPT: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32 +// XSAVEOPT: call void @llvm.x86.xsaveopt(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]]) + (void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi); +#endif + +#ifdef TEST_XSAVEC +// XSAVEC: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4 +// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8 +// XSAVEC: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32 +// XSAVEC: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32 +// XSAVEC: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32 +// XSAVEC: call void @llvm.x86.xsavec(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]]) + (void)__builtin_ia32_xsavec(tmp_vp, tmp_ULLi); +#endif + +#ifdef TEST_XSAVES +// XSAVES: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4 +// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8 +// XSAVES: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32 +// XSAVES: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32 +// XSAVES: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32 +// XSAVES: call void @llvm.x86.xsaves(i8* [[tmp_vp_1]], i32 [[high32_1]], i
Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud marked an inline comment as done. Comment at: include/clang/Basic/Attr.td:1657 @@ +1656,3 @@ + TargetSpecificAttr { + let Spellings = [GNU<"no_caller_saved_registers">]; + let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">; aaron.ballman wrote: > Any particular reason this isn't (also) a C++-style attribute under the clang > namespace? I am not sure about that, I was just following the way the "interrupt" attribute was defined. Do you think we should change both to consider C++ style attribute as well? Comment at: include/clang/Basic/AttrDocs.td:2177 @@ +2176,3 @@ +Use this attribute to indicate that the specified function has no +caller-saved registers. That is, all registers are callee-saved. +The compiler generates proper function entry and exit sequences to aaron.ballman wrote: > How does this interact with calling convention attributes? For instance, if I > have a function that is explicitly marked cdecl and has this attribute, what > is the behavior for EAX, ECX, and EDX? > > Also, why is this an attribute rather than a calling convention? I'm > wondering how this works through function pointers, for instance (whether it > is intended to work or not). Please, correct me if I am mistaken, but calling convention determine not only what the callee and the caller function saved registers are, but also how we move parameters to the called function, right? The idea behind no_caller_saved_registers attribute, is that it can be combined with any other calling convention, and it only override the callee/caller saved register list, but not the way parameters are passed to the called function. So, using a calling convention for this attribute will not be right. H.J., can you confirm this? https://reviews.llvm.org/D22045 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud updated this revision to Diff 65269. aaboud added a comment. Updated test according to comments. https://reviews.llvm.org/D22045 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CGCall.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp test/SemaCXX/attr-x86-no_caller_saved_registers.cpp Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1673,6 +1673,8 @@ RetAttrs.addAttribute(llvm::Attribute::NoAlias); if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute("no_caller_saved_registers"); HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5910,6 +5910,10 @@ handleTypeTagForDatatypeAttr(S, D, Attr); break; + case AttributeList::AT_AnyX86NoCallerSavedRegisters: +handleSimpleAttribute(S, D, Attr); +break; + case AttributeList::AT_RenderScriptKernel: handleSimpleAttribute(S, D, Attr); break; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -2170,6 +2170,20 @@ }]; } +def AnyX86NoCallerSavedRegistersDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use this attribute to indicate that the specified function has no +caller-saved registers. That is, all registers are callee-saved. +The compiler generates proper function entry and exit sequences to +save and restore any modified registers. + +The user can call functions specified with the 'no_caller_saved_registers' +attribute from an interrupt handler without saving and restoring all +call clobbered registers. + }]; +} + def SwiftCallDocs : Documentation { let Category = DocCatVariable; let Content = [{ Index: include/clang/Basic/Attr.td === --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1652,6 +1652,13 @@ let Documentation = [AnyX86InterruptDocs]; } +def AnyX86NoCallerSavedRegisters : InheritableAttr, + TargetSpecificAttr { + let Spellings = [GNU<"no_caller_saved_registers">]; + let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">; + let Documentation = [AnyX86NoCallerSavedRegistersDocs]; +} + def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"force_align_arg_pointer">]; // Technically, this appertains to a FunctionDecl, but the target-specific Index: test/SemaCXX/attr-x86-no_caller_saved_registers.cpp === --- test/SemaCXX/attr-x86-no_caller_saved_registers.cpp +++ test/SemaCXX/attr-x86-no_caller_saved_registers.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 -fsyntax-only -verify %s + +struct a { + int b __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}} + static void foo(int *a) __attribute__((no_caller_saved_registers)) {} +}; + +struct a test __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}} + +__attribute__((no_caller_saved_registers(999))) void bar(int *) {} // expected-error {{'no_caller_saved_registers' attribute takes no arguments}} + +__attribute__((no_caller_saved_registers)) void foo(int *) {} + +int main(int argc, char **argv) { + a::foo(&argc); + foo(&argc); + return 0; +} Index: test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp === --- test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp +++ test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %s -emit-llvm -o - | FileCheck %s + +// CHECK: foo{{[^#]*}}#[[ATTRS:[0-9]+]] +__attribute__((no_caller_saved_registe
Re: [PATCH] D16135: Macro Debug Info support in Clang
aaboud added reviewers: erichkeane, bwyma. aaboud updated this revision to Diff 65551. aaboud added a comment. Updated patch to top of trunk (r276746) - Thanks to Ranjeet Singh. Please, provide your feedback. https://reviews.llvm.org/D16135 Files: include/clang/AST/ASTConsumer.h lib/AST/ASTConsumer.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGenAction.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/ModuleBuilder.cpp lib/Parse/ParseAST.cpp Index: lib/Parse/ParseAST.cpp === --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -127,6 +127,12 @@ new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); + std::unique_ptr Callbacks = + Consumer->CreatePreprocessorCallbacks(S.getPreprocessor()); + if (Callbacks) { +S.getPreprocessor().addPPCallbacks(std::move(Callbacks)); + } + llvm::CrashRecoveryContextCleanupRegistrar CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P); Index: lib/CodeGen/ModuleBuilder.cpp === --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/PPCallbacks.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LLVMContext.h" @@ -130,6 +131,11 @@ Builder->AppendLinkerOptions(Opt); } +std::unique_ptr +CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Builder->createPreprocessorCallbacks(PP); +} + void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { if (Diags.hasErrorOccurred()) return; Index: lib/CodeGen/CodeGenModule.cpp === --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -25,6 +25,7 @@ #include "CodeGenPGO.h" #include "CodeGenTBAA.h" #include "CoverageMappingGen.h" +#include "MacroPPCallbacks.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -204,6 +205,16 @@ CUDARuntime.reset(CreateNVCUDARuntime(*this)); } +std::unique_ptr +CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) { + // Enable generating macro debug info only in FullDebugInfo mode. + if (CodeGenOpts.getDebugInfo() < codegenoptions::FullDebugInfo || + !getModuleDebugInfo()) +return nullptr; + + return llvm::make_unique(*getModuleDebugInfo(), PP); +} + void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { Replacements[Name] = C; } Index: lib/CodeGen/CMakeLists.txt === --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -73,6 +73,7 @@ CodeGenTypes.cpp CoverageMappingGen.cpp ItaniumCXXABI.cpp + MacroPPCallbacks.cpp MicrosoftCXXABI.cpp ModuleBuilder.cpp ObjectFilePCHContainerOperations.cpp Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -386,6 +386,16 @@ void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD); + /// Get Macro debug info. + llvm::DIMacro *CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, + SourceLocation LineLoc, StringRef Name, + StringRef Value); + + /// Get Macro File debug info. + llvm::DIMacroFile *CreateMacroFile(llvm::DIMacroFile *Parent, + SourceLocation LineLoc, + SourceLocation FileLoc); + private: /// Emit call to llvm.dbg.declare for a variable declaration. void EmitDeclare(const VarDecl *decl, llvm::Value *AI, Index: lib/CodeGen/CodeGenAction.cpp === --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -222,6 +222,11 @@ Gen->HandleVTable(RD); } +std::unique_ptr +CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Gen->CreatePreprocessorCallbacks(PP); +} + static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, unsigned LocCookie) { SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2264,6 +2264,22 @@ FullName); } +llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent, +
Re: [PATCH] D22900: Revert r244207 - Mark calls in thunk functions as tail-call optimization
aaboud added a comment. Reverting https://reviews.llvm.org/rL244207, would be fine if we assure that PR24235, is fixed in another way. I added Reid who helped reviewing the original patch https://reviews.llvm.org/D11476. https://reviews.llvm.org/D22900 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22900: Revert r244207 - Mark calls in thunk functions as tail-call optimization
aaboud added a comment. > ISTM that the DWARF spec intended such thunks to be encoded as > `DW_AT_trampoline`. That seems more appropriate than relying on codegen > emitting a tailcall. This way the debugger can make the policy decision of > whether or not thunks should show up in the backtrace. > > In any case, correctness must always trump all else. Reverting to green > should take precedence over a QoI bug like PR24235. I agree to the revert, though I am not sure about the new test, it looks too complected, especially the command line. I will let David decide on accepting that test or ask for improvement. Regards, Amjad https://reviews.llvm.org/D22900 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud updated this revision to Diff 66810. aaboud added a comment. Made "no_caller_saved_registers" part of function prototype. This will allow Clang to yell a warning when there is a mismatch between function pointer and assigned function value. Thanks to Erich for implementing this addition change. https://reviews.llvm.org/D22045 Files: include/clang/AST/Type.h include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td include/clang/CodeGen/CGFunctionInfo.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/TypePrinter.cpp lib/CodeGen/CGCall.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaType.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp test/SemaCXX/attr-x86-no_caller_saved_registers.cpp Index: lib/Serialization/ASTWriter.cpp === --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -221,6 +221,7 @@ // FIXME: need to stabilize encoding of calling convention... Record.push_back(C.getCC()); Record.push_back(C.getProducesResult()); + Record.push_back(C.getNoCallerSavedRegs()); if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult()) AbbrevToUse = 0; @@ -731,6 +732,7 @@ Abv->Add(BitCodeAbbrevOp(0)); // RegParm Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult + Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs // FunctionProtoType Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn Index: lib/Serialization/ASTReader.cpp === --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -5368,13 +5368,14 @@ } case TYPE_FUNCTION_NO_PROTO: { -if (Record.size() != 6) { +if (Record.size() != 7) { Error("incorrect encoding of no-proto function type"); return QualType(); } QualType ResultType = readType(*Loc.F, Record, Idx); FunctionType::ExtInfo Info(Record[1], Record[2], Record[3], - (CallingConv)Record[4], Record[5]); + (CallingConv)Record[4], Record[5], + Record[6]); return Context.getFunctionNoProtoType(ResultType, Info); } @@ -5386,9 +5387,10 @@ /*hasregparm*/ Record[2], /*regparm*/ Record[3], static_cast(Record[4]), -/*produces*/ Record[5]); +/*produces*/ Record[5], +/*nocallersavedregs*/ Record[6]); -unsigned Idx = 6; +unsigned Idx = 7; EPI.Variadic = Record[Idx++]; EPI.HasTrailingReturn = Record[Idx++]; Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -746,6 +746,7 @@ FI->ChainCall = chainCall; FI->NoReturn = info.getNoReturn(); FI->ReturnsRetained = info.getProducesResult(); + FI->NoCallerSavedRegs = info.getNoCallerSavedRegs(); FI->Required = required; FI->HasRegParm = info.getHasRegParm(); FI->RegParm = info.getRegParm(); @@ -1673,6 +1674,8 @@ RetAttrs.addAttribute(llvm::Attribute::NoAlias); if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute("no_caller_saved_registers"); HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); Index: lib/AST/ASTContext.cpp === --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -7564,6 +7564,8 @@ if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult()) return QualType(); + if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs()) +return QualType(); // FIXME: some uses, e.g. conditional exprs, really want this to be 'both'. bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn(); Index: lib/AST/TypePrinter.cpp === --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -745,6 +745,8 @@ if (Info.getRegParm()) OS << " __attribute__((regparm (" << Info.getRegParm() << ")))"; + if (Info.getNoCallerSavedRegs()) +OS << "__attribute__((no_caller_saved_registers))"; if (unsigned quals = T->getTypeQuals()) { OS << ' '; Index: lib/Sema/SemaType.cpp === --- lib/Sema/
Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud marked 3 inline comments as done. aaboud added a comment. In https://reviews.llvm.org/D22045#506996, @joerg wrote: > For what it is worth, this certainly seems to be misnamed. By nature, if it > doesn't preserve at least the stack pointer, there is no way to recover on > return, right? I am not sure I understand what you mean! When you said "if it does not preserve the stack pointer", did you mean the "caller"? Maybe it need more clarification on that, but stack pointer should be saved by the caller (via the call instruction), but even in this case the callee must preserve the stack pointer, right? otherwise the return will not work. So, from callee point of view it still cannot assume that any register is a scratch register and it need to preserve it before modifying. https://reviews.llvm.org/D22045 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud marked an inline comment as not done. Comment at: include/clang/Basic/Attr.td:1674 @@ +1673,3 @@ + TargetSpecificAttr { + let Spellings = [GNU<"no_caller_saved_registers">]; + let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">; aaron.ballman wrote: > Yes, though interrupt should be handled in a separate patch since it's a > logically separate change. How about using GCC Spelling instead of GNU and C++? 1. These attributes are compatible with GCC. 2. This is what is said about GCC class: ``` // The GCC spelling implies GNU and CXX11<"gnu", name> and also // sets KnownToGCC to 1. This spelling should be used for any GCC-compatible // attributes. class GCC : Spelling { let KnownToGCC = 1; } ``` https://reviews.llvm.org/D22045 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud marked an inline comment as done. aaboud added a comment. Thanks David for the comments. See answer below. Comment at: lib/CodeGen/CGDebugInfo.cpp:1489 @@ +1488,3 @@ + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; dblaikie wrote: > aaboud wrote: > > dblaikie wrote: > > > Why does the type need to be added to the retained types list? > > Excellent question :) > > This was your suggestion few months ago. > > The reason is that backend will need to know what types are declared in > > lexical blocks. > > Imported entities are collected in the import entity list, while types are > > collected in the retained types. > > > > Check line 518 at DwarfDebug.cpp (http://reviews.llvm.org/D15976#51cfb106) > Not quite following - could we discover the types lazily as we're generating > DWARF in the backend - if we happen to emit a variable of that type & > generate the DIE* for the type, etc? (so that if a type becomes unused it's > able to be dropped - rather than being preserved only when the type is local) > > I suppose that would make it difficult to choose which scopes we had to > preserve when emitting debug info in the backend (if we didn't see a type > until after the scope was created - we wouldn't've known whether to > emit/create that scope or collapse it into its parent, etc) - so this > probably isn't possible/practical. Your analysis is correct. I just tried to re-check how we can discover types lazily, but I could not figure out how to make sure the lexical scope would be created for these types. I guess we can revisit this issue later and re-think a better implementation that make sure optimized types will not be emitted in the debug info. However, I think we can do that in a separate (following) patch. Comment at: test/CodeGenCXX/debug-info-lb.cpp:14 @@ +13,3 @@ +static int bar = 0; +{ + X a(x); dblaikie wrote: > This block seems unnecessary, and its contents are probably more complicated > than needed. This seems to suffice: > > X a; > Y b; > > & the global variable is emitted without referencing it anyway. > > (you could drop the int return and x parameter, too - no need to return > anything from the function, and the if (x) could be removed - the scope can > remain & still produce the same debug info I think) OK, I simplify the test, and it is still does what I needed. The only thing that I need to clarify is the extra block scope that I added to wrap the "a" and "b" variable definition. The reason I did that is to test the case where the types "X" and "Y" are defined in a different scope than they are used at. Without handling this case correctly, the LLVM IR could mistakenly associate "X" and "Y" to the scope of the usage and not the definition, i.e. the scope of "a" and "b", to test that I had to have different scope as in the example. I added a comment in the test explaining that. http://reviews.llvm.org/D15977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud updated this revision to Diff 46708. aaboud added a comment. Reduced the LIT tests and added comment explaining part of it. http://reviews.llvm.org/D15977 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp test/CodeGenCXX/debug-info-lb.cpp Index: lib/CodeGen/CGDecl.cpp === --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -83,26 +83,30 @@ case Decl::UsingShadow: case Decl::ObjCTypeParam: llvm_unreachable("Declaration should not be in declstmts!"); - case Decl::Function: // void X(); - case Decl::Record:// struct/union/class X; - case Decl::Enum: // enum X; - case Decl::EnumConstant: // enum ? { X = ? } - case Decl::CXXRecord: // struct/union/class X; [C++] + case Decl::Function: // void X(); case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label:// __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: case Decl::Empty: // None of these decls require codegen support. return; + case Decl::Record: // struct/union/class X; + case Decl::Enum: // enum X; + case Decl::EnumConstant: // enum ? { X = ? } + case Decl::CXXRecord:// struct/union/class X; [C++] +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); +return; + case Decl::NamespaceAlias: if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitNamespaceAlias(cast(D)); + DI->EmitNamespaceAlias(cast(D)); return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitUsingDecl(cast(D)); + DI->EmitUsingDecl(cast(D)); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -120,6 +124,9 @@ const TypedefNameDecl &TD = cast(D); QualType Ty = TD.getUnderlyingType(); +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); + if (Ty->isVariablyModifiedType()) EmitVariablyModifiedType(Ty); } Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -114,6 +114,11 @@ /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; + + /// Map of AST declaration to its lexical block scope. + llvm::DenseMap> + LexicalBlockMap; + llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -365,6 +370,12 @@ /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); + /// Map AST declaration to its lexical block scope if available. + void recordDeclarationLexicalScope(const Decl &D); + + /// Get lexical scope of AST declaration. + llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); + /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) return; @@ -2043,7
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud updated this revision to Diff 47988. aaboud added a comment. Simplified LIT tests according to David comment. http://reviews.llvm.org/D15977 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp test/CodeGenCXX/debug-info-lb.cpp Index: lib/CodeGen/CGDecl.cpp === --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -83,26 +83,30 @@ case Decl::UsingShadow: case Decl::ObjCTypeParam: llvm_unreachable("Declaration should not be in declstmts!"); - case Decl::Function: // void X(); - case Decl::Record:// struct/union/class X; - case Decl::Enum: // enum X; - case Decl::EnumConstant: // enum ? { X = ? } - case Decl::CXXRecord: // struct/union/class X; [C++] + case Decl::Function: // void X(); case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label:// __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: case Decl::Empty: // None of these decls require codegen support. return; + case Decl::Record: // struct/union/class X; + case Decl::Enum: // enum X; + case Decl::EnumConstant: // enum ? { X = ? } + case Decl::CXXRecord:// struct/union/class X; [C++] +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); +return; + case Decl::NamespaceAlias: if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitNamespaceAlias(cast(D)); + DI->EmitNamespaceAlias(cast(D)); return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitUsingDecl(cast(D)); + DI->EmitUsingDecl(cast(D)); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -120,6 +124,9 @@ const TypedefNameDecl &TD = cast(D); QualType Ty = TD.getUnderlyingType(); +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); + if (Ty->isVariablyModifiedType()) EmitVariablyModifiedType(Ty); } Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -114,6 +114,11 @@ /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; + + /// Map of AST declaration to its lexical block scope. + llvm::DenseMap> + LexicalBlockMap; + llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -365,6 +370,12 @@ /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); + /// Map AST declaration to its lexical block scope if available. + void recordDeclarationLexicalScope(const Decl &D); + + /// Get lexical scope of AST declaration. + llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); + /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) return; @@ -2043,7 +2063,7 @@
Re: [PATCH] D16135: Macro Debug Info support in Clang
aaboud updated this revision to Diff 47997. aaboud marked an inline comment as done. aaboud added a comment. Applied Adrian comment. http://reviews.llvm.org/D16135 Files: include/clang/AST/ASTConsumer.h lib/AST/ASTConsumer.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGenAction.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/CodeGen/ModuleBuilder.cpp lib/Parse/ParseAST.cpp Index: lib/Parse/ParseAST.cpp === --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -128,6 +128,12 @@ new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); + std::unique_ptr Callbacks = + Consumer->CreatePreprocessorCallbacks(S.getPreprocessor()); + if (Callbacks) { +S.getPreprocessor().addPPCallbacks(std::move(Callbacks)); + } + llvm::CrashRecoveryContextCleanupRegistrar CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P); Index: lib/CodeGen/ModuleBuilder.cpp === --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/PPCallbacks.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LLVMContext.h" @@ -234,6 +235,11 @@ void HandleDependentLibrary(llvm::StringRef Lib) override { Builder->AddDependentLib(Lib); } + +std::unique_ptr +CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Builder->createPreprocessorCallbacks(PP); +} }; } Index: lib/CodeGen/CodeGenModule.cpp === --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -24,6 +24,7 @@ #include "CodeGenPGO.h" #include "CodeGenTBAA.h" #include "CoverageMappingGen.h" +#include "MacroPPCallbacks.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -208,6 +209,16 @@ CUDARuntime = CreateNVCUDARuntime(*this); } +std::unique_ptr +CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) { + // Enable generating macro debug info only in FullDebugInfo mode. + if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo || + !getModuleDebugInfo()) +return nullptr; + + return std::make_unique(*getModuleDebugInfo(), PP); +} + void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { Replacements[Name] = C; } Index: lib/CodeGen/MacroPPCallbacks.h === --- lib/CodeGen/MacroPPCallbacks.h +++ lib/CodeGen/MacroPPCallbacks.h @@ -0,0 +1,82 @@ +//===--- MacroPPCallbacks.h -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines implementation for the macro preprocessors callbacks. +// +//===--===// + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Parse/Parser.h" +#include + +namespace llvm { +class DIMacroFile; +} +namespace clang { + +namespace CodeGen { +class CGDebugInfo; +} +class MacroPPCallbacks : public PPCallbacks { + /// Debug info code generator + CodeGen::CGDebugInfo &DebugInfo; + /// Preprocessor + Preprocessor &PP; + /// Location (used for line number) for recent included file. + SourceLocation LastHashLoc; + /// Location (used for file name) for first included file (source main). + SourceLocation FirstIncludeFile; + /// Indicates that first file inclusion occurred. + bool FirstInclude; + /// Indicates that DIMacroFile entry was created for first included file. + bool FirstIncludeDone; + /// Counts current number of command line included files, which was entered + /// and was not exited yet. + int CommandIncludeFiles; + /// Number of fake files that should skip that were not exited yet. + int SkipFiles; + /// Parent contains all entered files that were not exited yet according to + /// the inclusion order. + std::vector Parents; + + /// Use the passed preprocessor to calculate the macro name and value from + /// the given macro info and identifier info. + static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, + Preprocessor &PP, raw_ostream &Name, + raw_ostream &Value); + +public: + MacroPPCallbacks(CodeGen::CGDebugInfo &DI, Preprocessor &PP)
r261634 - Supporting all entities declared in lexical scope in LLVM debug info.
Author: aaboud Date: Tue Feb 23 07:37:18 2016 New Revision: 261634 URL: http://llvm.org/viewvc/llvm-project?rev=261634&view=rev Log: Supporting all entities declared in lexical scope in LLVM debug info. Differential Revision: http://reviews.llvm.org/D15977 Added: cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=261634&r1=261633&r2=261634&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Feb 23 07:37:18 2016 @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2068,7 +2088,8 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp // Cache the enum type so it is available when building the declcontext // and replace the declcontect with the real thing. TypeCache[Ty].reset(RetTy); -TmpContext->replaceAllUsesWith(getDeclContextDescriptor(ED)); +TmpContext->replaceAllUsesWith( +getDeclarationLexicalScope(*ED, QualType(Ty, 0))); ReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(Ty), @@ -2103,7 +2124,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); + llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2364,7 +2385,7 @@ llvm::DICompositeType *CGDebugInfo::Crea unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclContextDescriptor(RD); + llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); // If we ended up creating the type during the context chain construction, // just return that. @@ -2511,8 +2532,15 @@ void CGDebugInfo::collectVarDeclProps(co if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + if (VD->isStaticLocal()) { +// Get context for static locals (that are technically globals) the same way +// we do for "local" locals -- by using current lexical block. +assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); +VDContext = LexicalBlockStack.back(); + } else { +llvm::DIScope *Mod = getParentModuleOrNull(VD); +VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + } } llvm::DISubprogram * Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=261634&r1=261633&r2=261634&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original) +++ cfe/trunk
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
This revision was automatically updated to reflect the committed changes. Closed by commit rL261634: Supporting all entities declared in lexical scope in LLVM debug info. (authored by aaboud). Changed prior to commit: http://reviews.llvm.org/D15977?vs=47988&id=48808#toc Repository: rL LLVM http://reviews.llvm.org/D15977 Files: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Index: cfe/trunk/lib/CodeGen/CGDebugInfo.h === --- cfe/trunk/lib/CodeGen/CGDebugInfo.h +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h @@ -116,6 +116,11 @@ /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; + + /// Map of AST declaration to its lexical block scope. + llvm::DenseMap> + LexicalBlockMap; + llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -378,6 +383,12 @@ /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); + /// Map AST declaration to its lexical block scope if available. + void recordDeclarationLexicalScope(const Decl &D); + + /// Get lexical scope of AST declaration. + llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); + /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp === --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2068,7 +2088,8 @@ // Cache the enum type so it is available when building the declcontext // and replace the declcontect with the real thing. TypeCache[Ty].reset(RetTy); -TmpContext->replaceAllUsesWith(getDeclContextDescriptor(ED)); +TmpContext->replaceAllUsesWith( +getDeclarationLexicalScope(*ED, QualType(Ty, 0))); ReplaceMap.emplace_back( std::piecewise_construct, std::make_tuple(Ty), @@ -2103,7 +2124,7 @@ llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); + llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2364,7 +2385,7 @@ unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclContextDescriptor(RD); + llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); // If we ended up creating the type during the context chain construction, // just return that. @@ -2511,8 +2532,15 @@ if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + if (VD->isStaticLocal()) { +
r268055 - Recommitted r264281 "Supporting all entities declared in lexical scope in LLVM debug info."
Author: aaboud Date: Fri Apr 29 11:08:08 2016 New Revision: 268055 URL: http://llvm.org/viewvc/llvm-project?rev=268055&view=rev Log: Recommitted r264281 "Supporting all entities declared in lexical scope in LLVM debug info." After fixing PR26942 in r267004. Added: cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=268055&r1=268054&r2=268055&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Apr 29 11:08:08 2016 @@ -814,15 +814,18 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1457,6 +1460,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2060,7 +2080,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp // entered into the ReplaceMap: finalize() will replace the first // FwdDecl with the second and then replace the second with // complete type. -llvm::DIScope *EDContext = getDeclContextDescriptor(ED); +llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); @@ -2104,7 +2124,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); + llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2365,7 +2385,7 @@ llvm::DICompositeType *CGDebugInfo::Crea unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclContextDescriptor(RD); + llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); // If we ended up creating the type during the context chain construction, // just return that. @@ -2536,8 +2556,15 @@ void CGDebugInfo::collectVarDeclProps(co if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + if (VD->isStaticLocal()) { +// Get context for static locals (that are technically globals) the same way +// we do for "local" locals -- by using current lexical block. +assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); +VDContext = LexicalBlockStack.back(); + } else { +llvm::DIScope *Mod = getParentModuleOrNull(VD); +VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + } } llvm::DISubprogram * Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=268055&r1=268054&r2=268055&view=diff =
Re: [PATCH] D19727: [MS] Improved implementation #pragma pack (MS pragmas, part 2)
aaboud added a subscriber: aaboud. Comment at: cfe/trunk/lib/Sema/SemaAttr.cpp:110 @@ -200,3 +109,3 @@ case POAK_Reset: // Reset just pops the top of the stack, or resets the current alignment to You forgot to initialize "Alignment" in this case. This is causing a build failure: http://lab.llvm.org:8011/builders/sanitizer-ppc64be-linux/builds/1758 Repository: rL LLVM http://reviews.llvm.org/D19727 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r268151 - Reverting 268055 as it caused PR27579.
Author: aaboud Date: Fri Apr 29 20:44:38 2016 New Revision: 268151 URL: http://llvm.org/viewvc/llvm-project?rev=268151&view=rev Log: Reverting 268055 as it caused PR27579. Removed: cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=268151&r1=268150&r2=268151&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Apr 29 20:44:38 2016 @@ -814,18 +814,15 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { - TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = TD->getLocation(); - - llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); + SourceLocation Loc = Ty->getDecl()->getLocation(); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - TDContext); + getDeclContextDescriptor(Ty->getDecl())); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1460,23 +1457,6 @@ llvm::DIType *CGDebugInfo::getOrCreateSt return T; } -void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { - assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && - "D is already mapped to lexical block scope"); - if (!LexicalBlockStack.empty()) -LexicalBlockMap[&D] = LexicalBlockStack.back(); -} - -llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, - QualType Ty) { - auto I = LexicalBlockMap.find(&D); - if (I != LexicalBlockMap.end()) { -RetainedTypes.push_back(Ty.getAsOpaquePtr()); -return I->second; - } - return getDeclContextDescriptor(cast(&D)); -} - void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2080,7 +2060,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp // entered into the ReplaceMap: finalize() will replace the first // FwdDecl with the second and then replace the second with // complete type. -llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); +llvm::DIScope *EDContext = getDeclContextDescriptor(ED); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); @@ -2124,7 +2104,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); + llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2385,7 +2365,7 @@ llvm::DICompositeType *CGDebugInfo::Crea unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); + llvm::DIScope *RDContext = getDeclContextDescriptor(RD); // If we ended up creating the type during the context chain construction, // just return that. @@ -2556,15 +2536,8 @@ void CGDebugInfo::collectVarDeclProps(co if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - if (VD->isStaticLocal()) { -// Get context for static locals (that are technically globals) the same way -// we do for "local" locals -- by using current lexical block. -assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); -VDContext = LexicalBlockStack.back(); - } else { -llvm::DIScope *Mod = getParentModuleOrNull(VD); -VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); - } + llvm::DIScope *Mod = getParentModuleOrNull(VD); + VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); } llvm::DISubprogram * Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=268151&r1=268150&r2=268151&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
[PATCH] D21766: [codeview][clang] Added support for unnamed bitfield type.
aaboud created this revision. aaboud added reviewers: rnk, majnemer. aaboud added subscribers: cfe-commits, bwyma. Allow creating DI metadata for non-zero width unnamed bitfield members when emitting CodeView. This is needed for patch D21489. http://reviews.llvm.org/D21766 Files: lib/CodeGen/CGDebugInfo.cpp Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -1010,14 +1010,20 @@ const RecordDecl *RD) { StringRef name = field->getName(); QualType type = field->getType(); + bool EmitCodeView = CGM.getCodeGenOpts().EmitCodeView; // Ignore unnamed fields unless they're anonymous structs/unions. if (name.empty() && !type->isRecordType()) -return; +// Do not ignore anonymous bitfield when emitting CodeView. +if(!EmitCodeView || !field->isBitField()) + return; uint64_t SizeInBitsOverride = 0; if (field->isBitField()) { SizeInBitsOverride = field->getBitWidthValue(CGM.getContext()); +if (!SizeInBitsOverride && name.empty()) + // Ignore unnamed 0-width bitfield. + return; assert(SizeInBitsOverride && "found named 0-width bitfield"); } Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -1010,14 +1010,20 @@ const RecordDecl *RD) { StringRef name = field->getName(); QualType type = field->getType(); + bool EmitCodeView = CGM.getCodeGenOpts().EmitCodeView; // Ignore unnamed fields unless they're anonymous structs/unions. if (name.empty() && !type->isRecordType()) -return; +// Do not ignore anonymous bitfield when emitting CodeView. +if(!EmitCodeView || !field->isBitField()) + return; uint64_t SizeInBitsOverride = 0; if (field->isBitField()) { SizeInBitsOverride = field->getBitWidthValue(CGM.getContext()); +if (!SizeInBitsOverride && name.empty()) + // Ignore unnamed 0-width bitfield. + return; assert(SizeInBitsOverride && "found named 0-width bitfield"); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21783: [CodeView] Implement support for bitfields in Clang
aaboud added a comment. Looks good, one minor comments below. Comment at: lib/CodeGen/CGDebugInfo.h:243 @@ +242,3 @@ + llvm::DIScope *RecordTy, + const RecordDecl *RD, SourceLocation Loc); + You have a mismatch between definition and this declaration, definition does not take SourceLocation parameter! http://reviews.llvm.org/D21783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21783: [CodeView] Implement support for bitfields in Clang
aaboud accepted this revision. aaboud added a comment. This revision is now accepted and ready to land. LGTM. Please update PR28162. http://reviews.llvm.org/D21783 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21766: [codeview][clang] Added support for unnamed bitfield type.
aaboud abandoned this revision. aaboud added a comment. Different implementation was committed at http://reviews.llvm.org/rL274201. http://reviews.llvm.org/D21766 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)
aaboud created this revision. aaboud added reviewers: ABataev, DavidKreitzer, hjl.tools, qcolombet. aaboud added a subscriber: cfe-commits. This patch implements the Clang part for no_caller_saved_registers attribute as appear in [[ https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=5ed3cc7b66af4758f7849ed6f65f4365be8223be | interrupt and exception handler proposal ]] http://reviews.llvm.org/D22045 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/CGCall.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp test/SemaCXX/attr-x86-no_caller_saved_registers.cpp Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1673,6 +1673,8 @@ RetAttrs.addAttribute(llvm::Attribute::NoAlias); if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +if (TargetDecl->hasAttr()) + FuncAttrs.addAttribute("no_caller_saved_registers"); HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5910,6 +5910,10 @@ handleTypeTagForDatatypeAttr(S, D, Attr); break; + case AttributeList::AT_AnyX86NoCallerSavedRegisters: +handleSimpleAttribute(S, D, Attr); +break; + case AttributeList::AT_RenderScriptKernel: handleSimpleAttribute(S, D, Attr); break; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -2170,6 +2170,20 @@ }]; } +def AnyX86NoCallerSavedRegistersDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use this attribute to indicate that the specified function has no +caller-saved registers. That is, all registers are callee-saved. +The compiler generates proper function entry and exit sequences to +save and restore any modified registers. + +The user can call functions specified with the 'no_caller_saved_registers' +attribute from an interrupt handler without saving and restoring all +call clobbered registers. + }]; +} + def SwiftCallDocs : Documentation { let Category = DocCatVariable; let Content = [{ Index: include/clang/Basic/Attr.td === --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -1652,6 +1652,13 @@ let Documentation = [AnyX86InterruptDocs]; } +def AnyX86NoCallerSavedRegisters : InheritableAttr, + TargetSpecificAttr { + let Spellings = [GNU<"no_caller_saved_registers">]; + let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">; + let Documentation = [AnyX86NoCallerSavedRegistersDocs]; +} + def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr { let Spellings = [GNU<"force_align_arg_pointer">]; // Technically, this appertains to a FunctionDecl, but the target-specific Index: test/SemaCXX/attr-x86-no_caller_saved_registers.cpp === --- test/SemaCXX/attr-x86-no_caller_saved_registers.cpp +++ test/SemaCXX/attr-x86-no_caller_saved_registers.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 -fsyntax-only -verify %s + +struct a { + int b __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}} + static void foo(int *a) __attribute__((no_caller_saved_registers)) {} +}; + +struct a test __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}} + +__attribute__((no_caller_saved_registers)) void foo(int *) {} + +int main(int argc, char **argv) { + a::foo(&argc); + foo(&argc); + return 0; +} Index: test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp === --- test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp +++ test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %
[PATCH] D17853: Disable tail-call optimization for X86 interrupt handlers
aaboud created this revision. aaboud added reviewers: hjl.tools, DavidKreitzer, ABataev. aaboud added a subscriber: cfe-commits. Resolved Bug 26414. https://llvm.org/bugs/show_bug.cgi?id=26414 Since interrupt handler must be returned with iretq, tail call can't be used. http://reviews.llvm.org/D17853 Files: lib/CodeGen/CGCall.cpp test/CodeGen/attr-x86-interrupt.c Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1451,6 +1451,7 @@ const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + bool HasAnyX86InterruptAttr = false; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr()) @@ -1488,6 +1489,7 @@ if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); } @@ -1527,10 +1529,11 @@ } bool DisableTailCalls = -CodeGenOpts.DisableTailCalls || +CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr || (TargetDecl && TargetDecl->hasAttr()); -FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(DisableTailCalls)); +FuncAttrs.addAttribute( +"disable-tail-calls", +llvm::toStringRef(DisableTailCalls)); FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); Index: test/CodeGen/attr-x86-interrupt.c === --- test/CodeGen/attr-x86-interrupt.c +++ test/CodeGen/attr-x86-interrupt.c @@ -15,12 +15,20 @@ // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_LINUX: "disable-tail-calls"="true" +// X86_64_LINUX-NOT: "disable-tail-calls"="false" // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_LINUX: "disable-tail-calls"="true" +// X86_LINUX-NOT: "disable-tail-calls"="false" // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_Win: "disable-tail-calls"="true" +// X86_64_Win-NOT: "disable-tail-calls"="false" // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_Win: "disable-tail-calls"="true" +// X86_Win-NOT: "disable-tail-calls"="false" Index: lib/CodeGen/CGCall.cpp === --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -1451,6 +1451,7 @@ const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + bool HasAnyX86InterruptAttr = false; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr()) @@ -1488,6 +1489,7 @@ if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); } @@ -1527,10 +1529,11 @@ } bool DisableTailCalls = -CodeGenOpts.DisableTailCalls || +CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr || (TargetDecl && TargetDecl->hasAttr()); -FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(DisableTailCalls)); +FuncAttrs.addAttribute( +"disable-tail-calls", +llvm::toStringRef(DisableTailCalls)); FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); Index: test/CodeGen/attr-x86-interrupt.c === --- test/CodeGen/attr-x86-interrupt.c +++ test/CodeGen/attr-x86-interrupt.c @@ -15,12 +15,20 @@ // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_LINUX: "disable-ta
Re: [PATCH] D17853: Disable tail-call optimization for X86 interrupt handlers
This revision was automatically updated to reflect the committed changes. Closed by commit rL262830: Resolved Bug 26414. (authored by aaboud). Changed prior to commit: http://reviews.llvm.org/D17853?vs=49746&id=49953#toc Repository: rL LLVM http://reviews.llvm.org/D17853 Files: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/test/CodeGen/attr-x86-interrupt.c Index: cfe/trunk/lib/CodeGen/CGCall.cpp === --- cfe/trunk/lib/CodeGen/CGCall.cpp +++ cfe/trunk/lib/CodeGen/CGCall.cpp @@ -1451,6 +1451,7 @@ const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + bool HasAnyX86InterruptAttr = false; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr()) @@ -1488,6 +1489,7 @@ if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); } @@ -1527,10 +1529,11 @@ } bool DisableTailCalls = -CodeGenOpts.DisableTailCalls || +CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr || (TargetDecl && TargetDecl->hasAttr()); -FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(DisableTailCalls)); +FuncAttrs.addAttribute( +"disable-tail-calls", +llvm::toStringRef(DisableTailCalls)); FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); Index: cfe/trunk/test/CodeGen/attr-x86-interrupt.c === --- cfe/trunk/test/CodeGen/attr-x86-interrupt.c +++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c @@ -15,12 +15,20 @@ // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_LINUX: "disable-tail-calls"="true" +// X86_64_LINUX-NOT: "disable-tail-calls"="false" // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_LINUX: "disable-tail-calls"="true" +// X86_LINUX-NOT: "disable-tail-calls"="false" // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_Win: "disable-tail-calls"="true" +// X86_64_Win-NOT: "disable-tail-calls"="false" // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_Win: "disable-tail-calls"="true" +// X86_Win-NOT: "disable-tail-calls"="false" Index: cfe/trunk/lib/CodeGen/CGCall.cpp === --- cfe/trunk/lib/CodeGen/CGCall.cpp +++ cfe/trunk/lib/CodeGen/CGCall.cpp @@ -1451,6 +1451,7 @@ const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + bool HasAnyX86InterruptAttr = false; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr()) @@ -1488,6 +1489,7 @@ if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); } @@ -1527,10 +1529,11 @@ } bool DisableTailCalls = -CodeGenOpts.DisableTailCalls || +CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr || (TargetDecl && TargetDecl->hasAttr()); -FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(DisableTailCalls)); +FuncAttrs.addAttribute( +"disable-tail-calls", +llvm::toStringRef(DisableTailCalls)); FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); Index: cfe/trunk/test/CodeGen/attr-x86-interrupt.c === --- cfe/trunk/test/CodeGen/attr-x86-interrupt.c +++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c @@ -15,12 +15,20 @@ // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define x86_intrcc void @foo7(i32*
r262830 - Resolved Bug 26414.
Author: aaboud Date: Mon Mar 7 08:22:46 2016 New Revision: 262830 URL: http://llvm.org/viewvc/llvm-project?rev=262830&view=rev Log: Resolved Bug 26414. https://llvm.org/bugs/show_bug.cgi?id=26414 Since interrupt handler must be returned with iret, tail call can't be used. Differential Revision: http://reviews.llvm.org/D17853 Modified: cfe/trunk/lib/CodeGen/CGCall.cpp cfe/trunk/test/CodeGen/attr-x86-interrupt.c Modified: cfe/trunk/lib/CodeGen/CGCall.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=262830&r1=262829&r2=262830&view=diff == --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) +++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Mar 7 08:22:46 2016 @@ -1451,6 +1451,7 @@ void CodeGenModule::ConstructAttributeLi const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + bool HasAnyX86InterruptAttr = false; // FIXME: handle sseregparm someday... if (TargetDecl) { if (TargetDecl->hasAttr()) @@ -1488,6 +1489,7 @@ void CodeGenModule::ConstructAttributeLi if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NonNull); +HasAnyX86InterruptAttr = TargetDecl->hasAttr(); HasOptnone = TargetDecl->hasAttr(); } @@ -1527,10 +1529,11 @@ void CodeGenModule::ConstructAttributeLi } bool DisableTailCalls = -CodeGenOpts.DisableTailCalls || +CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr || (TargetDecl && TargetDecl->hasAttr()); -FuncAttrs.addAttribute("disable-tail-calls", - llvm::toStringRef(DisableTailCalls)); +FuncAttrs.addAttribute( +"disable-tail-calls", +llvm::toStringRef(DisableTailCalls)); FuncAttrs.addAttribute("less-precise-fpmad", llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD)); Modified: cfe/trunk/test/CodeGen/attr-x86-interrupt.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-x86-interrupt.c?rev=262830&r1=262829&r2=262830&view=diff == --- cfe/trunk/test/CodeGen/attr-x86-interrupt.c (original) +++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c Mon Mar 7 08:22:46 2016 @@ -15,12 +15,20 @@ __attribute__((interrupt)) void foo8(int // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_LINUX: "disable-tail-calls"="true" +// X86_64_LINUX-NOT: "disable-tail-calls"="false" // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_LINUX: "disable-tail-calls"="true" +// X86_LINUX-NOT: "disable-tail-calls"="false" // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}}) // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_64_Win: "disable-tail-calls"="true" +// X86_64_Win-NOT: "disable-tail-calls"="false" // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}}) // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}}) +// X86_Win: "disable-tail-calls"="true" +// X86_Win-NOT: "disable-tail-calls"="false" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r263380 - Added test that covers changes in r263379.
Author: aaboud Date: Sun Mar 13 06:12:57 2016 New Revision: 263380 URL: http://llvm.org/viewvc/llvm-project?rev=263380&view=rev Log: Added test that covers changes in r263379. Added: cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp Added: cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp?rev=263380&view=auto == --- cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp (added) +++ cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp Sun Mar 13 06:12:57 2016 @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm -debug-info-kind=limited %s | FileCheck %s + +namespace std { class A; } +using std::A; using ::A; + + +// CHECK: [[CompileUnit:![0-9]+]] = distinct !DICompileUnit({{.+}} imports: [[Imports:![0-9]+]]) +// CHECK: [[Imports]] = !{[[ImportedEntity:![0-9]+]]} +// CHECK: [[ImportedEntity]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CompileUnit]], entity: !"_ZTSSt1A", line: 4) + ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r263425 - Recommitted r261634 "Supporting all entities declared in lexical scope in LLVM debug info."
Author: aaboud Date: Mon Mar 14 07:03:55 2016 New Revision: 263425 URL: http://llvm.org/viewvc/llvm-project?rev=263425&view=rev Log: Recommitted r261634 "Supporting all entities declared in lexical scope in LLVM debug info." After fixing PR26715 at r263379. Added: cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp - copied unchanged from r261669, cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=263425&r1=263424&r2=263425&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Mar 14 07:03:55 2016 @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2057,7 +2077,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp // entered into the ReplaceMap: finalize() will replace the first // FwdDecl with the second and then replace the second with // complete type. -llvm::DIScope *EDContext = getDeclContextDescriptor(ED); +llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); @@ -2101,7 +2121,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); + llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2362,7 +2382,7 @@ llvm::DICompositeType *CGDebugInfo::Crea unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclContextDescriptor(RD); + llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); // If we ended up creating the type during the context chain construction, // just return that. @@ -2509,8 +2529,15 @@ void CGDebugInfo::collectVarDeclProps(co if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + if (VD->isStaticLocal()) { +// Get context for static locals (that are technically globals) the same way +// we do for "local" locals -- by using current lexical block. +assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); +VDContext = LexicalBlockStack.back(); + } else { +llvm::DIScope *Mod = getParentModuleOrNull(VD); +VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + } } llvm::DISubprogram * Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?re
r264281 - Recommitted r263425 "Supporting all entities declared in lexical scope in LLVM debug info."
Author: aaboud Date: Thu Mar 24 08:30:41 2016 New Revision: 264281 URL: http://llvm.org/viewvc/llvm-project?rev=264281&view=rev Log: Recommitted r263425 "Supporting all entities declared in lexical scope in LLVM debug info." After fixing PR26942 (the fix is included in this commit). Differential Revision: http://reviews.llvm.org/D18350 Added: cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp - copied unchanged from r263435, cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=264281&r1=264280&r2=264281&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Mar 24 08:30:41 2016 @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } + return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; @@ -2057,7 +2077,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp // entered into the ReplaceMap: finalize() will replace the first // FwdDecl with the second and then replace the second with // complete type. -llvm::DIScope *EDContext = getDeclContextDescriptor(ED); +llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType( llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0)); @@ -2101,7 +2121,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); unsigned Line = getLineNumber(ED->getLocation()); - llvm::DIScope *EnumContext = getDeclContextDescriptor(ED); + llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIType *ClassTy = ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr; return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, @@ -2362,7 +2382,7 @@ llvm::DICompositeType *CGDebugInfo::Crea unsigned Line = getLineNumber(RD->getLocation()); StringRef RDName = getClassName(RD); - llvm::DIScope *RDContext = getDeclContextDescriptor(RD); + llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0)); // If we ended up creating the type during the context chain construction, // just return that. @@ -2509,8 +2529,15 @@ void CGDebugInfo::collectVarDeclProps(co if (DC->isRecord()) DC = CGM.getContext().getTranslationUnitDecl(); - llvm::DIScope *Mod = getParentModuleOrNull(VD); - VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + if (VD->isStaticLocal()) { +// Get context for static locals (that are technically globals) the same way +// we do for "local" locals -- by using current lexical block. +assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); +VDContext = LexicalBlockStack.back(); + } else { +llvm::DIScope *Mod = getParentModuleOrNull(VD); +VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU); + } } llvm::DISubprogram * Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
[PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud created this revision. aaboud added reviewers: probinson, aprantl, echristo, dblaikie. aaboud added a subscriber: cfe-commits. This is the full implementation in Clang of the proposal: http://lists.llvm.org/pipermail/llvm-dev/2015-December/093313.html http://reviews.llvm.org/D15977 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp test/CodeGenCXX/debug-info-lb-class.cpp test/CodeGenCXX/debug-info-lb-static.cpp test/CodeGenCXX/debug-info-lb-static2.cpp test/CodeGenCXX/debug-info-lb-typedef.cpp Index: lib/CodeGen/CGDecl.cpp === --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -83,26 +83,30 @@ case Decl::UsingShadow: case Decl::ObjCTypeParam: llvm_unreachable("Declaration should not be in declstmts!"); - case Decl::Function: // void X(); - case Decl::Record:// struct/union/class X; - case Decl::Enum: // enum X; - case Decl::EnumConstant: // enum ? { X = ? } - case Decl::CXXRecord: // struct/union/class X; [C++] + case Decl::Function: // void X(); case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label:// __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: case Decl::Empty: // None of these decls require codegen support. return; + case Decl::Record: // struct/union/class X; + case Decl::Enum: // enum X; + case Decl::EnumConstant: // enum ? { X = ? } + case Decl::CXXRecord:// struct/union/class X; [C++] +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); +return; + case Decl::NamespaceAlias: if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitNamespaceAlias(cast(D)); + DI->EmitNamespaceAlias(cast(D)); return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitUsingDecl(cast(D)); + DI->EmitUsingDecl(cast(D)); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -120,6 +124,9 @@ const TypedefNameDecl &TD = cast(D); QualType Ty = TD.getUnderlyingType(); +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); + if (Ty->isVariablyModifiedType()) EmitVariablyModifiedType(Ty); } Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -114,6 +114,11 @@ /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; + + /// Map of AST declaration to its lexical block scope. + llvm::DenseMap> + LexicalBlockMap; + llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -365,6 +370,12 @@ /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); + /// Map AST declaration to its lexical block scope if available. + void recordDeclarationLexicalScope(const Decl &D); + + /// Get lexical scope of AST declaration. + llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); + /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +
[PATCH] D16135: Macro Debug Info support in Clang
aaboud created this revision. aaboud added reviewers: dblaikie, rsmith, aprantl, probinson. aaboud added a subscriber: cfe-commits. Added support for FE Clang to create Debug Info entries (DIMacro and DIMacroFile) into generated module if "debug-info-kind" flag is set to "standalone". http://reviews.llvm.org/D16135 Files: include/clang/AST/ASTConsumer.h lib/AST/ASTConsumer.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGenAction.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/CodeGen/ModuleBuilder.cpp lib/Parse/ParseAST.cpp Index: lib/Parse/ParseAST.cpp === --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -128,6 +128,12 @@ new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); + std::unique_ptr Callbacks = + Consumer->CreatePreprocessorCallbacks(S.getPreprocessor()); + if (Callbacks) { +S.getPreprocessor().addPPCallbacks(std::move(Callbacks)); + } + llvm::CrashRecoveryContextCleanupRegistrar CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P); Index: lib/CodeGen/ModuleBuilder.cpp === --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/PPCallbacks.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LLVMContext.h" @@ -234,6 +235,11 @@ void HandleDependentLibrary(llvm::StringRef Lib) override { Builder->AddDependentLib(Lib); } + +std::unique_ptr +CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Builder->createPreprocessorCallbacks(PP); +} }; } Index: lib/CodeGen/CodeGenModule.cpp === --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -24,6 +24,7 @@ #include "CodeGenPGO.h" #include "CodeGenTBAA.h" #include "CoverageMappingGen.h" +#include "MacroPPCallbacks.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -208,6 +209,16 @@ CUDARuntime = CreateNVCUDARuntime(*this); } +std::unique_ptr +CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) { + // Enable generating macro debug info only in FullDebugInfo mode. + if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo || + !getModuleDebugInfo()) +return nullptr; + + return std::make_unique(*getModuleDebugInfo(), PP); +} + void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { Replacements[Name] = C; } Index: lib/CodeGen/MacroPPCallbacks.h === --- lib/CodeGen/MacroPPCallbacks.h +++ lib/CodeGen/MacroPPCallbacks.h @@ -0,0 +1,94 @@ +//===--- MacroPPCallbacks.h ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines implementation for the macro preprocessors callbacks. +// +//===--===// + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Parse/Parser.h" +#include + +namespace llvm { + class DIMacroFile; +} +namespace clang { + +namespace CodeGen { + class CGDebugInfo; +} +class MacroPPCallbacks : public PPCallbacks { + CodeGen::CGDebugInfo &DebugInfo; + Preprocessor &PP; + SourceLocation LastHashLoc; + SourceLocation FirstIncludeFile; + bool FirstInclude; + bool FirstIncludeDone; + int CommandIncludeFiles; + int SkipFiles; + std::vector Parents; + + + static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, + Preprocessor &PP, raw_ostream &Name, + raw_ostream &Value); + +public: + MacroPPCallbacks(CodeGen::CGDebugInfo& DI, Preprocessor &PP); + + /// \brief Callback invoked whenever a source file is entered or exited. + /// + /// \param Loc Indicates the new location. + /// \param PrevFID the file that was exited if \p Reason is ExitFile. + virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, + SrcMgr::CharacteristicKind FileType, + FileID PrevFID = FileID()); + + /// \brief Callback invoked whenever a source file is skipped as the result + /// of header guard optimization. + /// + /// \param SkippedFile The file that is skipped i
Re: [PATCH] D16135: Macro Debug Info support in Clang
aaboud added inline comments. Comment at: include/clang/AST/ASTConsumer.h:163 @@ -155,1 +162,3 @@ + /// The caller takes ownership on the returned pointer. + virtual std::unique_ptr CreatePreprocessorCallbacks(Preprocessor &PP); }; Richard, I know that you suggested not to introduce the Preprocessor in anyway to the ASTConsumer. However, as I could not understand the other way to support macros in Clang without applying a huge redesign, I decided to upload the code I suggested in the proposal. http://lists.llvm.org/pipermail/llvm-dev/2015-November/092449.html If you still think that this approach is not the right one, I would appreciate it if you can explain again how to implement the macro support differently. http://reviews.llvm.org/D16135 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud updated this revision to Diff 45400. aaboud added a comment. Merged all 4 Lit tests into one. http://reviews.llvm.org/D15977 Files: lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp test/CodeGenCXX/debug-info-lb.cpp Index: lib/CodeGen/CGDecl.cpp === --- lib/CodeGen/CGDecl.cpp +++ lib/CodeGen/CGDecl.cpp @@ -83,26 +83,30 @@ case Decl::UsingShadow: case Decl::ObjCTypeParam: llvm_unreachable("Declaration should not be in declstmts!"); - case Decl::Function: // void X(); - case Decl::Record:// struct/union/class X; - case Decl::Enum: // enum X; - case Decl::EnumConstant: // enum ? { X = ? } - case Decl::CXXRecord: // struct/union/class X; [C++] + case Decl::Function: // void X(); case Decl::StaticAssert: // static_assert(X, ""); [C++0x] case Decl::Label:// __label__ x; case Decl::Import: case Decl::OMPThreadPrivate: case Decl::Empty: // None of these decls require codegen support. return; + case Decl::Record: // struct/union/class X; + case Decl::Enum: // enum X; + case Decl::EnumConstant: // enum ? { X = ? } + case Decl::CXXRecord:// struct/union/class X; [C++] +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); +return; + case Decl::NamespaceAlias: if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitNamespaceAlias(cast(D)); + DI->EmitNamespaceAlias(cast(D)); return; case Decl::Using: // using X; [C++] if (CGDebugInfo *DI = getDebugInfo()) -DI->EmitUsingDecl(cast(D)); + DI->EmitUsingDecl(cast(D)); return; case Decl::UsingDirective: // using namespace X; [C++] if (CGDebugInfo *DI = getDebugInfo()) @@ -120,6 +124,9 @@ const TypedefNameDecl &TD = cast(D); QualType Ty = TD.getUnderlyingType(); +if (CGDebugInfo *DI = getDebugInfo()) + DI->recordDeclarationLexicalScope(D); + if (Ty->isVariablyModifiedType()) EmitVariablyModifiedType(Ty); } Index: lib/CodeGen/CGDebugInfo.h === --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -114,6 +114,11 @@ /// Keep track of our current nested lexical block. std::vector> LexicalBlockStack; + + /// Map of AST declaration to its lexical block scope. + llvm::DenseMap> + LexicalBlockMap; + llvm::DenseMap RegionMap; /// Keep track of LexicalBlockStack counter at the beginning of a /// function. This is used to pop unbalanced regions at the end of a @@ -365,6 +370,12 @@ /// Emit an Objective-C interface type standalone debug info. llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc); + /// Map AST declaration to its lexical block scope if available. + void recordDeclarationLexicalScope(const Decl &D); + + /// Get lexical scope of AST declaration. + llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty); + /// Emit standalone debug info for a type. llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc); Index: lib/CodeGen/CGDebugInfo.cpp === --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile *Unit) { + TypedefNameDecl *TD = Ty->getDecl(); // We don't set size information, but do specify where the typedef was // declared. - SourceLocation Loc = Ty->getDecl()->getLocation(); + SourceLocation Loc = TD->getLocation(); + + llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0)); // Typedefs are derived from some other type. return DBuilder.createTypedef( getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit), Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc), - getDeclContextDescriptor(Ty->getDecl())); + TDContext); } llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty, @@ -1472,6 +1475,23 @@ return T; } +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); +} + +llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D, + QualType Ty) { + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; + } else +return getDeclContextDescriptor(cast(&D)); +} + void CGDebugInfo::completeType(const EnumDecl *ED) { if (DebugKind <= CodeGenOptions::DebugLineTablesOnly) return; @@ -2043,7 +2063,7 @@ // If thi
Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info
aaboud marked an inline comment as done. aaboud added a comment. Thanks David for the feedback. I have some answers below, please let me know if they are not sufficient or you are still have concerns. Comment at: lib/CodeGen/CGDebugInfo.cpp:1479 @@ +1478,3 @@ +void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) { + assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() && + "D is already mapped to lexical block scope"); dblaikie wrote: > Dose this assert not fire if there are two decls in the same lexical scope? Why two decls would have the same object instance "Decl"? I am not sure even that you can declare two decls with same name at same lexical-scope, but even if they are defined in the same lexical scope, they will have different line numbers, right? Comment at: lib/CodeGen/CGDebugInfo.cpp:1481 @@ +1480,3 @@ + "D is already mapped to lexical block scope"); + if (!LexicalBlockStack.empty()) +LexicalBlockMap[&D] = LexicalBlockStack.back(); dblaikie wrote: > Should we assert that LexicalBlockStack isn't empty? It might be empty, if the declaration is in the program scope, right? So, we do not want to assert, just to check. Comment at: lib/CodeGen/CGDebugInfo.cpp:1488 @@ +1487,3 @@ + auto I = LexicalBlockMap.find(&D); + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); dblaikie wrote: > Perhaps we should assert here that if D's scope is a lexical block, that it > should have a corresponding entry in the LexicalBlockMap? We will get to this function also for D's that are not in lexical scope. We should not assert, that is also why we have the else handling (which is how we used to get context before). I can agree with you that the function name is misleading, and I am open to other suggestions. Comment at: lib/CodeGen/CGDebugInfo.cpp:1489 @@ +1488,3 @@ + if (I != LexicalBlockMap.end()) { +RetainedTypes.push_back(Ty.getAsOpaquePtr()); +return I->second; dblaikie wrote: > Why does the type need to be added to the retained types list? Excellent question :) This was your suggestion few months ago. The reason is that backend will need to know what types are declared in lexical blocks. Imported entities are collected in the import entity list, while types are collected in the retained types. Check line 518 at DwarfDebug.cpp (http://reviews.llvm.org/D15976#51cfb106) Comment at: lib/CodeGen/CGDebugInfo.cpp:2066 @@ -2045,3 +2065,3 @@ if (isImportedFromModule || !ED->getDefinition()) { -llvm::DIScope *EDContext = getDeclContextDescriptor(ED); +llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0)); llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation()); dblaikie wrote: > Would it be reasonable/possible to do these changes one at a time & > demonstrate the different situations in which types were not correctly nested > in lexical scopes? Or are they all necessary for some correctness/invariant > that must hold? Clang changes cannot be committed before the LLVM changes, otherwise we would crash in backend. Regarding splitting Clang changes into several comments it is possible with the following splits: 1. Static variable (lines 2508-2517) 2. Types (all the others) Now types can be split into several comments as well: Records and Typedef But the infrastructure of recording lexical-scope declarations and getting the lexical-scope context should be committed with the first patch (nevertheless what one it would be, Records or Typedef). Regarding the test, I used to have 3 (even 4) separate tests, but I was asked to merged them. Now, if we do commit patches in steps, I suggest that I still end up with one final test, but I will need to modify it with each patch (I will be building it step by step). Now, what is your call? do you want me to commit the this patch in 3 steps? Or just go with it as one piece? http://reviews.llvm.org/D15977 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16135: Macro Debug Info support in Clang
aaboud updated this revision to Diff 46034. aaboud marked 6 inline comments as done. aaboud added a comment. Added comments explaining the implementation. http://reviews.llvm.org/D16135 Files: include/clang/AST/ASTConsumer.h lib/AST/ASTConsumer.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGenAction.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/MacroPPCallbacks.cpp lib/CodeGen/MacroPPCallbacks.h lib/CodeGen/ModuleBuilder.cpp lib/Parse/ParseAST.cpp Index: lib/Parse/ParseAST.cpp === --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -128,6 +128,12 @@ new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); + std::unique_ptr Callbacks = + Consumer->CreatePreprocessorCallbacks(S.getPreprocessor()); + if (Callbacks) { +S.getPreprocessor().addPPCallbacks(std::move(Callbacks)); + } + llvm::CrashRecoveryContextCleanupRegistrar CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P); Index: lib/CodeGen/ModuleBuilder.cpp === --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/PPCallbacks.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LLVMContext.h" @@ -234,6 +235,11 @@ void HandleDependentLibrary(llvm::StringRef Lib) override { Builder->AddDependentLib(Lib); } + +std::unique_ptr +CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Builder->createPreprocessorCallbacks(PP); +} }; } Index: lib/CodeGen/CodeGenModule.cpp === --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -24,6 +24,7 @@ #include "CodeGenPGO.h" #include "CodeGenTBAA.h" #include "CoverageMappingGen.h" +#include "MacroPPCallbacks.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -208,6 +209,16 @@ CUDARuntime = CreateNVCUDARuntime(*this); } +std::unique_ptr +CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) { + // Enable generating macro debug info only in FullDebugInfo mode. + if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo || + !getModuleDebugInfo()) +return nullptr; + + return std::make_unique(*getModuleDebugInfo(), PP); +} + void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { Replacements[Name] = C; } Index: lib/CodeGen/MacroPPCallbacks.h === --- lib/CodeGen/MacroPPCallbacks.h +++ lib/CodeGen/MacroPPCallbacks.h @@ -0,0 +1,82 @@ +//===--- MacroPPCallbacks.h -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file defines implementation for the macro preprocessors callbacks. +// +//===--===// + +#include "clang/Lex/PPCallbacks.h" +#include "clang/Parse/Parser.h" +#include + +namespace llvm { +class DIMacroFile; +} +namespace clang { + +namespace CodeGen { +class CGDebugInfo; +} +class MacroPPCallbacks : public PPCallbacks { + /// Debug info code generator + CodeGen::CGDebugInfo &DebugInfo; + /// Preprocessor + Preprocessor &PP; + /// Location (used for line number) for recent included file. + SourceLocation LastHashLoc; + /// Location (used for file name) for first included file (source main). + SourceLocation FirstIncludeFile; + /// Indicates that first file inclusion occurred. + bool FirstInclude; + /// Indicates that DIMacroFile entry was created for first included file. + bool FirstIncludeDone; + /// Counts current number of command line included files, which was entered + /// and was not exited yet. + int CommandIncludeFiles; + /// Number of fake files that should skip that were not exited yet. + int SkipFiles; + /// Parent contains all entered files that were not exited yet according to + /// the inclusion order. + std::vector Parents; + + /// Use the passed preprocessor to calculate the macro name and value from + /// the given macro info and identifier info. + static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI, + Preprocessor &PP, raw_ostream &Name, + raw_ostream &Value); + +public: + MacroPPCallbacks(CodeGen::CGDebugInfo