Skip to content

Commit 8a39a67

Browse files
dlei6ggfxbot
authored andcommitted
Changes in code.
Change-Id: I884efc1f74311741f9556f8217850d662b968963
1 parent d04016b commit 8a39a67

File tree

4 files changed

+129
-87
lines changed

4 files changed

+129
-87
lines changed

IGC/AdaptorCommon/ProcessFuncAttributes.cpp

Lines changed: 87 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,22 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
233233
// It is not a defined function
234234
continue;
235235
}
236+
237+
// If EnableOCLNoInlineAttr is on and F does have
238+
// NoInline, do not reset it.
239+
if (IGC_IS_FLAG_ENABLED(EnableOCLNoInlineAttr) &&
240+
pCtx->type == ShaderType::OPENCL_SHADER &&
241+
F->hasFnAttribute(llvm::Attribute::NoInline) &&
242+
!F->hasFnAttribute(llvm::Attribute::Builtin))
243+
{
244+
continue;
245+
}
246+
247+
// Remove noinline attr if present.
248+
F->removeFnAttr(llvm::Attribute::NoInline);
249+
250+
// Add AlwaysInline attribute to force inlining all calls.
251+
F->addFnAttr(llvm::Attribute::AlwaysInline);
236252

237253
// Go through call sites and remove NoInline atrributes.
238254
for (auto I : F->users()) {
@@ -271,67 +287,86 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
271287
Changed = true;
272288
}
273289

274-
// Always try inline unless we find reasons not to
275-
F->addFnAttr(llvm::Attribute::AlwaysInline);
276-
277290
// inline all OCL math functions if __FastRelaxedMath is set
278-
// Always inline builtins by default for now
279-
if ((IGC_GET_FLAG_VALUE(FunctionControl) == FLAG_FCALL_FORCE_INLINE) ||
280-
(fastMathFunct.find(F) != fastMathFunct.end()) ||
281-
(F->hasFnAttribute(llvm::Attribute::Builtin)))
282-
{
283-
F->removeFnAttr(llvm::Attribute::NoInline);
284-
continue;
285-
}
286-
287-
bool keepAlwaysInline = true;
288-
289-
// Honor noinline attribute
290-
if (F->hasFnAttribute(llvm::Attribute::NoInline))
291-
keepAlwaysInline = false;
291+
if (fastMathFunct.find(F) != fastMathFunct.end()) continue;
292292

