Ben Niu
2013-Sep-11 02:13 UTC
[LLVMdev] Why a function pointer field in a LLVM IR struct is replaced by {}*?
Dear LLVM developers, My name is Ben Niu and I am a Ph.D. student at Lehigh University. I compiled the MUSL C library using Clang 3.3, and dumped the generated LLVM IR files. I found that the MUSL-defined FILE struct (aliasing __FILE_s) struct __FILE_s { unsigned flags; unsigned char *rpos, *rend; int (*close)(FILE *); unsigned char *wend, *wpos; unsigned char *mustbezero_1; unsigned char *wbase; size_t (*read)(FILE *, unsigned char *, size_t); size_t (*write)(FILE *, const unsigned char *, size_t); off_t (*seek)(FILE *, off_t, int); unsigned char *buf; size_t buf_size; FILE *prev, *next; int fd; int pipe_pid; long lockcount; short dummy3; signed char mode; signed char lbf; int lock; int waiters; void *cookie; off_t off; char *getln_buf; void *mustbezero_2; unsigned char *shend; off_t shlim, shcnt;}; was represented by %struct.__FILE_s = type { i32, i8*, i8*, i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, i64 (%struct.__FILE_s*, i8*, i64)*, i64 (%struct.__FILE_s*, i8*, i64)*, i64 (%struct.__FILE_s*, i64, i32)*, i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, i32, i32, i64, i16, i8, i8, i32, i32, i8*, i64, i8*, i8*, i8*, i64, i64 } in some IR files, but was represented by %struct.__FILE_s = type { i32, i8*, i8*, i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, i64 (%struct.__FILE_s*, i8*, i64)*, {}*, i64 (%struct.__FILE_s*, i64, i32)*, i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, i32, i32, i64, i16, i8, i8, i32, i32, i8*, i64, i8*, i8*, i8*, i64, i64 } in other source files. All these source files include the complete FILE struct definition. The only difference between these two IR structs is that a function pointer type field in the first form is replaced by {}* in the second form. Could anyone tell me why this happens and how to disable the {}* replacement? -- Thanks, Ben Niu Homepage: www.cse.lehigh.edu/~ben210 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130910/1121da2c/attachment.html>
Eli Friedman
2013-Sep-11 03:16 UTC
[LLVMdev] Why a function pointer field in a LLVM IR struct is replaced by {}*?
On Tue, Sep 10, 2013 at 7:13 PM, Ben Niu <niuben003 at gmail.com> wrote:> Dear LLVM developers, > > My name is Ben Niu and I am a Ph.D. student at Lehigh University. I > compiled the MUSL C library using Clang 3.3, and dumped the generated LLVM > IR files. I found that the MUSL-defined FILE struct (aliasing __FILE_s) > > struct __FILE_s { > unsigned flags; > unsigned char *rpos, *rend; > int (*close)(FILE *); > unsigned char *wend, *wpos; > unsigned char *mustbezero_1; > unsigned char *wbase; > size_t (*read)(FILE *, unsigned char *, size_t); > size_t (*write)(FILE *, const unsigned char *, size_t); > off_t (*seek)(FILE *, off_t, int); > unsigned char *buf; > size_t buf_size; > FILE *prev, *next; > int fd; > int pipe_pid; > long lockcount; > short dummy3; > signed char mode; > signed char lbf; > int lock; > int waiters; > void *cookie; > off_t off; > char *getln_buf; > void *mustbezero_2; > unsigned char *shend; > off_t shlim, shcnt;}; > > was represented by > > %struct.__FILE_s = type { i32, i8*, i8*, > i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, > i64 (%struct.__FILE_s*, i8*, i64)*, > i64 (%struct.__FILE_s*, i8*, i64)*, > i64 (%struct.__FILE_s*, i64, i32)*, > i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, > i32, i32, i64, i16, i8, i8, i32, i32, i8*, > i64, i8*, i8*, i8*, i64, i64 } > > in some IR files, but was represented by > > %struct.__FILE_s = type { i32, i8*, i8*, > i32 (%struct.__FILE_s*)*, i8*, i8*, i8*, i8*, > i64 (%struct.__FILE_s*, i8*, i64)*, {}*, > i64 (%struct.__FILE_s*, i64, i32)*, > i8*, i64, %struct.__FILE_s*, %struct.__FILE_s*, > i32, i32, i64, i16, i8, i8, i32, i32, i8*, > i64, i8*, i8*, i8*, i64, i64 } > > in other source files. All these source files include the complete FILE > struct definition. The only difference between these two IR structs is that > a function pointer type field in the first form is replaced by {}* in the > second form. Could anyone tell me why this happens and how to disable the > {}* replacement? > > > See CodeGenTypes::isFuncTypeArgumentConvertible inclang/lib/CodeGen/CodeGenTypes.cpp; this behavior exists to protect the type conversion code from infinite recursion. Our behavior could probably be improved here; patches welcome (but be warned the code is rather complicated). Off the top of my head, I can't say why this is triggering in some files, but not others. -Eli -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130910/5d171065/attachment.html>
Renato Golin
2013-Sep-11 09:42 UTC
[LLVMdev] Why a function pointer field in a LLVM IR struct is replaced by {}*?
On 11 September 2013 04:16, Eli Friedman <eli.friedman at gmail.com> wrote:> Off the top of my head, I can't say why this is triggering in some files, > but not others. >If the member is unused on that particular file, it might not have been fully converted as it was unnecessary (or haven't triggered final conversion). cheers, --renato -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130911/8f9c0a5e/attachment.html>
Possibly Parallel Threads
- [LLVMdev] Why a function pointer field in a LLVM IR struct is replaced by {}*?
- [LLVMdev] assert when mixing static and non-static members with an external AST source
- problems with truncate() with files > 2Gb under Windows (possibly (PR#7879)
- [LLVMdev] assert when mixing static and non-static members with an external AST source
- problems with truncate() with files > 2Gb under Windows (PR#7880)