This is an archive of the discontinued LLVM Phabricator instance.

[Polly][Fortran Array] generate run-time size computation for outermost dimension of fortran array
ClosedPublic

Authored by bollu on May 8 2017, 7:58 AM.

Details

Summary

This patch tracks D32639, so this must be kept in sync with it.

  • 1. Change ScopArrayInfo and its building phase to track that it is a

Fortran array. Before, this was entirely in MemoryAccess. Now, the SAI
needs to know whether it contains a fortran array or not.

  • 2. Add a "dummy" pwAff into ScopArrayInfo for the virtual

outermost dimension.

  • 3. Synthesize a custom Value for the pwAff isl Id such that it

computes the outermost dimension size. This matches code generated by
dragonegg

  • 4. Anyone who tries to refer to the outermost dimension size from now

on will use the synthesized Value

The changes are quite large, and are somewhat "sweeping". Also note that
the diff will look much smaller once D32639 has been mainlined.

Also, I am unfamiliar with the schedule API, and I believe
that what I have done in ScopInfo.cpp is a hack. However, I'm not sure
what the right of doing this is.

Diff Detail

Repository
rL LLVM

Event Timeline

bollu created this revision.May 8 2017, 7:58 AM
Meinersbur edited edge metadata.May 9 2017, 7:59 AM

Can you upload a diff to D32639 (that is git diff 3526edc9617a 444607a22002)?

bollu added a comment.May 9 2017, 8:13 AM

@Meinersbur: I put this up here to "track progress" in some sense. I think it will be easier to merge this if I ship parts of functionality from this in separate patches (it is also easier to discuss). But sure, I can diff against 444607a22002.

Phabricator has a "dependent commit" feature (Top right "Edit Related Revisions...") which was made for such cases.

bollu updated this revision to Diff 98601.May 11 2017, 2:28 AM
  • [FortranArrays] Codegen runtime size computation for Fortran Arrays
  • Merge branch 'fortran-arrays-add-match-for-param' into fortran-arrays-generate-bounds-checks
  • fix merge commit with fortran-arrays-add-param
bollu added a comment.May 11 2017, 2:38 AM

@Meinersbur: Please don't review this thoroughly till I fix the issue with the getContext() as mentioned. I'm putting this up as a general "follow along" as I mentioned before. It's diffed against D33075

