[llvm-dev] Debug info error on bitcode inline modification
Ku Nanashi via llvm-dev
llvm-dev at lists.llvm.org
Mon Feb 5 03:22:59 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.
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>
More information about the llvm-dev
mailing list