Simplify ScopDetection::isInvariant. Essentially deny everything that is defined within the SCoP and is not load-hoisted.
The previous understanding of "invariant" has a few holes:
- Expressions without side-effects with only invariant arguments, but are defined withing the SCoP's region with the exception of selects [sic!] and PHIs. These should be part of the index expression and not of the base pointer.
- Function calls with !mayHaveSideEffects() (readnone nounwind). These must always return the same value and have no side-effect. However, we do not know which value it returns. For instance, a call
@C = external global i32 ... %ptr = call float* @getNextBasePtr(float* %A, float %B)
Might return
- %A, so it aliases with it in the SCoP
- %B, so it aliases with it in the SCoP
- @C, so it aliases with it in the SCoP
- a new pointer everytime it is called, such as malloc()
- a pointer into the allocated block of one of the aforementioned
- any of the above, at random
Hence we cannot know whether it aliases with something. It might still be useful with -polly-ignore-aliasing, if the user really wants unsafe code generation. Functions such as getNextBasePtr are usually inlined anyway (or not marked with readnone nounwind because they are defined in another translation unit).
On the other side it is a problem for the code generator if the base pointer is not available anywhere in the SCoP, when it needs to regenerate the access function (when setNewAccessRelation is called, such as in D28518, DeLICM and JSONImporter). The code generator currently assumes that base pointers are availably globally and generates invalid code (referring to the base pointer of the original code).