Ku Nanashi via llvm-dev
2018-Feb-02 09:03 UTC
[llvm-dev] Debug info error on bitcode inline modification
Hi, I'm trying to inline function defined in another bitcode module via bitcode modification. I'm linking multiple bitcode modules, setting inline related attributes, applying -always-inline pass, but then debug info error occurs. It seems debug info metadata isn't properly updated on inlining. How can I fix it? I'm using LLVM 3.8.1 on OS X (On below example target is Android but it should be same on others). I'll appreciate any advice. Thanks. * Targets caller.cpp ----------------------------------------------------------------- #include <android/log.h> #ifdef __cplusplus extern "C" { #endif void caller() { __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); } #ifdef __cplusplus } #endif ----------------------------------------------------------------- callee.cpp ----------------------------------------------------------------- #include <android/log.h> #ifdef __cplusplus extern "C" { #endif void callee() { __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", __FILE__, __LINE__, __FUNCTION__); } #ifdef __cplusplus } #endif ----------------------------------------------------------------- * Building bitcode ----------------------------------------------------------------- $ clang++ (...snip target specific flags...) -emit-llvm caller.cpp -o caller.bc $ clang++ (...snip target specific flags...) -emit-llvm callee.cpp -o callee.bc ----------------------------------------------------------------- * Linking bitcode ----------------------------------------------------------------- $ llvm-link caller.o callee.o -o=test.bc ----------------------------------------------------------------- * Modifying bitcode inliner.cpp ----------------------------------------------------------------- #include "llvm/IR/Type.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IRBuilder.h" #include "llvm/Support/SourceMgr.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/FileSystem.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; int main(int argc, char *argv[]) { SMDiagnostic error; LLVMContext context; Module *M = parseIRFile(argv[1], error, context).release(); for (Module::iterator F = M->getFunctionList().begin(); F !M->getFunctionList().end(); F++) { if (!F->isDeclaration()) { if (F->getName() == "caller") { Function* callee = M->getFunction("callee"); inst_iterator I = inst_begin((Function *)F); Instruction *inst = &*I; CallInst::Create(callee, "", inst); } if (F->getName() == "callee") { F->setLinkage(GlobalValue::InternalLinkage); F->addFnAttr(Attribute::AlwaysInline); F->addFnAttr(Attribute::InlineHint); } } } std::error_code ec; raw_fd_ostream os(argv[1], ec, sys::fs::F_None); WriteBitcodeToFile(M, os); } ----------------------------------------------------------------- ----------------------------------------------------------------- $ g++ (...snip host specific flags...) inliner.cpp -o inliner $ ./inliner test.bc ----------------------------------------------------------------- * Applying -always-inline pass (Debug info error occurs) ----------------------------------------------------------------- $ opt -debug-pass=Structure -always-inline test.bc -o test.bc.inline Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg -always-inline -verify Target Library Information Target Transform Information Assumption Cache Tracker ModulePass Manager CallGraph Construction Call Graph SCC Pass Manager Inliner for always_inline functions FunctionPass Manager Module Verifier Bitcode Writer !dbg attachment points at wrong subprogram for function !16 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: true, variables: !19) void ()* @caller %call.i = call i32 (i32, i8*, i8*, ...) @__android_log_print(i32 3, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1.4, i32 0, i32 0), i8* getelementptr inbounds ([111 x i8], [111 x i8]* @.str.2.5, i32 0, i32 0), i32 13, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @__FUNCTION__.callee, i32 0, i32 0)) #2, !dbg !30 !30 = !DILocation(line: 13, column: 2, scope: !23) !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: true, variables: !19) !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: true, variables: !19) LLVM ERROR: Broken function found, compilation aborted! ----------------------------------------------------------------- If I add -strip-debug pass, no error occurs, but of course debug info is lost... ----------------------------------------------------------------- $ opt -debug-pass=Structure -strip-debug -always-inline test.bc -o test.bc.inline Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg -always-inline -verify Target Library Information Target Transform Information Assumption Cache Tracker ModulePass Manager CallGraph Construction Call Graph SCC Pass Manager Inliner for always_inline functions FunctionPass Manager Module Verifier Bitcode Writer ----------------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180202/13a2f8c5/attachment-0001.html>
David Blaikie via llvm-dev
2018-Feb-02 22:53 UTC
[llvm-dev] Debug info error on bitcode inline modification
Every inlinable call in a function that has debug info (F->getSubprogram() returns non-null) must have a DebugLoc associated with it that has a scope chain that ends in that same DISubprogram. https://llvm.org/docs/SourceLevelDebugging.html discusses some of the debug info IR metadata in LLVM. On Fri, Feb 2, 2018 at 1:03 AM Ku Nanashi via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi, > > I'm trying to inline function defined in another bitcode module via > bitcode modification. > I'm linking multiple bitcode modules, setting inline related attributes, > applying -always-inline pass, but then debug info error occurs. > It seems debug info metadata isn't properly updated on inlining. How can I > fix it? > I'm using LLVM 3.8.1 on OS X (On below example target is Android but it > should be same on others). > I'll appreciate any advice. Thanks. > > * Targets > caller.cpp > ----------------------------------------------------------------- > #include <android/log.h> > > #ifdef __cplusplus > extern "C" { > #endif > > void caller() > { > __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", > __FILE__, __LINE__, __FUNCTION__); > } > > #ifdef __cplusplus > } > #endif > ----------------------------------------------------------------- > > callee.cpp > ----------------------------------------------------------------- > #include <android/log.h> > > #ifdef __cplusplus > extern "C" { > #endif > > void callee() > { > __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", > __FILE__, __LINE__, __FUNCTION__); > } > > #ifdef __cplusplus > } > #endif > ----------------------------------------------------------------- > > * Building bitcode > ----------------------------------------------------------------- > $ clang++ (...snip target specific flags...) -emit-llvm caller.cpp -o > caller.bc > $ clang++ (...snip target specific flags...) -emit-llvm callee.cpp -o > callee.bc > ----------------------------------------------------------------- > > * Linking bitcode > ----------------------------------------------------------------- > $ llvm-link caller.o callee.o -o=test.bc > ----------------------------------------------------------------- > > * Modifying bitcode > inliner.cpp > ----------------------------------------------------------------- > #include "llvm/IR/Type.h" > #include "llvm/IR/Module.h" > #include "llvm/IR/Function.h" > #include "llvm/IR/GlobalValue.h" > #include "llvm/IR/InstIterator.h" > #include "llvm/IR/Instructions.h" > #include "llvm/IR/IRBuilder.h" > #include "llvm/Support/SourceMgr.h" > #include "llvm/IRReader/IRReader.h" > #include "llvm/Support/FileSystem.h" > #include "llvm/Bitcode/ReaderWriter.h" > #include "llvm/Support/raw_ostream.h" > > using namespace llvm; > > int main(int argc, char *argv[]) > { > SMDiagnostic error; > LLVMContext context; > Module *M = parseIRFile(argv[1], error, context).release(); > > for (Module::iterator F = M->getFunctionList().begin(); F !> M->getFunctionList().end(); F++) > { > if (!F->isDeclaration()) > { > if (F->getName() == "caller") > { > Function* callee > M->getFunction("callee"); > > inst_iterator I = inst_begin((Function > *)F); > Instruction *inst = &*I; > > CallInst::Create(callee, "", inst); > } > > if (F->getName() == "callee") > { > > F->setLinkage(GlobalValue::InternalLinkage); > F->addFnAttr(Attribute::AlwaysInline); > F->addFnAttr(Attribute::InlineHint); > } > } > } > > std::error_code ec; > raw_fd_ostream os(argv[1], ec, sys::fs::F_None); > WriteBitcodeToFile(M, os); > } > ----------------------------------------------------------------- > > ----------------------------------------------------------------- > $ g++ (...snip host specific flags...) inliner.cpp -o inliner > $ ./inliner test.bc > ----------------------------------------------------------------- > > * Applying -always-inline pass (Debug info error occurs) > ----------------------------------------------------------------- > $ opt -debug-pass=Structure -always-inline test.bc -o test.bc.inline > Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg > -always-inline -verify > Target Library Information > Target Transform Information > Assumption Cache Tracker > ModulePass Manager > CallGraph Construction > Call Graph SCC Pass Manager > Inliner for always_inline functions > FunctionPass Manager > Module Verifier > Bitcode Writer > !dbg attachment points at wrong subprogram for function > !16 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: > 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: > DIFlagPrototyped, isOptimized: true, variables: !19) > void ()* @caller > %call.i = call i32 (i32, i8*, i8*, ...) @__android_log_print(i32 3, i8* > getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i32 0, i32 0), i8* > getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1.4, i32 0, i32 0), i8* > getelementptr inbounds ([111 x i8], [111 x i8]* @.str.2.5, i32 0, i32 0), > i32 13, i8* getelementptr inbounds ([7 x i8], [7 x i8]* > @__FUNCTION__.callee, i32 0, i32 0)) #2, !dbg !30 > !30 = !DILocation(line: 13, column: 2, scope: !23) > !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: > 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: > DIFlagPrototyped, isOptimized: true, variables: !19) > !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: > 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: > DIFlagPrototyped, isOptimized: true, variables: !19) > LLVM ERROR: Broken function found, compilation aborted! > ----------------------------------------------------------------- > > If I add -strip-debug pass, no error occurs, but of course debug info is > lost... > ----------------------------------------------------------------- > $ opt -debug-pass=Structure -strip-debug -always-inline test.bc -o > test.bc.inline > Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg > -always-inline -verify > Target Library Information > Target Transform Information > Assumption Cache Tracker > ModulePass Manager > CallGraph Construction > Call Graph SCC Pass Manager > Inliner for always_inline functions > FunctionPass Manager > Module Verifier > Bitcode Writer > ----------------------------------------------------------------- > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180202/8367c799/attachment.html>
Ku Nanashi via llvm-dev
2018-Feb-05 11:22 UTC
[llvm-dev] Debug info error on bitcode inline modification
> Every inlinable call in a function that has debug info(F->getSubprogram() returns non-null) must have a DebugLoc associated with it that has a scope chain that ends in that same DISubprogram. Thank you for the comment! I don't know if this is a proper way to fix, but after I add DebugLoc same as inserting position instruction, no error occurs. ----------------------------------------------------------------- @@ -33,7 +33,8 @@ int main(int argc, char *argv[]) inst_iterator I = inst_begin((Function *)F); Instruction *inst = &*I; - CallInst::Create(callee, "", inst); + CallInst* ci = CallInst::Create(callee, "", inst); + ci->setDebugLoc(inst->getDebugLoc()); } if (F->getName() == "callee") ----------------------------------------------------------------- 2018-02-03 7:53 GMT+09:00 David Blaikie <dblaikie at gmail.com>:> Every inlinable call in a function that has debug info (F->getSubprogram() > returns non-null) must have a DebugLoc associated with it that has a scope > chain that ends in that same DISubprogram. > > https://llvm.org/docs/SourceLevelDebugging.html discusses some of the > debug info IR metadata in LLVM. > > On Fri, Feb 2, 2018 at 1:03 AM Ku Nanashi via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hi, >> >> I'm trying to inline function defined in another bitcode module via >> bitcode modification. >> I'm linking multiple bitcode modules, setting inline related attributes, >> applying -always-inline pass, but then debug info error occurs. >> It seems debug info metadata isn't properly updated on inlining. How can >> I fix it? >> I'm using LLVM 3.8.1 on OS X (On below example target is Android but it >> should be same on others). >> I'll appreciate any advice. Thanks. >> >> * Targets >> caller.cpp >> ----------------------------------------------------------------- >> #include <android/log.h> >> >> #ifdef __cplusplus >> extern "C" { >> #endif >> >> void caller() >> { >> __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", >> __FILE__, __LINE__, __FUNCTION__); >> } >> >> #ifdef __cplusplus >> } >> #endif >> ----------------------------------------------------------------- >> >> callee.cpp >> ----------------------------------------------------------------- >> #include <android/log.h> >> >> #ifdef __cplusplus >> extern "C" { >> #endif >> >> void callee() >> { >> __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", >> __FILE__, __LINE__, __FUNCTION__); >> } >> >> #ifdef __cplusplus >> } >> #endif >> ----------------------------------------------------------------- >> >> * Building bitcode >> ----------------------------------------------------------------- >> $ clang++ (...snip target specific flags...) -emit-llvm caller.cpp -o >> caller.bc >> $ clang++ (...snip target specific flags...) -emit-llvm callee.cpp -o >> callee.bc >> ----------------------------------------------------------------- >> >> * Linking bitcode >> ----------------------------------------------------------------- >> $ llvm-link caller.o callee.o -o=test.bc >> ----------------------------------------------------------------- >> >> * Modifying bitcode >> inliner.cpp >> ----------------------------------------------------------------- >> #include "llvm/IR/Type.h" >> #include "llvm/IR/Module.h" >> #include "llvm/IR/Function.h" >> #include "llvm/IR/GlobalValue.h" >> #include "llvm/IR/InstIterator.h" >> #include "llvm/IR/Instructions.h" >> #include "llvm/IR/IRBuilder.h" >> #include "llvm/Support/SourceMgr.h" >> #include "llvm/IRReader/IRReader.h" >> #include "llvm/Support/FileSystem.h" >> #include "llvm/Bitcode/ReaderWriter.h" >> #include "llvm/Support/raw_ostream.h" >> >> using namespace llvm; >> >> int main(int argc, char *argv[]) >> { >> SMDiagnostic error; >> LLVMContext context; >> Module *M = parseIRFile(argv[1], error, context).release(); >> >> for (Module::iterator F = M->getFunctionList().begin(); F !>> M->getFunctionList().end(); F++) >> { >> if (!F->isDeclaration()) >> { >> if (F->getName() == "caller") >> { >> Function* callee >> M->getFunction("callee"); >> >> inst_iterator I = inst_begin((Function >> *)F); >> Instruction *inst = &*I; >> >> CallInst::Create(callee, "", inst); >> } >> >> if (F->getName() == "callee") >> { >> F->setLinkage(GlobalValue:: >> InternalLinkage); >> F->addFnAttr(Attribute::AlwaysInline); >> F->addFnAttr(Attribute::InlineHint); >> } >> } >> } >> >> std::error_code ec; >> raw_fd_ostream os(argv[1], ec, sys::fs::F_None); >> WriteBitcodeToFile(M, os); >> } >> ----------------------------------------------------------------- >> >> ----------------------------------------------------------------- >> $ g++ (...snip host specific flags...) inliner.cpp -o inliner >> $ ./inliner test.bc >> ----------------------------------------------------------------- >> >> * Applying -always-inline pass (Debug info error occurs) >> ----------------------------------------------------------------- >> $ opt -debug-pass=Structure -always-inline test.bc -o test.bc.inline >> Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg >> -always-inline -verify >> Target Library Information >> Target Transform Information >> Assumption Cache Tracker >> ModulePass Manager >> CallGraph Construction >> Call Graph SCC Pass Manager >> Inliner for always_inline functions >> FunctionPass Manager >> Module Verifier >> Bitcode Writer >> !dbg attachment points at wrong subprogram for function >> !16 = distinct !DISubprogram(name: "caller", scope: !1, file: !1, line: >> 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: >> DIFlagPrototyped, isOptimized: true, variables: !19) >> void ()* @caller >> %call.i = call i32 (i32, i8*, i8*, ...) @__android_log_print(i32 3, i8* >> getelementptr inbounds ([5 x i8], [5 x i8]* @.str.3, i32 0, i32 0), i8* >> getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1.4, i32 0, i32 0), i8* >> getelementptr inbounds ([111 x i8], [111 x i8]* @.str.2.5, i32 0, i32 0), >> i32 13, i8* getelementptr inbounds ([7 x i8], [7 x i8]* >> @__FUNCTION__.callee, i32 0, i32 0)) #2, !dbg !30 >> !30 = !DILocation(line: 13, column: 2, scope: !23) >> !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: >> 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: >> DIFlagPrototyped, isOptimized: true, variables: !19) >> !23 = distinct !DISubprogram(name: "callee", scope: !21, file: !21, line: >> 11, type: !17, isLocal: false, isDefinition: true, scopeLine: 12, flags: >> DIFlagPrototyped, isOptimized: true, variables: !19) >> LLVM ERROR: Broken function found, compilation aborted! >> ----------------------------------------------------------------- >> >> If I add -strip-debug pass, no error occurs, but of course debug info is >> lost... >> ----------------------------------------------------------------- >> $ opt -debug-pass=Structure -strip-debug -always-inline test.bc -o >> test.bc.inline >> Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg >> -always-inline -verify >> Target Library Information >> Target Transform Information >> Assumption Cache Tracker >> ModulePass Manager >> CallGraph Construction >> Call Graph SCC Pass Manager >> Inliner for always_inline functions >> FunctionPass Manager >> Module Verifier >> Bitcode Writer >> ----------------------------------------------------------------- >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180205/33f00740/attachment.html>