@@ -241,7 +241,7 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
241241 bool Changed = false ;
242242 for (Module::iterator I = M.begin (), E = M.end (); I != E; ++I)
243243 {
244- Function * F = &(*I);
244+ Function* F = &(*I);
245245 if (F->isDeclaration ())
246246 {
247247 if (F->getName () == " __translate_sampler_initializer" )
@@ -275,32 +275,6 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
275275 // Remove noinline attr if present.
276276 F->removeFnAttr (llvm::Attribute::NoInline);
277277
278- if (IGC_IS_FLAG_ENABLED (DisableAddingAlwaysAttribute))
279- {
280- // Add always attribute if function has an argument with opaque type
281- // Curently, ExtensionArgAnalysis assumes that all functions with image arguments to be inlined
282- // This patch makes sure that we add always inline for such cases
283- for (auto & arg : F->args ())
284- {
285- if (containsOpaque (arg.getType ()))
286- {
287- F->addFnAttr (llvm::Attribute::AlwaysInline);
288- break ;
289- }
290- }
291-
292- // Add always attribtue if function is a builtin
293- if (F->hasFnAttribute (llvm::Attribute::Builtin))
294- {
295- F->addFnAttr (llvm::Attribute::AlwaysInline);
296- }
297- }
298- else
299- {
300- // Add AlwaysInline attribute to force inlining all calls.
301- F->addFnAttr (llvm::Attribute::AlwaysInline);
302- }
303-
304278 // Go through call sites and remove NoInline atrributes.
305279 for (auto I : F->users ()) {
306280 if (CallInst* callInst = dyn_cast<CallInst>(&*I)) {
@@ -314,7 +288,7 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
314288 // inliner doesn't conservatively turn off unsafe optimizations
315289 // when inlining BIFs (see mergeAttributesForInlining() in inliner).
316290
317- const auto & opts = modMD->compOpt ;
291+ const auto & opts = modMD->compOpt ;
318292
319293 if (opts.MadEnable )
320294 F->addFnAttr (" less-precise-fpmad" , " true" );
@@ -330,82 +304,100 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
330304
331305 // F is not a kernel
332306 // it is builtin, or user function
333- const bool notKernel = pMdUtils->findFunctionsInfoItem (F) == pMdUtils->end_FunctionsInfo ();
307+ const bool notKernel = pMdUtils->findFunctionsInfoItem (F) == pMdUtils->end_FunctionsInfo ();
334308
335309 if (notKernel)
336310 {
337311 F->setLinkage (GlobalValue::InternalLinkage);
338312 Changed = true ;
339313 }
340314
315+ // Add Optnone to user functions but not on builtins. This allows to run
316+ // optimizations on builtins.
317+ if (getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ()->compOpt .OptDisable )
318+ {
319+ if (!F->hasFnAttribute (llvm::Attribute::Builtin))
320+ {
321+ F->addFnAttr (llvm::Attribute::OptimizeNone);
322+ }
323+ }
324+
325+ // Flag for function calls where alwaysinline must be true
326+ bool mustAlwaysInline = false ;
327+
328+ // Add always attribute if function has an argument with opaque type
329+ for (auto & arg : F->args ())
330+ {
331+ if (containsOpaque (arg.getType ()))
332+ {
333+ mustAlwaysInline = true ;
334+ break ;
335+ }
336+ }
337+ // Add always attribtue if function is a builtin
338+ if (F->hasFnAttribute (llvm::Attribute::Builtin) ||
339+ F->getName ().startswith (spv::kLLVMName ::builtinPrefix))
340+ {
341+ mustAlwaysInline = true ;
342+ }
341343 // inline all OCL math functions if __FastRelaxedMath is set
342- if (fastMathFunct.find (F) != fastMathFunct.end ()) continue ;
344+ else if (fastMathFunct.find (F) != fastMathFunct.end ())
345+ {
346+ mustAlwaysInline = true ;
347+ }
348+ if (mustAlwaysInline)
349+ {
350+ F->addFnAttr (llvm::Attribute::AlwaysInline);
351+ Changed = true ;
352+ continue ;
353+ }
343354
344- // The following subroutine check is added to disable two-phase-inlining
345- // when we do not enable subroutines.
346- bool keepAlwaysInline = (MemPoolFuncs.count (F) != 0 );
347- if (IGC_GET_FLAG_VALUE (FunctionControl) != FLAG_FCALL_FORCE_INLINE)
355+ if (IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_DEFAULT)
348356 {
349- if (!keepAlwaysInline)
357+ // Set default inline mode
358+ if (IGC_IS_FLAG_DISABLED (DisableAddingAlwaysAttribute))
350359 {
351- for (auto &arg : F->args ())
360+ bool shouldAlwaysInline = (MemPoolFuncs.count (F) != 0 );
361+ if (!shouldAlwaysInline)
352362 {
353- // If argument contains an opaque type e.g. image, then always inline it.
354- // If argument is a pointer to GAS, always inline it for perf reason.
355- //
356- // Note that this workaround should be removed.
357- if (containsOpaque (arg.getType ()) || isSupportedAggregateArgument (&arg) ||
358- isGASPointer (&arg))
363+ for (auto & arg : F->args ())
359364 {
360- keepAlwaysInline = true ;
361- break ;
365+ // If argument is a pointer to GAS or aggregate type, always inline it for perf reasons
366+ if (isSupportedAggregateArgument (&arg) || isGASPointer (&arg))
367+ {
368+ shouldAlwaysInline = true ;
369+ break ;
370+ }
362371 }
363372 }
364-
365- // SPIR-V image functions don't contain opaque types for images,
366- // they use i64 values instead.
367- // We need to detect them based on function name.
368- if (F->getName ().startswith (spv::kLLVMName ::builtinPrefix) &&
369- F->getName ().contains (" Image" )) {
370- keepAlwaysInline = true ;
373+ if (shouldAlwaysInline)
374+ {
375+ F->addFnAttr (llvm::Attribute::AlwaysInline);
371376 }
372377 }
373-
374- if (!keepAlwaysInline)
375- {
376- F->removeFnAttr (llvm::Attribute::AlwaysInline);
377- }
378378 }
379-
380- // Add Optnone to user functions but not on builtins. This allows to run
381- // optimizations on builtins.
382- if (getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ()->compOpt .OptDisable )
379+ else if (IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_FORCE_INLINE)
383380 {
384- if (!F->hasFnAttribute (llvm::Attribute::Builtin))
385- {
386- F->addFnAttr (llvm::Attribute::OptimizeNone);
387- }
381+ // Forced inlining all functions
382+ F->addFnAttr (llvm::Attribute::AlwaysInline);
388383 }
389384
390385 bool istrue = false ;
386+ // Forcing subroutines/stack-call/indirect-call
387+ // Do not add alwaysinline
391388 if (notKernel || istrue)
392389 {
393- if (!keepAlwaysInline)
390+ bool forceSubroutine = IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_FORCE_SUBROUTINE;
391+ bool forceStackCall = IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_FORCE_STACKCALL;
392+ if ((forceSubroutine || forceStackCall) && (istrue == false ))
394393 {
395- bool forceSubroutine = IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_FORCE_SUBROUTINE;
396- bool forceStackCall = IGC_GET_FLAG_VALUE (FunctionControl) == FLAG_FCALL_FORCE_STACKCALL;
397-
398- if ((forceSubroutine || forceStackCall) && (istrue == false ))
394+ F->removeFnAttr (llvm::Attribute::AlwaysInline);
395+ F->addFnAttr (llvm::Attribute::NoInline);
396+ if (forceStackCall)
399397 {
400- // add the following line in order to stress-test
401- // subroutine call or stack call
402- F->removeFnAttr (llvm::Attribute::AlwaysInline);
403- F->addFnAttr (llvm::Attribute::NoInline);
404- if (forceStackCall)
405- {
406- F->addFnAttr (" visaStackCall" );
407- }
398+ F->addFnAttr (" visaStackCall" );
408399 }
400+ Changed = true ;
409401 }
410402
411403 if (IGC_IS_FLAG_ENABLED (EnableFunctionPointer))
@@ -430,17 +422,17 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
430422 pCtx->m_enableFunctionPointer = true ;
431423 SetIndirectFuncAttributes (F);
432424
433- if (istrue)
425+ if (istrue)
434426 F->removeFnAttr (" visaStackCall" );
435427
436428 if (isExtern)
437429 {
438430 F->setLinkage (GlobalValue::ExternalLinkage);
439431 }
432+ Changed = true ;
440433 }
441434 }
442435 }
443- Changed = true ;
444436 }
445437 return Changed;
446438}
0 commit comments