293-
// Force inline mempool funcs
294-
if (!keepAlwaysInline && MemPoolFuncs.count(F) != 0)
295-
keepAlwaysInline = true;
296-
297-
if (!keepAlwaysInline)
293+
// The following subroutine check is added to disable two-phase-inlining
294+
// when we do not enable subroutines.
295+
bool keepAlwaysInline = (MemPoolFuncs.count(F) != 0);
296+
if (IGC_GET_FLAG_VALUE(FunctionControl) != FLAG_FCALL_FORCE_INLINE)
298297
{
299-
for (auto &arg : F->args())
298+
// keep inline if function pointers not enabled and there are uses
299+
// for function pointers other than call instructions
300+
if (IGC_IS_FLAG_DISABLED(EnableFunctionPointer) && !keepAlwaysInline)
300301
{
301-
// If argument contains an opaque type e.g. image, then always inline it.
302-
// If argument is a pointer to GAS, always inline it for perf reason.
303-
//
304-
// Note that this workaround should be removed.
305-
if (containsOpaque(arg.getType()) || isSupportedAggregateArgument(&arg) ||
306-
isGASPointer(&arg))
302+
for (auto U : F->users())
307303
{
308-
keepAlwaysInline = true;
309-
break;
304+
if (!isa<CallInst>(U))
305+
{
306+
keepAlwaysInline = true;
307+
break;
308+
}
310309
}
311310
}
312311

313-
// SPIR-V image functions don't contain opaque types for images,
314-
// they use i64 values instead.
315-
// We need to detect them based on function name.
316-
if (F->getName().startswith(spv::kLLVMName::builtinPrefix) &&
317-
F->getName().contains("Image")) {
318-
keepAlwaysInline = true;
312+
if (!keepAlwaysInline)
313+
{
314+
for (auto &arg : F->args())
315+
{
316+
// If argument contains an opaque type e.g. image, then always inline it.
317+
// If argument is a pointer to GAS, always inline it for perf reason.
318+
//
319+
// Note that this workaround should be removed.
320+
if (containsOpaque(arg.getType()) || isSupportedAggregateArgument(&arg) ||
321+
isGASPointer(&arg))
322+
{
323+
keepAlwaysInline = true;
324+
break;
325+
}
326+
}
327+
328+
// SPIR-V image functions don't contain opaque types for images,
329+
// they use i64 values instead.
330+
// We need to detect them based on function name.
331+
if (F->getName().startswith(spv::kLLVMName::builtinPrefix) &&
332+
F->getName().contains("Image")) {
333+
keepAlwaysInline = true;
334+
}
335+
}
336+
337+
if (!keepAlwaysInline)
338+
{
339+
F->removeFnAttr(llvm::Attribute::AlwaysInline);
340+
}
341+
}
342+
343+
// Add Optnone to user functions but not on builtins. This allows to run
344+
// optimizations on builtins.
345+
if (getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData()->compOpt.OptDisable)
346+
{
347+
if (!F->hasFnAttribute(llvm::Attribute::Builtin))
348+
{
349+
F->addFnAttr(llvm::Attribute::OptimizeNone);
319350
}
320351
}
321352

322353
if (notKernel)
323354
{
324-
bool forceSubroutine = IGC_GET_FLAG_VALUE(FunctionControl) == FLAG_FCALL_FORCE_SUBROUTINE;
325-
bool forceStackCall = IGC_GET_FLAG_VALUE(FunctionControl) == FLAG_FCALL_FORCE_STACKCALL;
326-
if (forceSubroutine || forceStackCall)
355+
if (!keepAlwaysInline)
327356
{
328-
// add the following line in order to stress-test
329-
// subroutine call or stack call
330-
F->addFnAttr(llvm::Attribute::NoInline);
331-
keepAlwaysInline = false;
332-
if (forceStackCall)
357+
bool forceSubroutine = IGC_GET_FLAG_VALUE(FunctionControl) == FLAG_FCALL_FORCE_SUBROUTINE;
358+
bool forceStackCall = IGC_GET_FLAG_VALUE(FunctionControl) == FLAG_FCALL_FORCE_STACKCALL;
359+
360+
if (forceSubroutine || forceStackCall)
333361
{
334-
F->addFnAttr("visaStackCall");
362+
// add the following line in order to stress-test
363+
// subroutine call or stack call
364+
F->removeFnAttr(llvm::Attribute::AlwaysInline);
365+
F->addFnAttr(llvm::Attribute::NoInline);
366+
if (forceStackCall)
367+
{
368+
F->addFnAttr("visaStackCall");
369+
}
335370
}
336371
}
337372

@@ -352,29 +387,14 @@ bool ProcessFuncAttributes::runOnModule(Module& M)
352387
}
353388
}
354389
if (isIndirect)
355-
{
390+
{
356391
pCtx->m_enableFunctionPointer = true;
392+
pCtx->m_enableSubroutine = false;
357393
F->addFnAttr("AsFunctionPointer");
358394
F->addFnAttr("visaStackCall");
359395
}
360396
}
361397
}
362-
363-
if (keepAlwaysInline)
364-
{
365-
F->removeFnAttr(llvm::Attribute::NoInline);
366-
}
367-
else
368-
{
369-
F->removeFnAttr(llvm::Attribute::AlwaysInline);
370-
}
371-
372-
// Add Optnone to user functions but not on builtins. This allows to run
373-
// optimizations on builtins.
374-
if (getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData()->compOpt.OptDisable)
375-
{
376-
F->addFnAttr(llvm::Attribute::OptimizeNone);
377-
}
378398
Changed = true;
379399
}
380400
return Changed;
@@ -452,6 +472,10 @@ bool ProcessBuiltinMetaData::runOnModule(Module& M)
452472
Function *F = &(*I);
453473
if (!F || F->isDeclaration()) continue;
454474

475+
// add AlwaysInline for functions. It will be handle in optimization phase
476+
if (!F->hasFnAttribute(llvm::Attribute::NoInline))
477+
F->addFnAttr(llvm::Attribute::AlwaysInline);
478+
455479
// disable JumpThread optimization on the block that contains this function
456480
F->setConvergent();
457481

