Update for IGC-Metrics

1. Updated the way how the metrics are collected from the debug info.
2. Added cost-model for the SIMD16
This commit is contained in:
Lukasz Wesierski
2021-12-13 13:16:05 +00:00
committed by igcbot
parent 0f6e10d5a4
commit 04c9de4bf2
15 changed files with 720 additions and 330 deletions

View File

@ -1086,6 +1086,11 @@ else()
"/ignore:4197"
)
endif()
set(IGC_BUILD__EXPORT_SYMBOLS_LINK_FLAGS_DEBUG
"${IGC_BUILD__EXPORT_SYMBOLS_LINK_FLAGS_DEBUG}"
"/ignore:4099")
# Disable LTCG due to release build time increase
#igc_config_flag_apply_settings(
# LinkerOptions
@ -1122,6 +1127,7 @@ if(_igc_compiler_is_clang)
endif()
# ================================== Compiler preprocessor definitions =================================
# ? CL_NUMBER < env:CL_NUMBER if env:CL_NUMBER != ''
@ -1352,10 +1358,9 @@ add_subdirectory(common)
igc_sg_define(IGC__common)
igc_sg_define(IGC__Common_CLElfLib)
#Metrcis
include(igc_find_protobuf)
include(Metrics/protobuf_metrics.cmake)
# Add protobuf
include(igc_find_protobuf)
set(IGC_BUILD__SPIRV_TOOLS_ENABLED ON)
@ -1428,6 +1433,9 @@ if(MSVC)
)
endif()
#Metrcis
include(Metrics/protobuf_metrics.cmake)
# Sources/headers for main libraries.
set(IGC_BUILD__SRC__IGC__igc_common
${IGC_BUILD__SRC__IGC_AdaptorOCL}
@ -1883,6 +1891,7 @@ if(UNIX)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AdaptorOCL/cif DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/igc COMPONENT igc-opencl-devel)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/common/StateSaveAreaHeader.h DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR}/igc/common COMPONENT igc-opencl-devel)
if(IGC_BUILD__LLVM_SOURCES AND IGC_OPTION__LLVM_LLD)
# For now lld could be included only via building from LLVM sources
if(NOT ${CMAKE_BUILD_TYPE} EQUAL "Release")

View File

@ -232,6 +232,9 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
if (finalize)
{
m_currShader->GetContext()->metrics.CollectDataFromDebugInfo(
&m_currShader->GetDebugInfoData(), &decodedDbg);
IDebugEmitter::Release(m_pDebugEmitter);
}
}

View File

