Skip to content

Commit 2e80890

Browse files
michalpaszkowskiigcbot
authored andcommitted
Migrate PrivateMemoryUsageAnalysis to opaque pointers
The original pass used getNonOpaquePtrEltTy to get the element type of pointer arguments. This is replaced by examining the uses of each pointer argument to see if they interact with struct types.
1 parent 6b62780 commit 2e80890

File tree

2 files changed

+88
-27
lines changed

2 files changed

+88
-27
lines changed

IGC/Compiler/Optimizer/OpenCLPasses/PrivateMemory/PrivateMemoryUsageAnalysis.cpp

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ PrivateMemoryUsageAnalysis::PrivateMemoryUsageAnalysis()
3131
: ModulePass(ID), m_hasPrivateMem(false)
3232
{
3333
initializePrivateMemoryUsageAnalysisPass(*PassRegistry::getPassRegistry());
34-
3534
}
3635

3736
bool PrivateMemoryUsageAnalysis::runOnModule(Module& M)
@@ -45,20 +44,20 @@ bool PrivateMemoryUsageAnalysis::runOnModule(Module& M)
4544
m_hasDPDivSqrtEmu = !pCtx->platform.hasNoFP64Inst() && !pCtx->platform.hasCorrectlyRoundedMacros() && pCtx->m_DriverInfo.NeedFP64DivSqrt();
4645

4746
// Run on all functions defined in this module
48-
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
47+
for (Function &F : M)
4948
{
50-
Function* pFunc = &(*I);
5149
// Skip functions called from function marked with stackcall attribute
52-
if (AddImplicitArgs::hasStackCallInCG(pFunc))
50+
if (AddImplicitArgs::hasStackCallInCG(&F))
5351
{
5452
hasStackCall = true;
5553
continue;
5654
}
57-
if (pFunc->isDeclaration())
55+
if (F.isDeclaration())
5856
continue;
59-
if (m_pMDUtils->findFunctionsInfoItem(pFunc) == m_pMDUtils->end_FunctionsInfo())
57+
if (m_pMDUtils->findFunctionsInfoItem(&F) == m_pMDUtils->end_FunctionsInfo())
6058
continue;
61-
if (runOnFunction(*pFunc))
59+
60+
if (runOnFunction(F))
6261
{
6362
changed = true;
6463
}
@@ -71,14 +70,13 @@ bool PrivateMemoryUsageAnalysis::runOnModule(Module& M)
7170
IGC_IS_FLAG_ENABLED(ForceAddingStackcallKernelPrerequisites) ||
7271
IGC_IS_FLAG_ENABLED(StackOverflowDetection))
7372
{
74-
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
73+
for (Function &F : M)
7574
{
76-
Function* pFunc = &(*I);
77-
if (isEntryFunc(m_pMDUtils, pFunc))
75+
if (isEntryFunc(m_pMDUtils, &F))
7876
{
7977
SmallVector<ImplicitArg::ArgType, 1> implicitArgs;
8078
implicitArgs.push_back(ImplicitArg::PRIVATE_BASE);
81-
ImplicitArgs::addImplicitArgs(*pFunc, implicitArgs, m_pMDUtils);
79+
ImplicitArgs::addImplicitArgs(F, implicitArgs, m_pMDUtils);
8280
changed = true;
8381
}
8482
}
@@ -99,27 +97,22 @@ bool PrivateMemoryUsageAnalysis::runOnFunction(Function& F)
9997
visit(F);
10098

10199
// Struct types always use private memory unless regtomem can
102-
// promote them. Check the function signature to see if any
103-
// structs are passesed as arguments.
100+
// promote them. Check the function signature to see if any
101+
// structs are passed as arguments.
104102
if (!m_hasPrivateMem)
105103
{
106-
Function::arg_iterator argument = F.arg_begin();
107-
for (; argument != F.arg_end(); ++argument)
104+
for (auto &Arg : F.args())
108105
{
109-
Argument* arg = &(*argument);
110-
111-
if (arg->getType()->isPointerTy())
106+
if (Arg.hasAttribute(llvm::Attribute::ByVal))
112107
{
113-
Type* type = IGCLLVM::getNonOpaquePtrEltTy(arg->getType());
114-
115-
if (StructType * structType = dyn_cast<StructType>(type))
116-
{
117-
if (!structType->isOpaque())
118-
{
119-
m_hasPrivateMem = true;
120-
}
121-
}
108+
Type* ByValTy = Arg.getParamByValType();
109+
visitType(ByValTy);
110+
if (m_hasPrivateMem)
111+
break;
122112
}
113+
114+
// Argument uses (which could signal they are of struct type) are
115+
// inspected in instruction visitors.
123116
}
124117
}
125118

@@ -150,6 +143,18 @@ bool PrivateMemoryUsageAnalysis::runOnFunction(Function& F)
150143
return true;
151144
}
152145

