[cfe-dev] How to inline a C-function during code generation ?

Nat! nat at mulle-kybernetik.com
Wed May 27 10:17:07 PDT 2015


> Am 27.05.2015 um 17:06 schrieb mats petersson <mats at planetcatfish.com>:
> 
> Looks like you are calling a function with no prototype or with the wrong prototype - which is why it's being bitcast. 
> 
> 32 (i8*, i64, i8*)* is 
> int (*)(void *, int64_t, char *)
> 
> [or void * instead of char * - impossible to tell apart in LLVM IR, but I'm guessing based on str in your inline function] in C. 
> 
> And your function is declared as 
> i8* (i8*, i64, i8*)*
> so 
> char* (*)(char *, int64_t, char *)
> 
> Do you actually want to return an i32 as a pointer?

The IR was the result of me trying to whittle the output down to something tiny. The code by itself makes not much sense ;)
But my intent is actually to return a void * and then return that casted to int.

In similiar circumstances "clang/opt" has no problems to inline that;
---
static inline void  *foo( void *p)
{
   return( p == (void *) 0x123456 ? (void *) 1 : (void *) 0);
}

int   bar( void *p)
{
   return( foo( p));
}
---
; Function Attrs: nounwind readnone ssp uwtable
define i32 @bar(i8* readnone %p) #0 {
entry:
  %cmp.i = icmp eq i8* %p, inttoptr (i64 1193046 to i8*)
  %0 = zext i1 %cmp.i to i32
  ret i32 %0
}
---

I would go along with your diagnosis, that the way I prototyped the function (in my generation code) and the way the function actually was written is the cause of the problem, which makes the emission of this bitcast necessary. I found it curious and unexpected though, that this seemingly uncomplicated casting prevented inlining. (A warning like "alwaysinline method could not be inlined due to..." would have made this easier :))

Thanks for your help!

Ciao
   Nat!
---------------------------------------------------------
Apple is the steam train that owns the tracks. - S. Jobs







More information about the cfe-dev mailing list