IGC/Compiler/CISACodeGen/EstimateFunctionSize.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -272,38 +272,49 @@ void EstimateFunctionSize::checkSubroutine() {
272272
if (!CGW || AL != AL_Module)
273273
return;
274274

275-
bool hasNoInlineAttrib = false;
275+
bool neverInline = false;
276276

277277
CodeGenContext *pContext = CGW->getCodeGenContext();
278278
bool EnableSubroutine = true;
279-
280-
if (IGC_GET_FLAG_VALUE(FunctionControl) != FLAG_FCALL_FORCE_SUBROUTINE)
281-
{
282-
if (pContext->type != ShaderType::OPENCL_SHADER &&
283-
pContext->type != ShaderType::COMPUTE_SHADER)
284-
EnableSubroutine = false;
285-
else if (pContext->m_instrTypes.hasIndirectCall)
286-
EnableSubroutine = false;
287-
288-
// Enable subroutine if function has the "UserSubroutine" attribute, or has noinline
279+
if (pContext->type != ShaderType::OPENCL_SHADER &&
280+
pContext->type != ShaderType::COMPUTE_SHADER)
281+
EnableSubroutine = false;
282+
else if (pContext->m_instrTypes.hasIndirectCall)
283+
EnableSubroutine = false;
284+
285+
// Enable subroutine if function has the "UserSubroutine" attribute
286+
if (!EnableSubroutine) {
289287
for (Function& F : *M) {
290288
if (F.hasFnAttribute("UserSubroutine")) {
291289
EnableSubroutine = true;
292-
}
293-
// Honor the noinline attribute
294-
if (F.hasFnAttribute(llvm::Attribute::NoInline)) {
295-
hasNoInlineAttrib = true;
296-
EnableSubroutine = true;
290+
if (F.hasFnAttribute(llvm::Attribute::NoInline)) {
291+
neverInline = true;
292+
}
297293
}
298294
}
295+
}
299296

300-
// We can still turn off subroutine if not beneficial
301-
if (!hasNoInlineAttrib && EnableSubroutine) {
302-
std::size_t Threshold = IGC_GET_FLAG_VALUE(SubroutineThreshold);
303-
std::size_t MaxSize = getMaxExpandedSize();
304-
if (MaxSize <= Threshold && !HasRecursion)
305-
EnableSubroutine = false;
306-
}
297+
if (neverInline) {
298+
EnableSubroutine = true;
299+
}
300+
else if (EnableSubroutine) {
301+
std::size_t Threshold = IGC_GET_FLAG_VALUE(SubroutineThreshold);
302+
std::size_t MaxSize = getMaxExpandedSize();
303+
if (MaxSize <= Threshold && !HasRecursion)
304+
EnableSubroutine = false;
305+
}
306+
307+
if (IGC_IS_FLAG_ENABLED(EnableOCLNoInlineAttr) &&
308+
pContext->type == ShaderType::OPENCL_SHADER)
309+
{
310+
for (Function& F : *M)
311+
{
312+
if (F.hasFnAttribute(llvm::Attribute::NoInline) &&
313+
!F.hasFnAttribute(llvm::Attribute::Builtin)) {
314+
EnableSubroutine = true;
315+
break;
316+
}
317+
}
307318
}
308319

309320
if (EnableSubroutine) {

IGC/Compiler/CISACodeGen/GenCodeGenModule.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,13 @@ InlineCost SubroutineInliner::getInlineCost(CallSite CS)
784784
if (pCtx->m_enableSubroutine == false)
785785
return IGCLLVM::InlineCost::getAlways();
786786

787-
if (Callee->hasFnAttribute(llvm::Attribute::NoInline))
787+
if (pCtx->type == ShaderType::OPENCL_SHADER &&
788+
IGC_IS_FLAG_ENABLED(EnableOCLNoInlineAttr) &&
789+
Callee->hasFnAttribute(llvm::Attribute::NoInline))
790+
return IGCLLVM::InlineCost::getNever();
791+
792+
if (Callee->hasFnAttribute("UserSubroutine") &&
793+
Callee->hasFnAttribute(llvm::Attribute::NoInline))
788794
return IGCLLVM::InlineCost::getNever();
789795

790796
if (FCtrl != FLAG_FCALL_FORCE_SUBROUTINE &&

IGC/common/igc_flags.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ DECLARE_IGC_REGKEY(bool, ForceDisableSrc0Alpha, false, "Force the compile
269269
DECLARE_IGC_REGKEY(bool, EnableLTO, true, "Enable link time optimization")
270270
DECLARE_IGC_REGKEY(bool, EnableLTODebug, false, "Enable debug information for LTO")
271271
DECLARE_IGC_REGKEY(DWORD, FunctionControl, 0, "Control function inlining/subroutine/stackcall. See value defs in igc_flags.hpp.")
272+
DECLARE_IGC_REGKEY(bool, EnableOCLNoInlineAttr, false, "If set, OCL kernel with noinline attribute is honored (only for user function). Thus, subroutine call is enabled.")
272273
DECLARE_IGC_REGKEY(DWORD, OCLInlineThreshold, 512, "Setting OCL inline thershold")
273274
DECLARE_IGC_REGKEY(bool, EnableForceGroupSize, false, "Enable forcing thread Group Size ForceGroupSizeX and ForceGroupSizeY")
274275
DECLARE_IGC_REGKEY(DWORD, ForceGroupSizeX, 8, "force group size along X")

0 commit comments

Comments
 (0)