Dear colleagues,<br><br>Thanks for replies,<br>I now see that I over-generalized the problem. Strict LLVM IR for C/C++ would mean conserving statics, template instantiations and more. And it seems I'm currently mostly interested only in keeping inline definitions.<br>
<br>In order to have inline functions kept in the resulting LLVM IR, we can externalize them either with __attribute__((used)), as John suggests, or by commenting out inner "if" in ASTContext.cpp:<br><br> if (!getLangOpts().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) {<br>
// if (FD->isInlineDefinitionExternallyVisible())<br> return External;<br><br>It works:<br><br>$ cat test.c <br>__attribute__((used)) __attribute__((always_inline)) __inline__ int f1() { return 0; }<br>__attribute__((always_inline)) __inline__ int f2() { return 0; }<br>
__inline__ int f3() { return 0; }<br><br>$ ~/sandbox/bin/clang -cc1 -emit-llvm test.c -o -<br>; ModuleID = 'test.c'<br>target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"<br>
target triple = "x86_64-unknown-linux-gnu"<br><br>@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @f1 to i8*)], section "llvm.metadata"<br><br>define i32 @f1() nounwind inlinehint alwaysinline {<br>
entry:<br> ret i32 0<br>}<br><br>define i32 @f2() nounwind inlinehint alwaysinline {<br>entry:<br> ret i32 0<br>}<br><br>define i32 @f3() nounwind inlinehint {<br>entry:<br> ret i32 0<br>}<br><br>- D.<br><br><div class="gmail_quote">
2012/6/11 John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div><div class="h5"><div><div>On Jun 9, 2012, at 2:43 PM, Dmitry N. Mikushin wrote:</div><blockquote type="cite">Dear colleagues,<br><br>Consider there is a need to mix sources and headers that are in two different high-level languages. It should be possible, if both languages are lowered down to LLVM IR and merged. But the problem is that clang is unable to generate strict IR code for headers. For example the code<br>
<br>extern __attribute__((device)) int var;<br><br>__attribute__((always_inline)) void kernel()<br>{<br> var = 2;<br>}<br><br>with<br><br>clang -cc1 <a href="http://test.cu/" target="_blank">test.cu</a> -emit-llvm -triple ptx64-unknown-unknown -fcuda-is-device <a href="http://test.cu/" target="_blank">test.cu</a> -o -<br>
<br>reasonably produces empty module: the only function is inline and not used.<br><br>So the question: is there an easy way to generate IR with clang strictly for entire header file, with all inlined functions and unused types?<br>
Probably one way would be to write a plugin to add a fictive call of every function and declare fictive variable of every type, but this is stupid. Any better solution?<br></blockquote></div><br></div></div><div>IIRC, LLVM's IR printer never prints types that aren't actually used. Types aren't really contained in a module like that.</div>
<div><br></div><div>__attribute__(("used")) should force the emission of a function even if it isn't called. I don't believe we have a "emit every function definition you see" mode.</div><span class="HOEnZb"><font color="#888888"><div>
<br></div><div>John.</div></font></span></div>
</blockquote></div><br>