[cfe-dev] A howto or template for adding a transformation pass
Hiren Patel
hirenvt at gmail.com
Sat Aug 9 12:14:31 PDT 2008
>
> My apologies for the vague question formulation. I'll explain my objective
> with an example.
>
> My initial source is as follows:
> unsigned int fib(unsigned int m) {
> unsigned int f0 = 0 ;
> unsigned int f1 = 1, f2, i ;
> unsigned int l1 = 0;
> if (m <= 1) {
> MARKSTART();
> printf("Return\n");
> MARKEND();
> return m;
> } else {
> for (i = 2; i <=m; i++) {
> f2 = f0 + f1;
> f0 = f1;
> f1 = f2;
> for (l1 = 0; l1 <5; l1++) {
> printf("woof\n");
> MARKSTART();
> }
> MARKEND();
> MARKSTART();
> }
> MARKEND();
> return f2;
> }
> }
>
> The MARKSTART and MARKEND represent MACROs that implement a certain
> instruction in a particular processor. The semantics of the MARKEND and
> MARKSTART can be simply thought of as starting and stopping cycle timers for
> segments of code between the MARKSTART and MARKEND. The resulting code after
> the transformation is as follows:
> unsigned int fib(unsigned int m) {
> unsigned int f0 = 0 ;
> unsigned int f1 = 1, f2, i ;
> unsigned int l1 = 0;
> if (m <= 1) {
> MARKSTART0("fib_seq0");
> printf("Return\n");
> MARKEND0("fib_seq0");
> return m;
> } else {
> for (i = 2; i <=m; i++) {
> MARKSTARTCOUNT("bb_k");
> f2 = f0 + f1;
> f0 = f1;
> f1 = f2;
> MARKENDCOUNT("bb_k");
> for (l1 = 0; l1 <5; l1++) {
> printf("woof\n");
> MARKSTART2("fib_loop1");
> }
> MARKEND2("fib_loop1");
> MARKSTART1("fib_loop0");
> }
> MARKEND1("fib_loop0");
> return f2;
> }
> }
>
> The number after a MARKSTART and MARKEND denotes a timer in the processor
> and the string, a unique label identifying blocks of interest used during
> profiling this code. We have certain rules that form a block, such as, a
> MARKSTART must always follow by a MARKEND and use of timers must be
> correctly nested. Notice the MARK*COUNT as only one example of labeling one
> basic block in the source. I would like to add these for every BB in the CFG
> as well. So the tasks here are:
>
> - Identify MARKSTART and MARKEND, allocate a cycle timer such that there
> are no conflicts between the START and END of a block.
> - Identify MARKSTART and MARKEND, add a unique label used in profiling. The
> labels much match the START and END that form a block.
> - For every basic block, add MARKSTARTCOUNT and MARKENDCOUNT respectively
> with a unique BB label.
>
>
> Are you talking about determining where in a function/method body you
> would want to insert code, or are you scanning for particular statements to
> replace?
>
> I want to scan the methods and insert code as described above. There are
> two levels of source changes: a) MARKSTARTCOUNTs from basic block
> information and b) transformation of MARKSTART and MARKENDs with unique
> labels and timer numbers.
>
>
>
> 2. Replace the statements with certain macros with additional labels.
>
>
> Which statements are you replacing? Inserting macros should be fairly
> straightforward by using the rewriter (this is a textual translation by
> editing the source code, not editing the ASTs).
>
> I believe the translation for MARKSTART and MARKEND are possible in the
> straightforward manner. However, I'm not so sure about the basic block
> information.
>
>
> 4. Output the changed C file.
>
>
> If you are using the rewriter to do your edits, this is very
> straightforward. I would like at how the Objective-C -> C translator
> (RewriteObjC) uses the Rewriter to make edits to the source file and then
> blast the new source to disk.
>
>
>
> I've successfully tried the following:
>
> - Added an Analysis consumer, but I noticed that this Analysis consumer
> method is invoked twice; once for each function in the C source. I'd like to
> have access to the full Analysis and then walk it using walker methods.
> - Added an ASTConsumer, but again, this is invoked twice. Once per
> function.
>
>
> I'm not certain what you mean by the "invoked twice" part. ASTConsumer
> implements an action/visitor interface where it receives callbacks for each
> top level declaration (HandleTopLevelDecl) as well as a single call back
> once the entire translation unit has been parsed (HandleTranslationUnit).
>
> Sorry. I sort of figured this out while learning more about clang.
>
>
>
> My gut feeling is that you want to use the Objective-C rewriter as your
> model, and that you want to rewrite pieces of the C source file by removing
> some statements and inserting others. You're probably just going to want to
> write a fresh ASTConsumer that contains a Rewriter object. You can either
> scan for functions/methods to edit using HandleTopLevelDecl, or you can wait
> until HandleTranslationUnit is called to scan all the declarations at once.
> In HandleTranlsationUnit you would also call the appropriate methods on the
> Rewriter to emit your changed source code to disk. If you need CFGs, it's
> very easy to create a CFG using a single method: CFG::BuildCFG (just pass as
> an argument the Stmt* that represents the body of the function or method you
> want to analyze).
>
> I will look more closely into the rewriter.
>
> Many thanks for your detailed responses.
>
> Regards,
> ~Hiren
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080809/69c4182f/attachment.html>
More information about the cfe-dev
mailing list