Peter Lammich via llvm-dev
2019-Apr-12 10:53 UTC
[llvm-dev] Generating C headers from LLVM
Hi List, is there any way to generate proper C header files for functions that are defined in LLVM-IR. My current attempts fail when clang does some fancy transformations (to adhere to some ABIs ??), e.g., for returning a struct. For example the declaration typedef struct {int64_t a; int64_t b;int64_t c;} test; test create_test(void);yields the LLVM code %struct.test = type { i64, i64, i64 } declare void @create_test(%struct.test* sret) #1 However, the function is defined in LLVM-IR as {i64,i64,i64} @create_test() Questions: 1) Is there any way to convince clang to generate the "correct" output, that fits the given definition in LLVM-IR? 2) What other surprises to expect? Is there a "safe fragment" where the obvious C code actually matches the obvious LLVM-IR? 3) If 1 does not exist, is there a way to generate "wrapper-functions" in LLVM-IR, that map the given functions to what clang expects? Thanks in advance for any help, Peter
Michael Spencer via llvm-dev
2019-Apr-12 17:19 UTC
[llvm-dev] Generating C headers from LLVM
On Fri, Apr 12, 2019 at 3:53 AM Peter Lammich via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi List, > > is there any way to generate proper C header files for functions that > are defined in LLVM-IR. My current attempts fail when clang does some > fancy transformations (to adhere to some ABIs ??), e.g., for returning > a struct. > > For example the declaration > > typedef struct {int64_t a; int64_t b;int64_t c;} test; > test create_test(void);yields the LLVM code > > %struct.test = type { i64, i64, i64 } > declare void @create_test(%struct.test* sret) #1 > > However, the function is defined in LLVM-IR as > {i64,i64,i64} @create_test() >Where are you getting this definition from? Clang outputs what is required by the target backend to generate the correct ABI. The mapping from C code to llvm ir is always target dependent. - Michael Spencer> > Questions: > 1) Is there any way to convince clang to generate the "correct" output, > that fits the given definition in LLVM-IR? > > 2) What other surprises to expect? Is there a "safe fragment" where the > obvious C code actually matches the obvious LLVM-IR? > > 3) If 1 does not exist, is there a way to generate "wrapper-functions" > in LLVM-IR, that map the given functions to what clang expects? > > > Thanks in advance for any help, > Peter > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190412/db27abce/attachment.html>
Doerfert, Johannes via llvm-dev
2019-Apr-12 20:33 UTC
[llvm-dev] Generating C headers from LLVM
Hi Peter, I inlined some comments below but it might also interest you that we plan to have a GSoC student work on something quite related [1]. I hope in the process we'll develop the functionality you are looking for as part of what we want to do. I know other people looked into your problem before* but I haven't seen anybody that trying to upstream the functionality yet. * I could look for references. [1] http://llvm.org/OpenProjects.html#header-generation On 04/12, Michael Spencer via llvm-dev wrote:> On Fri, Apr 12, 2019 at 3:53 AM Peter Lammich via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > Hi List, > > > > is there any way to generate proper C header files for functions that > > are defined in LLVM-IR. My current attempts fail when clang does some > > fancy transformations (to adhere to some ABIs ??), e.g., for returning > > a struct. > > > > For example the declaration > > > > typedef struct {int64_t a; int64_t b;int64_t c;} test; > > test create_test(void);yields the LLVM code > > > > %struct.test = type { i64, i64, i64 } > > declare void @create_test(%struct.test* sret) #1 > > > > However, the function is defined in LLVM-IR as > > {i64,i64,i64} @create_test() > > > > Where are you getting this definition from? Clang outputs what is required > by the target backend to generate the correct ABI. The mapping from C code > to llvm ir is always target dependent. > > - Michael SpencerI'm also confused about this part.> > Questions: > > 1) Is there any way to convince clang to generate the "correct" output, > > that fits the given definition in LLVM-IR?Could you elaborate what you would call "correct output", what "incorrect output" you currently see, and how you generate the latter?> > 2) What other surprises to expect? Is there a "safe fragment" where the > > obvious C code actually matches the obvious LLVM-IR?This is a though question. Probably, depending on the target, but Idk if it is written down. You can try to change the target architecture to extend this subset* but as Michael noted above, LLVM-IR is always target dependent. * Try adding '-target spir' or '-target spir-v' to the clang call if you want to use the IR only to generate C code again. It is however still not a target independent IR because of things like the datalayout (=> sizeof, offsetof, ...). See the constant 8 in the example below: ******* INPUT ****** struct S { int a; int b; }; int foo(struct S s) { return s.a + s.b + sizeof(long); } **** INPUT END ***** ****** SPIR IR ****** target triple = "spir" %struct.S = type { i32, i32 } ; Function Attrs: noinline nounwind optnone define dso_local spir_func i32 @foo(%struct.S* byval align 4 %s) #0 { entry: %a = getelementptr inbounds %struct.S, %struct.S* %s, i32 0, i32 0 %0 = load i32, i32* %a, align 4 %b = getelementptr inbounds %struct.S, %struct.S* %s, i32 0, i32 1 %1 = load i32, i32* %b, align 4 %add = add nsw i32 %0, %1 %add1 = add i32 %add, 8 ret i32 %add1 } **** SPIR IR END ****> > 3) If 1 does not exist, is there a way to generate "wrapper-functions" > > in LLVM-IR, that map the given functions to what clang expects?I'm not 100% sure I get your question but maybe it helps to remember that there is a (target dependent) N to 1 mapping between C (signatures) and LLVM-IR (types). That being said, it is probably possible to "remember" the original C type and map generated IR back, we'll hope to explore this during the GSoC. Cheers, Johannes> _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Johannes Doerfert Researcher Argonne National Laboratory Lemont, IL 60439, USA jdoerfert at anl.gov -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 228 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190412/9733f00f/attachment.sig>
Adrien Guinet via llvm-dev
2019-Apr-16 14:09 UTC
[llvm-dev] Generating C headers from LLVM
On 4/12/19 12:53 PM, Peter Lammich via llvm-dev wrote:> Hi List, > > is there any way to generate proper C header files for functions that > are defined in LLVM-IR. My current attempts fail when clang does some > fancy transformations (to adhere to some ABIs ??), e.g., for returning > a struct. > > For example the declaration > > typedef struct {int64_t a; int64_t b;int64_t c;} test; > test create_test(void);yields the LLVM code > > %struct.test = type { i64, i64, i64 } > declare void @create_test(%struct.test* sret) #1 > > However, the function is defined in LLVM-IR as > {i64,i64,i64} @create_test() > > Questions: > 1) Is there any way to convince clang to generate the "correct" output, > that fits the given definition in LLVM-IR? > > 2) What other surprises to expect? Is there a "safe fragment" where the > obvious C code actually matches the obvious LLVM-IR? > > 3) If 1 does not exist, is there a way to generate "wrapper-functions" > in LLVM-IR, that map the given functions to what clang expects? > > > Thanks in advance for any help, > PeterHello, In DragonFFI [1], I use the debug information emitted by clang to "reconstruct" the C function types. This could be used to potentially emit proper C headers that define these functions. Regards, [1] https://github.com/aguinet/dragonffi