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

Douglas Gregor dgregor at apple.com
Sat Jan 9 22:54:22 PST 2010


On Jan 9, 2010, at 10:04 PM, Prakash Prabhu <prakash.prabhu at gmail.com>  
wrote:

> 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!

Glad to hear it!

   - Doug
>
>
> 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.llvm.org/pipermail/cfe-dev/attachments/20100109/797c03bd/attachment.html>


More information about the cfe-dev mailing list