Skip to content

Commit f762f62

Browse files
srividyakarumurisys_zuul
authored and
sys_zuul
committed
Buffer offset adjustment if the buffer access is stateful and is
non-dword aligned type Change-Id: I66396f02831f08ea05a8a1ec8d94489961965dfc
1 parent f79741d commit f762f62

File tree

6 files changed

+76
-10
lines changed

6 files changed

+76
-10
lines changed

IGC/Compiler/CISACodeGen/helper.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,10 @@ namespace IGC
504504
}
505505
}
506506

507-
bool GetResourcePointerInfo(Value* srcPtr, unsigned& resID, IGC::BufferType& resTy, BufferAccessType& accessTy)
507+
bool GetResourcePointerInfo(Value* srcPtr, unsigned& resID, IGC::BufferType& resTy, BufferAccessType& accessTy, bool& needBufferOffset)
508508
{
509509
accessTy = BufferAccessType::ACCESS_READWRITE;
510+
needBufferOffset = false;
510511
if (GenIntrinsicInst * inst = dyn_cast<GenIntrinsicInst>(srcPtr))
511512
{
512513
// For bindless pointers with encoded metadata
@@ -517,6 +518,7 @@ namespace IGC
517518
auto resIDBundle = inst->getOperandBundle("resID");
518519
auto resTyBundle = inst->getOperandBundle("resTy");
519520
auto accessTyBundle = inst->getOperandBundle("accessTy");
521+
auto needBufferOffsetBundle = inst->getOperandBundle("needBufferOffset");
520522
if (resIDBundle && resTyBundle)
521523
{
522524
resID = (unsigned)(cast<ConstantInt>(resIDBundle->Inputs.front()))->getZExtValue();
@@ -526,6 +528,10 @@ namespace IGC
526528
accessTy = (BufferAccessType)(cast<ConstantInt>(accessTyBundle->Inputs.front()))->getZExtValue();
527529
else
528530
accessTy = getDefaultAccessType(resTy);
531+
532+
if(needBufferOffsetBundle)
533+
needBufferOffset = (bool)(cast<ConstantInt>(needBufferOffsetBundle->Inputs.front()))->getZExtValue();
534+
529535
return true;
530536
}
531537
}
@@ -570,8 +576,9 @@ namespace IGC
570576
// tracing the pointer to where it's created.
571577
Value * src = IGC::TracePointerSource(pointer);
572578
BufferAccessType accType;
579+
bool needBufferOffset; // Unused
573580
if (!src) return false;
574-
if (IGC::GetResourcePointerInfo(src, bufIdOrGRFOffset, bufferTy, accType))
581+
if (IGC::GetResourcePointerInfo(src, bufIdOrGRFOffset, bufferTy, accType, needBufferOffset))
575582
{
576583
bufferSrcPtr = src;
577584
isDirectBuf = true;

IGC/Compiler/CISACodeGen/helper.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ namespace IGC
152152
llvm::Value* TracePointerSource(llvm::Value* resourcePtr);
153153
llvm::Value* TracePointerSource(llvm::Value* resourcePtr, bool hasBranching, bool fillList, std::vector<llvm::Value*>& instList);
154154
llvm::Value* TracePointerSource(llvm::Value* resourcePtr, bool hasBranching, bool fillList, std::vector<llvm::Value*>& instList, llvm::SmallSet<llvm::PHINode*, 8> & visitedPHIs);
155-
bool GetResourcePointerInfo(llvm::Value* srcPtr, unsigned& resID, IGC::BufferType& resTy, IGC::BufferAccessType& accessTy);
155+
bool GetResourcePointerInfo(llvm::Value* srcPtr, unsigned& resID, IGC::BufferType& resTy, IGC::BufferAccessType& accessTy, bool& needBufferOffset);
156156
bool GetGRFOffsetFromRTV(llvm::Value* pointerSrc, unsigned& GRFOffset);
157157
bool GetStatelessBufferInfo(llvm::Value* pointer, unsigned& bufIdOrGRFOffset, IGC::BufferType& bufferTy, llvm::Value*& bufferSrcPtr, bool& isDirectBuf);
158158
// try to evaluate the address if it is constant.

IGC/Compiler/CodeGenPublic.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ namespace IGC
716716
TimeStats* m_compilerTimeStats = nullptr;
717717
ShaderStats* m_sumShaderStats = nullptr;
718718
/// output: list of buffer IDs which are promoted to direct AS
719-
std::unordered_set<unsigned> m_buffersPromotedToDirectAS;
719+
// Map of promoted buffer ids with their respective buffer offsets if needed. Buffer offset will be -1 if no need of buffer offset
720+
std::map<unsigned, int> m_buffersPromotedToDirectAS;
720721
// float 16, float32 and float64 denorm mode
721722
Float_DenormMode m_floatDenormMode16 = FLOAT_DENORM_FLUSH_TO_ZERO;
722723
Float_DenormMode m_floatDenormMode32 = FLOAT_DENORM_FLUSH_TO_ZERO;

IGC/Compiler/Optimizer/MarkReadOnlyLoad.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ void MarkReadOnlyLoad::visitLoadInst(LoadInst& LI)
115115
unsigned bufId;
116116
BufferType bufTy;
117117
BufferAccessType accTy;
118+
bool needBufferOffset; // Unused
118119

119120
// check whether we are doing read only access on buffer (e.g. on UAV)
120-
if (GetResourcePointerInfo(srcPtr, bufId, bufTy, accTy))
121+
if (GetResourcePointerInfo(srcPtr, bufId, bufTy, accTy, needBufferOffset))
121122
{
122123
if (accTy == BufferAccessType::ACCESS_READ)
123124
{

IGC/Compiler/PromoteResourceToDirectAS.cpp

+60-5
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ void PromoteResourceToDirectAS::PromoteSamplerTextureToDirectAS(GenIntrinsicInst
200200
unsigned bufID = 0;
201201
BufferType bufTy;
202202
BufferAccessType accTy;
203+
bool needBufferOffset; // Unused
203204
bool canPromote = false;
204205
Value* arrayIndex = nullptr;
205206

@@ -229,7 +230,7 @@ void PromoteResourceToDirectAS::PromoteSamplerTextureToDirectAS(GenIntrinsicInst
229230
// If we can find it, we can promote the indirect access to direct access
230231
// by encoding the BTI as a direct addrspace
231232
if (srcPtr->getType()->isPointerTy() &&
232-
IGC::GetResourcePointerInfo(srcPtr, bufID, bufTy, accTy))
233+
IGC::GetResourcePointerInfo(srcPtr, bufID, bufTy, accTy, needBufferOffset))
233234
{
234235
canPromote = true;
235236
}
@@ -495,6 +496,35 @@ bool PatchInstructionAddressSpace(const std::vector<Value*>& instList, Type* dst
495496
return success;
496497
}
497498

499+
Value* PromoteResourceToDirectAS::getOffsetValue(Value* srcPtr, int& bufferOffsetHandle)
500+
{
501+
auto offsetEntry = m_SrcPtrToBufferOffsetMap.find(srcPtr);
502+
if (offsetEntry != m_SrcPtrToBufferOffsetMap.end())
503+
{
504+
GenIntrinsicInst* runtimevalue = dyn_cast<GenIntrinsicInst>(offsetEntry->second);
505+
assert(runtimevalue && "Buffer offset must be a runtime value");
506+
bufferOffsetHandle = (int)llvm::cast<llvm::ConstantInt>(runtimevalue->getOperand(0))->getZExtValue();
507+
return offsetEntry->second;
508+
}
509+
else
510+
{
511+
Instruction* srcPtrInst;
512+
srcPtrInst = dyn_cast<Instruction>(srcPtr);
513+
assert(srcPtrInst && "source pointer must have been an instruction");
514+
IGCIRBuilder<> builder(srcPtrInst);
515+
516+
Instruction* bufferOffset;
517+
ModuleMetaData* modMD = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData();
518+
// Create runtime value for buffer offset
519+
Function* pFunc = GenISAIntrinsic::getDeclaration(srcPtrInst->getParent()->getParent()->getParent(), GenISAIntrinsic::GenISA_RuntimeValue, builder.getInt32Ty());
520+
bufferOffset = builder.CreateCall(pFunc, builder.getInt32(modMD->MinNOSPushConstantSize));
521+
bufferOffsetHandle = modMD->MinNOSPushConstantSize;
522+
modMD->MinNOSPushConstantSize++;
523+
m_SrcPtrToBufferOffsetMap[srcPtr] = bufferOffset;
524+
return bufferOffset;
525+
}
526+
}
527+
498528
void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value* resourcePtr)
499529
{
500530
IGCIRBuilder<> builder(inst);
@@ -528,7 +558,8 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
528558
unsigned bufferID;
529559
BufferType bufType;
530560
BufferAccessType accType;
531-
if (!IGC::GetResourcePointerInfo(srcPtr, bufferID, bufType, accType))
561+
bool needBufferOffset;
562+
if (!IGC::GetResourcePointerInfo(srcPtr, bufferID, bufType, accType, needBufferOffset))
532563
{
533564
// Can't promote if we don't know the explicit buffer ID and type
534565
return;
@@ -546,19 +577,30 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
546577
return;
547578
}
548579

580+
// If needBufferOffset set, we need to adjust stateful buffer accesses with the buffer offset from payload
581+
Value* pointerValue;
582+
int bufferOffsetHandle = -1;
583+
if (needBufferOffset)
584+
{
585+
pointerValue = builder.CreatePtrToInt(pBuffer, builder.getInt32Ty());
586+
pointerValue = builder.CreateAdd(pointerValue, getOffsetValue(srcPtr, bufferOffsetHandle));
587+
pBuffer = builder.CreateIntToPtr(pointerValue, pBuffer->getType());
588+
}
589+
590+
bool canpromote = false;
549591
if (LoadInst * load = dyn_cast<LoadInst>(inst))
550592
{
551593
LoadInst* newload = IGC::cloneLoad(load, pBuffer);
552594
load->replaceAllUsesWith(newload);
553595
load->eraseFromParent();
554-
m_pCodeGenContext->m_buffersPromotedToDirectAS.insert(bufferID);
596+
canpromote = true;
555597
}
556598
else if (StoreInst * store = dyn_cast<StoreInst>(inst))
557599
{
558600
StoreInst* newstore = IGC::cloneStore(store, store->getOperand(0), pBuffer);
559601
store->replaceAllUsesWith(newstore);
560602
store->eraseFromParent();
561-
m_pCodeGenContext->m_buffersPromotedToDirectAS.insert(bufferID);
603+
canpromote = true;
562604
}
563605
else if (GenIntrinsicInst * pIntr = dyn_cast<GenIntrinsicInst>(inst))
564606
{
@@ -687,7 +729,20 @@ void PromoteResourceToDirectAS::PromoteBufferToDirectAS(Instruction* inst, Value
687729
}
688730
oldInst->replaceAllUsesWith(newInst);
689731
oldInst->eraseFromParent();
690-
m_pCodeGenContext->m_buffersPromotedToDirectAS.insert(bufferID);
732+
canpromote = true;
733+
}
734+
}
735+
if (canpromote)
736+
{
737+
int handle = needBufferOffset ? bufferOffsetHandle : -1;
738+
if ((m_pCodeGenContext->m_buffersPromotedToDirectAS.find(bufferID) == m_pCodeGenContext->m_buffersPromotedToDirectAS.end()) ||
739+
(m_pCodeGenContext->m_buffersPromotedToDirectAS[bufferID] == -1))
740+
{
741+
m_pCodeGenContext->m_buffersPromotedToDirectAS[bufferID] = handle;
742+
}
743+
else
744+
{
745+
assert((m_pCodeGenContext->m_buffersPromotedToDirectAS[bufferID] == handle));
691746
}
692747
}
693748
}

IGC/Compiler/PromoteResourceToDirectAS.h

+2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ namespace IGC
6262
private:
6363
void PromoteSamplerTextureToDirectAS(llvm::GenIntrinsicInst*& pIntr, llvm::Value* resourcePtr);
6464
void PromoteBufferToDirectAS(llvm::Instruction* inst, llvm::Value* resourcePtr);
65+
llvm::Value* getOffsetValue(llvm::Value* srcPtr, int& bufferoffset);
6566

6667
CodeGenContext* m_pCodeGenContext;
6768
IGCMD::MetaDataUtils* m_pMdUtils;
69+
std::unordered_map<llvm::Value*, llvm::Value*> m_SrcPtrToBufferOffsetMap;
6870
};
6971

7072
} // namespace IGC

0 commit comments

Comments
 (0)