@ -928,7 +928,6 @@ static bool hasMultipleExits(Loop* L, WIAnalysis* WI) {
/// L6
/// L7
/// then it returns {L2, L5}
///
static void getNestedLoopsWithMultpleExists(Loop* L, WIAnalysis* WI,
SmallVectorImpl<Loop*>& Result) {
if (getNumOfNonUniformExits(L, WI) > 1) {
@ -947,9 +946,10 @@ static void getNestedLoopsWithMultpleExists(Loop* L, WIAnalysis* WI,
getNestedLoopsWithMultpleExists(InnerL, WI, Result);
}
static const float NestedLoopsWithMultipleExits_THRESHOLD = 0.7f;
/// Check if loops with multiple exists dominate the entire function.
static bool hasNestedLoopsWithMultipleExits(Function* F, LoopInfo* LI,
/// Return the ratio between loops with multiple exists to other instructions in function.
static float NestedLoopsWithMultipleExitsRatio(Function* F, LoopInfo* LI,
WIAnalysis* WI) {
// Find top level nested loops with multiple non-uniform exists.
SmallVector<Loop*, 8> Loops;
@ -971,16 +971,26 @@ static bool hasNestedLoopsWithMultipleExits(Function* F, LoopInfo* LI,
for (auto& BB : F->getBasicBlockList())
FuncSize += (unsigned)BB.size();
bool retVal = false;
if (FuncSize > 0)
{
retVal = float(LoopSize) / FuncSize >= 0.7f;
return float(LoopSize) / FuncSize;
}
else
{
return 0.0f;
}
return retVal;
}
static bool hasLongStridedLdStInLoop(Function* F, LoopInfo* LI, WIAnalysis* WI) {
static const unsigned LongStridedLdStInLoop_THRESHOLD = 3;
typedef struct {
unsigned LDs = 0;
unsigned STs = 0;
llvm::Loop* pProblematicLoop = nullptr;
} LdStInLoop;
static const LdStInLoop LongStridedLdStInLoop(Function* F, LoopInfo* LI, WIAnalysis* WI) {
LdStInLoop retVal;
SmallVector<Loop*, 32> Loops;
// Collect innermost simple loop.
for (auto I = LI->begin(), E = LI->end(); I != E; ++I) {
@ -1018,27 +1028,65 @@ static bool hasLongStridedLdStInLoop(Function* F, LoopInfo* LI, WIAnalysis* WI)
++STs;
}
}
if (LDs > 3 || STs > 3)
return true;
if (LDs > LongStridedLdStInLoop_THRESHOLD ||
STs > LongStridedLdStInLoop_THRESHOLD)
{
retVal.LDs = LDs;
retVal.STs = STs;
retVal.pProblematicLoop = L;
return retVal;
}
}
return false;
return retVal;
}
bool Simd32ProfitabilityAnalysis::checkSimd16Profitable(CodeGenContext* ctx) {
if ((IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x1) &&
getLoopCyclomaticComplexity() >= CYCLOMATIC_COMPLEXITY_THRESHOLD) {
return false;
if ((IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x1))
{
int loopCyclomaticComplexity = getLoopCyclomaticComplexity();
ctx->metrics.CollectLoopCyclomaticComplexity(
F,
loopCyclomaticComplexity,
CYCLOMATIC_COMPLEXITY_THRESHOLD);
if (loopCyclomaticComplexity >= CYCLOMATIC_COMPLEXITY_THRESHOLD)
{
return false;
}
}
if ((IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x2) &&
hasNestedLoopsWithMultipleExits(F, LI, WI)) {
return false;
if (IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x2)
{
float nestedLoopsWithMultipleExits = NestedLoopsWithMultipleExitsRatio(F, LI, WI);
ctx->metrics.CollectNestedLoopsWithMultipleExits(
F,
nestedLoopsWithMultipleExits,
NestedLoopsWithMultipleExits_THRESHOLD);
if (nestedLoopsWithMultipleExits >= NestedLoopsWithMultipleExits_THRESHOLD)
{
return false;
}
}
// If there's wider vector load/store in a loop, skip SIMD16.
if ((IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x4) &&
hasLongStridedLdStInLoop(F, LI, WI)) {
return false;
if (IGC_GET_FLAG_VALUE(OCLSIMD16SelectionMask) & 0x4)
{
LdStInLoop ldStInLoop = LongStridedLdStInLoop(F, LI, WI);
ctx->metrics.CollectLongStridedLdStInLoop(
F,
ldStInLoop.pProblematicLoop,
ldStInLoop.LDs,
ldStInLoop.STs,
LongStridedLdStInLoop_THRESHOLD);
if (ldStInLoop.pProblematicLoop != nullptr)
{
return false;
}
}
auto hasDouble = [](Function& F) {
@ -1056,9 +1104,15 @@ bool Simd32ProfitabilityAnalysis::checkSimd16Profitable(CodeGenContext* ctx) {
const CPlatform* platform = &ctx->platform;
if (platform->GetPlatformFamily() == IGFX_GEN9_CORE &&
platform->getPlatformInfo().eProductFamily == IGFX_GEMINILAKE &&
hasDouble(*F)) {
hasDouble(*F))
{
ctx->metrics.CollectIsGeminiLakeWithDoubles(F, false);
return false;
}
else
{
ctx->metrics.CollectIsGeminiLakeWithDoubles(F, true);
}
return true;
}

View File

@ -9,6 +9,8 @@ SPDX-License-Identifier: MIT
#include "IGCMetric.h"
#include "IGCMetricImpl.h"
class VISAModule;
namespace IGCMetrics
{
inline IGCMetricImpl* get(void* pIGCMetric)
@ -74,8 +76,57 @@ namespace IGCMetrics
get(igcMetric)->CollectLoops(loopInfo);
}
void IGCMetric::CollectLoopCyclomaticComplexity(
llvm::Function* pFunc,
int LoopCyclomaticComplexity,
int LoopCyclomaticComplexity_Max)
{
get(igcMetric)->CollectLoopCyclomaticComplexity(
pFunc,
LoopCyclomaticComplexity,
LoopCyclomaticComplexity_Max);
}
void IGCMetric::CollectNestedLoopsWithMultipleExits(
llvm::Function* pFunc,
float NestedLoopsWithMultipleExitsRatio,
float NestedLoopsWithMultipleExitsRatio_Max)
{
get(igcMetric)->CollectNestedLoopsWithMultipleExits(
pFunc,
NestedLoopsWithMultipleExitsRatio,
NestedLoopsWithMultipleExitsRatio_Max);
}
void IGCMetric::CollectLongStridedLdStInLoop(
llvm::Function* pFunc,
llvm::Loop* pProblematicLoop,
int LongStridedLdStInLoop_LdCnt,
int LongStridedLdStInLoop_StCnt,
int LongStridedLdStInLoop_MaxCntLdOrSt)
{
get(igcMetric)->CollectLongStridedLdStInLoop(
pFunc,
pProblematicLoop,
LongStridedLdStInLoop_LdCnt,
LongStridedLdStInLoop_StCnt,
LongStridedLdStInLoop_MaxCntLdOrSt);
}
void IGCMetric::CollectIsGeminiLakeWithDoubles(
llvm::Function* pFunc,
bool IsGeminiLakeWithDoubles)
{
get(igcMetric)->CollectIsGeminiLakeWithDoubles(pFunc, IsGeminiLakeWithDoubles);
}
void IGCMetric::FinalizeStats()
{
get(igcMetric)->FinalizeStats();
}
void IGCMetric::CollectDataFromDebugInfo(IGC::DebugInfoData* pDebugInfo, IGC::DbgDecoder* pDebugDecoder)
{
get(igcMetric)->CollectDataFromDebugInfo(pDebugInfo, pDebugDecoder);
}
}

View File

@ -19,6 +19,12 @@ SPDX-License-Identifier: MIT
#pragma once
namespace IGC
{
class DebugInfoData;
class DbgDecoder;
}
namespace IGCMetrics
{
class IGCMetric
@ -44,6 +50,29 @@ namespace IGCMetrics
void CollectRegStats(KERNEL_INFO* vISAstats);
void CollectLoopCyclomaticComplexity(
llvm::Function* pFunc,
int LoopCyclomaticComplexity,
int LoopCyclomaticComplexity_Max);
void CollectNestedLoopsWithMultipleExits(
llvm::Function* pFunc,
float NestedLoopsWithMultipleExitsRatio,
float NestedLoopsWithMultipleExitsRatio_Max);
void CollectLongStridedLdStInLoop(
llvm::Function* pFunc,
llvm::Loop* pProblematicLoop,
int LongStridedLdStInLoop_LdCnt,
int LongStridedLdStInLoop_StCnt,
int LongStridedLdStInLoop_MaxCntLdOrSt);
void CollectIsGeminiLakeWithDoubles(
llvm::Function* pFunc,
bool IsGeminiLakeWithDoubles);
void CollectDataFromDebugInfo(IGC::DebugInfoData* pDebugInfo, IGC::DbgDecoder* pDebugDecoder);
void FinalizeStats();
void OutputMetrics();

View File

@ -6,25 +6,30 @@ SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
#include "common/LLVMWarningsPush.hpp"
#include <llvm/IR/Instructions.h>
#include <llvm/Support/Path.h>
#include "common/LLVMWarningsPop.hpp"
#include <algorithm>
#include <string>
#include <unordered_map>
#include <iostream>
#include <fstream>
#include <Metrics/IGCMetricImpl.h>
#include <Probe/Assertion.h>
#include <iomanip>
#include <common/igc_regkeys.hpp>
#include <visa/G4_IR.hpp>
#include <visa/SpillManagerGMRF.h>
#include <visa/LinearScanRA.h>
#include <visa/LocalRA.h>
#include <visa/LocalScheduler/Dependencies_G4IR.h>
#include <Metrics/IGCMetricImpl.h>
#include <Probe/Assertion.h>
#include <Compiler/CISACodeGen/ShaderCodeGen.hpp>
#include <DebugInfo/VISAModule.hpp>
#include <Compiler/DebugInfo/ScalarVISAModule.h>
#include <visaBuilder_interface.h>
#include <visa/Common_ISA.h>
#include "common/LLVMWarningsPush.hpp"
#include <llvm/IR/Instructions.h>
#include <llvm/Support/Path.h>
#include <llvm/IR/DebugInfo.h>
#include "common/LLVMWarningsPop.hpp"
#define DEBUG_METRIC 0
namespace IGCMetrics
{
@ -40,11 +45,6 @@ namespace IGCMetrics
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
this->map_EmuCalls.clear();
this->map_Func.clear();
for (auto func : map_InstrLoc2Func)
{
delete func.second;
}
this->map_InstrLoc2Func.clear();
this->map_Loops.clear();
#endif
}
@ -65,9 +65,9 @@ namespace IGCMetrics
std::stringstream ss;
ss << std::hex
<< std::setfill('0')
<< std::setw(sizeof(Hash->asmHash) * CHAR_BIT / 4)
<< Hash->asmHash;
<< std::setfill('0')
<< std::setw(sizeof(Hash->asmHash) * CHAR_BIT / 4)
<< Hash->asmHash;
oclProgram.set_hash(ss.str());
#endif
@ -81,7 +81,7 @@ namespace IGCMetrics
if (IGC_GET_FLAG_VALUE(MetricsDumpEnable) > 0)
{
// Out file with ext OPTRPT - OPTimization RePoT
std::string fileName = "OCL_" + oclProgram.hash() + ".optrpt";
std::string fileName = oclProgram.hash() + ".optrpt";
std::ofstream metric_data;
metric_data.open(fileName);
@ -147,49 +147,47 @@ namespace IGCMetrics
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
llvm::DILocation* debLoc = (llvm::DILocation*)emulatedInstruction->getDebugLoc();
auto func_m_list = GetFuncMetric(emulatedInstruction);
if (func_m_list == nullptr)
auto func_m = GetFuncMetric(emulatedInstruction);
if (func_m == nullptr)
{
return;
}
for (auto func_m : *func_m_list)
IGC_METRICS::InstrStats* stats = func_m->mutable_instruction_stats();
IGC_METRICS::FuncEmuCalls* emuCall_m = nullptr;
// Count how many instructions we added
int extraInstrAdded = CountInstInFunc(emulatedInstruction->getParent()->getParent()) -
countInstInFunc;
// reset counter
countInstInFunc = 0;
if (map_EmuCalls.find(debLoc) != map_EmuCalls.end())
{
IGC_METRICS::InstrStats* stats = func_m->mutable_instruction_stats();
IGC_METRICS::FuncEmuCalls* emuCall_m = nullptr;
// For case when receive extra instruction to already recoreded emu-function
emuCall_m = map_EmuCalls[debLoc];
}
else
{
// For case if we discover new emulated function
emuCall_m = func_m->add_emufunctioncalls();
map_EmuCalls.insert({ debLoc, emuCall_m });
// Count how many instructions we added
int extraInstrAdded = CountInstInFunc(emulatedInstruction->getParent()->getParent()) -
countInstInFunc;
// reset counter
countInstInFunc = 0;
auto emuCall_m_loc = emuCall_m->add_funccallloc();
FillCodeRef(emuCall_m_loc, debLoc);
stats->set_countemulatedinst(stats->countemulatedinst() + 1);
if (map_EmuCalls.find(debLoc) != map_EmuCalls.end())
if (IGC_IS_FLAG_ENABLED(ForceDPEmulation) && isDPType(emulatedInstruction))
{
// For case when receive extra instruction to already recoreded emu-function
emuCall_m = map_EmuCalls[debLoc];
emuCall_m->set_type(IGC_METRICS::FuncEmuCalls_Reason4FuncEmu_FP_MODEL_MODE);
}
else
{
// For case if we discover new emulated function
emuCall_m = func_m->add_emufunctioncalls();
map_EmuCalls.insert({ debLoc, emuCall_m });
auto emuCall_m_loc = emuCall_m->add_funccallloc();
FillCodeRef(emuCall_m_loc, debLoc);
stats->set_countemulatedinst(stats->countemulatedinst() + 1);
if (IGC_IS_FLAG_ENABLED(ForceDPEmulation) && isDPType(emulatedInstruction))
{
emuCall_m->set_type(IGC_METRICS::FuncEmuCalls_Reason4FuncEmu_FP_MODEL_MODE);
}
else
{
emuCall_m->set_type(IGC_METRICS::FuncEmuCalls_Reason4FuncEmu_NO_HW_SUPPORT);
}
emuCall_m->set_type(IGC_METRICS::FuncEmuCalls_Reason4FuncEmu_NO_HW_SUPPORT);
}
// Count amount of instructions created to emulate not supported instruction
emuCall_m->set_count(emuCall_m->count() + extraInstrAdded);
}
// Count amount of instructions created to emulate not supported instruction
emuCall_m->set_count(emuCall_m->count() + extraInstrAdded);
#endif
}
@ -197,16 +195,14 @@ namespace IGCMetrics
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
auto func_m_list = GetFuncMetric(coalescedAccess);
if (func_m_list == nullptr)
auto func_m = GetFuncMetric(coalescedAccess);
if (func_m == nullptr)
{
return;
}
for (auto func_m : *func_m_list)
{
IGC_METRICS::InstrStats* stats = func_m->mutable_instruction_stats();
stats->set_countcoalescedaccess(stats->countcoalescedaccess() + 1);
}
IGC_METRICS::InstrStats* stats = func_m->mutable_instruction_stats();
stats->set_countcoalescedaccess(stats->countcoalescedaccess() + 1);
#endif
}
@ -218,63 +214,6 @@ namespace IGCMetrics
{
return;
}
for (auto record = kernelInfo->variables.begin();
record != kernelInfo->variables.end(); ++record)
{
auto varInfo = record->second;
// Find to which function this var info belongs
auto keyMap = GetHash(varInfo->srcFilename, varInfo->lineNb);
auto func_m_list = GetFuncMetric(keyMap);
if (func_m_list == nullptr)
{
continue;
}
for (auto func_m : *func_m_list)
{
bool alreadyRecord = false;
for (int i = 0; i < func_m->variables_size(); ++i)
{
if (func_m->variables(i).name() == record->first)
{
alreadyRecord = true;
break;
}
}
if (alreadyRecord)
{
continue;
}
auto varInfo_m = func_m->add_variables();
varInfo_m->set_name(record->first);
varInfo_m->set_type((IGC_METRICS::VarInfo_VarType)varInfo->type);
varInfo_m->set_memoryaccess((IGC_METRICS::VarInfo_MemAccess)varInfo->memoryAccess);
varInfo_m->set_addrmodel((IGC_METRICS::VarInfo_AddressModel)varInfo->addrModel);
varInfo_m->set_size(varInfo->size);
varInfo_m->set_promoted2grf(varInfo->promoted2GRF);
varInfo_m->set_isspill(varInfo->isSpill);
varInfo_m->set_isuniform(varInfo->isUniform);
varInfo_m->set_isconst(varInfo->isConst);
auto bcInfo = varInfo_m->mutable_bc_stats();
bcInfo->set_count(varInfo->bc_count);
bcInfo->set_samebank(varInfo->bc_sameBank);
bcInfo->set_twosrc(varInfo->bc_twoSrc);
if (varInfo->srcFilename == nullptr)
{
continue;
}
auto codeRef = varInfo_m->mutable_varloc();
FillCodeRef(codeRef, varInfo->srcFilename, varInfo->lineNb);
}
}
#endif
}
@ -343,71 +282,337 @@ namespace IGCMetrics
#endif
}
void IGCMetricImpl::CollectLoopCyclomaticComplexity(
llvm::Function* pFunc,
int LoopCyclomaticComplexity,
int LoopCyclomaticComplexity_Max)
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
IGC_METRICS::Function* func_metric = GetFuncMetric(pFunc);
if (func_metric)
{
auto costmodel = func_metric->mutable_costmodel_stats();
auto simd16cost = costmodel->mutable_simd16();
simd16cost->set_loopcyclomaticcomplexity(LoopCyclomaticComplexity);
simd16cost->set_loopcyclomaticcomplexity_max(LoopCyclomaticComplexity_Max);
simd16cost->set_loopcyclomaticcomplexity_status(
LoopCyclomaticComplexity < LoopCyclomaticComplexity_Max ?
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_OK :
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_BAD);
}
#endif
}
void IGCMetricImpl::CollectNestedLoopsWithMultipleExits(
llvm::Function* pFunc,
float NestedLoopsWithMultipleExitsRatio,
float NestedLoopsWithMultipleExitsRatio_Max)
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
IGC_METRICS::Function* func_metric = GetFuncMetric(pFunc);
if (func_metric)
{
auto costmodel = func_metric->mutable_costmodel_stats();
auto simd16cost = costmodel->mutable_simd16();
simd16cost->set_nestedloopswithmultipleexitsratio(NestedLoopsWithMultipleExitsRatio);
simd16cost->set_nestedloopswithmultipleexitsratio_max(NestedLoopsWithMultipleExitsRatio_Max);
simd16cost->set_nestedloopswithmultipleexitsratio_status(
NestedLoopsWithMultipleExitsRatio < NestedLoopsWithMultipleExitsRatio_Max ?
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_OK :
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_BAD);
}
#endif
}
void IGCMetricImpl::CollectLongStridedLdStInLoop(
llvm::Function* pFunc,
llvm::Loop* pProblematicLoop,
int LongStridedLdStInLoop_LdCnt,
int LongStridedLdStInLoop_StCnt,
int LongStridedLdStInLoop_MaxCntLdOrSt)
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
IGC_METRICS::Function* func_metric = GetFuncMetric(pFunc);
if (func_metric)
{
auto costmodel = func_metric->mutable_costmodel_stats();
auto simd16cost = costmodel->mutable_simd16();
if (pProblematicLoop == nullptr)
{
simd16cost->set_longstridedldstinloop_status(
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_OK);
}
else
{
simd16cost->set_longstridedldstinloop_status(
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_BAD);
simd16cost->set_longstridedldstinloop_ldcnt(LongStridedLdStInLoop_LdCnt);
simd16cost->set_longstridedldstinloop_stcnt(LongStridedLdStInLoop_StCnt);
simd16cost->set_longstridedldstinloop_maxcntldorst(LongStridedLdStInLoop_MaxCntLdOrSt);
FillCodeRef(simd16cost->mutable_longstridedldstinloop_problematicloop(),
pProblematicLoop->getStartLoc());
}
}
#endif
}
void IGCMetricImpl::CollectIsGeminiLakeWithDoubles(
llvm::Function* pFunc,
bool IsGeminiLakeWithDoubles)
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
IGC_METRICS::Function* func_metric = GetFuncMetric(pFunc);
if (func_metric)
{
auto costmodel = func_metric->mutable_costmodel_stats();
auto simd16cost = costmodel->mutable_simd16();
simd16cost->set_isgeminilakewithdoubles_status(IsGeminiLakeWithDoubles ?
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_OK :
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_BAD);
}
#endif
}
void IGCMetricImpl::FinalizeStats()
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
UpdateLoopsInfo();
UpdateModelCost();
#endif
}
void IGCMetricImpl::CollectDataFromDebugInfo(IGC::DebugInfoData* pDebugInfo, IGC::DbgDecoder* pDebugDecoder)
{
if (!Enable()) return;
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
oclProgram.set_device((IGC_METRICS::DeviceType)
pDebugInfo->m_pShader->m_Platform->getPlatformInfo().eProductFamily);
llvm::DenseMap<llvm::Function*, IGC::VISAModule*>* pListFuncData =
&pDebugInfo->m_VISAModules;
llvm::DenseMap< llvm::DIVariable*, IGC_METRICS::VarInfo*> var_db2metric;
for (auto pListFuncData_it = pListFuncData->begin();
pListFuncData_it != pListFuncData->end(); ++pListFuncData_it)
{
llvm::Function* pFunc = pListFuncData_it->first;
IGC::VISAModule* vISAData = pListFuncData_it->second;
//IGC::ScalarVisaModule* scalarVM = llvm::dyn_cast<IGC::ScalarVisaModule>(vISAData);
#ifdef DEBUG_METRIC
std::printf("\nList of symbols:\n");
for (auto it_dbgInfo = pDebugInfo->m_FunctionSymbols[pFunc].begin();
it_dbgInfo != pDebugInfo->m_FunctionSymbols[pFunc].end(); ++it_dbgInfo)
{
std::printf("pointer{%p} key{%s} val{%s}\n",
it_dbgInfo->first,
it_dbgInfo->first->getName().str().c_str(), it_dbgInfo->second->getName().getCString());
it_dbgInfo->first->dump();
}
#endif
const llvm::Value* pVal = nullptr;
llvm::MDNode* pNode = nullptr;
// Iterate over all instruction ported to vISA
for (auto instr = vISAData->begin(); instr != vISAData->end(); ++instr)
{
llvm::DebugLoc* dbLoc = nullptr;
if (const llvm::DbgDeclareInst* pDbgAddrInst =
llvm::dyn_cast<llvm::DbgDeclareInst>(*instr))
{
// Get : call void @llvm.dbg.value
dbLoc = (llvm::DebugLoc*) & pDbgAddrInst->getDebugLoc();
pVal = pDbgAddrInst->getAddress();
pNode = pDbgAddrInst->getVariable();
}
else if (const llvm::DbgValueInst* pDbgValInst =
llvm::dyn_cast<llvm::DbgValueInst>(*instr))
{
// Get : call void @llvm.dbg.value
// Avoid undef values in metadata
{
llvm::MetadataAsValue* mdAv = llvm::dyn_cast<llvm::MetadataAsValue>(pDbgValInst->getArgOperand(0));
if (mdAv != nullptr)
{
llvm::ValueAsMetadata* vAsMD = llvm::dyn_cast<llvm::ValueAsMetadata>(mdAv->getMetadata());
if (vAsMD != nullptr &&
llvm::isa<llvm::UndefValue>(vAsMD->getValue()))
{
continue;
}
}
}
dbLoc = (llvm::DebugLoc*) & pDbgValInst->getDebugLoc();
pVal = pDbgValInst->getValue();
pNode = pDbgValInst->getVariable();
}
else
{
continue;
}
// Extract debuginfo variable data
llvm::DIVariable* diVar = llvm::cast<llvm::DIVariable>(pNode);
std::string varName = diVar->getName().str();
// Get CVariable data for this user variable
auto cvar = pDebugInfo->getMapping(*pFunc, pVal);
if (cvar == nullptr)
{
// If not found check in whole shader data
cvar = pDebugInfo->m_pShader->GetSymbol((llvm::Value*)pVal);
}
IGC_METRICS::Function* func_m = GetFuncMetric(*instr);
#ifdef DEBUG_METRIC
std::printf("\ninstr (varname:%s, pointer:%p) :\n", varName.c_str(), pVal);
(*instr)->dump();
#endif
IGC_METRICS::VarInfo* varInfo_m = nullptr;
if (var_db2metric.find(diVar) != var_db2metric.end())
{
// Already added user variable
// It is for case when one of the user variables
// is referenced in many places and requires new registers
varInfo_m = var_db2metric[diVar];
}
else
{
// New user variable
varInfo_m = func_m->add_variables();
varInfo_m->set_name(varName);
varInfo_m->set_size(cvar->GetSize());
varInfo_m->set_type((IGC_METRICS::VarInfo_VarType)cvar->GetType());
FillCodeRef(varInfo_m->mutable_varloc(),
diVar);
var_db2metric.insert(std::pair{ diVar, varInfo_m });
}
// Loop in case when we have simd32 splitted into two simd16
auto varLocList = vISAData->GetVariableLocation(*instr);
for (auto varLoc = varLocList.begin(); varLoc != varLocList.end(); ++varLoc)
{
const auto* varInfo = vISAData->getVarInfo(*pDebugDecoder, varLoc->GetRegister());
auto varInfo_reg_m = varInfo_m->add_reg();
varInfo_reg_m->set_addrmodel(varLoc->IsInGlobalAddrSpace() ?
IGC_METRICS::VarInfo_AddressModel::VarInfo_AddressModel_GLOBAL :
IGC_METRICS::VarInfo_AddressModel::VarInfo_AddressModel_LOCAL);
varInfo_reg_m->set_promoted2grf(varLoc->IsRegister());
//varInfo_m->set_memoryaccess((IGC_METRICS::VarInfo_MemAccess)varInfo->memoryAccess);
if (varInfo != nullptr)
{
// check if any?
varInfo_reg_m->set_isspill(varInfo->lrs[0].isSpill());
varInfo_reg_m->set_liverangestart(varInfo->lrs[0].start);
varInfo_reg_m->set_liverangeend(varInfo->lrs[0].end);
}
varInfo_reg_m->set_isuniform(cvar->IsUniform());
varInfo_reg_m->set_isconst(cvar->IsImmediate());
}
}
}
#endif
}
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
void IGCMetricImpl::UpdateCollectInstructions(llvm::Function* func)
void IGCMetricImpl::UpdateModelCost()
{
for (auto bb = func->begin(); bb != func->end(); ++bb)
// Function which checks the overall model cost of kernel status for SIMD16 and SIMD32
auto isOkStatus = [](IGC_METRICS::CostModelStats_CostStatus Status)
{
for (auto inst_i = bb->begin(); inst_i != bb->end(); ++inst_i)
return Status !=
IGC_METRICS::CostModelStats_CostStatus::CostModelStats_CostStatus_BAD;
};
for (auto func_m_i = map_Func.begin(); func_m_i != map_Func.end(); ++func_m_i)
{
auto func_m = func_m_i->second;
if (func_m->has_costmodel_stats())
{
llvm::DILocation* dbLoc = inst_i->getDebugLoc();
auto costmodel = func_m->mutable_costmodel_stats();
if (dbLoc)
if (costmodel->has_simd16())
{
MFuncList* func_m_list = nullptr;
HashKey key = GetHash(dbLoc);
llvm::DISubprogram* subProg = func->getSubprogram();
auto simd16 = costmodel->mutable_simd16();
if (map_InstrLoc2Func.find(key) == map_InstrLoc2Func.end())
{
func_m_list = new MFuncList();
func_m_list->push_back(map_Func[subProg]);
map_InstrLoc2Func.insert({ key, func_m_list });
}
else
{
func_m_list = map_InstrLoc2Func[key];
if (std::find(func_m_list->begin(),
func_m_list->end(), map_Func[subProg]) == func_m_list->end())
{
func_m_list->push_back(map_Func[subProg]);
}
}
simd16->set_overallstatus(
isOkStatus(simd16->loopcyclomaticcomplexity_status()) &&
isOkStatus(simd16->nestedloopswithmultipleexitsratio_status()) &&
isOkStatus(simd16->longstridedldstinloop_status()) &&
isOkStatus(simd16->isgeminilakewithdoubles_status()));
}
if (costmodel->has_simd32())
{
auto simd32 = costmodel->mutable_simd32();
simd32->set_overallstatus(
isOkStatus(simd32->instructioncount_status()) &&
isOkStatus(simd32->threadgroupsize_status()) &&
isOkStatus(simd32->threadgroupsizehint_status()) &&
isOkStatus(simd32->subgroupfunctionarepresent_status()) &&
isOkStatus(simd32->gen9orgen10withieeesqrtordivfunc_status()) &&
isOkStatus(simd32->nonuniformloop_status()));
}
}
}
}
void IGCMetricImpl::UpdateCollectInstructions(llvm::Function* func)
{
}
void IGCMetricImpl::CollectLoop(llvm::Loop* loop)
{
if (loop->getStartLoc() && loop->getStartLoc()->getScope())
{
if (map_Loops.find(loop->getStartLoc()->getScope()) == map_Loops.end())
{
auto func_m_list = GetFuncMetric(loop);
if (func_m_list == nullptr)
auto func_m = GetFuncMetric(loop);
if (func_m == nullptr)
{
return;
}
for (auto func_m : *func_m_list)
{
auto cfg_stats = func_m->mutable_cfg_stats();
auto loop_m = cfg_stats->add_loops_stats();
auto loopLoc = loop_m->mutable_looploc();
FillCodeRef(loopLoc, loop->getStartLoc());
loop_m->set_nestinglevel(loop->getLoopDepth());
auto cfg_stats = func_m->mutable_cfg_stats();
auto loop_m = cfg_stats->add_loops_stats();
auto loopLoc = loop_m->mutable_looploc();
map_Loops.insert({ loop->getStartLoc()->getScope(), loop_m });
}
FillCodeRef(loopLoc, loop->getStartLoc());
loop_m->set_nestinglevel(loop->getLoopDepth());
map_Loops.insert({ loop->getStartLoc()->getScope(), loop_m });
}
}
}
@ -467,7 +672,7 @@ namespace IGCMetrics
func_m->functioncalls(i).name()))
{
// For case if we have already record created
callFunc_m = (IGC_METRICS::FuncCalls*)&func_m->functioncalls(i);
callFunc_m = (IGC_METRICS::FuncCalls*) & func_m->functioncalls(i);
callFunc_m->set_count(callFunc_m->count() + 1);
break;
}
@ -515,71 +720,32 @@ namespace IGCMetrics
return instCount;
}
MFuncList* IGCMetricImpl::GetFuncMetric(HashKey Key)
IGC_METRICS::Function* IGCMetricImpl::GetFuncMetric(const llvm::Instruction* const pInstr)
{
if (Key == HashKey_NULL)
return map_Func[
pInstr->getDebugLoc()->getScope()->getSubprogram()];
}
IGC_METRICS::Function* IGCMetricImpl::GetFuncMetric(llvm::Instruction* pInstr)
{
return GetFuncMetric(pInstr->getParent()->getParent());
}
IGC_METRICS::Function* IGCMetricImpl::GetFuncMetric(llvm::Loop* pLoop)
{
return GetFuncMetric(pLoop->getBlocks()[0]->getParent());
}
IGC_METRICS::Function* IGCMetricImpl::GetFuncMetric(llvm::Function* pFunc)
{
if (map_Func.find(pFunc->getSubprogram()) == map_Func.end())
{
return nullptr;
}
if (map_InstrLoc2Func.find(Key) == map_InstrLoc2Func.end())
else
{
return nullptr;
return map_Func[pFunc->getSubprogram()];
}
return map_InstrLoc2Func[Key];
}
MFuncList* IGCMetricImpl::GetFuncMetric(llvm::Instruction* pInstr)
{
return GetFuncMetric(GetHash(pInstr->getDebugLoc()));
}
MFuncList* IGCMetricImpl::GetFuncMetric(llvm::Loop* pLoop)
{
return GetFuncMetric(GetHash(pLoop->getStartLoc()));
}
HashKey IGCMetricImpl::GetHash(llvm::DILocation* Loc)
{
if (Loc == nullptr || Loc->getDirectory().empty() || Loc->getFilename().empty())
{
return HashKey_NULL;
}
return GetHash(
GetFullPath(Loc->getDirectory().str(), Loc->getFilename().str()),
Loc->getLine());
}
HashKey IGCMetricImpl::GetHash(const std::string& dir, const std::string& fileName, int line)
{
return GetHash(GetFullPath(dir, fileName), line);
}
HashKey IGCMetricImpl::GetHash(const char* dir, const char* fileName, int line)
{
if (dir == nullptr || fileName == nullptr)
{
return HashKey_NULL;
}
return GetHash(std::string(dir), std::string(fileName), line);
}
HashKey IGCMetricImpl::GetHash(const char* filePathName, int line)
{
if (filePathName == nullptr)
{
return HashKey_NULL;
}
return GetHash(std::string(filePathName), line);
}
HashKey IGCMetricImpl::GetHash(const std::string& filePathName, int line)
{
if (filePathName.length() == 0 && line == 0)
{
return HashKey_NULL;
}
std::hash<std::string> hasher;
return hasher(filePathName + std::to_string(line));
}
void IGCMetricImpl::FillCodeRef(IGC_METRICS::CodeRef* codeRef, llvm::DISubprogram* Loc)
@ -602,6 +768,16 @@ namespace IGCMetrics
Loc->getLine());
}
void IGCMetricImpl::FillCodeRef(IGC_METRICS::CodeRef* codeRef, llvm::DIVariable* Var)
{
if (Var == nullptr || Var->getDirectory().empty() || Var->getFilename().empty())
{
return;
}
FillCodeRef(codeRef, GetFullPath(Var->getDirectory().str(), Var->getFilename().str()),
Var->getLine());
}
void IGCMetricImpl::FillCodeRef(IGC_METRICS::CodeRef* codeRef, const std::string& filePathName, int line)
{
if (filePathName.empty())

View File

@ -8,6 +8,7 @@ SPDX-License-Identifier: MIT
#include "common/LLVMWarningsPush.hpp"
#include <llvm/IR/Module.h>
#include <llvm/IR/Instructions.h>
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include <llvm/Analysis/LoopInfo.h>
@ -16,24 +17,23 @@ SPDX-License-Identifier: MIT
#include <3d/common/iStdLib/types.h>
#include <common/shaderHash.hpp>
#include "KernelInfo.h"
#include "IGCMetric.h"
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
#include <google/protobuf/util/json_util.h>
#include <Metrics/proto_schema/igc_metrics.pb.h>
#include <Metrics/proto_schema/instruction_stats.pb.h>
#define HashKey size_t
#define HashKey_NULL 0
#endif // IGC_METRICS
#include "Compiler/CISACodeGen/CVariable.hpp"
#include <Compiler/CISACodeGen/DebugInfoData.hpp>
#include <DebugInfo/VISADebugDecoder.hpp>
#pragma once
namespace IGCMetrics
{
#ifdef IGC_METRICS__PROTOBUF_ATTACHED
typedef std::vector<IGC_METRICS::Function*> MFuncList;
#endif
class IGCMetricImpl
{
private:
@ -42,9 +42,6 @@ namespace IGCMetrics
IGC_METRICS::Program oclProgram;
// Helpers
// Map all instruction line number, filepath to Function
// { Key: Hash(fullPathFile+LineNb), Value:Function list containing this instruction }
std::map<HashKey, MFuncList*> map_InstrLoc2Func;
// Map Function debuginfo to Function metrics
std::map<llvm::DISubprogram*, IGC_METRICS::Function*> map_Func;
// helpers for emulated calls
@ -58,23 +55,21 @@ namespace IGCMetrics
void GetFunctionCalls(IGC_METRICS::Function* func_m, llvm::Function& func);
inline MFuncList* GetFuncMetric(llvm::Instruction* pInstr);
inline MFuncList* GetFuncMetric(llvm::Loop* pLoop);
inline MFuncList* GetFuncMetric(HashKey Key);
inline IGC_METRICS::Function* GetFuncMetric(const llvm::Instruction* const pInstr);
inline IGC_METRICS::Function* GetFuncMetric(llvm::Instruction* pInstr);
inline IGC_METRICS::Function* GetFuncMetric(llvm::Loop* pLoop);
inline IGC_METRICS::Function* GetFuncMetric(llvm::Function* pFunc);
void CollectInstructions(llvm::Module* pModule);
void UpdateLoopsInfo();
void UpdateModelCost();
void CollectLoop(llvm::Loop* loop);
static HashKey GetHash(const char* dir, const char* fileName, int line);
static HashKey GetHash(const char* filePathName, int line);
static HashKey GetHash(const std::string& dir, const std::string& fileName, int line);
static HashKey GetHash(const std::string& filePathName, int line);
static HashKey GetHash(llvm::DILocation* Loc);
static inline void FillCodeRef(IGC_METRICS::CodeRef* codeRef, llvm::DISubprogram* Loc);
static inline void FillCodeRef(IGC_METRICS::CodeRef* codeRef, llvm::DILocation* Loc);
static inline void FillCodeRef(IGC_METRICS::CodeRef* codeRef, llvm::DIVariable* Var);
static inline void FillCodeRef(IGC_METRICS::CodeRef* codeRef, const std::string& filePathName, int line);
static inline const std::string GetFullPath(const char* dir, const char* fileName);
@ -101,6 +96,29 @@ namespace IGCMetrics
void CollectRegStats(KERNEL_INFO* vISAstats);
void CollectLoopCyclomaticComplexity(
llvm::Function* pFunc,
int LoopCyclomaticComplexity,
int LoopCyclomaticComplexity_Max);
void CollectNestedLoopsWithMultipleExits(
llvm::Function* pFunc,
float NestedLoopsWithMultipleExitsRatio,
float NestedLoopsWithMultipleExitsRatio_Max);
void CollectLongStridedLdStInLoop(
llvm::Function* pFunc,
llvm::Loop* pProblematicLoop,
int LongStridedLdStInLoop_LdCnt,
int LongStridedLdStInLoop_StCnt,
int LongStridedLdStInLoop_MaxCntLdOrSt);
void CollectIsGeminiLakeWithDoubles(
llvm::Function* pFunc,
bool IsGeminiLakeWithDoubles);
void CollectDataFromDebugInfo(IGC::DebugInfoData* pDebugInfo, IGC::DbgDecoder* pDebugDecoder);
void FinalizeStats();
void OutputMetrics();

View File

@ -0,0 +1,88 @@
/*========================== begin_copyright_notice ============================
Copyright (C) 2021 Intel Corporation
SPDX-License-Identifier: MIT
============================= end_copyright_notice ===========================*/
syntax = "proto3";
import "Metrics/proto_schema/code_reference.proto";
package IGC_METRICS;
message CostModelStats
{
enum CostStatus
{
NOT_CHECK = 0;
OK = 1;
BAD = 2;
}
message CostSIMD16
{
CostStatus LoopCyclomaticComplexity_Status = 1;
int32 LoopCyclomaticComplexity = 2;
int32 LoopCyclomaticComplexity_Max = 3;
CostStatus NestedLoopsWithMultipleExitsRatio_Status = 4;
float NestedLoopsWithMultipleExitsRatio = 5;
float NestedLoopsWithMultipleExitsRatio_Max = 6;
// If LdCnt OR StCnt is bigger than MaxCntLdOrSt
// then LongStridedLdStInLoop_Status is BAD
CostStatus LongStridedLdStInLoop_Status = 7;
// If LongStridedLdStInLoop_Status is BAD
// then data below will have the information
// for problematic loop
int32 LongStridedLdStInLoop_LdCnt = 8;
int32 LongStridedLdStInLoop_StCnt = 9;
int32 LongStridedLdStInLoop_MaxCntLdOrSt = 10;
CodeRef LongStridedLdStInLoop_ProblematicLoop = 11;
// If this flag is true - then we don't have GeminiLake
// or existing doubles in shader
CostStatus IsGeminiLakeWithDoubles_Status = 12;
// If we met all requirements for SIMD 16 then set true
bool OverallStatus = 13;
}
message CostSIMD32
{
enum LoopCount
{
LIKELY_SMALL = 0;
LOOPCOUNT_LIKELY_LARGE = 1;
LOOPCOUNT_UNKNOWN = 2;
}
CostStatus InstructionCount_Status = 1;
int32 InstructionCount = 2;
int32 InstructionCount_Max = 3;
CostStatus ThreadGroupSize_Status = 4;
int32 ThreadGroupSize = 5;
int32 ThreadGroupSize_Max = 6;
CostStatus ThreadGroupSizeHint_Status = 7;
int32 ThreadGroupSizeHint = 8;
int32 ThreadGroupSizeHint_Max = 9;
CostStatus SubgroupFunctionArePresent_Status = 10;
CostStatus Gen9OrGen10WithIEEESqrtOrDivFunc_Status = 11;
CostStatus NonUniformLoop_Status = 12;
LoopCount NonUniformLoop_Count = 13;
CodeRef NonUniformLoop_ProblematicLoop = 14;
// If we met all requirements for SIMD 32 then set true
bool OverallStatus = 15;
}
CostSIMD16 simd16 = 1;
CostSIMD32 simd32 = 2;
}

View File

@ -18,6 +18,7 @@ import "Metrics/proto_schema/mem_alloc_stats.proto";
import "Metrics/proto_schema/code_reference.proto";
import "Metrics/proto_schema/local_reg_stats.proto";
import "Metrics/proto_schema/cfg_stats.proto";
import "Metrics/proto_schema/cost_model_stats.proto";
package IGC_METRICS;
@ -51,4 +52,6 @@ message Function
LocalRegStats local_reg_stats = 11;
CFGStats cfg_stats = 12;
CostModelStats costModel_stats = 13;
}

View File

@ -21,18 +21,17 @@ message VarInfo {
Type_W = 3; // signed word integer
Type_UB = 4; // unsigned byte integer
Type_B = 5; // signed byte integer
Type_F = 6; // signed single precision
Type_VF = 7; // 32-bit restricted Vector Float
Type_DF = 6;
Type_F = 7; // signed single precision
Type_V = 8; // 32-bit halfbyte integer Vector
Type_DF = 9;
Type_VF = 9; // 32-bit restricted Vector Float
Type_BOOL = 10;
Type_UV = 11;
Type_Q = 12; // 64-bit signed integer
Type_UQ = 13; // 64-bit unsigned integer
Type_UQ = 11; // 64-bit unsigned integer
Type_UV = 12;
Type_Q = 13; // 64-bit signed integer
Type_HF = 14; // half float
Type_NF = 15; // native float (only used by plane macro)
Type_BF = 16; // bfloat16 (used in mov only)
Type_UNDEF = 17;
Type_BF = 15; // bfloat16 (used in mov only)
Type_UNDEF = 16;
}
enum AddressModel {
@ -48,6 +47,18 @@ message VarInfo {
ATOMIC = 4;
}
message RegUsage {
bool promoted2GRF = 1;
AddressModel addrModel = 2;
MemAccess memoryAccess = 3;
bool isSpill = 4;
bool isUniform = 5;
bool isConst = 6;
int32 liveRangeStart = 7;
int32 liveRangeEnd = 8;
}
message BankConflictInfo {
int32 count = 1;
int32 sameBank = 2;
@ -57,13 +68,9 @@ message VarInfo {
optional string name = 1;
int32 size = 2;
VarType type = 3;
bool promoted2GRF = 4;
AddressModel addrModel = 5;
MemAccess memoryAccess = 6;
bool isSpill = 7;
bool isUniform = 8;
bool isConst = 9;
BankConflictInfo bc_stats = 10;
repeated RegUsage reg = 4;
optional CodeRef varLoc = 11;
}
BankConflictInfo bc_stats = 5;
optional CodeRef varLoc = 6;
}

View File

@ -50,6 +50,7 @@ list(APPEND IGC_METRICS_HDRS "Metrics/IGCMetricImpl.h")
add_library(igc_metric STATIC ${IGC_METRICS_SRCS} ${IGC_METRICS_HDRS})
add_dependencies(igc_metric intrinsics_gen)
add_dependencies(igc_metric ${IGC_BUILD__PROJ__GenISAIntrinsics})
if(IGC_METRICS)
target_link_libraries(igc_metric protobuf::libprotobuf)

View File

@ -14,6 +14,8 @@ SPDX-License-Identifier: MIT
#include <string.h>
#include <stdio.h>
#ifndef MEMCPY_S
#define MEMCPY_S
typedef int errno_t;
inline errno_t memcpy_s( void *dst, size_t numberOfElements, const void *src, size_t count )
{
@ -28,9 +30,10 @@ inline errno_t memcpy_s( void *dst, size_t numberOfElements, const void *src, si
memcpy( dst, src, count );
return 0;
}
#endif
inline errno_t fopen_s( FILE** pFile, const char* filename, const char *mode )
{
{
if( pFile == NULL )
{
return EINVAL;

View File

@ -498,50 +498,9 @@ void* VISAKernelImpl::encodeAndEmit(unsigned int& binarySize)
if (getOptions()->getOption(vISA_GenerateKernelInfo))
{
auto kernel = getKernel();
m_kernelInfo = new KERNEL_INFO();
m_kernelInfo->name = kernel->getName();
BB_LIST_ITER bbItEnd = kernel->fg.end();
for (auto bbIt = kernel->fg.begin();
bbIt != bbItEnd;
bbIt++)
{
G4_BB* bb = (*bbIt);
for (auto inst : bb->getInstList())
{
auto loc = inst->getLocation();
if (loc == nullptr) continue;
auto dstRg = inst->getDst();
if (dstRg == nullptr) continue;
auto decl = dstRg->getTopDcl();
if (decl == nullptr) continue;
//auto reg = decl->getRegVar();
VarInfo* varInfo = nullptr;
if ((varInfo = m_kernelInfo->AddVarInfo(decl->getName())) != nullptr)
{
varInfo->lineNb = loc->getLineNo();
varInfo->srcFilename = loc->getSrcFilename();
varInfo->isSpill = decl->isSpilled();
// fixed values == const variable?
varInfo->isConst = dstRg->isImm();
varInfo->promoted2GRF = dstRg->isGreg();
varInfo->size = decl->getByteSize();
varInfo->type = (short)decl->getElemType();
//varInfo->isUniform = N\A
//varInfo->addrModel = N\A
//varInfo->memoryAccess = N\A
//varInfo->bc_count = N\A
//varInfo->bc_sameBank = N\A
//varInfo->bc_twoSrc = N\A
}
}
}
//auto kernel = getKernel();
//m_kernelInfo = new KERNEL_INFO();
// TODO check if this will be needed anymore
}
if (m_options->getOption(vISA_outputToFile))

View File

@ -19,6 +19,8 @@ SPDX-License-Identifier: MIT
#include <errno.h>
#include "common/secure_string.h"
#ifndef MEMCPY_S
#define MEMCPY_S
typedef int errno_t;
static errno_t memcpy_s(void* dst, size_t numberOfElements, const void* src, size_t count)
{
@ -37,6 +39,7 @@ static errno_t memcpy_s(void* dst, size_t numberOfElements, const void* src, siz
return 0;
}
#endif
#endif
/* stdio.h portability code end */

View File

@ -49,8 +49,7 @@ public:
class KERNEL_INFO
{
public:
std::map<std::string, VarInfo*> variables;
std::string name;
std::map<int, VarInfo*> variables;
KERNEL_INFO() { }
~KERNEL_INFO()
@ -61,19 +60,6 @@ public:
}
variables.clear();
}
VarInfo* AddVarInfo(const char* name)
{
// Add only not existing item
if (variables.find(name) == variables.end())
{
VarInfo* varInfo = new VarInfo();
variables.insert({name, varInfo });
return varInfo;
}
// If exists, return nullptr
return nullptr;
}
};
#endif