This is an archive of the discontinued LLVM Phabricator instance.

Add read_write_arg_mem attribute
ClosedPublic

Authored by igor-laevsky on Jun 11 2015, 11:43 AM.

Details

Summary

This change adds new attribute called "read_write_arg_mem"

Function marked with this attribute can only access memory through it's argument pointers. This attribute directly corresponds to the "OnlyAccessesArgumentPointees" ModRef behaviour in alias analysis.

Diff Detail

Repository
rL LLVM

Event Timeline

igor-laevsky retitled this revision from to Add read_write_arg_mem attribute.
igor-laevsky updated this object.
igor-laevsky edited the test plan for this revision. (Show Details)
igor-laevsky added reviewers: hfinkel, sanjoy, reames.
igor-laevsky added a subscriber: Unknown Object (MLST).
sanjoy edited edge metadata.Jun 11 2015, 12:57 PM

A meta comment: why not mark a _specific_ set of arguments with ReadWriteOnlyViaArg? That seems to convey more information. Some other comments inline.

lib/AsmParser/LLParser.cpp
937 ↗(On Diff #27533)

There's a whitespace issue here.

lib/IR/Verifier.cpp
1449 ↗(On Diff #27533)

I'm not sure these should fail the verifier -- we should just drop ReadWriteArgMem in the readonly case, in in the readnone case replace with ReadArgMem.

I believe that all pointer arguments are ReadWrite by default. So there is no point in adding explicit ReadWrite attribute for each argument separately, if I understood you correctly.

If user wants to encode function which can read and write only from specific set of arguments he can use readonly or readnone attributes. I will add a test for this case.

lib/AsmParser/LLParser.cpp
937 ↗(On Diff #27533)

Since length of "kw_read_write_arg_mem" is one symbol more than maximum length of other kw_* identifiers in this case, I was forced to align all cases accordingly. Not sure what llvm coding standart says about such cases, but it seems reasonable to keep the alignment.

lib/IR/Verifier.cpp
1449 ↗(On Diff #27533)

I think it should fail here. It is safe to consider readonly function as ReadWriteArgMem, but not safe to do the opposite. If function is marked with both attributes it would mean that we can always consider it as readonly. If in reality it was ReadWriteArgMem, something would fail. Anyway even from intuitive point of view it is weird two have this two attributes on one function. It is like saying this function can write memory, but it also can not write memory.

If user wants to encode function which can read and write only from specific set of arguments he can use readonly or readnone attributes. I will add a test for this case.

Actually this does not work :) But it's easy to fix, so I will send a separate follow-up patch.

reames added inline comments.Jun 17 2015, 4:52 PM
include/llvm/Analysis/AliasAnalysis.h
208 ↗(On Diff #27533)

This now matches read_write_arg_mem + readonly right? If so, please update comment.

lib/Analysis/BasicAliasAnalysis.cpp
684 ↗(On Diff #27533)

I think you can get the only reads arguments from this attribute and readonly.

lib/IR/Verifier.cpp
1449 ↗(On Diff #27533)

It is specifically not legal to consider a readonly function as ReadWriteArgMem. A readonly function could read from a global which is not passed as an argument.

I think the combination of read_write_arg_mem and readonly is meaningful. This is specifically read_arg_mem (i.e. only read memory pointer to by arguments).

One way of framing this is that read_write_arg_mem is a special form of a read/write set for the function. Where the set is interpreted as RW or just R depends on other knowledge of the function (i.e. the readonly attribute.)

For this reason, I'd be tempted to rename this as "access_arg_mem_only" or something. Before actually doing that mechanical change, please raise this in an email to llvmdev. I think this needs broader attention. (In particular, I wouldn't feel comfortable signing off on this. The scope is too large.)

@reames,

It is specifically not legal to consider a readonly function as ReadWriteArgMem. A readonly function could read from a global which is not passed as an argument.

Your are right. I probably confused readonly with readnone here.

One way of framing this is that read_write_arg_mem is a special form of a read/write set for the function. Where the set is interpreted as RW or just R depends on other knowledge of the function (i.e. the readonly attribute.)

For this reason, I'd be tempted to rename this as "access_arg_mem_only" or something. Before actually doing that mechanical change, please raise this in an email to llvmdev. I think this needs broader attention. (In particular, I wouldn't feel comfortable signing off on this. The scope is too large.)

I agree, this framing of a problem is better. It reduces confusion regarding dependencies between different function attributes.

hfinkel edited edge metadata.Jun 22 2015, 5:49 PM

@reames,

...

For this reason, I'd be tempted to rename this as "access_arg_mem_only" or something. Before actually doing that mechanical change, please raise this in an email to llvmdev. I think this needs broader attention. (In particular, I wouldn't feel comfortable signing off on this. The scope is too large.)

I agree with this suggestion, access or accesses is better. I also agree that we should discuss this on llvmdev, as with any other change to the IR.

...

igor-laevsky edited edge metadata.

Renamed attribute to the argmemonly.

hfinkel added inline comments.Jul 8 2015, 7:27 PM
docs/LangRef.rst
1328 ↗(On Diff #28695)

acesses -> accesses

1329 ↗(On Diff #28695)

Also non-atomic?

1331 ↗(On Diff #28695)

this -> its

1334 ↗(On Diff #28695)

it's -> its

include/llvm/IR/Attributes.h
102 ↗(On Diff #28695)

passed in as -> based on its

include/llvm/IR/CallSite.h
293 ↗(On Diff #28695)

using it's -> based on its

295 ↗(On Diff #28695)

For grammatical consistency, we should name this:

onlyAccessesArgMemory

and the same goes for the other functions below.

include/llvm/IR/Function.h
296 ↗(On Diff #28695)

using it's -> based on its

include/llvm/IR/Instructions.h
1585 ↗(On Diff #28695)

using it's -> based on its

3356 ↗(On Diff #28695)

using it's -> based on its

lib/AsmParser/LLParser.cpp
978 ↗(On Diff #28695)

We treat the 80 column limit as strict. You'll need to reformat these in some other way.

igor-laevsky set the repository for this revision to rL LLVM.
igor-laevsky marked 10 inline comments as done.
hfinkel added inline comments.Jul 9 2015, 7:03 PM
include/llvm/IR/CallSite.h
295 ↗(On Diff #29351)

I will not approve this patch without this change. All of the other functions read correctly by placing "it" in front of the function name:

"it does Not Access Memory"
"it does Not Return"
"it is NoInline"

and so this needs to be "it only Accesses ArgMemory" because "it only Access ArgMemory" is not grammatically correct.

igor-laevsky marked an inline comment as done.
igor-laevsky added inline comments.
include/llvm/IR/CallSite.h
295 ↗(On Diff #29351)

Sorry, didn't notice "es" suffix.

hfinkel accepted this revision.Jul 10 2015, 4:15 AM
hfinkel edited edge metadata.

With the change below, LGTM.

docs/LangRef.rst
1331 ↗(On Diff #29437)

Actually, I think these are orthogonal concepts. Can you remove mentioning both volatile and atomic? How it accesses memory, and whether that access might have side effects, can be specified separately (via readonly, or the lack thereof, etc.) from which memory might be accessed.

This revision is now accepted and ready to land.Jul 10 2015, 4:15 AM
Closed by commit rL241979: Add argmemonly attribute. (authored by igor.laevsky). · Explain WhyJul 11 2015, 3:30 AM
This revision was automatically updated to reflect the committed changes.