diff options
Diffstat (limited to 'llvm/lib/MCA/HardwareUnits/LSUnit.cpp')
-rw-r--r-- | llvm/lib/MCA/HardwareUnits/LSUnit.cpp | 84 |
1 files changed, 63 insertions, 21 deletions
diff --git a/llvm/lib/MCA/HardwareUnits/LSUnit.cpp b/llvm/lib/MCA/HardwareUnits/LSUnit.cpp index 0ee084c7ce1a9..e945e8cecce93 100644 --- a/llvm/lib/MCA/HardwareUnits/LSUnit.cpp +++ b/llvm/lib/MCA/HardwareUnits/LSUnit.cpp @@ -77,9 +77,6 @@ unsigned LSUnit::dispatch(const InstRef &IR) { acquireSQSlot(); if (Desc.MayStore) { - // Always create a new group for store operations. - - // A store may not pass a previous store or store barrier. unsigned NewGID = createMemoryGroup(); MemoryGroup &NewGroup = getGroup(NewGID); NewGroup.addInstruction(); @@ -91,16 +88,32 @@ unsigned LSUnit::dispatch(const InstRef &IR) { MemoryGroup &IDom = getGroup(ImmediateLoadDominator); LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" << ImmediateLoadDominator << ") --> (" << NewGID << ")\n"); - IDom.addSuccessor(&NewGroup); + IDom.addSuccessor(&NewGroup, !assumeNoAlias()); + } + + // A store may not pass a previous store barrier. + if (CurrentStoreBarrierGroupID) { + MemoryGroup &StoreGroup = getGroup(CurrentStoreBarrierGroupID); + LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" + << CurrentStoreBarrierGroupID + << ") --> (" << NewGID << ")\n"); + StoreGroup.addSuccessor(&NewGroup, true); } - if (CurrentStoreGroupID) { + + // A store may not pass a previous store. + if (CurrentStoreGroupID && + (CurrentStoreGroupID != CurrentStoreBarrierGroupID)) { MemoryGroup &StoreGroup = getGroup(CurrentStoreGroupID); LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" << CurrentStoreGroupID << ") --> (" << NewGID << ")\n"); - StoreGroup.addSuccessor(&NewGroup); + StoreGroup.addSuccessor(&NewGroup, !assumeNoAlias()); } + CurrentStoreGroupID = NewGID; + if (IsMemBarrier) + CurrentStoreBarrierGroupID = NewGID; + if (Desc.MayLoad) { CurrentLoadGroupID = NewGID; if (IsMemBarrier) @@ -112,31 +125,59 @@ unsigned LSUnit::dispatch(const InstRef &IR) { assert(Desc.MayLoad && "Expected a load!"); - // Always create a new memory group if this is the first load of the sequence. + unsigned ImmediateLoadDominator = + std::max(CurrentLoadGroupID, CurrentLoadBarrierGroupID); + + // A new load group is created if we are in one of the following situations: + // 1) This is a load barrier (by construction, a load barrier is always + // assigned to a different memory group). + // 2) There is no load in flight (by construction we always keep loads and + // stores into separate memory groups). + // 3) There is a load barrier in flight. This load depends on it. + // 4) There is an intervening store between the last load dispatched to the + // LSU and this load. We always create a new group even if this load + // does not alias the last dispatched store. + // 5) There is no intervening store and there is an active load group. + // However that group has already started execution, so we cannot add + // this load to it. + bool ShouldCreateANewGroup = + IsMemBarrier || !ImmediateLoadDominator || + CurrentLoadBarrierGroupID == ImmediateLoadDominator || + ImmediateLoadDominator <= CurrentStoreGroupID || + getGroup(ImmediateLoadDominator).isExecuting(); - // A load may not pass a previous store unless flag 'NoAlias' is set. - // A load may pass a previous load. - // A younger load cannot pass a older load barrier. - // A load barrier cannot pass a older load. - bool ShouldCreateANewGroup = !CurrentLoadGroupID || IsMemBarrier || - CurrentLoadGroupID <= CurrentStoreGroupID || - CurrentLoadGroupID <= CurrentLoadBarrierGroupID; if (ShouldCreateANewGroup) { unsigned NewGID = createMemoryGroup(); MemoryGroup &NewGroup = getGroup(NewGID); NewGroup.addInstruction(); + // A load may not pass a previous store or store barrier + // unless flag 'NoAlias' is set. if (!assumeNoAlias() && CurrentStoreGroupID) { - MemoryGroup &StGroup = getGroup(CurrentStoreGroupID); + MemoryGroup &StoreGroup = getGroup(CurrentStoreGroupID); LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" << CurrentStoreGroupID << ") --> (" << NewGID << ")\n"); - StGroup.addSuccessor(&NewGroup); + StoreGroup.addSuccessor(&NewGroup, true); } - if (CurrentLoadBarrierGroupID) { - MemoryGroup &LdGroup = getGroup(CurrentLoadBarrierGroupID); - LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" << CurrentLoadBarrierGroupID - << ") --> (" << NewGID << ")\n"); - LdGroup.addSuccessor(&NewGroup); + + // A load barrier may not pass a previous load or load barrier. + if (IsMemBarrier) { + if (ImmediateLoadDominator) { + MemoryGroup &LoadGroup = getGroup(ImmediateLoadDominator); + LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" + << ImmediateLoadDominator + << ") --> (" << NewGID << ")\n"); + LoadGroup.addSuccessor(&NewGroup, true); + } + } else { + // A younger load cannot pass a older load barrier. + if (CurrentLoadBarrierGroupID) { + MemoryGroup &LoadGroup = getGroup(CurrentLoadBarrierGroupID); + LLVM_DEBUG(dbgs() << "[LSUnit]: GROUP DEP: (" + << CurrentLoadBarrierGroupID + << ") --> (" << NewGID << ")\n"); + LoadGroup.addSuccessor(&NewGroup, true); + } } CurrentLoadGroupID = NewGID; @@ -145,6 +186,7 @@ unsigned LSUnit::dispatch(const InstRef &IR) { return NewGID; } + // A load may pass a previous load. MemoryGroup &Group = getGroup(CurrentLoadGroupID); Group.addInstruction(); return CurrentLoadGroupID; |