[cfe-dev] Intrinsic/Custom Function Creation with Pragmas

Prakash Prabhu prakash.prabhu at gmail.com
Sun Jan 10 00:04:21 CST 2010


Hi Doug,

Never mind about the earlier mail. I looked up Lookup.h (!) and was able to
code in identifier resolution without much hassle and also the creation of
CallExpr's with appropriate calls to the variadic functions. clang really is
easy-to-use/modify ... thanks!

- Prakash


On Fri, Jan 8, 2010 at 10:25 PM, Prakash Prabhu <prakash.prabhu at gmail.com>wrote:

> Hi Doug,
>
> Thanks a lot for your reply. I was able to add the #pragma, parse it
> successfully, determine the functions/compound statements to which they are
> attached by adding code to Sema's ActOnCompoundStmt() and a new function
> called from ParseFunctionDeclarator(). For the pragmas associated with the
> function interface, I am able to generate calls in a global function inside
> the LLVM bit code (by changing CodeGenModule.cpp) to:
>
> " void __AbstractLockInfoAtInterface(char* functionName, char*
> abstractLockName, ...); // the additional parameters are 0/1/2 ...
> indicating the positional parameters of original function in question. "
>
> Multiple pragma's attached to a single block also seem to work (with the
> help of a pragma stack).
>
> Although some of the above places may not be the best (in terms of their
> actual semantics and diagnostics/error checking which I may need at some
> point in the future), right now it gets the job done.
>
> Now, I am at point where I would like to add calls in the LLVM bit code for
> compound statements. After looking around in the code for a while,  I still
> do not have a straightforward solution on how to go about generating calls
> for compound statments as mentioned in my previous mail:
>
> " -- 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 main issue is how to generate the Value* passed in as parameters to
> __AbstractLockInfoAtClientSiteBegin(), after validating that the variables
> specified in the #pragma:
>
> // L1 is parameterized by x
> int x;
> x= ...
> #pragma AbstractLock L2 x
> {
>   int tmp;
>   tmp = a;
>   a = tmp + 1;
> }
>
> In the above code, I would like to verify that x is declared and is in
> scope before I generate a Value* for it in the AbstractLock...Begin function
> call. I was thinking of the following possibility: In Semantic Actions phase
> (ActOnCompoundStmt() to be more specific), verify that x is in scope and
> generate CallExpr before and after the Compound Stmt, wrap this whole triple
> into a Compound statment and return it. To do this: (a) How do I get access
> to the variable declaration of 'x' from this point (ActOnCompoundStmt) -- is
> there a way to walk up the scope tree/AST and at each point look for a
> declaration of x in some kind of symbol table/declaration structure ? (b) Is
> there a easy way to create two AST nodes having CallExpr's  to functions
> that do not have a declaration yet (maybe I need to create the
> declarations?).
>
> Alternatively, if there is way to verify the scope and find the type of the
> variables used (given just the identifier name), at the code generation
> time, that would be great too.
>
>  Thanks, again, for your time!
>
> regards,
> Prakash
>
> On Tue, Jan 5, 2010 at 11:15 AM, Douglas Gregor <dgregor at apple.com> wrote:
>
>>
>> On Jan 4, 2010, at 2:37 PM, Prakash Prabhu wrote:
>>
>> > Hi,
>> >
>> > 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.
>>
>>        - Doug
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.uiuc.edu/pipermail/cfe-dev/attachments/20100110/85c8e893/attachment.html 


More information about the cfe-dev mailing list