Skip to content

Commit

Permalink
Mark loads/stores for private variables
Browse files Browse the repository at this point in the history
Mark loads/stores which are created for fill/spill of user private variables.
Adding this mark, because during compilation the orginal addrspace is changed
(for ex. from PRIVATE to GLOBAL) and is not visible on end stages of compilation.
This will help to identify - which load/store is related for the private variables of user.

In llvm-IR load/stores it has mark "user_addrspace_priv".
In asm dumps it has mark "address space: private;"
  • Loading branch information
lwesiers authored and igcbot committed Sep 5, 2023
1 parent 5a8e871 commit 427f3d3
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 1 deletion.
86 changes: 86 additions & 0 deletions IGC/Compiler/CISACodeGen/LowerGEPForPrivMem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ namespace IGC {
StatusPrivArr2Reg CheckIfAllocaPromotable(llvm::AllocaInst* pAlloca);
bool IsNativeType(Type* type);

void MarkNotPromtedAllocas(llvm::AllocaInst& I, IGC::StatusPrivArr2Reg status);
public:
static char ID;

Expand Down Expand Up @@ -491,6 +492,90 @@ bool IGC::CanUseSOALayout(AllocaInst* I, Type*& base, bool& allUsesAreVector)
return useSOA;
}

void LowerGEPForPrivMem::MarkNotPromtedAllocas(llvm::AllocaInst& I, IGC::StatusPrivArr2Reg status)
{
const char* reason = nullptr;
// The reason why the user private variable
// wasn't promoted to grfs
switch (status)
{
case StatusPrivArr2Reg::CannotUseSOALayout:
reason = "CannotUseSOALayout";
break;
case StatusPrivArr2Reg::IsDynamicAlloca:
reason = "IsDynamicAlloca";
break;
case StatusPrivArr2Reg::IsNotNativeType:
reason = "IsNotNativeType";
break;
case StatusPrivArr2Reg::OutOfAllocSizeLimit:
reason = "OutOfAllocSizeLimit";
break;
case StatusPrivArr2Reg::OutOfMaxGRFPressure:
reason = "OutOfMaxGRFPressure";
break;
default:
reason = "NotDefine";
break;
}
MDNode* node = MDNode::get(
I.getContext(),
MDString::get(I.getContext(), reason));

UserAddrSpaceMD& userASMD = m_ctx->m_UserAddrSpaceMD;
std::function<void(Instruction*, MDNode*)> markAS_PRIV;
markAS_PRIV = [&markAS_PRIV, &userASMD](Instruction* instr, MDNode* node) -> void
{
// Avoid instruction which has already md set
if (!userASMD.Has(instr, LSC_DOC_ADDR_SPACE::PRIVATE))
{
// Adding this mark because, during compilation the orginal
// addrspace is changed (for ex. from PRIVATE to GLOBAL) and
// is not visible on end stages of compilation. This will help
// to identify - which load/store is related for the private
// variables of user.

bool isLoadStore =
instr->getOpcode() == Instruction::Store ||
instr->getOpcode() == Instruction::Load;

if (isLoadStore)
{
// Add mark for any load/store which will read/write the data from
// user private variable. This information will be passed
// to the assembly level.
userASMD.Set(instr, LSC_DOC_ADDR_SPACE::PRIVATE, node);
}
else
{
// Special case to avoid stack overflow
userASMD.Set(instr, LSC_DOC_ADDR_SPACE::PRIVATE);

bool allowedInst =
instr->getOpcode() == Instruction::Alloca ||
instr->getOpcode() == Instruction::PHI ||
instr->getOpcode() == Instruction::GetElementPtr ||
instr->getOpcode() == Instruction::PtrToInt ||
instr->getOpcode() == Instruction::IntToPtr ||
instr->isBinaryOp();


if (allowedInst)
{
for (auto user_i = instr->user_begin();
user_i != instr->user_end();
++user_i)
{
markAS_PRIV(llvm::dyn_cast<Instruction>(*user_i), node);
}
}
}
}
};

markAS_PRIV(&I, node);
}

void LowerGEPForPrivMem::visitAllocaInst(AllocaInst& I)
{
// Alloca should always be private memory
Expand All @@ -504,6 +589,7 @@ void LowerGEPForPrivMem::visitAllocaInst(AllocaInst& I)
}
if (status != StatusPrivArr2Reg::OK)
{
MarkNotPromtedAllocas(I, status);
// alloca size extends remain per-lane-reg space
return;
}
Expand Down
1 change: 0 additions & 1 deletion IGC/Compiler/DebugInfo/ScalarVISAModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,6 @@ ScalarVisaModule::GetVariableLocation(const llvm::Instruction* pInst) const
{
if (!isa<GlobalVariable>(pVal) && !isa<ConstantExpr>(pVal))
{
IGC_ASSERT_MESSAGE(!isDbgDclInst, "address cannot be immediate!");
return VISAVariableLocation(pConstVal, this);
}
}
Expand Down
71 changes: 71 additions & 0 deletions IGC/ocloc_tests/features/metadata_travel_check/user_private_var.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*========================== begin_copyright_notice ============================
Copyright (C) 2023 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
// REQUIRES: regkeys
// windows unsupported due to issues on 32bit build, to be debugged.
// UNSUPPORTED: system-windows

