Support for per-loop pragma

Many compilers support per-loop pragma, such as loop unrolling (ie
#pragma unroll=2). Is there any LLVM project/effort going on
in this area ? What is the expected way for implementing per-loop
pragma, or general pragma ? Suggestions/comments ?

Thanks
Junjie

Hi Junjie,

I don't know of anyone working on it, but it seems like a natural application of the metadata support in mainline:
http://blog.llvm.org/2010/04/extensible-metadata-in-llvm-ir.html

We'd want to tag something, perhaps the backedge branches with metadata, then have the loop canonicalization passes preserve them.

-Chris

Hi Chris,

Thanks. I will see what I can do for this.

Junjie

I'd like to add a pragma support in llvm. I am thinking about using a
llvm intrinsic to represent each pragma, such as
   llvm.pragma (metadata, ...)
where metadata describes a pragma. So if an application has:

  #pragma p1 ..
  #pragma p2...
  for (...)

The llvm IR would be

  llvm.pragma (metadata..) // for p1
  llvm.pragma (metadata..) // for p2
  llvm IR for "for (...)"

In this way, the pragma handling is quite general (for example, it can
be used to support frequency hint for a branch, etc).
And it should be easy for any frontend to generate.

A possible issue might be that optimizations might make the
association between pragmas and their loops (in this case)
less obvious.

Any suggestions/ideas ?

Junjie

Hi Junjie,

In this way, the pragma handling is quite general (for example, it can
be used to support frequency hint for a branch, etc).
And it should be easy for any frontend to generate.

since metadata can be attached to instructions, couldn't you just attach
some metadata containing frequency information directly to the branch
instruction?

Ciao,

Duncan.

This approach assumes that these two llvm.pragma intrinsics and the
llvm IR for "for (...)" always stay together in same order all the
time. This ordering is extremely hard to maintain. Using attached
metadata, as suggested by others, is much better alternative.

IIUC, Chris suggested something like following ...

header:
  br i1 %x, label %then, %label endif
then:
  ...
  br i1 %y, label %loop_exit, label %header, !loop_pragma !1
endif:
  ...
  br i1 %z, label %loop_exit, label %header, !loop_pragma !2
loop_exit:
  ret i32 1

Where !1 and !2 are the metadata for your loop pragma.

Thanks for comments/suggestions.

Yes, attaching metadata to instructions will be good choices for many
cases. But for loops,
attaching metadata to back-edges requires that the front end to build
loops, which is an
additional task for the front end. And this task is really a backend's
job, not the front end's.

If the only concern is that it is hard for pragma intrinsics to stay
with their associated code,
another choice is to process pragma intrinsic at the beginning of
optimizer and associates
them to instructions by either attaching metadata to instructions and
some kind maps (between
instructions/BB to metadata, etc).

Junjie

If LLVM would like to support OpenMP pragma in the future, not sure
if attaching metadata to instructions is still a good choice.

Junjie

Thanks for comments/suggestions.

Yes, attaching metadata to instructions will be good choices for many
cases. But for loops,
attaching metadata to back-edges requires that the front end to build
loops, which is an
additional task for the front end. And this task is really a backend's
job, not the front end's.

The front-ends (llvm-gcc and clang) typically lower their internal AST
into llvm IR. The front-end's will have to do a job of attaching
pragma to respective AST node any way. Which node will it chose to
annotate #pragma, irrespective of how it is annotated ?

If the only concern is that it is hard for pragma intrinsics to stay
with their associated code,
another choice is to process pragma intrinsic at the beginning of
optimizer and associates
them to instructions by either attaching metadata to instructions and
some kind maps (between
instructions/BB to metadata, etc).

Note, The loop optimizer may not be the first thing run by the
optimizer. If you wait until loop optimizer to form loop then it may
be too late. Whoever is converting llvm.pragma intrinsic into
attached metadata will likely attach metadata to immediate next
instruction anyway.

Thanks for comments/suggestions.

Yes, attaching metadata to instructions will be good choices for many
cases. But for loops,
attaching metadata to back-edges requires that the front end to build
loops, which is an
additional task for the front end. And this task is really a backend's
job, not the front end's.

The front-ends (llvm-gcc and clang) typically lower their internal AST
into llvm IR. The front-end's will have to do a job of attaching
pragma to respective AST node any way. Which node will it chose to
annotate #pragma, irrespective of how it is annotated ?

For a loop pragma, I am thinking that it should annotate #pragma on
the head basic block of the following loop (or a branch instruction
that forms a back edge for this loop, as suggested by Chris and
others).

If the only concern is that it is hard for pragma intrinsics to stay
with their associated code,
another choice is to process pragma intrinsic at the beginning of
optimizer and associates
them to instructions by either attaching metadata to instructions and
some kind maps (between
instructions/BB to metadata, etc).

Note, The loop optimizer may not be the first thing run by the
optimizer. If you wait until loop optimizer to form loop then it may
be too late. Whoever is converting llvm.pragma intrinsic into
attached metadata will likely attach metadata to immediate next
instruction anyway.

Right, the loop optimization isn't the first thing run by the
optimizer. I meant that we may add a new pass that just extracts
those pragma intrinsics and make this new pass to be the first thing
run by the optimizer.

Anyway, I will look into the alternative carefully ....

Thanks for all your comments.
Junjie

FYI, LLVM already supports OpenMP with the llvm-gcc frontend. Lowering OpenMP is a job for the frontend to do.

-Chris