I'm testing a main function that simply returns void and am get core dump errors (signal 65 or 73) when running the bitcode with lli:
define void #main() {
entry:
ret void
}
Is it a limitation of lli or just plain illegal in LLVM?
I'm well aware that in C++ the declaration of a main function with a return type of void is incorrect. In fact I've tried this with Clang (it's just a warning to do so) and get almost the same code (not exactly the same because of the #0 attributes, but close enough that I believe the differences are not causing this problem):
; Function Attrs: nounwind
define void #main() #0 {
entry:
ret void
}
It doesn't crash for me, so the culprit must be something else:
$ echo "define void #main() {entry: ret void}" | lli -
$
In any case, lli supports void main methods, as you can see in ExecutionEngine::runFunctionAsMain().
Related
I expected __attribute__((noinline)), when added to a function, to make sure that that function gets emitted. This works with gcc, but clang still seems to inline it.
Here is an example, which you can also open on Godbolt:
namespace {
__attribute__((noinline))
int inner_noinline() {
return 3;
}
int inner_inline() {
return 4;
}
int outer() {
return inner_noinline() + inner_inline();
}
}
int main() {
return outer();
}
When build with -O3, gcc emits inner_noinline, but not inner_inline:
(anonymous namespace)::inner_noinline():
mov eax, 3
ret
main:
call (anonymous namespace)::inner_noinline()
add eax, 4
ret
Clang insists on inlining it:
main: # #main
mov eax, 7
ret
If adding a parameter to the functions and letting them perform some trivial work, clang respects the noinline attribute: https://godbolt.org/z/NNSVab
Shouldn't noinline be independent of how complex the function is? What am I missing?
__attribute__((noinline)) prevents the compiler from inlining the function. It doesn't prevent it from doing constant folding. In this case, the compiler was able to recognize that there was no need to call inner_noinline, either as an inline insertion or an out-of-line call. It could just replace the function call with the constant 3.
It sounds like you want to use the optnone attribute instead, to prevent the compiler from applying even the most obvious of optimizations (as this one is).
I would like to define a function in LLVM IR and somehow expose it into Clang so I can call it from C++. Is there a way to do this?
For example, in LLVM IR:
declare { i64, i64 } #divrem(i64, i64)
And then in C++:
struct ret { long div, rem; };
extern "LLVM IR" ret divrem(long, long);
...
auto dr = divrem(30, 11);
Or whatever mapping of the LLVM IR function to a C++ function makes the most sense.
In c++, considering a single compilation unit, does the definition of a function has to come above the call(s) to it in order to be inlined, or is it enought that the definition is somewhere in the compilation unit?
In other words, is there any difference between :
class A {
public:
void f();
};
class B {
A a;
public:
void g();
};
inline void A::f() {
printf("Func'ing A!\n");
}
void B::g() {
//...
a.f();
}
and
class A {
public:
void f();
};
class B {
A a;
public:
void g();
};
void B::g() {
//...
a.f();
}
inline void A::f() {
printf("Func'ing A!\n");
}
regarding A::f() being inlined inside B::g() ?
Thanks
I think this is a reasonable question. There are several cases in C++ where order of text in the file does matter. This fortunately is not one of them - your two code samples are equivalent. As covered by Claudio, writing 'inline' in the source makes no difference either way.
Questions of the variety of "does this optimisation happen" are usually compiler dependent, so can best be answered by asking the compiler, for example:
# clang++ -c first.cpp -O3 -S -emit-llvm -o first.ll
; ModuleID = 'first.cpp'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
%class.B = type { %class.A }
%class.A = type { i8 }
#str = private unnamed_addr constant [12 x i8] c"Func'ing A!\00"
; Function Attrs: nounwind uwtable
define void #_ZN1B1gEv(%class.B* nocapture readnone %this) #0 align 2 {
%puts.i = tail call i32 #puts(i8* getelementptr inbounds ([12 x i8]* #str, i64 0, i64 0)) #1
ret void
}
; Function Attrs: nounwind
declare i32 #puts(i8* nocapture readonly) #1
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)"}
Or, if you prefer x86-64,
# clang++ -c first.cpp -O3 -S -o first.s
.text
.file "first.cpp"
.globl _ZN1B1gEv
.align 16, 0x90
.type _ZN1B1gEv,#function
_ZN1B1gEv: # #_ZN1B1gEv
.cfi_startproc
# BB#0:
movl $.Lstr, %edi
jmp puts # TAILCALL
.Ltmp0:
.size _ZN1B1gEv, .Ltmp0-_ZN1B1gEv
.cfi_endproc
.type .Lstr,#object # #str
.section .rodata.str1.1,"aMS",#progbits,1
.Lstr:
.asciz "Func'ing A!"
.size .Lstr, 12
.ident "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)"
.section ".note.GNU-stack","",#progbits
Both snippets compile to exactly the same intermediate representation with clang 3.5 - most easily verified using a diff tool - so we can be confident that relative position in the source made no difference.
This is actually the case without optimisation as well (using -O0), at least for the compiler I'm using.
inline is a hint for the compiler, which can choose if actually inlining or not.
You may want to have a look at this answer.
Ok, maybe somebody can help me.
I am writing a small LLVM IR testprogram:
; ModuleID = 'main'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-cygwin"
define i32 #my_main() {
entry:
%0 = alloca i64
store i64 42, i64* %0
%1 = load i64* %0
call void #put_integer(i32 15)
ret i32 0
}
declare void #put_integer(i32)
Actually it can be stripped down to this:
; ModuleID = 'main'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-cygwin"
define i32 #my_main() {
entry:
call void #put_integer(i32 15)
ret i32 0
}
declare void #put_integer(i32)
Where _put_integer is an external program that I compile with gcc or clang (doesn't matter for the problem).
The external program is this:
#include <stdio.h>
void put_integer(int Value)
{
printf("%d", Value);
}
and I compile it like this:
clang -c -Wall -g source/put_integer.c -o object/put_integer.o
I also have a small c-main program which calls my IR program:
#include <stdio.h>
extern int my_main(void);
int main(int argc, char *args[])
{
printf("Calling Mainprogram\n\n");
int n_return_value = my_main();
printf("\n\nMainprogram Returned: %u\n", n_return_value);
return n_return_value;
}
which is compiled with the same arguments as above. I put both external object files into a library and then I assemble my LLVM IR program and link it with the two external C-functions in the following way:
llc -filetype=obj test.bc -o test.o
gcc -L ./../RuntimeSystem/ test.o -lmy_runtime -o test.exe
This works fine and the program starts and runs.
The problem is that the actual printf() call prints 0 instead of the 15 that I give as parameter to the IR call. I went into the created program with gdb and checked the stack frame inside my put_integer() function and sure enough it says that 0 is passed as parameter.
So right now there is the problem that somehow the parameter that I pass to the LLVM IR call is not handed to the external C function, instead 0 is handed.
Can anybody please tell me what I'm doing wrong?
Thank you
Edit:
based on a comment below I include the IRBuilder code here that creates the relevant part of my IR code above in the first block.
Constant *left = ConstantInt::get( getGlobalContext(), APInt( 32, 15 ) );
FunctionType *printf_type =
TypeBuilder<void( int ), false>::get( getGlobalContext() );
Function *func = cast<Function>( MODULE.getOrInsertFunction(
"put_integer", printf_type ) );
BUILDER.CreateCall(func,left );
It is my understanding that a proper call to a function in IR must include the function type as in this example which is from the LLVM reference manual:
call i32 (i8*, ...)* #printf(i8* %msg, i32 12, i8 42)
Yet my code (which I got from an answer here in SO by the way) does not generate, but then I guess the IRBuilder class should know best what code to generate, so I don't know if this is a problem or not.
Well, in my case the answer was that I used a wrong target triple in my LLVM module. There is no list of valid triples and I obtained mine in some obscure way by compiling and dissembling a C program but it turned out it was wrong.
In case anybody works with cygwin, the correct target triple is:
x86_64-unknown-windows-cygnus
it appears that with the wrong target triple, the call to the external function uses the wrong type of parameter passing and the result was that no parameter arrived in it.
Say I have the following trivial C header file:
// foo1.h
typedef int foo;
typedef struct {
foo a;
char const* b;
} bar;
bar baz(foo*, bar*, ...);
My goal is to take this file, and produce an LLVM module that looks something like this:
%struct.bar = type { i32, i8* }
declare { i32, i8* } #baz(i32*, %struct.bar*, ...)
In other words, convert a C .h file with declarations into the equivalent LLVM IR, including type resolution, macro expansion, and so on.
Passing this through Clang to generate LLVM IR produces an empty module (as none of the definitions are actually used):
$ clang -cc1 -S -emit-llvm foo1.h -o -
; ModuleID = 'foo1.h'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin13.3.0"
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5 (trunk 200156) (llvm/trunk 200155)"}
My first instinct was to turn to Google, and I came across two related questions: one from a mailing list, and one from StackOverflow. Both suggested using the -femit-all-decls flag, so I tried that:
$ clang -cc1 -femit-all-decls -S -emit-llvm foo1.h -o -
; ModuleID = 'foo1.h'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin13.3.0"
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5 (trunk 200156) (llvm/trunk 200155)"}
Same result.
I've also tried disabling optimizations (both with -O0 and -disable-llvm-optzns), but that made no difference for the output. Using the following variation did produce the desired IR:
// foo2.h
typedef int foo;
typedef struct {
foo a;
char const* b;
} bar;
bar baz(foo*, bar*, ...);
void doThings() {
foo a = 0;
bar myBar;
baz(&a, &myBar);
}
Then running:
$ clang -cc1 -S -emit-llvm foo2.h -o -
; ModuleID = 'foo2.h'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-darwin13.3.0"
%struct.bar = type { i32, i8* }
; Function Attrs: nounwind
define void #doThings() #0 {
entry:
%a = alloca i32, align 4
%myBar = alloca %struct.bar, align 8
%coerce = alloca %struct.bar, align 8
store i32 0, i32* %a, align 4
%call = call { i32, i8* } (i32*, %struct.bar*, ...)* #baz(i32* %a, %struct.bar* %myBar)
%0 = bitcast %struct.bar* %coerce to { i32, i8* }*
%1 = getelementptr { i32, i8* }* %0, i32 0, i32 0
%2 = extractvalue { i32, i8* } %call, 0
store i32 %2, i32* %1, align 1
%3 = getelementptr { i32, i8* }* %0, i32 0, i32 1
%4 = extractvalue { i32, i8* } %call, 1
store i8* %4, i8** %3, align 1
ret void
}
declare { i32, i8* } #baz(i32*, %struct.bar*, ...) #1
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.ident = !{!0}
!0 = metadata !{metadata !"clang version 3.5 (trunk 200156) (llvm/trunk 200155)"}
Besides the placeholder doThings, this is exactly what I want the output to look like! The problem is that this requires 1.) using a modified version of the header, and 2.) knowing the types of things in advance. Which leads me to...
Why?
Basically, I'm building an implementation for a language using LLVM to generate code. The implementation should support C interop by specifying C header files and associated libs only (no manual declarations), which will then be used by the compiler before link-time to ensure that function invocations match their signatures. Hence, I've narrowed the problem down to 2 possible solutions:
Turn the header files into LLVM IR/bitcode, which can then get the type signature of each function
Use libclang to parse the headers, then query the types from the resulting AST (my 'last resort' in case there is no sufficient answer for this question)
TL;DR
I need to take a C header file (such as the above foo1.h) and, without changing it, generate the aforementioned expected LLVM IR using Clang, OR, find another way to get function signatures from C header files (preferrably using libclang or building a C parser)
Perhaps the less elegant solution, but staying with the idea of a doThings function that forces the compiler to emit IR because the definitions are used:
The two problems you identify with this approach are that it requires modifying the header, and that it requires a deeper understanding of the types involved in order to generate "uses" to put in the function. Both of these can be overcome relatively simply:
Instead of compiling the header directly, #include it (or more likely, a preprocessed version of it, or multiple headers) from a .c file that contains all the "uses" code. Straightforward enough:
// foo.c
#include "foo.h"
void doThings(void) {
...
}
You don't need detailed type information to generate specific usages of the names, matching up struct instantiations to parameters and all that complexity as you have in the "uses" code above. You don't actually need to gather the function signatures yourself.
All you need is the list of the names themselves and to keep track of whether they're for a function or for an object type. You can then redefine your "uses" function to look like this:
void * doThings(void) {
typedef void * (*vfun)(void);
typedef union v { void * o; vfun f; } v;
return (v[]) {
(v){ .o = &(bar){0} },
(v){ .f = (vfun)baz },
};
}
This greatly simplifies the necessary "uses" of a name to either casting it to a uniform function type (and taking its pointer rather than calling it), or wrapping it in &( and ){0} (instantiating it regardless of what it is). This means you don't need to store actual type information at all, only the kind of context from which you extracted the name in the header.
(obviously give the dummy function and the placeholder types extended unique names so they don't clash with the code you actually want to keep)
This simplifies the parsing step tremendously since you only have to recognise the context of a struct/union or function declaration, without actually needing to do very much with the surrounding information.
A simple but hackish starting point (which I would probably use because I have low standards :D ) might be:
grep through the headers for #include directives that take an angle-bracketed argument (i.e. an installed header you don't want to also generate declarations for).
use this list to create a dummy include folder with all of the necessary include files present but empty
preprocess it in the hope that'll simplify the syntax (clang -E -I local-dummy-includes/ -D"__attribute__(...)=" foo.h > temp/foo_pp.h or something similar)
grep through for struct or union followed by a name, } followed by a name, or name (, and use this ridiculously simplified non-parse to build the list of uses in the dummy function, and emit the code for the .c file.
It won't catch every possibility; but with a bit of tweaking and extension, it probably will actually deal with a large subset of realistic header code. You could replace this with a dedicated simplified parser (one built to only look at the patterns of the contexts you need) at a later stage.