// checking the asm dump file
// RUN: ocloc compile -file %s -options " -g -igc_opts 'VISAOptions=-asmToConsole'" -device pvc 2>&1 | FileCheck %s --check-prefix=CHECK-ASM
// checking the llvm-IR after EmitVISAPass
// RUN: ocloc compile -file %s -options " -g -igc_opts 'PrintToConsole=1 PrintMDBeforeModule=1 PrintAfter=EmitPass'" -device pvc 2>&1 | FileCheck %s --check-prefix=CHECK-LLVM
// RUN: ocloc compile -file %s -options " -g -igc_opts 'PrintToConsole=1 PrintMDBeforeModule=1 PrintAfter=EmitPass'" -device pvc 2>&1 | FileCheck %s --check-prefix=CHECK-LLVM2
// RUN: ocloc compile -file %s -options " -g -igc_opts 'PrintToConsole=1 PrintMDBeforeModule=1 PrintAfter=EmitPass'" -device pvc 2>&1 | FileCheck %s --check-prefix=CHECK-LLVM3
// RUN: ocloc compile -file %s -options " -g -igc_opts 'PrintToConsole=1 PrintMDBeforeModule=1 PrintAfter=EmitPass'" -device pvc 2>&1 | FileCheck %s --check-prefix=CHECK-LLVM4

// Looking for the comment attached to the instructions ex:
// (W) store.ugm .... // address space: private; ; $193
// CHECK-ASM: address space: private;

// Looking for the MD attached to the instructions ex:
// store <4 x i32> %39, <4 x i32>* %40, align 4, !user_as_priv !348 ; visa id: 82
// %55 = load i32, i32* %54, align 4, !user_as_priv !348 ; visa id: 127
// Looking for the reason of not promoting the user variable to grf


kernel void test_simple(global int* output)
{
// To force spill of the variable private_array.
// This will generate the metadata !user_as_priv in LLVM-IR
// and comment in asm dump "address space: private;"
int private_array[1024];
int private_array_2[1024];

for(int i = 0; i < 1024; ++i)
{
// Look first for the debugInfo mark which indetify the asign place
// CHECK-LLVM: [[PA1:![0-9]+]] = !DILocation(line: [[@LINE+7]], column: 22,
// Look if we have any load/store pointing to the dbg loc which don't have
// md attribute !user_as_priv
// regex in POSIX: !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])
// equals negative lookahead !(?!user_as_p)
// CHECK-LLVM-NOT: {{^ store .*, !dbg }}[[PA1]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
// CHECK-LLVM-NOT: {{^ .* = load .*, !dbg }}[[PA1]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
private_array[i] = i;
}

for(int i = 1023; i >= 0 ; --i)
{
// CHECK-LLVM2: [[PA2:![0-9]+]] = !DILocation(line: [[@LINE+3]], column: 21,
// CHECK-LLVM2-NOT: {{^ store .*, !dbg }}[[PA2]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
// CHECK-LLVM2-NOT: {{^ .* = load .*, !dbg }}[[PA2]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
const int tmp = private_array[i];
// CHECK-LLVM3: [[PA3:![0-9]+]] = !DILocation(line: [[@LINE+3]], column: 24,
// CHECK-LLVM3-NOT: {{^ store .*, !dbg }}[[PA3]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
// CHECK-LLVM3-NOT: {{^ .* = load .*, !dbg }}[[PA3]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
private_array_2[i] = tmp;
}

for(int i = 0; i < 1024; ++i)
{
// CHECK-LLVM4: [[PA4:![0-9]+]] = !DILocation(line: [[@LINE+3]], column: 21,
// CHECK-LLVM4-NOT: {{^ store .*, !dbg }}[[PA4]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
// CHECK-LLVM4-NOT: {{^ .* = load .*, !dbg }}[[PA4]]{{, !([^u]|u[^s]|us[^e]|use[^r]|user[^_]|user_[^a]|user_a[^s]|user_as[^_]|user_as_[^p])}}
const int tmp = private_array_2[i];
output[i] = tmp;
}
}

0 comments on commit 427f3d3

Please sign in to comment.