@@ -31,7 +31,6 @@ PrivateMemoryUsageAnalysis::PrivateMemoryUsageAnalysis()
3131 : ModulePass(ID), m_hasPrivateMem(false )
3232{
3333 initializePrivateMemoryUsageAnalysisPass (*PassRegistry::getPassRegistry ());
34-
3534}
3635
3736bool 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+
153158void 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}
0 commit comments