This is an archive of the discontinued LLVM Phabricator instance.

[LV] Vectorize backward dependence
Needs ReviewPublic

Authored by hujp on Jan 29 2021, 1:31 AM.

Details

Summary

This patch enable the vectorization of backward dependence. For
example:

for (int i = 0; i < n; i++) {
  a[i] = c[i] * 2;
  b[i] = a[i + 1] + 1;
}

for (int i = 0; i < n; i++) {
  a[i] = c[i] * 2;
  a[i + 1] = b[i] + 1;
}

// When compiled with -force-vector-width=4, before this patch it
// is not vectorizable.
for (int i = 0; i < n; i++) {
  c[i] = a[i] * 2;
  a[i + 2] = b[i] + 1;
}

The MemoryDepChecker does analysis without reordering accesses,
while this patch appends checking on the unsafe dependences with
reordering accesses.

Tested on AArch64 and x86_64 Linux.

Diff Detail

Event Timeline

hujp created this revision.Jan 29 2021, 1:31 AM
hujp requested review of this revision.Jan 29 2021, 1:31 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 29 2021, 1:31 AM

Please upload all patches with full context (-U99999)

llvm/test/Transforms/LoopVectorize/memdep.ll
94

Just fix the test to check new output?

llvm/test/Transforms/LoopVectorize/pr47929-vectorize-backward-load-after-store.ll
1–2 ↗(On Diff #320072)

Please don't use -O2, this should only be -loop-vectorize

hujp updated this revision to Diff 320078.Jan 29 2021, 2:08 AM

Update patch with full context.

hujp updated this revision to Diff 320412.Feb 1 2021, 1:22 AM

fix tests to use only -loop-vectorize option, and correct c codes format.

hujp marked 2 inline comments as done.Feb 1 2021, 1:34 AM

Thank you for your comments.

llvm/test/Transforms/LoopVectorize/pr47929-vectorize-backward-load-after-store.ll
1–2 ↗(On Diff #320072)

Please don't use -O2, this should only be -loop-vectorize

hujp marked an inline comment as done.Feb 1 2021, 1:37 AM
hujp added a reviewer: mkuper.Feb 9 2021, 9:21 PM
hujp added a comment.Feb 17 2021, 10:17 PM

Ping. @hsaito Could you take a look when you have time?

hujp updated this revision to Diff 329252.Mar 9 2021, 1:48 AM
hujp retitled this revision from [LV] Vectorize backward load after store accesses to [LV] Vectorize backward dependence.
hujp edited the summary of this revision. (Show Details)

Add the processing of other backward dependences, to make this function more general.

fhahn added a comment.Mar 10 2021, 1:05 PM

Hi! Thanks for the patch. I won't have time to take a closer look until next week the earliest but I have a few high level questions/comments:

  1. Can the initial patch be focused on initial support and only handle the case where only pairs of instructions need to be moved before/after another, not a list of instructions needs to be moved before/after another instruction?
  2. Does the re-order map generation need to happen in LVL or could it be part of LoopAccessInfo, like the other memory checks? That way, other clients could also benefit.
  3. Can we just use AliasAnalysis to check for instructions that block moving?
  4. Why do we need to handle EnableForwardingConflictDetection again? Could LAI remember/mark those dependences, so we do not need to re-check them?
hujp added a comment.Mar 11 2021, 3:03 AM
  1. Does the re-order map generation need to happen in LVL or could it be part of LoopAccessInfo, like the other memory checks? That way, other clients could also benefit.

Hi fhahn! Thank you for your review. I'll consider your questions and comments carefully.
Firstly, for the No.2, I think we can do the checks after MemoryDepChecker::isDependent returned Dependence::Backward ,and extend the MemoryDepChecker::Dependence struct to save the reorder list. What do you think about?

hujp updated this revision to Diff 331444.Mar 17 2021, 7:46 PM

Fix comment 2 from @fhahn

hujp added a comment.Mar 17 2021, 7:52 PM

Hi fhahn! I have update the patch according to your comment No.2. For the others, here are our considerations.

  1. Can the initial patch be focused on initial support and only handle the case where only pairs of instructions need to be moved before/after another, not a list of instructions needs to be moved before/after another instruction?

The instruction we really want to move is a load or a store, but the instruction that needs to be moved is usually not a single instruction, at least including the operands of it. In addition, the instructions in front of them that access the same array may also need to be moved, so that the access order of the same element remains unchanged after moving, and there will be no new backward type dependency for different elements. Therefore, it is not representative to move only one instruction, so we consider moving a list.

  1. Can we just use AliasAnalysis to check for instructions that block moving?

We refer to the existing processing of LoopAccessInfo for the processing of finding aliases. By looking for aliases, we want to find all the instructions that need to be moved together, which, of course, may block moving. But there's something else may block moving.

  1. Why do we need to handle EnableForwardingConflictDetection again? Could LAI remember/mark those dependences, so we do not need to re-check them?

EnableForwardingConflictDetection was handled in MemoryDepChecker::isDependent, before that, if the dependency is backward, then the processing has returned. So when we analyze backward dependency, as a supplement, we also need to handle EnableForwardingConflictDetection.