146+
inline void PrivateMemoryUsageAnalysis::visitType(Type* Ty)
147+
{
148+
// Struct types always use private memory unless regtomem can promote them.
149+
if (auto *ST = dyn_cast<StructType>(Ty))
150+
{
151+
if (!ST->isOpaque())
152+
{
153+
m_hasPrivateMem = true;
154+
}
155+
}
156+
}
157+
153158
void PrivateMemoryUsageAnalysis::visitAllocaInst(llvm::AllocaInst& AI)
154159
{
155160
IGC_ASSERT_MESSAGE(AI.getType()->getAddressSpace() == ADDRESS_SPACE_PRIVATE,
@@ -199,4 +204,40 @@ void PrivateMemoryUsageAnalysis::visitCallInst(llvm::CallInst& CI)
199204
m_hasPrivateMem = true;
200205
}
201206
}
207+
208+
// Check byval arguments for struct usage
209+
Function* CalledF = CI.getCalledFunction();
210+
if (CalledF)
211+
{
212+
unsigned ArgNo = 0;
213+
for (auto It = CI.arg_begin(), End = CI.arg_end(); It != End; ++It)
214+
{
215+
if (CI.paramHasAttr(ArgNo, llvm::Attribute::ByVal))
216+
{
217+
Type* ByValTy = CI.getParamByValType(ArgNo);
218+
visitType(ByValTy);
219+
if (m_hasPrivateMem)
220+
return;
221+
}
222+
ArgNo++;
223+
}
224+
}
225+
}
226+
227+
void PrivateMemoryUsageAnalysis::visitLoadInst(LoadInst& LI)
228+
{
229+
Type *LoadTy = LI.getType();
230+
visitType(LoadTy);
231+
}
232+
233+
void PrivateMemoryUsageAnalysis::visitStoreInst(StoreInst& SI)
234+
{
235+
Type* ValTy = SI.getValueOperand()->getType();
236+
visitType(ValTy);
237+
}
238+
239+
void PrivateMemoryUsageAnalysis::visitGetElementPtrInst(GetElementPtrInst& GEP)
240+
{
241+
Type *SrcTy = GEP.getSourceElementType();
242+
visitType(SrcTy);
202243
}

IGC/Compiler/Optimizer/OpenCLPasses/PrivateMemory/PrivateMemoryUsageAnalysis.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,33 @@ namespace IGC
6666
/// @param CI The binary op
6767
void visitCallInst(llvm::CallInst& CI);
6868

69+
/// @brief LoadInst instructions visitor.
70+
/// Analyzes if there are struct types loaded.
71+
/// @param LI The load instruction.
72+
void visitLoadInst(llvm::LoadInst& LI);
73+
74+
/// @brief StoreInst instructions visitor.
75+
/// Analyzes if there are struct types stored.
76+
/// @param SI The store instruction.
77+
void visitStoreInst(llvm::StoreInst& SI);
78+
79+
/// @brief GetElementPtrInst instructions visitor.
80+
/// Analyzes if there are struct types accessed.
81+
/// @param GEP The GEP instruction.
82+
void visitGetElementPtrInst(llvm::GetElementPtrInst& GEP);
83+
6984
private:
7085
/// @brief Function entry point.
7186
/// Finds all alloca instructions in this function, analyzes them and adds
7287
/// private base implicit argument if needed.
7388
/// @param F The destination function.
7489
bool runOnFunction(llvm::Function& F);
7590

91+
/// @brief Type visitor.
92+
/// Checks if the type is a non-opaque struct.
93+
/// @param Ty The type to inspect.
94+
inline void visitType(llvm::Type* Ty);
95+
7696
/// @brief A flag signaling if the current function uses private memory
7797
bool m_hasPrivateMem;
7898

0 commit comments

Comments
 (0)