[llvm-dev] Debug info error on bitcode inline modification

David Blaikie via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 2 14:53:09 PST 2018


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>


More information about the llvm-dev mailing list