@@ -241,7 +241,7 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
241
241
bool Changed = false ;
242
242
for (Module::iterator I = M.begin (), E = M.end (); I != E; ++I)
243
243
{
244
- Function * F = &(*I);
244
+ Function* F = &(*I);
245
245
if (F->isDeclaration ())
246
246
{
247
247
if (F->getName () == " __translate_sampler_initializer" )
@@ -275,32 +275,6 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
275
275
// Remove noinline attr if present.
276
276
F->removeFnAttr (llvm::Attribute::NoInline);
277
277
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
-
304
278
// Go through call sites and remove NoInline atrributes.
305
279
for (auto I : F->users ()) {
306
280
if (CallInst* callInst = dyn_cast<CallInst>(&*I)) {
@@ -314,7 +288,7 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
314
288
// inliner doesn't conservatively turn off unsafe optimizations
315
289
// when inlining BIFs (see mergeAttributesForInlining() in inliner).
316
290
317
- const auto & opts = modMD->compOpt ;
291
+ const auto & opts = modMD->compOpt ;
318
292
319
293
if (opts.MadEnable )
320
294
F->addFnAttr (" less-precise-fpmad" , " true" );
@@ -330,82 +304,100 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
330
304
331
305
// F is not a kernel
332
306
// 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 ();
334
308
335
309
if (notKernel)
336
310
{
337
311
F->setLinkage (GlobalValue::InternalLinkage);
338
312
Changed = true ;
339
313
}
340
314
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
+ }
341
343
// 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
+ }
343
354
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)
348
356
{
349
- if (!keepAlwaysInline)
357
+ // Set default inline mode
358
+ if (IGC_IS_FLAG_DISABLED (DisableAddingAlwaysAttribute))
350
359
{
351
- for (auto &arg : F->args ())
360
+ bool shouldAlwaysInline = (MemPoolFuncs.count (F) != 0 );
361
+ if (!shouldAlwaysInline)
352
362
{
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 ())
359
364
{
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
+ }
362
371
}
363
372
}
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);
371
376
}
372
377
}
373
-
374
- if (!keepAlwaysInline)
375
- {
376
- F->removeFnAttr (llvm::Attribute::AlwaysInline);
377
- }
378
378
}
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)
383
380
{
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);
388
383
}
389
384
390
385
bool istrue = false ;
386
+ // Forcing subroutines/stack-call/indirect-call
387
+ // Do not add alwaysinline
391
388
if (notKernel || istrue)
392
389
{
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 ))
394
393
{
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)
399
397
{
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" );
408
399
}
400
+ Changed = true ;
409
401
}
410
402
411
403
if (IGC_IS_FLAG_ENABLED (EnableFunctionPointer))
@@ -430,17 +422,17 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
430
422
pCtx->m_enableFunctionPointer = true ;
431
423
SetIndirectFuncAttributes (F);
432
424
433
- if (istrue)
425
+ if (istrue)
434
426
F->removeFnAttr (" visaStackCall" );
435
427
436
428
if (isExtern)
437
429
{
438
430
F->setLinkage (GlobalValue::ExternalLinkage);
439
431
}
432
+ Changed = true ;
440
433
}
441
434
}
442
435
}
443
- Changed = true ;
444
436
}
445
437
return Changed;
446
438
}
0 commit comments