lib/Analysis/ScopInfo.cpp
2194 ↗(On Diff #98601)

From what I can tell, this is a memory leak since getContext() creates a new isl_set. However, I seem to need the new copy for this code to work.

Ah, I just understood what's going on: it's shadowing the Scop::Context and is performing the isl_schedule_gist_domain_params on that?

bollu added inline comments.May 11 2017, 2:41 AM
lib/Analysis/ScopInfo.cpp
2194 ↗(On Diff #98601)

Now I don't understand why this even works. How does creating a new isl_set and using it to isl_schedule_gist_domain_params allow me to access these parameters in the code generation phase? I need to read up on what exactly isl_schedule_gist_domain_params does).

bollu updated this revision to Diff 98737.May 12 2017, 1:33 AM
  • refactor fortran array addition into schedule into a separate function. still using isl_schedule_gist_domain_params
Meinersbur added inline comments.May 12 2017, 4:49 AM
include/polly/CodeGen/IslNodeBuilder.h
80 ↗(On Diff #98737)

Fortran

81 ↗(On Diff #98737)

Could you document here hat "materialize" means?

lib/Analysis/ScopInfo.cpp
2194 ↗(On Diff #98601)

If you have trouble with leak, try using

auto FortranArraysContext = give(getContextWithFortranArrays(Context, arrays());

isl_schedule_gist_domain_params simplifies a schedule using information from the set. The set may say e.g. that a parameter is always greater than zero, such that the generated AST for the schedule does not need to add a condition whether the parameter is at least zero.

317 ↗(On Diff #98737)

Just assert(FAD && ... (Here and everywhere; no need to compare to nullptr)

Spelling: "Fortran array descriptor"

403 ↗(On Diff #98737)

Local variables in LLVM style start with capital letter.

2231 ↗(On Diff #98737)

Unintended change?

3447 ↗(On Diff #98737)

Drop this->

lib/CodeGen/IslNodeBuilder.cpp
998–1009 ↗(On Diff #98737)

I assume you are going to make this more readable

lib/CodeGen/PPCGCodeGeneration.cpp
2173–2174 ↗(On Diff #98737)

assert(i && "...");

test/Isl/CodeGen/fortran_array_runtime_size_generation.ll
3–7 ↗(On Diff #98737)

Please only add required switches

bollu updated this revision to Diff 98991.May 15 2017, 5:59 AM
Meinersbur added inline comments.May 15 2017, 8:12 AM
include/polly/CodeGen/IslNodeBuilder.h
80 ↗(On Diff #98737)

Don't forget to also capitalize Fortran in the title.

include/polly/ScopInfo.h
267 ↗(On Diff #98991)

array, dot at the end of sentence.

268 ↗(On Diff #98991)

I suggest some other terminology. "make" sounds like the funcion adds a new array.

Suggestion: updateFortranArraySize

428 ↗(On Diff #98991)

Dot at the end of sentence.

lib/Analysis/ScopInfo.cpp
324–325 ↗(On Diff #98991)

No need to compare to nullptr.

330 ↗(On Diff #98991)

Remove this->

332 ↗(On Diff #98991)

You can pass this ScopArrayInfo as user pointer. Might potentially avoid name collision (Maybe the name is already unique, the adding the ScopArrayPointer still helps isl's hash algorithm and might be useful to extract later)

403 ↗(On Diff #98991)

const is unnecessary.

Suggestion for name: IsOutermostSizeKnown.

You could also just print [*] whenever getDimensionSizePw() returns nullptr. This should simplify the function. You can add asserta to check whether there is a situation where nullptr (not) is allowed.

2207 ↗(On Diff #98991)

Declare as static or in anonymous namespace if not in polly namespace.

2207 ↗(On Diff #98991)

Naming suggestion: getFortranArraysContext

2211 ↗(On Diff #98991)

Capital first letter for local variables and function parameters.

2212 ↗(On Diff #98991)

Fortran, incomplete sentence

2213 ↗(On Diff #98991)

Use TODO instead of HACK

2216 ↗(On Diff #98991)

Comparison with nullptr

2218 ↗(On Diff #98991)

Please use LLVM style variable names.

2256–2258 ↗(On Diff #98991)

Did you consider updating Scop::Context instead?

If you do so, be sure to to it before Stmt.realignParams(), which reads that context.

3485 ↗(On Diff #98991)

We start local variables with capital letters.

3489–3491 ↗(On Diff #98991)

I'd suggest to remove the const from getLatestScopArrayInfo. It doesn't serve a purpose if we have to cast it away.

Objects of type ScopArrayInfo are (like llvm::Value) are identified by address or BasePtr and kind. These are immutable properties, so we don't need to pass objects of type ScopArrayInfo as const.

lib/CodeGen/IslNodeBuilder.cpp
1051 ↗(On Diff #98991)

Unnecessary const_cast

1071 ↗(On Diff #98991)

Unnecessary dyn_cast

bollu updated this revision to Diff 99117.May 16 2017, 1:47 AM
  • [NFC wrt patch] Style & naming convention changes
bollu added inline comments.May 16 2017, 1:49 AM
include/polly/ScopInfo.h
268 ↗(On Diff #98991)

that is slightly misleading, since it holds on to the FAD. update to me means that it should use the FAD and then not keep a reference to it. I'm not sure if the terminology within llvm/Polly for update means something else.

How about receiveFortranArrayDescriptor?

lib/Analysis/ScopInfo.cpp
324–325 ↗(On Diff #98991)

Ah, because of the combination of the first and second assert?

332 ↗(On Diff #98991)

I can see the benefit of giving it to improve the hashing (did not know that isl used the user pointer in its hash function).

However, I personally dislike using the user for isl_id in general: it's non-local, indirect, and there is no simple way to find out where the user came from (as far as I know). What are your opinions on this?

2256–2258 ↗(On Diff #98991)

I wanted to work on a separate context because I felt it would be "cleaner", but I'm not sure about that anymore. What do you suggest, updating Scop::Context?

3489–3491 ↗(On Diff #98991)

Alternate option is to follow OO philosophy: Ask, don't tell :). So just ask MemoryAccess to make its ScopArrayInfo model a Fortran array.

@Meinersbur: Addressed comments for most things, left comments on things I want to discuss on. Could you take another look?

Meinersbur added inline comments.May 18 2017, 9:14 AM
include/polly/ScopInfo.h
2079 ↗(On Diff #99117)

arrays

2080 ↗(On Diff #99117)

Fortran

268 ↗(On Diff #98991)

We already use the verb "update" for this purpose in Scop::updateAccessDimensionality and ScopArrayInfo::updateSizes. I suggest use the same terminology for consistency (or suggestion another patch that changes all these names).

With "receive", I'd assume some communication is going on.

Another suggestion is the verb "apply".

lib/Analysis/ScopInfo.cpp
324–325 ↗(On Diff #98991)

What I mean is to generally use

if (ptr)
if (!ptr)
assert(ptr && "...");
...

instead of

if (ptr != nullptr)
if (ptr == nullptr)
assert(ptr != nullptr && "...")
...

There is no explicit rule about this, it is just that Polly's current code base uses the former. This is for internal code style consistency.

332 ↗(On Diff #98991)

First, I was wrong that the user pointer is used for the hash here. isl uses the it only when the isl_id has no name. Id does so such that iteration order over hastables remains deterministic when user is a pointer. Unfortunately isl has no equivalent of SetVector.

I "feel" that using the user pointer is a good safety precaution to protect from duplicate names. For instance, I could call a variable "${param_name}_fortranarr_size" that is used as an for-loop upper bound. In this case, it would not conflict, but only because that parameter's isl_id has the user pointer set (to the llvm::Value).

Since I think it it just good practice, just keep if you wish. Maybe also also Tobias for his toughts.

Anyway, I don't get you arguments against it. What do you mean by

  • non-local
  • indirect
  • there is no simple way to find out where the user came from

?

2256–2258 ↗(On Diff #98991)

Yes, it is supposed to do exactly that later (call isl_schedule_gist_domain_params on the context).

3489–3491 ↗(On Diff #98991)

Possible, sure. But it clutters the MemoryAccess interface with a function that can only be called from here. I'd prefer it to have only general purpose methods since ScopInfo.h is imported by from a lot of other places.

Analogon: llvm::Instruction having a makeVectorInstruction() method.

lib/CodeGen/PPCGCodeGeneration.cpp
2173–2174 ↗(On Diff #98737)

Correction: i==0 is ok, i is not pointer.

test/ScopInfo/fortran_array_param_nonmalloc_nonvectored.ll
55 ↗(On Diff #99117)

What information does this add?

bollu updated this revision to Diff 99554.May 19 2017, 6:19 AM
  • Updated style changes.
  • Added the Fortran arrays' outermost dimension into the Context of

the Scop. This needs a change in one test case that checks the context.

  • Cleaned up the getContextWithFortranArrays() function, and its interaction with Scop::Context.
bollu added a comment.May 19 2017, 6:19 AM

@Meinersbur: made changes as requested. Could you take a look?

lib/Analysis/ScopInfo.cpp
403 ↗(On Diff #98991)

You could also just print [*] whenever getDimensionSizePw() returns nullptr. This should simplify the function. You can add asserta to check whether there is a situation where nullptr (not) is allowed.

This will not work, because we will need to print [*] in the case when we are printing SCEV as well. So, we will need to specialise for the outermost dimension anyway.

3489–3491 ↗(On Diff #98991)

If I have to remove the const, then code in other parts would be affected as well. Shall I do that in a separate patch?

bollu updated this revision to Diff 99555.May 19 2017, 6:29 AM
  • fortran -> Fortran
  • pwAff -> isl_pw_aff
bollu updated this revision to Diff 99556.May 19 2017, 6:32 AM
  • . and newline for comments
bollu updated this revision to Diff 99557.May 19 2017, 6:34 AM
  • [NFC] remove metadata from comment
bollu updated this revision to Diff 99562.May 19 2017, 6:55 AM
  • Squash all commits into one, fix some style stuff.
This revision is now accepted and ready to land.May 19 2017, 7:19 AM
This revision was automatically updated to reflect the committed changes.
RKSimon added inline comments.
polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
1036

@bollu I realise this is a very old patch, but coverity has a dead code warning about the first 'size' not being used: https://bugs.llvm.org/show_bug.cgi?id=52173