[LLVMdev] Generating target dependent function calls

Eric Christopher echristo at apple.com
Sat Dec 25 22:31:57 PST 2010


>>> 
>>> 
>>> The reason for the difference is that e.g "long" in
>>> 
>>>> bool GOMP_loop_runtime_next(long, long)
>>> 
>>> has a different size on different architectures.
>>> 
>>> Currently we generate the prototypes and functions ourselves:
>>>> declare i8 @GOMP_loop_runtime_next(i64*, i64*) nounwind
>>> 
>>> To support a 32bit architecture we would need to generate:
>>>> declare i8 @GOMP_loop_runtime_next(i32*, i32*) nounwind
>>> 
>>> Has anybody an idea what's a conceptually clean way to generate OpenMP
>>> function calls for different architectures and best even for different
>>> OpenMP implementations (e.g. mpc.sf.net)
>>> 
>>> Would overloaded intrinsics be a possible approach? How could we
>>> model/derive the right signature for our target architecture. TargetData
>>> does not seem to be enough for this. Is there a better approach than
>>> passing this information using a command line switch?
>>> 
>>> Cheers and thanks for your help
>> 
>> Hi Tobias,
>> 
>> I'm facing a similar problem generating CUDA runtime code for
>> different architectures.  One solution I'm currently considering
>> is to use the TargetInfo class from Clang's Basic library which can
>> be used to obtain target specific parameters (such as sizeof(long))
>> given a target triple.
> 
> Interesting. Maybe I can get enough information from the target triple 
> itself. Module::&getTargetTriple should be enough. I did not think about 
> this, but that might work. Thanks for the pointer.

You could also just use a small function to define the API function you
wish to use and then use TargetData to get some of the final parts:

i.e. if you know you've got something like

char GOMP_foo(pointer, pointer)

you could declare in a function that would then inquire pointer size
from TargetData like:

FunctionType *geti8LongLong() {
  const PointerType *LongTy = Type::getIntNPtrTy(Context, TD.getPointerSizeInBits());
  std::vector<const Type*> Params = { LongTy, LongTy };
  const Type *ResultTy = Type::getInt8Ty(Context);
  return FunctionType::get(ResultTy, ArgTys, 0);
}

and then just use the return from geti8LongLong() as the function type when you declare the function. Or you can abstract out away the LongTy and use it in general.

-eric




















More information about the llvm-dev mailing list