[cfe-dev] Recursively Rewriting Expressions

Argyrios Kyrtzidis kyrtzidis at apple.com
Thu Jun 16 12:21:03 PDT 2011


On Jun 16, 2011, at 12:12 PM, Gabriel Martinez wrote:

> On Thu, Jun 16, 2011 at 14:16, Argyrios Kyrtzidis <kyrtzidis at apple.com> wrote:
> On Jun 16, 2011, at 10:58 AM, Gabriel Martinez wrote:
> 
> > I am working on a source-to-source translator plugin for clang to transform CUDA into OpenCL. I have made my own ASTConsumer and am using the Rewriter class to perform the rewrites. The way I traverse the AST is manually, stopping to rewrite the AST nodes of interest.
> >
> > Much of the rewriting involves changing function calls into other ones (CUDA API calls to equivalent OpenCL ones), along with rewriting some data structures. My issue is with nested expressions in which there may be multiple portions that must be rewritten at separate levels. The simplest way I could think of is to rewrite the portions I have to in a string and combine those with clang's statement printer so as to get a final string. I would then pass the string to the Rewriter and replace the existing Expr at the top level.
> >
> > For example, let's look at creating a dim3 in CUDA:
> >
> > dim3 a(1, 2, 3);
> > a = dim3(a.y, a.z, a.x);
> >
> > In OpenCL, the dim3s would be rewritten as size_t arrays, and would be initialized as arrays normally are:
> >
> > size_t a[3] = {1, 2, 3};
> > a = {a[1], a[2], a[0]};
> >
> > The issue here is that, in rewriting the dim3 constructor expression on the second line, I do not know how to recursively rewrite the argument expressions. I currently rewrite the constructor to use braces, but then just use the Stmt class's printPretty call to print the argument expressions. As a result, the argument expressions are not rewritten. This is what I get, then:
> >
> > size_t a[3] = {1, 2, 3};
> > a = {a.y, a.z, a.x};
> >
> > The reason for this is that I use clang's existing printPretty call for each argument (to pass to the Rewriter), which allows me to avoid creating my own printing methods for every possible Expr type. In order to make use of this but allow for my own printing when rewrites are necessary, my idea is to create a new class that extends clang's StmtPrinter. In that way, I could overwrite the methods that print Expr classes of interest (say, MemberExprs that reference members of dim3s). As for the rest, I would allow the existing Visit* implementations to do what they normally do. However, StmtPrinter is an internal class, so extending it outside of clang isn't really possible.
> >
> > So, my questions are:
> >
> > 1. Is this a good approach, trying to rewrite expressions recursively by outputting the rewrites to a string?
> > 2. Would it be possible to extend the StmtPrinter?
> > 3. If not, is there a good alternative?
> 
> Why are you using the Rewriter just to replace at the top level and not inside the nested expressions ?
> 
> Well, in the example I gave I could. The bigger problem comes with rewriting some function calls, as the order of arguments in OpenCL may differ from the ones found in CUDA.
> 
> For example:
> 
> cudaMemcpy(dst, src, count, cudaMemcpyHostToDevice);
> 
> Becomes:
> 
> clEnqueueWriteBuffer(commandQueue, src, CL_TRUE, 0, count, dst, 0, NULL, NULL);
> 
> Where the original dst, src, and count are argument expressions that are reused, but in different locations of the new call. In order to support this, I want to be able to take the relevant argument expressions and write them in the string that will replace the full CUDA call. Even better, I wanted to create a generic method of rewriting expressions to strings while printing the rest as normally, which is what I proposed. 

Instead of pretty-printing the expression, how about getting the string that is contained in its SourceRange ?

> 
> 
> Gabriel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110616/75c0fa4b/attachment.html>


More information about the cfe-dev mailing list