@@ -20,7 +20,6 @@ SPDX-License-Identifier: MIT
2020#include < fstream>
2121#include < mutex>
2222#include < numeric>
23- #include < chrono>
2423
2524#include " AdaptorCommon/customApi.hpp"
2625#include " AdaptorOCL/OCL/LoadBuffer.h"
@@ -125,7 +124,6 @@ SPDX-License-Identifier: MIT
125124#if !defined(_WIN32)
126125# define strtok_s strtok_r
127126# define _strdup strdup
128- # define _snprintf snprintf
129127#endif
130128
131129#include " common/LLVMWarningsPush.hpp"
@@ -1128,6 +1126,13 @@ void dumpOCLProgramBinary(OpenCLProgramContext &Ctx, const char *binaryOutput,
11281126 dumpOCLProgramBinary (name.str ().data (), binaryOutput, binarySize);
11291127}
11301128
1129+ static std::unique_ptr<llvm::MemoryBuffer> GetGenericModuleBuffer ()
1130+ {
1131+ char Resource[5 ] = {' -' };
1132+ _snprintf_s (Resource, sizeof (Resource), sizeof (Resource), " #%d" , OCL_BC);
1133+ return std::unique_ptr<llvm::MemoryBuffer>{llvm::LoadBufferFromResource (Resource, " BC" )};
1134+ }
1135+
11311136static void WriteSpecConstantsDump (
11321137 const STB_TranslateInputArgs* pInputArgs,
11331138 QWORD hash)
@@ -1410,17 +1415,111 @@ bool TranslateBuildSPMD(
14101415 splitter.setSplittedModuleInOCLContext ();
14111416 }
14121417
1418+ std::unique_ptr<llvm::Module> BuiltinGenericModule = nullptr ;
1419+ std::unique_ptr<llvm::Module> BuiltinSizeModule = nullptr ;
1420+ std::unique_ptr<llvm::MemoryBuffer> pGenericBuffer = nullptr ;
1421+ std::unique_ptr<llvm::MemoryBuffer> pSizeTBuffer = nullptr ;
1422+ {
1423+ // IGC has two BIF Modules:
1424+ // 1. kernel Module (pKernelModule)
1425+ // 2. BIF Modules:
1426+ // a) generic Module (BuiltinGenericModule)
1427+ // b) size Module (BuiltinSizeModule)
1428+ //
1429+ // OCL builtin types, such as clk_event_t/queue_t, etc., are struct (opaque) types. For
1430+ // those types, its original names are themselves; the derived names are ones with
1431+ // '.<digit>' appended to the original names. For example, clk_event_t is the original
1432+ // name, its derived names are clk_event_t.0, clk_event_t.1, etc.
1433+ //
1434+ // When llvm reads in multiple modules, say, M0, M1, under the same llvmcontext, if both
1435+ // M0 and M1 has the same struct type, M0 will have the original name and M1 the derived
1436+ // name for that type. For example, clk_event_t, M0 will have clk_event_t, while M1 will
1437+ // have clk_event_t.2 (number is arbitrary). After linking, those two named types should be
1438+ // mapped to the same type, otherwise, we could have type-mismatch (for example, OCL GAS
1439+ // builtin_functions tests will assertion fail during inlining due to type-mismatch). Furthermore,
1440+ // when linking M1 into M0 (M0 : dstModule, M1 : srcModule), the final type is the type
1441+ // used in M0.
1442+
1443+ // Load the builtin module - Generic BC
1444+ // Load the builtin module - Generic BC
1445+ {
1446+ COMPILER_TIME_START (&oclContext, TIME_OCL_LazyBiFLoading);
1447+
1448+ pGenericBuffer = GetGenericModuleBuffer ();
1449+
1450+ if (pGenericBuffer == NULL )
1451+ {
1452+ SetErrorMessage (" Error loading the Generic builtin resource" , *pOutputArgs);
1453+ return false ;
1454+ }
1455+
1456+ llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
1457+ getLazyBitcodeModule (pGenericBuffer->getMemBufferRef (), *oclContext.getLLVMContext ());
1458+
1459+ if (llvm::Error EC = ModuleOrErr.takeError ())
1460+ {
1461+ std::string error_str = " Error lazily loading bitcode for generic builtins,"
1462+ " is bitcode the right version and correctly formed?" ;
1463+ SetErrorMessage (error_str, *pOutputArgs);
1464+ return false ;
1465+ }
1466+ else
1467+ {
1468+ BuiltinGenericModule = std::move (*ModuleOrErr);
1469+ }
1470+
1471+ if (BuiltinGenericModule == NULL )
1472+ {
1473+ SetErrorMessage (" Error loading the Generic builtin module from buffer" , *pOutputArgs);
1474+ return false ;
1475+ }
1476+ COMPILER_TIME_END (&oclContext, TIME_OCL_LazyBiFLoading);
1477+ }
1478+
1479+ // Load the builtin module - pointer depended
1480+ {
1481+ char ResNumber[5 ] = { ' -' };
1482+ switch (PtrSzInBits)
1483+ {
1484+ case 32 :
1485+ _snprintf_s (ResNumber, sizeof (ResNumber), 5 , " #%d" , OCL_BC_32);
1486+ break ;
1487+ case 64 :
1488+ _snprintf_s (ResNumber, sizeof (ResNumber), 5 , " #%d" , OCL_BC_64);
1489+ break ;
1490+ default :
1491+ IGC_ASSERT_MESSAGE (0 , " Unknown bitness of compiled module" );
1492+ }
1493+
1494+ // the MemoryBuffer becomes owned by the module and does not need to be managed
1495+ pSizeTBuffer.reset (llvm::LoadBufferFromResource (ResNumber, " BC" ));
1496+ IGC_ASSERT_MESSAGE (pSizeTBuffer, " Error loading builtin resource" );
1497+
1498+ llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr =
1499+ getLazyBitcodeModule (pSizeTBuffer->getMemBufferRef (), *oclContext.getLLVMContext ());
1500+ if (llvm::Error EC = ModuleOrErr.takeError ())
1501+ IGC_ASSERT_MESSAGE (0 , " Error lazily loading bitcode for size_t builtins" );
1502+ else
1503+ BuiltinSizeModule = std::move (*ModuleOrErr);
1504+
1505+ IGC_ASSERT_MESSAGE (BuiltinSizeModule, " Error loading builtin module from buffer" );
1506+ }
1507+
1508+ BuiltinGenericModule->setDataLayout (BuiltinSizeModule->getDataLayout ());
1509+ BuiltinGenericModule->setTargetTriple (BuiltinSizeModule->getTargetTriple ());
1510+ }
1511+
14131512 oclContext.getModuleMetaData ()->csInfo .forcedSIMDSize |= IGC_GET_FLAG_VALUE (ForceOCLSIMDWidth);
14141513
14151514 try
14161515 {
14171516 if (llvm::StringRef (oclContext.getModule ()->getTargetTriple ()).startswith (" spir" ))
14181517 {
1419- IGC::UnifyIRSPIR (&oclContext);
1518+ IGC::UnifyIRSPIR (&oclContext, std::move (BuiltinGenericModule), std::move (BuiltinSizeModule) );
14201519 }
14211520 else // not SPIR
14221521 {
1423- IGC::UnifyIROCL (&oclContext);
1522+ IGC::UnifyIROCL (&oclContext, std::move (BuiltinGenericModule), std::move (BuiltinSizeModule) );
14241523 }
14251524
14261525 if (oclContext.HasError ())
0 commit comments