Skip to content

Commit

Permalink
Adjust FPGA IVDep translation for embedded loops
Browse files Browse the repository at this point in the history
The semantics of the `"!llvm.loop.parallel_access_indices"`
loop metadata node could be defined as follows:
```
The IVDep hint of this loop applies to all arrays whose
GEP instructions are marked with:
1. !llvm.index.group metadata nodes that are operands of
the given !llvm.loop.parallel_access_indices node
2. !llvm.index.group metadata nodes that are used by the
operands of the given !llvm.loop.parallel_access_indices
node
```
Case **2** is vital for IVDep's representation on loop
nests. This patch fixes its improper translation by
mapping **all** operands of a given !llvm.index.group
(if present) onto the affected array IDs.

Additionally, the test was updated to include the legacy
ivdep metadata (Clang emits it alongside the
`parallel_access_indices`-based layout).

Signed-off-by: Artem Gindinson <artem.gindinson@intel.com>
  • Loading branch information
AGindinson authored and AlexeySotkin committed May 12, 2020
1 parent bc23f64 commit 08849f5
Show file tree
Hide file tree
Showing 2 changed files with 246 additions and 38 deletions.
18 changes: 10 additions & 8 deletions lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1199,24 +1199,26 @@ SPIRVValue *LLVMToSPIRV::transValueWithoutDecoration(Value *V,
// the accessed array variables, our GEP may have been marked into
// a so-called index group, an MDNode by itself.
if (MDNode *IndexGroup = GEP->getMetadata("llvm.index.group")) {
// When where we work with embedded loops, it's natural that
SPIRVId AccessedArrayId = TransPointerOperand->getId();
unsigned NumOperands = IndexGroup->getNumOperands();
// When we're working with embedded loops, it's natural that
// the outer loop's hints apply to all code contained within.
// The inner loop's specific hints, however, should stay private
// to the inner loop's scope.
// Consequently, the following division of the index group metadata
// nodes emerges:

// 1) The metadata node has no operands. It will be directly referenced
// from within the optimization hint metadata.
if (NumOperands == 0)
IndexGroupArrayMap[IndexGroup] = AccessedArrayId;
// 2) The metadata node has several operands. It serves to link an index
// group specific to some embedded loop with other index groups that
// mark the same array variable for the outer loop(s).
unsigned NumOperands = IndexGroup->getNumOperands();
if (NumOperands > 0)
// The index group for this particular "embedded loop depth" is always
// signalled by the last variable. We'll want to associate this loop's
// control parameters with this inner-loop-specific index group
IndexGroup = getMDOperandAsMDNode(IndexGroup, NumOperands - 1);
IndexGroupArrayMap[IndexGroup] = TransPointerOperand->getId();
for (unsigned I = 0; I < NumOperands; ++I) {
auto *ContainedIndexGroup = getMDOperandAsMDNode(IndexGroup, I);
IndexGroupArrayMap[ContainedIndexGroup] = AccessedArrayId;
}
}

return mapValue(V, BM->addPtrAccessChainInst(transType(GEP->getType()),
Expand Down
Loading

0 comments on commit 08849f5

Please sign in to comment.