Taught [unroll] that barriers are safe to unroll (#3123)

This commit is contained in:
Adam Yang 2020-09-09 17:09:05 -07:00 коммит произвёл GitHub
Родитель 4446237655
Коммит 05115ab926
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 93 добавлений и 1 удалений

Просмотреть файл

@ -81,6 +81,7 @@
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "dxc/DXIL/DxilUtil.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/HLSL/HLModule.h"
#include "llvm/Analysis/DxilValueCache.h"
@ -130,6 +131,7 @@ public:
}
const char *getPassName() const override { return "Dxil Loop Unroll"; }
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
bool IsLoopSafeToClone(Loop *L);
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<LoopInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
@ -636,6 +638,33 @@ static void RecursivelyRemoveLoopFromQueue(LPPassManager &LPM, Loop *L) {
LPM.deleteLoopFromQueue(L);
}
// Mostly copied from Loop::isSafeToClone, but making exception
// for dx.op.barrier.
//
bool DxilLoopUnroll::IsLoopSafeToClone(Loop *L) {
// Return false if any loop blocks contain indirectbrs, or there are any calls
// to noduplicate functions.
for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) {
if (isa<IndirectBrInst>((*I)->getTerminator()))
return false;
if (const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator()))
if (II->cannotDuplicate())
return false;
for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) {
if (const CallInst *CI = dyn_cast<CallInst>(BI)) {
if (CI->cannotDuplicate() &&
!hlsl::OP::IsDxilOpFuncCallInst(CI, hlsl::OP::OpCode::Barrier))
{
return false;
}
}
}
}
return true;
}
bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
DebugLoc LoopLoc = L->getStartLoc(); // Debug location for the start of the loop.
@ -663,7 +692,7 @@ bool DxilLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
ExplicitUnrollCount = (unsigned)ExplicitUnrollCountSigned;
}
if (!L->isSafeToClone())
if (!IsLoopSafeToClone(L))
return false;
unsigned TripCount = 0;

Просмотреть файл

@ -0,0 +1,63 @@
// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s
// Regression test for loops that contain barriers
// CHECK: @main
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
// CHECK: barrier
// CHECK: bufferUpdateCounter
// CHECK: bufferStore
AppendStructuredBuffer<float4> buf0;
AppendStructuredBuffer<float4> buf1;
AppendStructuredBuffer<float4> buf2;
AppendStructuredBuffer<float4> buf3;
uint g_cond;
[numthreads( 128, 1, 1 )]
void main() {
AppendStructuredBuffer<float4> buffers[] = { buf0, buf1, buf2, buf3, };
float ret = 0;
[unroll]
for (uint i = 0; i < 2; i++) {
GroupMemoryBarrierWithGroupSync();
buffers[i].Append(i);
[unroll]
for (uint j = 0; j < 2; j++) {
ret++;
GroupMemoryBarrierWithGroupSync();
buffers[i].Append(j);
GroupMemoryBarrierWithGroupSync();
buffers[i].Append(j);
}
}
}