[cfe-dev] Intrinsic/Custom Function Creation with Pragmas
dgregor at apple.com
Tue Jan 5 08:15:21 PST 2010
On Jan 4, 2010, at 2:37 PM, Prakash Prabhu wrote:
> I would like to define some custom pragmas of the following kind, where one can associate abstract locks with functions/structured code blocks using annotations:
> Abstract Locks at the function interface level:
> #pragma AbstractLock L1
> void foo();
> Abstract Locks for anonymous code blocks:
> #pragma AbstractLock L2
> int tmp;
> tmp = a;
> a = tmp + 1;
> Abstract locks could even be parameterized and depend additionally on variables live at point of specification/function parameters:
> // L1 is parameterized by param1 and param2
> #pragma AbstractLock L1 param1 param2
> void foo(int param1, int param2, int param3);
It might be easier to implement this as a new attribute on functions, since attributes are automatically associated with declarations or types. Then, you can avoid the problem of teaching a #pragma that comes *before* a declaration to associate itself with the correct declaration.
It might look something like:
void __attribute__((lock(L1, param1, param2))) foo(int param1, int param2, int param3);
> // L1 is parameterized by x
> int x;
> x= ...
> #pragma AbstractLock L2 x
> int tmp;
> tmp = a;
> a = tmp + 1;
> I would like to use clang to pre-process these pragmas, create some kind of annotation structure in the emitted bit code, for use in the llvm backend (in one of the opt passes). I was thinking of creating an LLVM intrinsic/Set of Custom function calls to represent the abstract lock information in the bit code -- the functions by themselves do not exist and the only purpose of these calls is to give info to the backend about abstract locks. I looked at the llvm.annotation intrinsic, but since it uses a global string, I thought references to variable names (inside the global string) etc may not remain consistent in wake of front-end refactoring/optimizations. My current plan is to:
> Create a custom Pragma Handler, say, PragmaAbstractLockHandler, that parses the AbstractLock pragma, and depending on whether the annotation is at the interface level or inside client code, create calls to the following functions:
> -- For annotations at interface level, insert a call to the following function into a global section:
> void __AbstractLockInfoAtInterface(char* functionName, char* abstractLockName, ...); // the additional parameters are 0/1/2 ... indicating the positional parameters of original function in question.
> -- For annotations at client site, insert call for begin/end of the section that is being abstractly locked:
> void __AbstractLockInfoAtClientSiteBegin(char* abstractLockName, ...); // the additional parameters are Value* representation of the abstract lock parameter variables
> void __AbstractLockInfoAtClientSiteEnd(char* abstractLockName); // marks the end of the abstract lock scope
> The above functions would be immediately processed in the backend as the first pass of opt (by creating appropriate data structures in the backend) and calls will be removed from the bit code -- after creating nonymous functions for the sections of code marked by abstract locks etc..
This makes perfect sense.
> I would greatly appreciate any suggestions on how to go about translating the pragmas to the above functions in clang, or if there might be a better way to achieve the same with other front-end constructs, that will be great. How do I create a HandlePragma method that Lexes till the end of the code section/function declaration, create an Action that adds these functions in source code ?
There's really no way to create a HandlePragma method that lexes until the end of the code section. Typically, what we do is have HandlePragma set some state in the Sema object that indicates the presence of your particular pragma. Then, when Clang parses the corresponding construct (say, a compound statement), the semantic analysis for that compound statement will check whether a #pragma was parsed and perform the appropriate transformations.
More information about the cfe-dev