<div dir="ltr">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.<br><br><a href="https://llvm.org/docs/SourceLevelDebugging.html">https://llvm.org/docs/SourceLevelDebugging.html</a> discusses some of the debug info IR metadata in LLVM.<br><br><div class="gmail_quote"><div dir="ltr">On Fri, Feb 2, 2018 at 1:03 AM Ku Nanashi via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi,<br><br>I'm trying to inline function defined in another bitcode module via bitcode modification.<br>I'm linking multiple bitcode modules, setting inline related attributes, applying -always-inline pass, but then debug info error occurs.<br>It seems debug info metadata isn't properly updated on inlining. How can I fix it?<br>I'm using LLVM 3.8.1 on OS X (On below example target is Android but it should be same on others).<br>I'll appreciate any advice. Thanks.<br><br>* Targets<br>caller.cpp<br>-----------------------------------------------------------------<br>#include <android/log.h><br><br>#ifdef __cplusplus<br>extern "C" {<br>#endif<br><br>void caller()<br>{<br> __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", __FILE__, __LINE__, __FUNCTION__);<br>}<br><br>#ifdef __cplusplus<br>}<br>#endif<br>-----------------------------------------------------------------<br><br>callee.cpp<br>-----------------------------------------------------------------<br>#include <android/log.h><br><br>#ifdef __cplusplus<br>extern "C" {<br>#endif<br><br>void callee()<br>{<br> __android_log_print(ANDROID_LOG_DEBUG, "TEST", "%s:%d:%s", __FILE__, __LINE__, __FUNCTION__);<br>}<br><br>#ifdef __cplusplus<br>}<br>#endif<br>-----------------------------------------------------------------<br><br>* Building bitcode<br>-----------------------------------------------------------------<br>$ clang++ (...snip target specific flags...) -emit-llvm caller.cpp -o caller.bc<br>$ clang++ (...snip target specific flags...) -emit-llvm callee.cpp -o callee.bc<br>-----------------------------------------------------------------<br><br>* Linking bitcode<br>-----------------------------------------------------------------<br>$ llvm-link caller.o callee.o -o=test.bc<br>-----------------------------------------------------------------<br><br>* Modifying bitcode<br>inliner.cpp<br>-----------------------------------------------------------------<br>#include "llvm/IR/Type.h"<br>#include "llvm/IR/Module.h"<br>#include "llvm/IR/Function.h"<br>#include "llvm/IR/GlobalValue.h"<br>#include "llvm/IR/InstIterator.h"<br>#include "llvm/IR/Instructions.h"<br>#include "llvm/IR/IRBuilder.h"<br>#include "llvm/Support/SourceMgr.h"<br>#include "llvm/IRReader/IRReader.h"<br>#include "llvm/Support/FileSystem.h"<br>#include "llvm/Bitcode/ReaderWriter.h"<br>#include "llvm/Support/raw_ostream.h"<br><br>using namespace llvm;<br><br>int main(int argc, char *argv[])<br>{<br> SMDiagnostic error;<br> LLVMContext context;<br> Module *M = parseIRFile(argv[1], error, context).release();<br><br> for (Module::iterator F = M->getFunctionList().begin(); F != M->getFunctionList().end(); F++)<br> {<br> if (!F->isDeclaration())<br> {<br> if (F->getName() == "caller")<br> {<br> Function* callee = M->getFunction("callee");<br><br> inst_iterator I = inst_begin((Function *)F);<br> Instruction *inst = &*I;<br><br> CallInst::Create(callee, "", inst);<br> }<br><br> if (F->getName() == "callee")<br> {<br> F->setLinkage(GlobalValue::InternalLinkage);<br> F->addFnAttr(Attribute::AlwaysInline);<br> F->addFnAttr(Attribute::InlineHint);<br> }<br> }<br> }<br><br> std::error_code ec;<br> raw_fd_ostream os(argv[1], ec, sys::fs::F_None);<br> WriteBitcodeToFile(M, os);<br>}<br>-----------------------------------------------------------------<br><br>-----------------------------------------------------------------<br>$ g++ (...snip host specific flags...) inliner.cpp -o inliner<br>$ ./inliner test.bc<br>-----------------------------------------------------------------<br><br>* Applying -always-inline pass (Debug info error occurs)<br>-----------------------------------------------------------------<br>$ opt -debug-pass=Structure -always-inline test.bc -o test.bc.inline<br>Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg -always-inline -verify<br>Target Library Information<br>Target Transform Information<br>Assumption Cache Tracker<br> ModulePass Manager<br> CallGraph Construction<br> Call Graph SCC Pass Manager<br> Inliner for always_inline functions<br> FunctionPass Manager<br> Module Verifier<br> Bitcode Writer<br>!dbg attachment points at wrong subprogram for function<br>!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)<br>void ()* @caller<br> %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<br>!30 = !DILocation(line: 13, column: 2, scope: !23)<br>!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)<br>!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)<br>LLVM ERROR: Broken function found, compilation aborted!<br>-----------------------------------------------------------------<br><br>If I add -strip-debug pass, no error occurs, but of course debug info is lost...<br>-----------------------------------------------------------------<br>$ opt -debug-pass=Structure -strip-debug -always-inline test.bc -o test.bc.inline<br>Pass Arguments: -targetlibinfo -tti -assumption-cache-tracker -basiccg -always-inline -verify<br>Target Library Information<br>Target Transform Information<br>Assumption Cache Tracker<br> ModulePass Manager<br> CallGraph Construction<br> Call Graph SCC Pass Manager<br> Inliner for always_inline functions<br> FunctionPass Manager<br> Module Verifier<br> Bitcode Writer<br>-----------------------------------------------------------------<br></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>