1 /*========================== begin_copyright_notice ============================
2
3 Copyright (C) 2017-2021 Intel Corporation
4
5 SPDX-License-Identifier: MIT
6
7 ============================= end_copyright_notice ===========================*/
8
9 #include "visa_igc_common_header.h"
10 #include "Common_ISA.h"
11 #include "Common_ISA_util.h"
12 #include "Common_ISA_framework.h"
13 #ifdef DLL_MODE
14 #include "RT_Jitter_Interface.h"
15 #else
16 #include "JitterDataStruct.h"
17 #endif
18 #include "VISAKernel.h"
19 #include "BinaryCISAEmission.h"
20 #include "Timer.h"
21 #include "BinaryEncoding.h"
22 #include "IsaDisassembly.h"
23
24 #include "G4_IR.hpp"
25 #include "FlowGraph.h"
26 #include "DebugInfo.h"
27 #include "IsaVerification.h"
28 #include "IGC/common/StringMacros.hpp"
29
30 #include <fstream>
31 #include <iostream>
32 #include <list>
33 #include <string>
34 #include <sstream>
35 #include <functional>
36 #include <mutex>
37
38 using namespace vISA;
39 extern "C" int64_t getTimerTicks(unsigned int idx);
40
41 #define IS_GEN_PATH (mBuildOption == VISA_BUILDER_GEN)
42 #define IS_BOTH_PATH (mBuildOption == VISA_BUILDER_BOTH)
43 #define IS_GEN_BOTH_PATH (mBuildOption == VISA_BUILDER_GEN || mBuildOption == VISA_BUILDER_BOTH)
44 #define IS_VISA_BOTH_PATH (mBuildOption == VISA_BUILDER_VISA || mBuildOption == VISA_BUILDER_BOTH)
45
~CISA_IR_Builder()46 CISA_IR_Builder::~CISA_IR_Builder()
47 {
48 m_cisaBinary->~CisaBinary();
49
50 std::list<VISAKernelImpl *>::iterator iter_start = m_kernelsAndFunctions.begin();
51 std::list<VISAKernelImpl *>::iterator iter_end = m_kernelsAndFunctions.end();
52
53 while (iter_start != iter_end)
54 {
55 VISAKernelImpl *kernel = *iter_start;
56 iter_start++;
57 // don't call delete since vISAKernelImpl is allocated in memory pool
58 kernel->~VISAKernelImpl();
59 }
60
61 if (needsToFreeWATable)
62 {
63 delete m_pWaTable;
64 }
65 }
66
CreateVisaWaTable(TARGET_PLATFORM platform,Stepping step)67 static const WA_TABLE *CreateVisaWaTable(TARGET_PLATFORM platform, Stepping step)
68 {
69 WA_TABLE *pWaTable = new WA_TABLE;
70 memset(pWaTable, 0, sizeof(WA_TABLE));
71
72
73 if ((platform == GENX_SKL && (step == Step_A || step == Step_B)) ||
74 (platform == GENX_BXT && step == Step_A))
75 {
76 VISA_WA_ENABLE(pWaTable, WaHeaderRequiredOnSimd16Sample16bit);
77 }
78 else
79 {
80 VISA_WA_DISABLE(pWaTable, WaHeaderRequiredOnSimd16Sample16bit);
81 }
82
83 if ((platform == GENX_SKL) && (step == Step_A))
84 {
85 VISA_WA_ENABLE(pWaTable, WaSendsSrc1SizeLimitWhenEOT);
86 }
87 else
88 {
89 VISA_WA_DISABLE(pWaTable, WaSendsSrc1SizeLimitWhenEOT);
90 }
91
92 if ((platform == GENX_SKL && (step == Step_A || step == Step_B)) ||
93 (platform == GENX_BXT && step == Step_A))
94 {
95 VISA_WA_ENABLE(pWaTable, WaDisallow64BitImmMov);
96 }
97 else
98 {
99 VISA_WA_DISABLE(pWaTable, WaDisallow64BitImmMov);
100 }
101
102 if (platform == GENX_BDW || platform == GENX_CHV ||
103 platform == GENX_BXT || platform == GENX_SKL)
104 {
105 VISA_WA_ENABLE(pWaTable, WaThreadSwitchAfterCall);
106 }
107 else
108 {
109 VISA_WA_DISABLE(pWaTable, WaThreadSwitchAfterCall);
110 }
111
112 if ((platform == GENX_SKL && step < Step_E) ||
113 (platform == GENX_BXT && step <= Step_B))
114 {
115 VISA_WA_ENABLE(pWaTable, WaSrc1ImmHfNotAllowed);
116 }
117 else
118 {
119 VISA_WA_DISABLE(pWaTable, WaSrc1ImmHfNotAllowed);
120 }
121
122 if (platform == GENX_SKL && step == Step_A)
123 {
124 VISA_WA_ENABLE(pWaTable, WaDstSubRegNumNotAllowedWithLowPrecPacked);
125 }
126 else
127 {
128 VISA_WA_DISABLE(pWaTable, WaDstSubRegNumNotAllowedWithLowPrecPacked);
129 }
130
131 if ((platform == GENX_SKL && step < Step_C))
132 {
133 VISA_WA_ENABLE(pWaTable, WaDisableMixedModeLog);
134 VISA_WA_ENABLE(pWaTable, WaDisableMixedModeFdiv);
135 VISA_WA_ENABLE(pWaTable, WaDisableMixedModePow);
136 }
137 else
138 {
139 VISA_WA_DISABLE(pWaTable, WaDisableMixedModeLog);
140 VISA_WA_DISABLE(pWaTable, WaDisableMixedModeFdiv);
141 VISA_WA_DISABLE(pWaTable, WaDisableMixedModePow);
142 }
143
144
145 if ((platform == GENX_SKL && step < Step_C) ||
146 platform == GENX_CHV)
147 {
148 VISA_WA_ENABLE(pWaTable, WaFloatMixedModeSelNotAllowedWithPackedDestination);
149 }
150 else
151 {
152 VISA_WA_DISABLE(pWaTable, WaFloatMixedModeSelNotAllowedWithPackedDestination);
153 }
154
155 // always disable in offline mode
156 VISA_WA_DISABLE(pWaTable, WADisableWriteCommitForPageFault);
157
158 if ((platform == GENX_SKL && step < Step_D) ||
159 (platform == GENX_BXT && step == Step_A))
160 {
161 VISA_WA_ENABLE(pWaTable, WaDisableSIMD16On3SrcInstr);
162 }
163
164 if (platform == GENX_SKL && (step == Step_C || step == Step_D))
165 {
166 VISA_WA_ENABLE(pWaTable, WaSendSEnableIndirectMsgDesc);
167 }
168 else
169 {
170 VISA_WA_DISABLE(pWaTable, WaSendSEnableIndirectMsgDesc);
171 }
172
173 if (platform == GENX_SKL || platform == GENX_BXT)
174 {
175 VISA_WA_ENABLE(pWaTable, WaClearArfDependenciesBeforeEot);
176 }
177
178 if (platform == GENX_SKL && step == Step_A)
179 {
180 VISA_WA_ENABLE(pWaTable, WaDisableSendsSrc0DstOverlap);
181 }
182
183 if (platform >= GENX_SKL)
184 {
185 VISA_WA_ENABLE(pWaTable, WaMixModeSelInstDstNotPacked);
186 }
187
188 if (platform == GENX_SKL || platform == GENX_BXT)
189 {
190 VISA_WA_ENABLE(pWaTable, WaResetN0BeforeGatewayMessage);
191 }
192
193 // WA for future platforms
194 if (platform == GENX_ICLLP)
195 {
196 VISA_WA_ENABLE(pWaTable, Wa_1406306137);
197 }
198 if (platform == GENX_ICLLP && (step == Step_A || step == Step_B))
199 {
200 VISA_WA_ENABLE(pWaTable, Wa_2201674230);
201 }
202 switch (platform)
203 {
204 case GENX_ICLLP:
205 VISA_WA_ENABLE(pWaTable, Wa_1406950495);
206 break;
207 case GENX_TGLLP:
208 VISA_WA_ENABLE(pWaTable, Wa_1406950495);
209 VISA_WA_ENABLE(pWaTable, Wa_16013338947);
210 break;
211 case XeHP_SDV:
212 VISA_WA_ENABLE(pWaTable, Wa_1406950495);
213 VISA_WA_ENABLE(pWaTable, Wa_16013338947);
214 break;
215 case GENX_DG2:
216 VISA_WA_ENABLE(pWaTable, Wa_16013338947);
217 break;
218 case GENX_PVC:
219 VISA_WA_ENABLE(pWaTable, Wa_16013338947);
220 break;
221 case GENX_PVCXT:
222 VISA_WA_ENABLE(pWaTable, Wa_16013338947);
223 break;
224 default:
225 break;
226 }
227
228 return pWaTable;
229 }
230
231 // Change default values of some options according to WA_TABLE
232 // The values are set before parsing any flags specified by client
233 // (either within CreateVISABuilder() call or via VISABuilder interface)
234 // and may be overriden by client flags
AddWAOptions(Options & options,const WA_TABLE & waTable)235 static void AddWAOptions(Options &options, const WA_TABLE &waTable)
236 {
237 if (waTable.Wa_1808850743 || waTable.Wa_1409909237)
238 {
239 options.setOptionInternally(vISA_noMaskWA, 2u);
240 // Turn off jmpi as there is no wa for jmpi
241 options.setOptionInternally(vISA_EnableScalarJmp, false);
242 }
243 }
244
CreateBuilder(CISA_IR_Builder * & builder,vISABuilderMode mode,VISA_BUILDER_OPTION buildOption,TARGET_PLATFORM platform,int numArgs,const char * flags[],const WA_TABLE * pWaTable)245 int CISA_IR_Builder::CreateBuilder(
246 CISA_IR_Builder *&builder,
247 vISABuilderMode mode,
248 VISA_BUILDER_OPTION buildOption,
249 TARGET_PLATFORM platform,
250 int numArgs,
251 const char* flags[],
252 const WA_TABLE *pWaTable)
253 {
254
255 initTimer();
256
257 if (builder)
258 {
259 assert(0);
260 return VISA_FAILURE;
261 }
262
263 startTimer(TimerID::TOTAL);
264 startTimer(TimerID::BUILDER); // builder time ends with we call compile (i.e., it covers the IR construction time)
265 //this must be called before any other API.
266 SetVisaPlatform(platform);
267
268 builder = new CISA_IR_Builder(buildOption, mode, COMMON_ISA_MAJOR_VER, COMMON_ISA_MINOR_VER, pWaTable);
269
270 if (pWaTable)
271 {
272 AddWAOptions(builder->m_options, *pWaTable);
273 }
274
275 if (!builder->m_options.parseOptions(numArgs, flags))
276 {
277 delete builder;
278 assert(0);
279 return VISA_FAILURE;
280 }
281
282 #if defined(_DEBUG) || defined(_INTERNAL)
283 builder->m_options.getOptionsFromEV();
284 #endif
285
286 // This should not matter anymore since each kernel should set its Target attribute to 3D/CM
287 auto targetMode = VISA_3D;
288 builder->m_options.setTarget(targetMode);
289 builder->m_options.setOptionInternally(vISA_isParseMode, mode == vISA_ASM_READER);
290
291 #ifndef DLL_MODE
292 if (mode == vISA_ASM_READER)
293 {
294 // For vISA text input we always want to dump out vISA
295 builder->m_options.setOptionInternally(vISA_DumpvISA, true);
296 }
297 #endif
298
299 // emit location info always for these cases
300 if (mode == vISABuilderMode::vISA_DEFAULT && builder->m_options.getOption(vISA_outputToFile))
301 {
302 builder->m_options.setOptionInternally(vISA_EmitLocation, true);
303 }
304
305 // driver WaTable is not available in offline vISA executable mode
306 // We instead create and initialize some of the known ones here
307 if (!pWaTable)
308 {
309 builder->m_pWaTable = CreateVisaWaTable(platform, builder->m_options.GetStepping());
310 builder->needsToFreeWATable = true;
311 }
312
313 if (mode == vISA_ASM_WRITER)
314 {
315 // If writing asm text, clear the stream and print the build version
316 builder->ClearAsmTextStreams();
317 builder->m_ssIsaAsm << printBuildVersion(builder->m_header) << "\n";
318 }
319
320 return VISA_SUCCESS;
321 }
322
DestroyBuilder(CISA_IR_Builder * builder)323 int CISA_IR_Builder::DestroyBuilder(CISA_IR_Builder *builder)
324 {
325
326 if (builder == NULL)
327 {
328 assert(0);
329 return VISA_FAILURE;
330 }
331
332 delete builder;
333
334 return VISA_SUCCESS;
335 }
336
GetVISAKernel(const std::string & kernelName)337 VISAKernel* CISA_IR_Builder::GetVISAKernel(const std::string& kernelName)
338 {
339 if (kernelName.empty())
340 {
341 if (m_builderMode == vISA_ASM_READER)
342 {
343 auto kernel = m_kernelsAndFunctions.front();
344 assert(kernel->getIsKernel());
345 return static_cast<VISAKernel*>(kernel);
346 }
347 return static_cast<VISAKernel*>(m_kernel);
348 }
349 return static_cast<VISAKernel*>(m_nameToKernel.at(kernelName));
350 }
351
ClearAsmTextStreams()352 int CISA_IR_Builder::ClearAsmTextStreams()
353 {
354 if (m_builderMode == vISA_ASM_WRITER)
355 {
356 m_ssIsaAsm.str(std::string());
357 m_ssIsaAsm.clear();
358 return VISA_SUCCESS;
359 }
360
361 assert(0 && "Should clear streams only in asm text writer mode!");
362 return VISA_FAILURE;
363 }
364
AddKernel(VISAKernel * & kernel,const char * kernelName)365 int CISA_IR_Builder::AddKernel(VISAKernel *& kernel, const char* kernelName)
366 {
367 if (kernel)
368 {
369 assert(0);
370 return VISA_FAILURE;
371 }
372
373 VISAKernelImpl * kerneltemp = new (m_mem) VISAKernelImpl(VISA_BUILD_TYPE::KERNEL, this, kernelName);
374 kernel = static_cast<VISAKernel*>(kerneltemp);
375 m_kernel = kerneltemp;
376
377 m_kernelsAndFunctions.push_back(kerneltemp);
378 this->m_kernel_count++;
379 this->m_nameToKernel[kernelName] = m_kernel;
380
381 if (m_builderMode == vISA_ASM_WRITER)
382 {
383 m_ssIsaAsm << "//// KERNEL: ////\n";
384 VISAKernel_format_provider fmt(m_kernel);
385 m_ssIsaAsm << printFunctionDecl(&fmt, true) << "\n";
386 }
387 return VISA_SUCCESS;
388 }
389
SetPrevKernel(VISAKernel * & prevKernel)390 int CISA_IR_Builder::SetPrevKernel(VISAKernel *& prevKernel)
391 {
392 if (prevKernel)
393 {
394 m_prevKernel = (VISAKernelImpl*)prevKernel;
395 }
396 return VISA_SUCCESS;
397 }
398
AddFunction(VISAFunction * & function,const char * functionName)399 int CISA_IR_Builder::AddFunction(VISAFunction *& function, const char* functionName)
400 {
401 if (function)
402 {
403 assert(0);
404 return VISA_FAILURE;
405 }
406
407 VISAKernelImpl* kerneltemp = new (m_mem) VISAKernelImpl(VISA_BUILD_TYPE::FUNCTION, this, functionName);
408 function = static_cast<VISAFunction*>(kerneltemp);
409 m_kernel = kerneltemp;
410 m_kernelsAndFunctions.push_back(kerneltemp);
411 m_kernel->m_functionId = this->m_function_count++;
412 this->m_nameToKernel[functionName] = m_kernel;
413
414 if (m_builderMode == vISA_ASM_WRITER)
415 {
416 m_ssIsaAsm << "\n" << "//// FUNCTION: ////\n";
417 VISAKernel_format_provider fmt(m_kernel);
418 m_ssIsaAsm << printFunctionDecl(&fmt, false) << "\n";
419 }
420 return VISA_SUCCESS;
421 }
422
AddPayloadSection(VISAFunction * & function,const char * functionName)423 int CISA_IR_Builder::AddPayloadSection(VISAFunction *& function, const char* functionName)
424 {
425 if (function != NULL)
426 {
427 assert(0);
428 return VISA_FAILURE;
429 }
430
431 VISAKernelImpl* kerneltemp = new (m_mem) VISAKernelImpl(VISA_BUILD_TYPE::PAYLOAD, this, functionName);
432 function = static_cast<VISAFunction*>(kerneltemp);
433 m_kernel = kerneltemp;
434 m_kernelsAndFunctions.push_back(kerneltemp);
435 m_kernel->m_functionId = this->m_function_count++;
436 this->m_nameToKernel[functionName] = m_kernel;
437
438 return VISA_SUCCESS;
439 }
440
441 // default size of the physical reg pool mem manager in bytes
442 #define PHY_REG_MEM_SIZE (16*1024)
443
restoreFCallState(G4_Kernel * kernel,const std::map<G4_BB *,G4_INST * > & savedFCallState)444 void restoreFCallState(
445 G4_Kernel* kernel, const std::map<G4_BB*, G4_INST*>& savedFCallState)
446 {
447 // Iterate over all BBs in kernel and fix all fcalls converted
448 // to calls by reconverting them to fcall. This is required
449 // because we want to reuse IR of function for next kernel.
450
451 for (auto&& iter : savedFCallState)
452 {
453 auto curBB = iter.first;
454 auto genOffset = curBB->back()->getGenOffset();
455 curBB->pop_back();
456 auto origInst = iter.second;
457 assert(origInst->isFCall() || origInst->isFReturn());
458 curBB->push_back(origInst);
459 // set the genOffset in case of GenOffset being used when creating symbol table
460 origInst->setGenOffset(genOffset);
461
462 if (origInst->isFCall() && !origInst->asCFInst()->isIndirectCall())
463 {
464 // curBB must have a physical successor as we don't allow calls that do not return
465 G4_BB* retBlock = curBB->getPhysicalSucc();
466 G4_BB* retbbToConvert = retBlock->Preds.back();
467 kernel->fg.removePredSuccEdges(retbbToConvert, retBlock);
468 // Remove edge between call and previously joined function
469 while (curBB->Succs.size() > 0)
470 {
471 kernel->fg.removePredSuccEdges(curBB, curBB->Succs.front());
472 }
473
474 // Restore edge to retBlock
475 kernel->fg.addPredSuccEdges(curBB, retBlock);
476 }
477 }
478
479 // Remove all in-edges to stack call function. These may have been added
480 // to connect earlier kernels with the function.
481 while (kernel->fg.getEntryBB()->Preds.size() > 0)
482 {
483 kernel->fg.removePredSuccEdges(
484 kernel->fg.getEntryBB()->Preds.front(), kernel->fg.getEntryBB());
485 }
486 }
487
GetCallerKernel(G4_INST * inst)488 G4_Kernel* CISA_IR_Builder::GetCallerKernel(G4_INST* inst)
489 {
490 return &inst->getBuilder().kernel;
491 }
492
GetCalleeKernel(G4_INST * fcall)493 G4_Kernel* CISA_IR_Builder::GetCalleeKernel(G4_INST* fcall)
494 {
495 assert(fcall->opcode() == G4_pseudo_fcall);
496 std::string funcName = fcall->getSrc(0)->asLabel()->getLabel();
497 auto iter = functionsNameMap.find(funcName);
498 assert(iter != functionsNameMap.end() && "can't find function with given name");
499 return iter->second;
500 }
501
ResetHasStackCall(std::list<std::list<vISA::G4_INST * >::iterator> & sgInvokeList,std::unordered_map<G4_Kernel *,std::list<std::list<G4_INST * >::iterator>> & callSites)502 void CISA_IR_Builder::ResetHasStackCall(
503 std::list<std::list<vISA::G4_INST*>::iterator>& sgInvokeList,
504 std::unordered_map<G4_Kernel*, std::list<std::list<G4_INST*>::iterator>>& callSites)
505 {
506 for (auto& [func, callsites] : callSites)
507 {
508 bool hasStackCall = false;
509 for (auto& it : callsites)
510 {
511 G4_INST* fcall = *it;
512 assert(fcall->opcode() == G4_pseudo_fcall);
513 bool isInSgInvokeList = std::find(sgInvokeList.begin(), sgInvokeList.end(), it) != sgInvokeList.end();
514 if (!isInSgInvokeList)
515 {
516 hasStackCall = true;
517 break;
518 }
519 }
520 if (!hasStackCall)
521 {
522 func->fg.resetHasStackCalls();
523 }
524 }
525 }
526
527
CheckHazardFeatures(std::list<std::list<vISA::G4_INST * >::iterator> & sgInvokeList,std::unordered_map<G4_Kernel *,std::list<std::list<G4_INST * >::iterator>> & callSites)528 void CISA_IR_Builder::CheckHazardFeatures(
529 std::list<std::list<vISA::G4_INST*>::iterator>& sgInvokeList,
530 std::unordered_map<G4_Kernel*, std::list<std::list<G4_INST*>::iterator>>& callSites)
531 {
532 std::function<void(G4_Kernel*, G4_Kernel*, std::set<G4_Kernel*>&)> traverse;
533 traverse = [&](G4_Kernel* root, G4_Kernel* func, std::set<G4_Kernel*>& visited)
534 {
535 for (auto& it : callSites[func])
536 {
537 G4_INST* fcall = *it;
538 assert(fcall->opcode() == G4_pseudo_fcall);
539 assert(func == GetCallerKernel(fcall));
540 G4_Kernel* callee = GetCalleeKernel(fcall);
541
542 assert(root != callee && "Detected a recursion that is not allowed");
543
544 if (visited.count(callee))
545 continue;
546
547 visited.insert(callee);
548 traverse(root, callee, visited);
549 }
550 };
551
552 for (auto& it : sgInvokeList)
553 {
554 G4_INST* fcall = *it;
555 // Check if there is a indirect call
556 assert(!fcall->asCFInst()->isIndirectCall() && "Not supported for indirect calls");
557
558 // Check recursion
559 std::set<G4_Kernel*> visited;
560 G4_Kernel* root = GetCalleeKernel(fcall);
561 visited.insert(root);
562 traverse(root, root, visited);
563 }
564
565 }
566
CollectCallSites(std::list<VISAKernelImpl * > & functions,std::unordered_map<G4_Kernel *,std::list<std::list<G4_INST * >::iterator>> & callSites,std::list<std::list<vISA::G4_INST * >::iterator> & sgInvokeList)567 void CISA_IR_Builder::CollectCallSites(
568 std::list<VISAKernelImpl *>& functions,
569 std::unordered_map<G4_Kernel*, std::list<std::list<G4_INST*>::iterator>>& callSites,
570 std::list<std::list<vISA::G4_INST*>::iterator>& sgInvokeList)
571 {
572 auto IsFCall = [](G4_INST* inst)
573 {
574 return inst->opcode() == G4_pseudo_fcall;
575 };
576
577 for (auto func : functions)
578 {
579 functionsNameMap[std::string(func->getName())] = func->getKernel();
580 auto& instList = func->getKernel()->fg.builder->instList;
581 std::list<G4_INST*>::iterator it = instList.begin();
582 while (it != instList.end())
583 {
584 if (!IsFCall(*it))
585 {
586 it++;
587 continue;
588 }
589 callSites[func->getKernel()].push_back(it);
590 it++;
591 }
592 }
593
594 // get sgInvokeList
595 for (auto& [func, callsites] : callSites)
596 {
597 for (auto& it : callsites)
598 {
599 G4_INST* fcall = *it;
600 assert(fcall->opcode() == G4_pseudo_fcall);
601 // When callee is a invoke_simd target
602 if (GetCalleeKernel(fcall)->getBoolKernelAttr(Attributes::ATTR_LTOInvokeOptTarget))
603 {
604 sgInvokeList.push_back(it);
605 }
606 }
607 }
608 }
609
RemoveOptimizingFunction(std::list<VISAKernelImpl * > & functions,const std::list<std::list<vISA::G4_INST * >::iterator> & sgInvokeList)610 void CISA_IR_Builder::RemoveOptimizingFunction(
611 std::list<VISAKernelImpl *>& functions,
612 const std::list<std::list<vISA::G4_INST*>::iterator>& sgInvokeList)
613 {
614 std::set<G4_Kernel*> removeList;
615 for (auto& it : sgInvokeList)
616 {
617 G4_INST* fcall = *it;
618 removeList.insert(GetCalleeKernel(fcall));
619 }
620 std::list<VISAKernelImpl*>::iterator i = functions.begin();
621 while (i != functions.end())
622 {
623 auto func = *i;
624 if (!removeList.count(func->getKernel())) {
625 ++i;
626 } else {
627 functions.erase(i++);
628 }
629 }
630 }
631
ProcessSgInvokeList(const std::list<std::list<vISA::G4_INST * >::iterator> & sgInvokeList,std::unordered_map<G4_Kernel *,std::list<std::list<vISA::G4_INST * >::iterator>> & callee2Callers)632 void CISA_IR_Builder::ProcessSgInvokeList(
633 const std::list<std::list<vISA::G4_INST*>::iterator>& sgInvokeList,
634 std::unordered_map<G4_Kernel*, std::list<std::list<vISA::G4_INST*>::iterator>>& callee2Callers)
635 {
636 for (auto& it : sgInvokeList)
637 {
638 G4_INST* fcall = *it;
639 G4_Kernel* callee = GetCalleeKernel(fcall);
640 callee2Callers[callee].push_back(it);
641 }
642 }
643
644 #define DEBUG_LTO
645 #ifdef DEBUG_LTO
646 #define DEBUG_PRINT(msg) \
647 std::cerr << __LINE__ << " " << msg;
648 #define DEBUG_UTIL(stmt) \
649 stmt;
650 #else
651 #define DEBUG_PRINT(msg)
652 #define DEBUG_UTIL(stmt)
653 #endif
654
655 // Perform LTO including transforming stack calls to subroutine calls, subroutine calls to jumps, and inlining
LinkTimeOptimization(std::unordered_map<G4_Kernel *,std::list<std::list<vISA::G4_INST * >::iterator>> & callee2Callers,uint32_t options)656 void CISA_IR_Builder::LinkTimeOptimization(
657 std::unordered_map<G4_Kernel*, std::list<std::list<vISA::G4_INST*>::iterator>>& callee2Callers,
658 uint32_t options)
659 {
660 bool call2jump = options & (1U << Linker_Call2Jump);
661 std::map<G4_INST*, std::list<G4_INST*>::iterator> callsite;
662 std::map<G4_INST*, std::list<G4_INST*>> rets;
663 std::set<G4_Kernel*> visited;
664 std::list<G4_INST*> dummyContainer;
665 unsigned int raUID = 0;
666
667 // append instructions from callee to caller
668 for (auto& [callee, sgInvokeList] : callee2Callers)
669 for (auto& it : sgInvokeList)
670 {
671 bool inlining = ( options & (1U << Linker_Inline) ) && sgInvokeList.size() == 1;
672 bool removeArgRet = ( options & (1U << Linker_RemoveArgRet) );
673 bool removeStackArg = ( options & (1U << Linker_RemoveStackArg) );
674 bool removeStackFrame = ( options & (1U << Linker_RemoveStackFrame) );
675 G4_INST* fcall = *it;
676 assert(fcall->opcode() == G4_pseudo_fcall);
677
678 G4_Kernel* caller = GetCallerKernel(fcall);
679 G4_Kernel* callee = GetCalleeKernel(fcall);
680 G4_INST* calleeLabel = *callee->fg.builder->instList.begin();
681 ASSERT_USER(calleeLabel->isLabel() == true, "Entry inst is not a label");
682
683 // Change fcall to call
684 fcall->setOpcode(G4_call);
685 fcall->setSrc(calleeLabel->getSrc(0), 0);
686 // we only record a single callsite to the target in order to convert to jumps
687 // note that we don't need call2jump when inlining kicks in
688 if ((!inlining) && callsite.find(calleeLabel) == callsite.end())
689 {
690 callsite[calleeLabel] = it;
691 }
692 else
693 {
694 callsite[calleeLabel] = dummyContainer.end();
695 }
696
697 auto& callerInsts = caller->fg.builder->instList;
698 auto calleeInsts = callee->fg.builder->instList;
699
700 if (removeArgRet)
701 {
702 auto& calleeBuilder = callee->fg.builder;
703 auto& callerBuilder = caller->fg.builder;
704 const RegionDesc *rDesc = callerBuilder->getRegionStride1();
705 G4_Declare *replacedArgDcl = callerBuilder->createDeclareNoLookup("newArg", G4_GRF, numEltPerGRF<Type_UD>(), 32, Type_UD);
706 G4_Declare *replacedRetDcl = callerBuilder->createDeclareNoLookup("newRet", G4_GRF, numEltPerGRF<Type_UD>(), 12, Type_UD);
707
708 for (G4_INST* inst : calleeInsts)
709 {
710 for (int i = 0, numSrc = inst->getNumSrc(); i < numSrc; ++i)
711 {
712 G4_Operand *src = inst->getSrc(i);
713 if (!src) continue;
714 G4_Declare* topDcl = src->getTopDcl();
715 if (!topDcl) continue;
716 G4_Declare* rootDcl = topDcl->getRootDeclare();
717 if (calleeBuilder->isPreDefArg(rootDcl))
718 {
719 G4_Operand *replacedArgSrc = callerBuilder->createSrc(
720 replacedArgDcl->getRegVar(),
721 src->asSrcRegRegion()->getRegOff(),
722 src->asSrcRegRegion()->getSubRegOff(),
723 rDesc,
724 src->getType());
725 inst->setSrc(replacedArgSrc, i);
726 }
727 }
728
729 G4_Operand *dst = inst->getDst();
730 if (!dst) continue;
731 G4_Declare* topDcl = dst->getTopDcl();
732 if (!topDcl) continue;
733 G4_Declare* rootDcl = topDcl->getRootDeclare();
734 if (calleeBuilder->isPreDefRet(rootDcl))
735 {
736 G4_DstRegRegion *replacedRetDst = callerBuilder->createDst(
737 replacedRetDcl->getRegVar(),
738 dst->asDstRegRegion()->getRegOff(),
739 dst->asDstRegRegion()->getSubRegOff(),
740 dst->asDstRegRegion()->getHorzStride(),
741 dst->getType());
742 inst->setDest(replacedRetDst);
743 }
744
745 }
746 for (G4_INST* inst : callerInsts)
747 {
748 G4_Operand *dst = inst->getDst();
749 if (!dst) continue;
750 G4_Declare* topDcl = dst->getTopDcl();
751 if (!topDcl) continue;
752 G4_Declare* rootDcl = topDcl->getRootDeclare();
753 if (callerBuilder->isPreDefArg(rootDcl))
754 {
755 G4_DstRegRegion *replacedArgDst = callerBuilder->createDst(
756 replacedArgDcl->getRegVar(),
757 dst->asDstRegRegion()->getRegOff(),
758 dst->asDstRegRegion()->getSubRegOff(),
759 dst->asDstRegRegion()->getHorzStride(),
760 dst->getType());
761 inst->setDest(replacedArgDst);
762 }
763
764 for (int i = 0, numSrc = inst->getNumSrc(); i < numSrc; ++i)
765 {
766 G4_Operand *src = inst->getSrc(i);
767 if (!src) continue;
768 G4_Declare* topDcl = src->getTopDcl();
769 if (!topDcl) continue;
770 G4_Declare* rootDcl = topDcl->getRootDeclare();
771 if (callerBuilder->isPreDefRet(rootDcl))
772 {
773 G4_Operand *replacedRetSrc = callerBuilder->createSrc(
774 replacedRetDcl->getRegVar(),
775 src->asSrcRegRegion()->getRegOff(),
776 src->asSrcRegRegion()->getSubRegOff(),
777 rDesc,
778 src->getType());
779 inst->setSrc(replacedRetSrc, i);
780 }
781 }
782 }
783 }
784
785 // A hash map to record how SP is populated from caller to callee
786 std::map<G4_Declare*, long long> stackPointers;
787 // A hash map to record where the instruction is on defs
788 std::map<G4_Declare*, std::list<vISA::G4_INST*>::iterator> defInst;
789
790 if (removeStackArg)
791 {
792 // collect instructions which store args to stack
793 auto& callerBuilder = caller->fg.builder;
794 auto& calleeBuilder = callee->fg.builder;
795 auto getPointerOffset = [&](G4_INST *inst, long long offset)
796 {
797 auto execSize = static_cast<int>(inst->getExecSize());
798 assert(execSize == 1);
799 switch(inst->opcode())
800 {
801 case G4_mov:
802 {
803 return offset;
804 }
805 case G4_add:
806 {
807 assert(inst->getSrc(1)->isImm());
808 return offset + inst->getSrc(1)->asImm()->getImm();
809 }
810 default:
811 {
812 assert(0);
813 return 0LL;
814 }
815 }
816 };
817
818 auto getRootDeclare = [&](G4_Operand *opnd)
819 {
820 if (!opnd)
821 return (G4_Declare*) nullptr;
822 G4_Declare* topDcl = opnd->getTopDcl();
823 if (!topDcl)
824 return (G4_Declare*) nullptr;
825 return topDcl->getRootDeclare();
826
827 };
828
829 auto getBeginIt = [&](std::list<vISA::G4_INST*>::iterator it)
830 {
831 // Trace backward until it reaches an update for SP
832 // This is where we start to push spilled arguments onto stack
833 auto beginIt = it;
834 for (; beginIt != callerInsts.begin(); --beginIt)
835 {
836 G4_INST *inst = *beginIt;
837 for (int i = 0, numSrc = inst->getNumSrc(); i < numSrc; ++i)
838 {
839 G4_Declare* rootDcl = getRootDeclare(inst->getSrc(i));
840 if (!rootDcl) continue;
841 G4_Operand *dst = inst->getDst();
842 if (rootDcl == callerBuilder->getFE_SP())
843 {
844 // the dst is updating SP
845 if (dst->getTopDcl() == callerBuilder->getFE_SP())
846 {
847 auto prevIt = beginIt;
848 prevIt --;
849 G4_INST *prevInst = *prevIt;
850 // It reaches the begining of function where it pushes a new frame.
851 // It is not where we are looking for.
852 if (prevInst->getDst()->getTopDcl() == callerBuilder->getFE_FP())
853 {
854 return it;
855 }
856 else
857 {
858 return beginIt;
859 }
860 }
861 }
862 }
863 }
864 return it;
865 };
866
867 // A list of store in order to perform store-to-load forwarding
868 std::list<std::list<vISA::G4_INST*>::iterator> storeList;
869
870 auto beginIt = getBeginIt(it);
871 bool noArgOnStack = (beginIt == it);
872 for (auto callerIt = beginIt; callerIt != it; callerIt ++)
873 {
874 G4_INST *inst = *callerIt;
875 for (int i = 0, numSrc = inst->getNumSrc(); i < numSrc; ++i)
876 {
877 G4_Declare* rootDcl = getRootDeclare(inst->getSrc(i));
878 if (!rootDcl) continue;
879 G4_Operand *dst = inst->getDst();
880 if (rootDcl == callerBuilder->getFE_SP())
881 {
882 stackPointers[dst->getTopDcl()] = getPointerOffset(inst, stackPointers[rootDcl]);
883 defInst[dst->getTopDcl()] = callerIt;
884 // beginIt is the update of SP before pushing arguments onto stack
885 // We do not remove it immediately since we don't know if all S2L can be perform at this stage
886 std::string prefix = (removeStackFrame && callerIt != beginIt) ? "removeFrame " : "";
887 DEBUG_PRINT(prefix << "(" << stackPointers[dst->getTopDcl()] << ") ");
888 DEBUG_UTIL(inst->dump());
889 if (removeStackFrame && callerIt != beginIt)
890 {
891 callerInsts.erase(callerIt);
892 }
893 }
894 else if (stackPointers.find(rootDcl) != stackPointers.end())
895 {
896 long long offset = stackPointers[rootDcl];
897 if (inst->opcode() == G4_mov ||
898 inst->opcode() == G4_add)
899 {
900 auto execSize = static_cast<int>(inst->getExecSize());
901 if (execSize != 1)
902 {
903 // Currently only support scalar type of operations
904 DEBUG_PRINT("skip nonaddress calc\n");
905 DEBUG_UTIL(inst->dump());
906 continue;
907 }
908 stackPointers[dst->getTopDcl()] = getPointerOffset(inst, offset);
909 defInst[dst->getTopDcl()] = callerIt;
910 DEBUG_PRINT("(" << stackPointers[dst->getTopDcl()] << ") ");
911 DEBUG_UTIL(inst->dump());
912 }
913 else if (inst->opcode() == G4_sends ||
914 inst->opcode() == G4_send)
915 {
916 assert(i == 0);
917 // Start adding argument stores to the list
918 storeList.push_back(callerIt);
919 DEBUG_PRINT("[ ]");
920 DEBUG_UTIL(inst->dump());
921 }
922 else
923 {
924 assert(0 && "not implemented");
925 }
926 }
927 }
928 }
929 // passing SP offset from caller to callee
930 stackPointers[calleeBuilder->getFE_SP()] = stackPointers[callerBuilder->getFE_SP()];
931 stackPointers[calleeBuilder->getFE_FP()] = stackPointers[callerBuilder->getFE_FP()];
932
933 for (auto calleeIt = calleeInsts.begin(); calleeIt != calleeInsts.end(); calleeIt++)
934 {
935 G4_INST *inst = *calleeIt;
936 for (int i = 0, numSrc = inst->getNumSrc(); i < numSrc; ++i)
937 {
938 G4_Declare* rootDcl = getRootDeclare(inst->getSrc(i));
939 if (!rootDcl) continue;
940 G4_Operand *dst = inst->getDst();
941 if (rootDcl == calleeBuilder->getFE_SP())
942 {
943 stackPointers[dst->getTopDcl()] = getPointerOffset(inst, stackPointers[rootDcl]);
944 defInst[dst->getTopDcl()] = calleeIt;
945 std::string prefix = removeStackFrame ? "removeFrame " : "";
946 DEBUG_PRINT(prefix << "(" << stackPointers[dst->getTopDcl()] << ") ");
947 DEBUG_UTIL(inst->dump());
948 if (removeStackFrame)
949 {
950 calleeInsts.erase(calleeIt);
951 break;
952 }
953 }
954 else if (stackPointers.find(rootDcl) != stackPointers.end())
955 {
956 long long offset = stackPointers[rootDcl];
957 if (inst->opcode() == G4_mov)
958 {
959 auto execSize = static_cast<int>(inst->getExecSize());
960 assert(execSize == 1);
961 stackPointers[dst->getTopDcl()] = getPointerOffset(inst, offset);
962 defInst[dst->getTopDcl()] = calleeIt;
963 std::string prefix = removeStackFrame ? "removeFrame " : "";
964 DEBUG_PRINT(prefix << "(" << stackPointers[dst->getTopDcl()] << ") ");
965 DEBUG_UTIL(inst->dump());
966 if (removeStackFrame)
967 {
968 calleeInsts.erase(calleeIt);
969 break;
970 }
971 }
972 else if (inst->opcode() == G4_sends ||
973 inst->opcode() == G4_send)
974 {
975 if (storeList.empty())
976 {
977 // store prevFP to the callee's frame
978 if (stackPointers[callerBuilder->getFE_SP()] ==
979 stackPointers[getRootDeclare(inst->getSrc(0))])
980 {
981 DEBUG_PRINT("remove prevFP on callee's frame:\n");
982 DEBUG_UTIL(inst->dump());
983 calleeInsts.erase(calleeIt);
984 break;
985 }
986 DEBUG_PRINT("skip for now (private variable on the callee's frame):\n");
987 DEBUG_UTIL(inst->dump());
988 assert(0);
989 }
990 auto storeIt = storeList.front();
991 G4_INST *storeInst = *storeIt;
992 G4_INST *loadInst = inst;
993 storeList.pop_front();
994 DEBUG_PRINT("store-to-load forwarding:\n");
995 DEBUG_PRINT("\tstore:\t");
996 DEBUG_UTIL(storeInst->dump());
997 DEBUG_PRINT("\tload :\t");
998 DEBUG_UTIL(loadInst->dump());
999 assert(stackPointers[getRootDeclare(storeInst->getSrc(0))] ==
1000 stackPointers[getRootDeclare( loadInst->getSrc(0))] &&
1001 "Store and load have different SP offset");
1002 // promote the load into mov
1003 inst->setOpcode(G4_mov);
1004 loadInst->setSrc(storeInst->getSrc(1), 0);
1005 DEBUG_PRINT("\tforwarded:");
1006 DEBUG_UTIL(inst->dump());
1007 // erase the store
1008 callerInsts.erase(storeIt);
1009 }
1010 else
1011 {
1012 assert(0 && "not implemented");
1013 }
1014 }
1015 }
1016 }
1017
1018 // All args has been removed on the stack
1019 // Remove SP updating instruction
1020 if (storeList.empty() && !noArgOnStack)
1021 {
1022 DEBUG_PRINT("removed:");
1023 DEBUG_UTIL((*defInst[callerBuilder->getFE_SP()])->dump());
1024 callerInsts.erase(defInst[callerBuilder->getFE_SP()]);
1025 }
1026
1027 }
1028
1029 if (inlining)
1030 {
1031 auto& builder = caller->fg.builder;
1032 std::string funcName = fcall->getSrc(0)->asLabel()->getLabel();
1033 G4_Label *raLabel = builder->createLabel(funcName + "_ret" + std::to_string(raUID++), LABEL_BLOCK);
1034 G4_INST* ra = caller->fg.createNewLabelInst(raLabel);
1035 // We don't need calleeLabel (first instruction) anymore after inlining
1036 calleeInsts.pop_front();
1037 for (G4_INST* fret : calleeInsts)
1038 {
1039 G4_INST* inst = fret->cloneInst();
1040 callerInsts.insert(it, inst);
1041 if (inst->opcode() != G4_pseudo_fret)
1042 continue;
1043 // Change inst to goto
1044 inst->setOpcode(G4_goto);
1045 inst->asCFInst()->setUip(raLabel);
1046 }
1047 // Append declarations from callee to caller
1048 auto callerDclCount = caller->Declares.size();
1049 for (auto curDcl : callee->Declares)
1050 {
1051 curDcl->setDeclId(curDcl->getDeclId() + callerDclCount);
1052 caller->Declares.push_back(curDcl);
1053 }
1054 // insert return label for goto
1055 callerInsts.insert(it, ra);
1056 // remove the call
1057 callerInsts.erase(it);
1058 }
1059 else
1060 {
1061 // We only have to copy callee's instructions once for subrountine calls
1062 if (visited.find(callee) != visited.end())
1063 {
1064 continue;
1065 }
1066 visited.insert(callee);
1067 for (G4_INST* fret : calleeInsts)
1068 {
1069 if (fret->opcode() != G4_pseudo_fret)
1070 continue;
1071 // Change fret to ret
1072 fret->setOpcode(G4_return);
1073 rets[calleeLabel].push_back(fret);
1074 }
1075 callerInsts.insert(callerInsts.end(), calleeInsts.begin(), calleeInsts.end());
1076 // Append declarations from callee to caller
1077 auto callerDclCount = caller->Declares.size();
1078 for (auto curDcl : callee->Declares)
1079 {
1080 curDcl->setDeclId(curDcl->getDeclId() + callerDclCount);
1081 caller->Declares.push_back(curDcl);
1082 }
1083 }
1084 }
1085
1086 if (call2jump)
1087 {
1088 for(auto& [label, itCall]: callsite)
1089 {
1090 if (itCall == dummyContainer.end())
1091 continue;
1092 G4_INST* call = *itCall;
1093 G4_Kernel* caller = GetCallerKernel(call);
1094 auto& builder = caller->fg.builder;
1095 call->setOpcode(G4_goto);
1096 call->asCFInst()->setUip(label->getLabel());
1097 std::string funcName = call->getSrc(0)->asLabel()->getLabel();
1098 G4_Label *raLabel = builder->createLabel(funcName + "_ret", LABEL_BLOCK);
1099 G4_INST* ra = caller->fg.createNewLabelInst(raLabel);
1100 auto& callerInsts = caller->fg.builder->instList;
1101 callerInsts.insert(++itCall, ra);
1102
1103 for (G4_INST* ret : rets[label])
1104 {
1105 ret->setOpcode(G4_goto);
1106 ret->asCFInst()->setUip(raLabel);
1107 }
1108 }
1109 }
1110
1111 }
1112
1113 // Stitch the FG of subFunctions to mainFunc
1114 // mainFunc could be a kernel or a non-kernel function.
1115 // It also modifies pseudo_fcall/fret in to call/ret opcodes.
1116 // ToDo: may consider stitching only functions that may be called by this kernel/function
Stitch_Compiled_Units(G4_Kernel * mainFunc,std::map<std::string,G4_Kernel * > & subFuncs,std::map<G4_BB *,G4_INST * > & FCallRetMap)1117 static void Stitch_Compiled_Units(
1118 G4_Kernel* mainFunc, std::map<std::string, G4_Kernel*>& subFuncs,
1119 std::map<G4_BB*, G4_INST*>& FCallRetMap)
1120 {
1121
1122 // Append subFunctions to mainFunc
1123 for (auto&& iter : subFuncs)
1124 {
1125 G4_Kernel* callee = iter.second;
1126 mainFunc->fg.append(callee->fg);
1127
1128 // merge the relocation when append
1129 if (!callee->getRelocationTable().empty())
1130 mainFunc->getRelocationTable().insert(mainFunc->getRelocationTable().end(),
1131 callee->getRelocationTable().begin(), callee->getRelocationTable().end());
1132
1133 ASSERT_USER(mainFunc->getNumRegTotal() == callee->getNumRegTotal(), "caller and callee cannot have different GRF modes");
1134 }
1135
1136 mainFunc->fg.reassignBlockIDs();
1137 mainFunc->fg.setPhysicalPredSucc(); // this is to locate the next BB after an fcall
1138
1139 auto builder = mainFunc->fg.builder;
1140 // Change fcall/fret to call/ret and setup caller/callee edges
1141 for (G4_BB* cur : mainFunc->fg)
1142 {
1143 if (cur->isEndWithFCall())
1144 {
1145 // Setup successor/predecessor
1146 G4_INST* fcall = cur->back();
1147
1148 if (!fcall->asCFInst()->isIndirectCall())
1149 {
1150 // Setup caller/callee edges for direct call
1151 // ToDo: remove this once SWSB is moved before stithcing, as we would not need to maintain CFG otherwise
1152 std::string funcName = fcall->getSrc(0)->asLabel()->getLabel();
1153
1154 auto iter = subFuncs.find(funcName);
1155 assert(iter != subFuncs.end() && "can't find function with given name");
1156 G4_Kernel* callee = iter->second;
1157 G4_BB* retBlock = cur->Succs.front();
1158 ASSERT_USER(cur->Succs.size() == 1, "fcall basic block cannot have more than 1 successor");
1159 ASSERT_USER(retBlock->Preds.size() == 1, "block after fcall cannot have more than 1 predecessor");
1160
1161 // Remove old edge
1162 retBlock->Preds.erase(retBlock->Preds.begin());
1163 cur->Succs.erase(cur->Succs.begin());
1164
1165 // Connect new fg
1166 mainFunc->fg.addPredSuccEdges(cur, callee->fg.getEntryBB());
1167 mainFunc->fg.addPredSuccEdges(callee->fg.getUniqueReturnBlock(), retBlock);
1168
1169 // propagate properties of callee to mainFunc
1170 // usesBarrier property is propagated to IGC and onwards in to NEO patch
1171 // token. we need this logic here to propagate barrier usage to IGC and
1172 // further to NEO so it can setup WG size appropriately. without this
1173 // setting barrier would cause machine to hang.
1174 // TODO: How to set usesBarrier when callee is indirect?
1175 mainFunc->fg.builder->getJitInfo()->usesBarrier |= callee->fg.builder->getJitInfo()->usesBarrier;
1176
1177 G4_INST* calleeLabel = callee->fg.getEntryBB()->front();
1178 ASSERT_USER(calleeLabel->isLabel() == true, "Entry inst is not label");
1179
1180 auto callInst = builder->createInternalInst(
1181 fcall->getPredicate(), G4_call, nullptr, g4::NOSAT, fcall->getExecSize(),
1182 fcall->getDst(), calleeLabel->getSrc(0), fcall->getSrc(0), fcall->getOption());
1183 callInst->inheritDIFrom(fcall);
1184 callInst->inheritSWSBFrom(fcall);
1185 cur->pop_back();
1186 cur->push_back(callInst);
1187 }
1188 else
1189 {
1190 // src0 is dont care for indirect call as long it's not a label
1191 auto callInst = builder->createInternalInst(
1192 fcall->getPredicate(), G4_call, nullptr, g4::NOSAT, fcall->getExecSize(),
1193 fcall->getDst(), fcall->getSrc(0), fcall->getSrc(0), fcall->getOption());
1194 callInst->inheritDIFrom(fcall);
1195 callInst->inheritSWSBFrom(fcall);
1196 cur->pop_back();
1197 cur->push_back(callInst);
1198 }
1199 FCallRetMap[cur] = fcall;
1200 }
1201 }
1202
1203 // Change fret to ret
1204 for (G4_BB* cur : mainFunc->fg)
1205 {
1206 if (cur->isEndWithFRet())
1207 {
1208 G4_INST* fret = cur->back();
1209 auto retInst = builder->createInternalInst(
1210 fret->getPredicate(), G4_return, nullptr, g4::NOSAT, fret->getExecSize(),
1211 builder->createNullDst(Type_UD), fret->getSrc(0), fret->getSrc(1), fret->getOption());
1212 retInst->inheritDIFrom(fret);
1213 retInst->inheritSWSBFrom(fret);
1214 cur->pop_back();
1215 cur->push_back(retInst);
1216 FCallRetMap[cur] = fret;
1217 }
1218 }
1219
1220 // Append declarations and color attributes from all callees to mainFunc
1221 for (auto iter : subFuncs)
1222 {
1223 G4_Kernel* callee = iter.second;
1224 for (auto curDcl : callee->Declares)
1225 {
1226 mainFunc->Declares.push_back(curDcl);
1227 }
1228 }
1229
1230 mainFunc->dumpToFile("after.stitched");
1231 }
1232
1233
1234 typedef struct yy_buffer_state * YY_BUFFER_STATE;
1235 extern int CISAparse(CISA_IR_Builder *builder);
1236 extern YY_BUFFER_STATE CISA_scan_string(const char* yy_str);
1237 extern void CISA_delete_buffer(YY_BUFFER_STATE buf);
1238 static std::mutex mtx;
1239
ParseVISAText(const std::string & visaText,const std::string & visaTextFile)1240 int CISA_IR_Builder::ParseVISAText(const std::string& visaText, const std::string& visaTextFile)
1241 {
1242 const std::lock_guard<std::mutex> lock(mtx);
1243 // Direct output of parser to null
1244 #if defined(_WIN64) || defined(_WIN32)
1245 CISAout = fopen("nul", "w");
1246 #else
1247 CISAout = fopen("/dev/null", "w");
1248 #endif
1249
1250 int status = VISA_SUCCESS;
1251
1252 // Dump the visa text
1253 if (m_options.getOption(vISA_GenerateISAASM) && !visaTextFile.empty())
1254 {
1255 std::ofstream ofs(visaTextFile.c_str(), std::ofstream::out);
1256 if (ofs.good()) {
1257 ofs << visaText;
1258 ofs.close();
1259 }
1260 }
1261
1262 YY_BUFFER_STATE visaBuf = CISA_scan_string(visaText.c_str());
1263 if (CISAparse(this) != 0)
1264 {
1265 #ifndef DLL_MODE
1266 std::cerr << "Parsing visa text failed.";
1267 if (!visaTextFile.empty())
1268 {
1269 std::cerr << " Please examine " << visaTextFile << " and fix the error";
1270 }
1271 std::cerr << "\n" << criticalMsg.str();
1272 #endif //DLL_MODE
1273 status = VISA_FAILURE;
1274 }
1275 CISA_delete_buffer(visaBuf);
1276
1277 if (CISAout)
1278 {
1279 fclose(CISAout);
1280 }
1281
1282 // run vISA verifier to cath any additional errors.
1283 // the subsequent vISABuilder::Compile() call is assumed to always succeed after verifier checks.
1284 if (status == VISA_SUCCESS)
1285 {
1286 status = verifyVISAIR();
1287 }
1288
1289 return status;
1290 }
1291
1292 // Parses inline asm file from ShaderOverride
ParseVISAText(const std::string & visaFile)1293 int CISA_IR_Builder::ParseVISAText(const std::string& visaFile)
1294 {
1295 // Direct output of parser to null
1296 #if defined(_WIN64) || defined(_WIN32)
1297 CISAout = fopen("nul", "w");
1298 #else
1299 CISAout = fopen("/dev/null", "w");
1300 #endif
1301 CISAin = fopen(visaFile.c_str(), "r");
1302 if (!CISAin)
1303 {
1304 assert(0 && "Failed to open file");
1305 return VISA_FAILURE;
1306 }
1307
1308 if (CISAparse(this) != 0)
1309 {
1310 assert(0 && "Parsing visa text failed");
1311 return VISA_FAILURE;
1312 }
1313 fclose(CISAin);
1314
1315 if (CISAout)
1316 {
1317 fclose(CISAout);
1318 }
1319 return VISA_SUCCESS;
1320 }
1321
1322 // default size of the kernel mem manager in bytes
1323 #define KERNEL_MEM_SIZE (4*1024*1024)
Compile(const char * nameInput,std::ostream * os,bool emit_visa_only)1324 int CISA_IR_Builder::Compile(const char* nameInput, std::ostream* os, bool emit_visa_only)
1325 {
1326 stopTimer(TimerID::BUILDER); // TIMER_BUILDER is started when builder is created
1327 int status = VISA_SUCCESS;
1328 std::string name = std::string(nameInput);
1329
1330 if (IS_VISA_BOTH_PATH)
1331 {
1332 if (m_builderMode == vISA_ASM_WRITER)
1333 {
1334 assert(0 && "Should not be calling Compile() in asm text writer mode!");
1335 return VISA_FAILURE;
1336 }
1337 if (IS_BOTH_PATH)
1338 {
1339 m_options.setOptionInternally(vISA_NumGenBinariesWillBePatched, (uint32_t) 1);
1340 }
1341 m_cisaBinary->initCisaBinary(m_kernel_count, m_function_count);
1342 m_cisaBinary->setMajorVersion((unsigned char)this->m_header.major_version);
1343 m_cisaBinary->setMinorVersion((unsigned char)this->m_header.minor_version);
1344 m_cisaBinary->setMagicNumber(COMMON_ISA_MAGIC_NUM);
1345
1346 CBinaryCISAEmitter cisaBinaryEmitter;
1347 int status = VISA_SUCCESS;
1348 int kernelIndex = 0;
1349 for (auto func : m_kernelsAndFunctions)
1350 {
1351 func->finalizeAttributes();
1352 unsigned int binarySize = 0;
1353 status = cisaBinaryEmitter.Emit(func, binarySize);
1354 m_cisaBinary->initKernel(kernelIndex, func);
1355 kernelIndex++;
1356 }
1357 m_cisaBinary->finalizeCisaBinary();
1358
1359 if (status != VISA_SUCCESS)
1360 {
1361 return status;
1362 }
1363
1364 if (m_options.getOption(vISA_GenerateISAASM))
1365 {
1366 status = m_cisaBinary->isaDump(m_kernelsAndFunctions, &m_options);
1367 if (status != VISA_SUCCESS)
1368 {
1369 return status;
1370 }
1371 }
1372
1373 if (!m_options.getOption(vISA_NoVerifyvISA))
1374 {
1375 status = verifyVISAIR();
1376 if (status != VISA_SUCCESS)
1377 {
1378 return status;
1379 }
1380 }
1381 }
1382
1383 /*
1384 In case there is an assert in compilation phase, at least vISA binary will be generated.
1385 */
1386 if (IS_VISA_BOTH_PATH && m_options.getOption(vISA_DumpvISA) && nameInput && !os)
1387 {
1388 if (CisaFramework::allowDump(m_options, name))
1389 status = m_cisaBinary->dumpToFile(name);
1390 }
1391
1392 if (os && emit_visa_only)
1393 {
1394 return m_cisaBinary->dumpToStream(os);
1395 }
1396
1397 if (m_options.getuInt32Option(vISA_Linker) & (1U << Linker_Subroutine))
1398 {
1399 std::map<std::string, G4_Kernel*> functionsNameMap;
1400 G4_Kernel* mainFunc = m_kernelsAndFunctions.front()->getKernel();
1401 assert(m_kernelsAndFunctions.front()->getIsKernel() && "mainFunc must be the kernel entry");
1402 std::unordered_map<G4_Kernel*, std::list<std::list<G4_INST*>::iterator>> callSites;
1403 std::list<std::list<G4_INST*>::iterator> sgInvokeList;
1404 CollectCallSites(m_kernelsAndFunctions, callSites, sgInvokeList);
1405
1406 assert(callSites.begin()->first == mainFunc);
1407 CheckHazardFeatures(sgInvokeList, callSites);
1408
1409 ResetHasStackCall(sgInvokeList, callSites);
1410
1411 RemoveOptimizingFunction(m_kernelsAndFunctions, sgInvokeList);
1412
1413 std::unordered_map<G4_Kernel*, std::list<std::list<vISA::G4_INST*>::iterator>> callee2Callers;
1414 ProcessSgInvokeList(sgInvokeList, callee2Callers);
1415
1416 // Copy callees' context to callers and convert to subroutine calls
1417 LinkTimeOptimization(callee2Callers,
1418 m_options.getuInt32Option(vISA_Linker));
1419 }
1420
1421
1422
1423 VISAKernelImpl* oldMainKernel = nullptr;
1424 if (IS_GEN_BOTH_PATH)
1425 {
1426 Mem_Manager mem(4096);
1427 common_isa_header pseudoHeader;
1428 // m_kernels contains kernels and functions to compile.
1429
1430 pseudoHeader.num_kernels = 0;
1431 pseudoHeader.num_functions = 0;
1432 for (const VISAKernelImpl* func : m_kernelsAndFunctions)
1433 {
1434 if (func->getIsKernel())
1435 {
1436 pseudoHeader.num_kernels++;
1437 }
1438 else
1439 {
1440 pseudoHeader.num_functions++;
1441 }
1442 }
1443
1444 pseudoHeader.functions = (function_info_t*)mem.alloc(sizeof(function_info_t) * pseudoHeader.num_functions);
1445
1446 int i;
1447 unsigned int k = 0;
1448 bool isInPatchingMode = m_options.getuInt32Option(vISA_CodePatch) >= CodePatch_Enable_NoLTO && m_prevKernel;
1449 VISAKernelImpl* mainKernel = nullptr;
1450 std::list<VISAKernelImpl*>::iterator iter = m_kernelsAndFunctions.begin();
1451 std::list<VISAKernelImpl*>::iterator end = m_kernelsAndFunctions.end();
1452 for (i = 0; iter != end; iter++, i++)
1453 {
1454 VISAKernelImpl* kernel = (*iter);
1455 mainKernel = (kernel->getIsKernel()) ? kernel : mainKernel;
1456 kernel->finalizeAttributes();
1457 kernel->getIRBuilder()->setType(kernel->getType());
1458 if (kernel->getIsKernel() == false)
1459 {
1460 if (kernel->getIRBuilder()->getArgSize() < kernel->getKernelFormat()->input_size)
1461 {
1462 kernel->getIRBuilder()->setArgSize(kernel->getKernelFormat()->input_size);
1463 }
1464 if (kernel->getIRBuilder()->getRetVarSize() < kernel->getKernelFormat()->return_value_size)
1465 {
1466 kernel->getIRBuilder()->setRetVarSize(kernel->getKernelFormat()->return_value_size);
1467 }
1468
1469 auto nameLen = strlen((*iter)->getKernel()->getName()) + 1;
1470 pseudoHeader.functions[k].name = (char*)mem.alloc(nameLen);
1471 strcpy_s(pseudoHeader.functions[k].name, nameLen, (*iter)->getKernel()->getName());
1472 k++;
1473 }
1474
1475 if (kernel->getIsPayload())
1476 {
1477 // Copy main kernel's declarations (shader body) into payload section
1478 kernel->CopyVars(mainKernel);
1479 kernel->getKernel()->Declares = mainKernel->getKernel()->Declares;
1480 kernel->getIRBuilder()->setInputR1(mainKernel->getIRBuilder()->getInputR1());
1481 // Set payload LiveOuts to be output
1482 uint32_t inputCount = mainKernel->getIRBuilder()->getInputCount();
1483 for (unsigned int id = 0; id < inputCount; id++)
1484 {
1485 input_info_t* input_info = mainKernel->getIRBuilder()->getInputArg(id);
1486 // skip pseudo input for register bindings.
1487 if (input_info->isPseudoInput())
1488 {
1489 continue;
1490 }
1491 vISA::G4_Declare* dcl = input_info->dcl;
1492 if (dcl->isPayloadLiveOut())
1493 {
1494 dcl->setLiveOut();
1495 }
1496 }
1497 mainKernel->getIRBuilder()->getRealR0()->setLiveOut();
1498 }
1499
1500 if ((kernel->getIsKernel() && isInPatchingMode) ||
1501 (kernel->getvIsaInstCount() == 0 && kernel->getIsPayload()))
1502 {
1503 continue;
1504 }
1505 int status = kernel->compileFastPath();
1506 if (status != VISA_SUCCESS)
1507 {
1508 stopTimer(TimerID::TOTAL);
1509 return status;
1510 }
1511 if (kernel->getIsPayload())
1512 {
1513 // Remove payload live-outs from the kernel after the compilation since
1514 // they will not be outputs anymore after stitching.
1515 mainKernel->getIRBuilder()->getRealR0()->resetLiveOut();
1516 const std::vector<input_info_t*>& inputs = mainKernel->getIRBuilder()->m_inputVect;
1517 for (const input_info_t* input_info : inputs)
1518 {
1519 vISA::G4_Declare* dcl = input_info->dcl;
1520 if (dcl->isPayloadLiveOut())
1521 {
1522 dcl->resetLiveOut();
1523 }
1524 }
1525 }
1526 }
1527 // Here we change the payload section as the main kernel in m_kernelsAndFunctions
1528 // During stitching, all functions will be cloned and stitched to the main kernel.
1529 // Demoting the shader body to a function type makes it intact
1530 // so we can stitch it again to another SIMD size of payload section
1531 if (m_options.getuInt32Option(vISA_CodePatch))
1532 {
1533 assert(m_kernelsAndFunctions.front()->getIsKernel());
1534 for (auto func : m_kernelsAndFunctions)
1535 {
1536 if (func->getIsKernel())
1537 {
1538 oldMainKernel = func;
1539 func->setType(VISA_BUILD_TYPE::FUNCTION);
1540 }
1541 else if (func->getIsPayload())
1542 {
1543 func->setType(VISA_BUILD_TYPE::KERNEL);
1544 }
1545 }
1546 m_kernelsAndFunctions.pop_front();
1547 if (isInPatchingMode)
1548 {
1549 m_kernelsAndFunctions.push_back(m_prevKernel);
1550 }
1551 else
1552 {
1553 m_kernelsAndFunctions.push_back(oldMainKernel);
1554 }
1555 // payloadSection is the main kernel at this point
1556 // We need to copy essential info from the shader body to the main kernel
1557 auto payloadSection = m_kernelsAndFunctions.front()->getIRBuilder();
1558 auto shaderBody = m_kernelsAndFunctions.back()->getIRBuilder();
1559 *payloadSection->getJitInfo() = *shaderBody->getJitInfo();
1560
1561 payloadSection->m_inputVect = shaderBody->m_inputVect;
1562 if (shaderBody->kernel.hasKernelDebugInfo())
1563 {
1564 payloadSection->kernel.setKernelDebugInfo(
1565 shaderBody->kernel.getKernelDebugInfo());
1566 }
1567
1568 if (shaderBody->kernel.hasGTPinInit())
1569 {
1570 std::vector<unsigned> globalFreeRegs;
1571 unsigned int i = 0, j = 0;
1572 auto payloadSectionGTPin = payloadSection->kernel.getGTPinData();
1573 auto shaderBodyGTPin = shaderBody->kernel.getGTPinData();
1574 while (i < payloadSectionGTPin->getNumFreeGlobalRegs() &&
1575 j < shaderBodyGTPin->getNumFreeGlobalRegs())
1576 {
1577 unsigned int iFreeGRF = payloadSectionGTPin->getFreeGlobalReg(i);
1578 unsigned int jFreeGRF = shaderBodyGTPin->getFreeGlobalReg(j);
1579 if (iFreeGRF < jFreeGRF)
1580 {
1581 i ++;
1582 }
1583 else if (iFreeGRF > jFreeGRF)
1584 {
1585 j ++;
1586 }
1587 else // iFreeGRF == jFreeGRF
1588 {
1589 globalFreeRegs.push_back(iFreeGRF);
1590 i ++;
1591 j ++;
1592 }
1593 }
1594 payloadSection->kernel.setGTPinData(
1595 shaderBody->kernel.getGTPinData());
1596 // If the number of free regs in payload section is 0,
1597 // it means the compilation is skipped and we don't have to do anything
1598 if (payloadSectionGTPin->getNumFreeGlobalRegs())
1599 {
1600 payloadSection->kernel.getGTPinData()->setFreeGlobalRegs(globalFreeRegs);
1601 }
1602 }
1603 }
1604
1605 // Preparing for stitching some functions to other functions
1606 // There are two stiching policies:
1607 // 1. vISA_noStitchExternFunc == false
1608 // Stitch all non-kernel functions to all kernels
1609 // 2. vISA_noStitchExternFunc == true
1610 // Stitch only non-external functions. Stich them to all kernels and external functions
1611
1612 // mainFunctions: functions or kernels those will be stiched by others
1613 // Thses functions/kernels will be the unit of compilePostOptimize
1614 VISAKernelImpl::VISAKernelImplListTy mainFunctions;
1615 // subFunctions: functions those will stitch to others
1616 VISAKernelImpl::VISAKernelImplListTy subFunctions;
1617 std::map<std::string, G4_Kernel*> subFunctionsNameMap;
1618 // For functions those will be stitch to others, create table to map their name to G4_Kernel
1619 for (auto func : m_kernelsAndFunctions)
1620 {
1621 if (func->getIsKernel()) {
1622 // kernels must be stitched
1623 mainFunctions.push_back(func);
1624 continue;
1625 } else {
1626 if (!m_options.getOption(vISA_noStitchExternFunc)) {
1627 // Policy 1: all functions will stitch to kernels
1628 subFunctions.push_back(func);
1629 subFunctionsNameMap[std::string(func->getName())] = func->getKernel();
1630 } else {
1631 // Policy 2: external functions will be stitched, non-external functions will stitch to others
1632 if (func->getKernel()->getBoolKernelAttr(Attributes::ATTR_Extern))
1633 {
1634 mainFunctions.push_back(func);
1635 }
1636 else
1637 {
1638 subFunctions.push_back(func);
1639 subFunctionsNameMap[std::string(func->getName())] = func->getKernel();
1640 }
1641 }
1642 }
1643 }
1644
1645 // reset debug info offset of functionsToStitch
1646 for (auto func : subFunctions)
1647 {
1648 if (m_options.getOption(vISA_GenerateDebugInfo))
1649 {
1650 func->getKernel()->getKernelDebugInfo()->resetRelocOffset();
1651 resetGenOffsets(*func->getKernel());
1652 }
1653 }
1654
1655 bool hasPayloadPrologue = m_options.getuInt32Option(vISA_CodePatch) >= CodePatch_Payload_Prologue;
1656 // stitch functions and compile to gen binary
1657 for (auto func : mainFunctions)
1658 {
1659 unsigned int genxBufferSize = 0;
1660
1661 // store the BBs with FCall and FRet, which must terminate the BB
1662 std::map<G4_BB*, G4_INST*> origFCallFRet;
1663 if (!hasPayloadPrologue)
1664 {
1665 Stitch_Compiled_Units(func->getKernel(), subFunctionsNameMap, origFCallFRet);
1666 }
1667
1668 func->compilePostOptimize();
1669 if (hasPayloadPrologue)
1670 {
1671 if (!isInPatchingMode)
1672 {
1673 for (auto shaderBody : subFunctions)
1674 {
1675 shaderBody->getKernel()->fg.reassignBlockIDs();
1676 shaderBody->getKernel()->fg.setPhysicalPredSucc();
1677 shaderBody->compilePostOptimize();
1678 }
1679 }
1680 // Append shader body to payload section
1681 for (auto&& iter : subFunctionsNameMap)
1682 {
1683 G4_Kernel* callee = iter.second;
1684 func->getKernel()->fg.append(callee->fg);
1685 }
1686 }
1687 void* genxBuffer = func->encodeAndEmit(genxBufferSize);
1688 func->setGenxBinaryBuffer(genxBuffer, genxBufferSize);
1689 if (m_options.getOption(vISA_GenerateDebugInfo))
1690 {
1691 func->computeAndEmitDebugInfo(subFunctions);
1692 }
1693 restoreFCallState(func->getKernel(), origFCallFRet);
1694
1695
1696 }
1697
1698
1699 }
1700
1701 if (IS_VISA_BOTH_PATH && m_options.getOption(vISA_DumpvISA))
1702 {
1703 unsigned int numGenBinariesWillBePatched = m_options.getuInt32Option(vISA_NumGenBinariesWillBePatched);
1704
1705 if (numGenBinariesWillBePatched)
1706 {
1707 //only patch for Both path; vISA path doesn't need this.
1708 int kernelCount = 0;
1709 int functionCount = 0;
1710 for (auto func : m_kernelsAndFunctions)
1711 {
1712 if (func->getIsKernel())
1713 {
1714 m_cisaBinary->patchKernel(
1715 kernelCount, func->getGenxBinarySize(), func->getGenxBinaryBuffer(), getGenxPlatformEncoding());
1716 kernelCount++;
1717 } else {
1718 // functions be treated as "mainFunctions" will have its own binary, will need to
1719 // specify its binary buffer in m_cisaBinary
1720 // FIXME: By this the external functions' gen-binary will be part of .isa output when
1721 // calling CisaBinary::dumpToStream, and avoid the assert in dumpToStream. But when
1722 // parsing the emited .isa file, our parser may not correctly support this case.
1723 if (m_options.getOption(vISA_noStitchExternFunc) &&
1724 func->getKernel()->getBoolKernelAttr(Attributes::ATTR_Extern)) {
1725 m_cisaBinary->patchFunctionWithGenBinary(functionCount, func->getGenxBinarySize(),
1726 func->getGenxBinaryBuffer());
1727 } else {
1728 m_cisaBinary->patchFunction(functionCount, func->getGenxBinarySize());
1729 }
1730 functionCount++;
1731 }
1732 }
1733 }
1734
1735 if (os)
1736 {
1737 status = m_cisaBinary->dumpToStream(os);
1738 }
1739 else
1740 {
1741 if (CisaFramework::allowDump(m_options, name))
1742 status = m_cisaBinary->dumpToFile(name);
1743 }
1744 }
1745
1746 stopTimer(TimerID::TOTAL); // have to record total time before dump the timer
1747 if (m_options.getOption(vISA_dumpTimer))
1748 {
1749 const char *asmName = nullptr;
1750 m_options.getOption(VISA_AsmFileName, asmName);
1751 dumpAllTimers(asmName, true);
1752 }
1753
1754 #ifndef DLL_MODE
1755 if (criticalMsg.str().length() > 0)
1756 {
1757 std::cerr << "[vISA Finalizer Messsages]\n" << criticalMsg.str();
1758 }
1759 #endif //DLL_MODE
1760
1761 if (m_options.getuInt32Option(vISA_CodePatch) && oldMainKernel)
1762 {
1763 m_kernelsAndFunctions.pop_back();
1764 m_kernelsAndFunctions.push_back(oldMainKernel);
1765 }
1766
1767 return status;
1768 }
1769
verifyVISAIR()1770 int CISA_IR_Builder::verifyVISAIR()
1771 {
1772
1773 #ifdef IS_RELEASE_DLL
1774 return VISA_SUCCESS;
1775 #endif
1776
1777 bool hasErrors = false;
1778 unsigned totalErrors = 0;
1779 std::string testName; // base kernel name saved for function's isaasm file name
1780
1781 for (auto kTemp : m_kernelsAndFunctions)
1782 {
1783 if (kTemp->getIsKernel())
1784 {
1785 //if asmName is test9_genx_0.asm, the testName is test9_genx.
1786 std::string asmName = kTemp->getOutputAsmPath();
1787 std::string::size_type asmNameEnd = asmName.find_last_of('_');
1788 if (asmNameEnd != std::string::npos)
1789 {
1790 testName = asmName.substr(0, asmNameEnd);
1791 }
1792 else
1793 {
1794 testName = asmName;
1795 }
1796 break;
1797 }
1798 }
1799
1800 std::vector<std::string> failedFiles;
1801 VISAKernelImpl* mainKernel = nullptr;
1802 for (auto kTemp : m_kernelsAndFunctions)
1803 {
1804 unsigned funcId = 0;
1805 if (kTemp->getIsKernel())
1806 {
1807 mainKernel = kTemp;
1808 }
1809 // Payload section is a mirror compilation to the main kernel
1810 // Load the main kernel to access its symbol table
1811 VISAKernelImpl* fmtKernel = kTemp->getIsPayload() ? mainKernel : kTemp;
1812
1813 VISAKernel_format_provider fmt(fmtKernel);
1814
1815 vISAVerifier verifier(m_header, &fmt, getOptions());
1816 verifier.run(kTemp);
1817
1818 if (verifier.hasErrors())
1819 {
1820 std::stringstream verifierName;
1821
1822 if (kTemp->getIsKernel())
1823 {
1824 verifierName << kTemp->getOutputAsmPath();
1825 }
1826 else
1827 {
1828 kTemp->GetFunctionId(funcId);
1829 verifierName << testName;
1830 verifierName << "_f";
1831 verifierName << funcId;
1832 }
1833 verifierName << ".errors.txt";
1834 verifier.writeReport(verifierName.str().c_str());
1835 failedFiles.push_back(verifierName.str());
1836 hasErrors = true;
1837 totalErrors += (uint32_t)verifier.getNumErrors();
1838 }
1839 }
1840 if (hasErrors)
1841 {
1842 std::stringstream ss;
1843 ss << "Found a total of " << totalErrors << " errors in vISA input.\n";
1844 ss << "Please check\n";
1845 for (auto&& name : failedFiles)
1846 {
1847 ss << "\t" << name << "\n";
1848 }
1849 ss << "for the exact error messages\n";
1850 #ifndef DLL_MODE
1851 std::cerr << ss.str();
1852 #endif //DLL_MODE
1853 criticalMsgStream() << ss.str();
1854 return VISA_FAILURE;
1855 }
1856
1857 return VISA_SUCCESS;
1858
1859 }
1860
CISA_lookup_builtin_constant(int lineNum,const char * symbol,int64_t & val)1861 bool CISA_IR_Builder::CISA_lookup_builtin_constant(int lineNum, const char *symbol, int64_t &val)
1862 {
1863 std::string sym(symbol);
1864 if (sym == "%DispatchSimd") {
1865 if (m_dispatchSimdSize <= 0) {
1866 m_dispatchSimdSize = -1;
1867 RecordParseError(lineNum,
1868 "symbol cannot be used before .kernel_attr DispatchSimd=... is set");
1869 return false;
1870 }
1871 val = m_dispatchSimdSize;
1872 return true;
1873 } else {
1874 RecordParseError(lineNum, sym, ": invalid built-in symbol");
1875 val = -1;
1876 return false;
1877 }
1878 }
1879
CISA_eval_sizeof_decl(int lineNum,const char * var,int64_t & val)1880 bool CISA_IR_Builder::CISA_eval_sizeof_decl(int lineNum, const char *var, int64_t &val)
1881 {
1882 auto *decl = (VISA_GenVar*)m_kernel->getDeclFromName(var);
1883 if (!decl) {
1884 if (std::string(var) == "GRF") {
1885 val = getGRFSize();
1886 return true;
1887 }
1888 RecordParseError(lineNum, var, ": unbound variable");
1889 return false;
1890 }
1891 switch (decl->type) {
1892 case GENERAL_VAR: val = (int64_t)decl->genVar.getSize(); break;
1893 case ADDRESS_VAR: val = (int64_t)decl->addrVar.num_elements * 2; break;
1894 default:
1895 RecordParseError(lineNum, var, ": unsupported operator on this variable kind");
1896 return false;
1897 }
1898 return true;
1899 }
1900
1901 // Use in a function returning bool (returns false on failure)
1902 // requires: int lineNum
1903 //
1904 // TODO: the long term goal is to have the vISA builder class store a
1905 // "last error" of some sort and then we can just change this macro.
1906 //
1907 // Note: this is exactly what C++ exceptions are for. This ugliness is the cost.
1908 #define VISA_CALL_TO_BOOL(FUNC, ...) \
1909 do { \
1910 int __status = m_kernel->FUNC(__VA_ARGS__); \
1911 if (__status != VISA_SUCCESS) { \
1912 RecordParseError(lineNum, #FUNC, ": unknown error (internal line: ", __LINE__, ")"); \
1913 return false; \
1914 } \
1915 } while (0)
1916 #define VISA_RESULT_CALL_TO_BOOL(FUNC_RESULT) \
1917 do { \
1918 int __status = FUNC_RESULT; \
1919 if (__status != VISA_SUCCESS) { \
1920 RecordParseError(lineNum, ""/*__FUNCTION__*/, ": unknown error (internal line: ", __LINE__, ")"); \
1921 return false; \
1922 } \
1923 } while (0)
1924 // similar to above, but returns nullptr on failure.
1925 #define VISA_CALL_TO_NULLPTR(FUNC, ...) \
1926 do { \
1927 int __status = m_kernel->FUNC(__VA_ARGS__); \
1928 if (__status != VISA_SUCCESS) { \
1929 RecordParseError(lineNum, #FUNC, ": unknown error (internal line: ", __LINE__, ")"); \
1930 return nullptr; \
1931 } \
1932 } while (0)
1933
1934 #define VISA_CALL_TO_BOOL_NOLINE(FUNC, ...) \
1935 do { \
1936 int lineNum = 0; \
1937 VISA_CALL_TO_BOOL(FUNC, __VA_ARGS__); \
1938 } while (0)
1939
1940
CISA_get_surface_variable(const char * varName,int lineNum)1941 VISA_StateOpndHandle *CISA_IR_Builder::CISA_get_surface_variable(
1942 const char *varName, int lineNum)
1943 {
1944 VISA_StateOpndHandle * surface = nullptr;
1945 VISA_SurfaceVar *surfaceVar = (VISA_SurfaceVar*)m_kernel->getDeclFromName(varName);
1946 if (!surfaceVar) {
1947 RecordParseError(lineNum, varName, ": undefined surface variable");
1948 } else if (surfaceVar->type != SURFACE_VAR && surfaceVar->type != SAMPLER_VAR) {
1949 RecordParseError(lineNum, varName, ": not a surface variable");
1950 } else {
1951 if (m_kernel->CreateVISAStateOperandHandle(surface, surfaceVar) != VISA_SUCCESS) {
1952 RecordParseError(lineNum, varName, ": internal error: creating surface variable");
1953 surface = nullptr;
1954 }
1955 }
1956 return surface;
1957 }
1958
CISA_get_sampler_variable(const char * varName,int lineNum)1959 VISA_StateOpndHandle *CISA_IR_Builder::CISA_get_sampler_variable(
1960 const char *varName, int lineNum)
1961 {
1962 VISA_StateOpndHandle * surface = nullptr;
1963 VISA_SamplerVar *samplerVar = (VISA_SamplerVar*)m_kernel->getDeclFromName(varName);
1964 if (!samplerVar) {
1965 RecordParseError(lineNum, varName, ": undefined sampler variable");
1966 } else if (samplerVar->type != SURFACE_VAR && samplerVar->type != SAMPLER_VAR) {
1967 RecordParseError(lineNum, varName, ": not a sampler variable");
1968 } else {
1969 if (m_kernel->CreateVISAStateOperandHandle(surface, samplerVar) != VISA_SUCCESS) {
1970 RecordParseError(lineNum, varName, ": internal error: creating sampler variable");
1971 surface = nullptr;
1972 }
1973 }
1974 return surface;
1975 }
1976
CISA_general_variable_decl(const char * var_name,unsigned int var_elemts_num,VISA_Type data_type,VISA_Align var_align,const char * var_alias_name,int var_alias_offset,std::vector<attr_gen_struct * > & scope,int lineNum)1977 bool CISA_IR_Builder::CISA_general_variable_decl(
1978 const char * var_name,
1979 unsigned int var_elemts_num,
1980 VISA_Type data_type,
1981 VISA_Align var_align,
1982 const char * var_alias_name,
1983 int var_alias_offset,
1984 std::vector<attr_gen_struct*>& scope,
1985 int lineNum)
1986 {
1987 VISA_GenVar * genVar = NULL;
1988
1989 VISA_GenVar *parentDecl = NULL;
1990
1991 if (m_kernel->declExistsInCurrentScope(var_name)) {
1992 RecordParseError(lineNum, var_name, ": variable redeclaration");
1993 return false;
1994 }
1995
1996 if (var_alias_name && strcmp(var_alias_name, "") != 0)
1997 {
1998 parentDecl = (VISA_GenVar *)m_kernel->getDeclFromName(var_alias_name);
1999 if (parentDecl == nullptr) {
2000 // alias=... points to a nonexistent variable
2001 RecordParseError(lineNum, var_alias_name, ": unbound alias referent");
2002 return false;
2003 }
2004 }
2005
2006 m_kernel->CreateVISAGenVar(
2007 genVar, var_name, var_elemts_num, data_type, var_align,
2008 parentDecl, var_alias_offset);
2009
2010 if (!addAllVarAttributes((CISA_GEN_VAR*)genVar, scope, lineNum))
2011 {
2012 return false;
2013 }
2014 return true;
2015 }
2016
CISA_addr_variable_decl(const char * var_name,unsigned int var_elements,VISA_Type data_type,std::vector<attr_gen_struct * > & scope,int lineNum)2017 bool CISA_IR_Builder::CISA_addr_variable_decl(
2018 const char *var_name, unsigned int var_elements,
2019 VISA_Type data_type, std::vector<attr_gen_struct *>& scope, int lineNum)
2020 {
2021 if (m_kernel->declExistsInCurrentScope(var_name)) {
2022 RecordParseError(lineNum, var_name, ": variable redeclaration");
2023 return false;
2024 }
2025
2026 VISA_AddrVar *decl = NULL;
2027 m_kernel->CreateVISAAddrVar(decl, var_name, var_elements);
2028 if (!addAllVarAttributes((CISA_GEN_VAR*)decl, scope, lineNum))
2029 {
2030 return false;
2031 }
2032 return true;
2033 }
2034
CISA_predicate_variable_decl(const char * var_name,unsigned int var_elements,std::vector<attr_gen_struct * > & attrs,int lineNum)2035 bool CISA_IR_Builder::CISA_predicate_variable_decl(
2036 const char *var_name, unsigned int var_elements, std::vector<attr_gen_struct*>& attrs, int lineNum)
2037 {
2038 if (m_kernel->declExistsInCurrentScope(var_name)) {
2039 RecordParseError(lineNum, var_name, ": variable redeclaration");
2040 return false;
2041 }
2042
2043 VISA_PredVar *decl = NULL;
2044 m_kernel->CreateVISAPredVar(decl, var_name, (unsigned short)var_elements);
2045 if (!addAllVarAttributes((CISA_GEN_VAR*)decl, attrs, lineNum))
2046 {
2047 return false;
2048 }
2049 return true;
2050 }
2051
CISA_sampler_variable_decl(const char * var_name,int num_elts,const char * name,int lineNum)2052 bool CISA_IR_Builder::CISA_sampler_variable_decl(
2053 const char *var_name, int num_elts, const char* name, int lineNum)
2054 {
2055 if (m_kernel->declExistsInCurrentScope(var_name)) {
2056 RecordParseError(lineNum, var_name, ": variable redeclaration");
2057 return false;
2058 }
2059
2060 VISA_SamplerVar *decl = NULL;
2061 m_kernel->CreateVISASamplerVar(decl, var_name, num_elts);
2062 return true;
2063 }
2064
CISA_surface_variable_decl(const char * var_name,int num_elts,const char * name,std::vector<attr_gen_struct * > & attrs,int lineNum)2065 bool CISA_IR_Builder::CISA_surface_variable_decl(
2066 const char *var_name, int num_elts, const char* name,
2067 std::vector<attr_gen_struct*>& attrs, int lineNum)
2068 {
2069 if (m_kernel->declExistsInCurrentScope(var_name)) {
2070 RecordParseError(lineNum, var_name, ": variable redeclaration");
2071 return false;
2072 }
2073
2074 //int reg_id = attr_val.value;
2075 //char * value = (char *)m_mem.alloc(1);
2076 //*value = (char)reg_id;
2077
2078 VISA_SurfaceVar *decl = NULL;
2079 m_kernel->CreateVISASurfaceVar(decl, var_name, num_elts);
2080 if (!addAllVarAttributes((CISA_GEN_VAR*)decl, attrs, lineNum))
2081 {
2082 return false;
2083 }
2084 return true;
2085 }
2086
CISA_implicit_input_directive(const char * argName,const char * varName,short offset,unsigned short size,int lineNum)2087 bool CISA_IR_Builder::CISA_implicit_input_directive(
2088 const char * argName, const char *varName,
2089 short offset, unsigned short size, int lineNum)
2090 {
2091 std::string implicitArgName = argName;
2092 auto pos = implicitArgName.find("UNDEFINED_");
2093 uint32_t numVal = 0;
2094 if (pos!= std::string::npos)
2095 {
2096 pos += strlen("UNDEFINED_");
2097 auto numValString = implicitArgName.substr(pos, implicitArgName.length());
2098 numVal = std::stoi(numValString);
2099 }
2100 else
2101 {
2102 auto implicitInputName = implicitArgName.substr(strlen(".implicit_"), implicitArgName.length());
2103 for (; numVal < IMPLICIT_INPUT_COUNT; ++numVal)
2104 {
2105 if (!implicitInputName.compare(input_info_t::getImplicitKindString(numVal)))
2106 {
2107 break;
2108 }
2109 }
2110 }
2111
2112 int status = VISA_SUCCESS;
2113 CISA_GEN_VAR *temp = m_kernel->getDeclFromName(varName);
2114 if (!temp) {
2115 RecordParseError(lineNum, varName, ": undefined variable");
2116 return false;
2117 }
2118 status = m_kernel->CreateVISAImplicitInputVar((VISA_GenVar *)temp, offset, size, numVal);
2119 if (status != VISA_SUCCESS)
2120 {
2121 RecordParseError(lineNum, "failed to create input variable");
2122 return false;
2123 }
2124 return true;
2125 }
2126
CISA_input_directive(const char * var_name,short offset,unsigned short size,int lineNum)2127 bool CISA_IR_Builder::CISA_input_directive(
2128 const char* var_name, short offset, unsigned short size, int lineNum)
2129 {
2130 int status = VISA_SUCCESS;
2131 CISA_GEN_VAR *var = m_kernel->getDeclFromName(var_name);
2132 if (var == nullptr) {
2133 RecordParseError(lineNum, var_name, ": unbound identifier");
2134 return false;
2135 }
2136
2137 status = m_kernel->CreateVISAInputVar((VISA_GenVar *)var, offset, size);
2138 if (status != VISA_SUCCESS)
2139 {
2140 RecordParseError(lineNum, var_name, ": internal error: failed to create input variable");
2141 return false;
2142 }
2143 return true;
2144 }
2145
CISA_attr_directive(const char * input_name,const char * input_var,int lineNum)2146 bool CISA_IR_Builder::CISA_attr_directive(
2147 const char* input_name, const char* input_var, int lineNum)
2148 {
2149 Attributes::ID attrID = Attributes::getAttributeID(input_name);
2150 if (!m_options.getOption(vISA_AsmFileNameOverridden) &&
2151 attrID == Attributes::ATTR_OutputAsmPath)
2152 {
2153 if (strcmp(input_name, "AsmName") == 0) {
2154 RecordParseWarning(lineNum,
2155 "AsmName deprecated (replace with OutputAsmPath)");
2156 }
2157 input_name = "OutputAsmPath"; // normalize to new name
2158
2159 char asmFileName[MAX_OPTION_STR_LENGTH];
2160
2161 strncpy_s(asmFileName,
2162 MAX_OPTION_STR_LENGTH, input_var, MAX_OPTION_STR_LENGTH - 1);
2163 char *pos = strstr(asmFileName, ".asm");
2164 if (pos != NULL)
2165 {
2166 *pos = '\0';
2167 }
2168 m_options.setOptionInternally(VISA_AsmFileName, asmFileName);
2169 }
2170
2171 if (attrID == Attributes::ATTR_Target) {
2172 unsigned char visa_target;
2173 if (input_var == nullptr) {
2174 RecordParseError(lineNum,
2175 ".kernel_attr Target=.. must be \"cm\" or \"3d\"");
2176 return false;
2177 }
2178 if (strcmp(input_var, "cm") == 0) {
2179 visa_target = VISA_CM;
2180 } else if (strcmp(input_var, "3d") == 0) {
2181 visa_target = VISA_3D;
2182 } else {
2183 RecordParseError(lineNum, "invalid kernel target attribute");
2184 return false;
2185 }
2186 m_kernel->AddKernelAttribute(input_name, 1, &visa_target);
2187 }
2188 else
2189 {
2190 m_kernel->AddKernelAttribute(input_name,
2191 input_var == nullptr ? 0 : (int)strlen(input_var), input_var);
2192 }
2193
2194 return true;
2195 }
2196
CISA_attr_directiveNum(const char * input_name,uint32_t input_var,int lineNum)2197 bool CISA_IR_Builder::CISA_attr_directiveNum(
2198 const char* input_name, uint32_t input_var, int lineNum)
2199 {
2200 if (std::string(input_name) == "SimdSize" ||
2201 std::string(input_name) == "DispatchSimdSize")
2202 {
2203 m_dispatchSimdSize = (int)input_var;
2204 }
2205 VISA_CALL_TO_BOOL(AddKernelAttribute, input_name, sizeof(uint32_t), &input_var);
2206 return true;
2207 }
2208
CISA_create_label(const char * label_name,int lineNum)2209 bool CISA_IR_Builder::CISA_create_label(const char *label_name, int lineNum)
2210 {
2211 VISA_LabelOpnd *opnd[1] = {nullptr};
2212
2213 //when we print out ./function from isa we also print out label.
2214 //if we don't skip it during re-parsing then we will have duplicate labels
2215 if (!m_kernel->getLabelOperandFromFunctionName(std::string(label_name)))
2216 {
2217 opnd[0] = m_kernel->getLabelOpndFromLabelName(std::string(label_name));
2218 if (!opnd[0])
2219 {
2220 // forward jump
2221 VISA_CALL_TO_BOOL(CreateVISALabelVar, opnd[0], label_name, LABEL_BLOCK);
2222 if (!m_kernel->setLabelOpndNameMap(label_name, opnd[0], LABEL_BLOCK))
2223 return false;
2224 }
2225 VISA_CALL_TO_BOOL(AppendVISACFLabelInst, opnd[0]);
2226 }
2227
2228 return true;
2229 }
2230
2231
CISA_function_directive(const char * func_name,int lineNum)2232 bool CISA_IR_Builder::CISA_function_directive(const char* func_name, int lineNum)
2233 {
2234 VISA_LabelOpnd *opnd[1] = {nullptr};
2235 opnd[0] = m_kernel->getLabelOperandFromFunctionName(std::string(func_name));
2236 if (!opnd[0])
2237 {
2238 VISA_CALL_TO_BOOL(CreateVISALabelVar, opnd[0], func_name, LABEL_SUBROUTINE);
2239 if (!m_kernel->setLabelOpndNameMap(func_name, opnd[0], LABEL_SUBROUTINE))
2240 return false;
2241 }
2242
2243 VISA_CALL_TO_BOOL(AppendVISACFLabelInst, opnd[0]);
2244 return true;
2245 }
2246
2247
CISA_create_arith_instruction(VISA_opnd * pred,ISA_Opcode opcode,bool sat,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst_cisa,VISA_opnd * src0_cisa,VISA_opnd * src1_cisa,VISA_opnd * src2_cisa,int lineNum)2248 bool CISA_IR_Builder::CISA_create_arith_instruction(
2249 VISA_opnd * pred,
2250 ISA_Opcode opcode,
2251 bool sat,
2252 VISA_EMask_Ctrl emask,
2253 unsigned exec_size,
2254 VISA_opnd * dst_cisa,
2255 VISA_opnd * src0_cisa,
2256 VISA_opnd * src1_cisa,
2257 VISA_opnd * src2_cisa,
2258 int lineNum)
2259 {
2260 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2261 VISA_CALL_TO_BOOL(AppendVISAArithmeticInst,
2262 opcode, (VISA_PredOpnd *)pred, sat, emask, executionSize,
2263 (VISA_VectorOpnd *)dst_cisa, (VISA_VectorOpnd *)src0_cisa,
2264 (VISA_VectorOpnd *)src1_cisa, (VISA_VectorOpnd *)src2_cisa);
2265 return true;
2266 }
2267
CISA_create_arith_instruction2(VISA_opnd * pred,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst_cisa,VISA_opnd * carry_borrow,VISA_opnd * src1_cisa,VISA_opnd * src2_cisa,int lineNum)2268 bool CISA_IR_Builder::CISA_create_arith_instruction2(
2269 VISA_opnd * pred,
2270 ISA_Opcode opcode,
2271 VISA_EMask_Ctrl emask,
2272 unsigned exec_size,
2273 VISA_opnd * dst_cisa,
2274 VISA_opnd * carry_borrow,
2275 VISA_opnd * src1_cisa,
2276 VISA_opnd * src2_cisa,
2277 int lineNum)
2278 {
2279 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2280 VISA_CALL_TO_BOOL(AppendVISATwoDstArithmeticInst,
2281 opcode, (VISA_PredOpnd *)pred, emask, executionSize,
2282 (VISA_VectorOpnd *)dst_cisa, (VISA_VectorOpnd *)carry_borrow,
2283 (VISA_VectorOpnd *)src1_cisa, (VISA_VectorOpnd *)src2_cisa);
2284 return true;
2285 }
2286
CISA_create_mov_instruction(VISA_opnd * pred,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,bool sat,VISA_opnd * dst,VISA_opnd * src0,int lineNum)2287 bool CISA_IR_Builder::CISA_create_mov_instruction(
2288 VISA_opnd *pred,
2289 ISA_Opcode opcode,
2290 VISA_EMask_Ctrl emask,
2291 unsigned exec_size,
2292 bool sat,
2293 VISA_opnd *dst,
2294 VISA_opnd *src0,
2295 int lineNum)
2296 {
2297 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2298 VISA_CALL_TO_BOOL(AppendVISADataMovementInst,
2299 opcode, (VISA_PredOpnd*) pred, sat, emask, executionSize, (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0);
2300 return true;
2301 }
2302
CISA_create_mov_instruction(VISA_opnd * dst,CISA_GEN_VAR * src0,int lineNum)2303 bool CISA_IR_Builder::CISA_create_mov_instruction(
2304 VISA_opnd* dst, CISA_GEN_VAR* src0, int lineNum)
2305 {
2306 MUST_BE_TRUE1(src0 != NULL, lineNum, "The source operand of a move instruction was null");
2307 VISA_CALL_TO_BOOL(AppendVISAPredicateMove,
2308 (VISA_VectorOpnd*)dst, (VISA_PredVar*)src0);
2309 return true;
2310 }
2311
CISA_create_movs_instruction(VISA_EMask_Ctrl emask,ISA_Opcode opcode,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,int lineNum)2312 bool CISA_IR_Builder::CISA_create_movs_instruction(
2313 VISA_EMask_Ctrl emask,
2314 ISA_Opcode opcode,
2315 unsigned exec_size,
2316 VISA_opnd *dst,
2317 VISA_opnd *src0,
2318 int lineNum)
2319 {
2320 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2321 VISA_CALL_TO_BOOL(AppendVISADataMovementInst,
2322 ISA_MOVS, NULL, false, emask, executionSize,
2323 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0);
2324 return true;
2325 }
2326
CISA_create_branch_instruction(VISA_opnd * pred,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,const char * target_label,bool is_fccall,int lineNum)2327 bool CISA_IR_Builder::CISA_create_branch_instruction(
2328 VISA_opnd *pred,
2329 ISA_Opcode opcode,
2330 VISA_EMask_Ctrl emask,
2331 unsigned exec_size,
2332 const char *target_label,
2333 bool is_fccall,
2334 int lineNum)
2335 {
2336 VISA_LabelOpnd * opnd[1];
2337 int i = 0;
2338
2339 switch (opcode)
2340 {
2341 case ISA_CALL:
2342 {
2343 //need second path over instruction stream to
2344 //determine correct IDs since function directive might not have been
2345 //encountered yet
2346 opnd[i] = m_kernel->getLabelOperandFromFunctionName(std::string(target_label));
2347
2348 VISA_Label_Kind lblKind = is_fccall ? LABEL_FC : LABEL_SUBROUTINE;
2349 if (!opnd[i])
2350 {
2351 VISA_CALL_TO_BOOL(CreateVISALabelVar, opnd[i], target_label, lblKind);
2352 if (!m_kernel->setLabelOpndNameMap(target_label, opnd[0], lblKind))
2353 return false;
2354 opnd[i]->tag = ISA_SUBROUTINE;
2355 }
2356 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2357 VISA_CALL_TO_BOOL(AppendVISACFCallInst,
2358 (VISA_PredOpnd *)pred, emask, executionSize, opnd[i]);
2359 return true;
2360 }
2361 case ISA_JMP:
2362 {
2363 opnd[i] = m_kernel->getLabelOpndFromLabelName(std::string(target_label));
2364
2365 //forward jump label: create the label optimistically
2366 if (!opnd[i])
2367 {
2368 VISA_CALL_TO_BOOL(CreateVISALabelVar, opnd[i], target_label, LABEL_BLOCK);
2369 if (!m_kernel->setLabelOpndNameMap(target_label, opnd[0], LABEL_BLOCK))
2370 return false;
2371 }
2372
2373 VISA_CALL_TO_BOOL(AppendVISACFJmpInst, (VISA_PredOpnd *) pred, opnd[i]);
2374 return true;
2375 }
2376 case ISA_GOTO:
2377 {
2378 opnd[i] = m_kernel->getLabelOpndFromLabelName(std::string(target_label));
2379
2380 //forward jump label: create the label optimistically
2381 if (!opnd[i])
2382 {
2383 VISA_CALL_TO_BOOL(CreateVISALabelVar, opnd[i], target_label, LABEL_BLOCK);
2384 if (!m_kernel->setLabelOpndNameMap(target_label, opnd[0], LABEL_BLOCK))
2385 return false;
2386 }
2387 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2388 VISA_CALL_TO_BOOL(AppendVISACFGotoInst,
2389 (VISA_PredOpnd*)pred, emask, executionSize, opnd[i]);
2390 return true;
2391 }
2392 default:
2393 {
2394 MUST_BE_TRUE(0, "UNKNOWN Branch OP not supported.");
2395 return false;
2396 }
2397 }
2398
2399 return true;
2400 }
2401
CISA_create_cmp_instruction(VISA_Cond_Mod sub_op,VISA_EMask_Ctrl emask,unsigned exec_size,CISA_GEN_VAR * decl,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2402 bool CISA_IR_Builder::CISA_create_cmp_instruction(
2403 VISA_Cond_Mod sub_op,
2404 VISA_EMask_Ctrl emask,
2405 unsigned exec_size,
2406 CISA_GEN_VAR *decl,
2407 VISA_opnd *src0,
2408 VISA_opnd *src1,
2409 int lineNum)
2410 {
2411 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2412 VISA_CALL_TO_BOOL(AppendVISAComparisonInst,
2413 sub_op, emask, executionSize,
2414 (VISA_PredVar *)decl, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1);
2415 return true;
2416 }
2417
CISA_create_cmp_instruction(VISA_Cond_Mod sub_op,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2418 bool CISA_IR_Builder::CISA_create_cmp_instruction(
2419 VISA_Cond_Mod sub_op,
2420 ISA_Opcode opcode,
2421 VISA_EMask_Ctrl emask,
2422 unsigned exec_size,
2423 VISA_opnd *dst,
2424 VISA_opnd *src0,
2425 VISA_opnd *src1,
2426 int lineNum)
2427 {
2428 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2429 VISA_CALL_TO_BOOL(AppendVISAComparisonInst,
2430 sub_op, emask, executionSize,
2431 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1);
2432 return true;
2433 }
2434
2435
CISA_create_media_instruction(ISA_Opcode opcode,MEDIA_LD_mod media_mod,int block_width,int block_height,unsigned int plane_ID,const char * surfaceName,VISA_opnd * xOffset,VISA_opnd * yOffset,VISA_opnd * raw_dst,int lineNum)2436 bool CISA_IR_Builder::CISA_create_media_instruction(
2437 ISA_Opcode opcode,
2438 MEDIA_LD_mod media_mod,
2439 int block_width,
2440 int block_height,
2441 unsigned int plane_ID,
2442 const char * surfaceName,
2443 VISA_opnd *xOffset,
2444 VISA_opnd *yOffset,
2445 VISA_opnd *raw_dst,
2446 int lineNum)
2447 {
2448 unsigned char mod;
2449 mod = media_mod & 0x7;
2450 if (mod >= MEDIA_LD_Mod_NUM) {
2451 RecordParseError(lineNum, "ISA_MEDIA_LD uses illegal exec size");
2452 return false;
2453 }
2454
2455 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2456 if (surface == nullptr)
2457 return false; // error already reported
2458
2459 VISA_CALL_TO_BOOL(AppendVISASurfAccessMediaLoadStoreInst,
2460 opcode, media_mod, surface,
2461 (unsigned char)block_width, (unsigned char)block_height,
2462 (VISA_VectorOpnd *)xOffset, (VISA_VectorOpnd *)yOffset,
2463 (VISA_RawOpnd *)raw_dst, (CISA_PLANE_ID)plane_ID);
2464
2465 return true;
2466 }
2467
2468 /*
2469 For both RET and FRET instructions
2470 */
CISA_Create_Ret(VISA_opnd * pred_opnd,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned int exec_size,int lineNum)2471 bool CISA_IR_Builder::CISA_Create_Ret(
2472 VISA_opnd *pred_opnd,
2473 ISA_Opcode opcode,
2474 VISA_EMask_Ctrl emask,
2475 unsigned int exec_size,
2476 int lineNum)
2477 {
2478 if (opcode == ISA_RET)
2479 {
2480 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2481 VISA_CALL_TO_BOOL(AppendVISACFRetInst,
2482 (VISA_PredOpnd *)pred_opnd, emask, executionSize);
2483 }
2484 else
2485 {
2486 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2487 VISA_CALL_TO_BOOL(AppendVISACFFunctionRetInst,
2488 (VISA_PredOpnd *)pred_opnd, emask, executionSize);
2489 }
2490
2491 return true;
2492 }
2493
CISA_create_oword_instruction(ISA_Opcode opcode,bool media_mod,unsigned int size,const char * surfaceName,VISA_opnd * offset_opnd,VISA_opnd * raw_dst_src,int lineNum)2494 bool CISA_IR_Builder::CISA_create_oword_instruction(
2495 ISA_Opcode opcode,
2496 bool media_mod,
2497 unsigned int size,
2498 const char *surfaceName,
2499 VISA_opnd *offset_opnd,
2500 VISA_opnd *raw_dst_src,
2501 int lineNum)
2502 {
2503 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2504 if (!surface)
2505 return false; // error recorded
2506
2507 VISA_CALL_TO_BOOL(AppendVISASurfAccessOwordLoadStoreInst,
2508 opcode, vISA_EMASK_M1, surface,
2509 Get_VISA_Oword_Num_From_Number(size),
2510 (VISA_VectorOpnd*)offset_opnd, (VISA_RawOpnd*)raw_dst_src);
2511 return true;
2512 }
2513
CISA_create_svm_block_instruction(SVMSubOpcode subopcode,unsigned owords,bool unaligned,VISA_opnd * address,VISA_opnd * srcDst,int lineNum)2514 bool CISA_IR_Builder::CISA_create_svm_block_instruction(
2515 SVMSubOpcode subopcode,
2516 unsigned owords,
2517 bool unaligned,
2518 VISA_opnd* address,
2519 VISA_opnd* srcDst,
2520 int lineNum)
2521 {
2522 switch (subopcode)
2523 {
2524 case SVM_BLOCK_LD:
2525 VISA_CALL_TO_BOOL(AppendVISASvmBlockLoadInst,
2526 Get_VISA_Oword_Num_From_Number(owords), unaligned,
2527 (VISA_VectorOpnd*)address, (VISA_RawOpnd*)srcDst);
2528 return true;
2529 case SVM_BLOCK_ST:
2530 VISA_CALL_TO_BOOL(AppendVISASvmBlockStoreInst,
2531 Get_VISA_Oword_Num_From_Number(owords), unaligned,
2532 (VISA_VectorOpnd*)address, (VISA_RawOpnd*)srcDst);
2533 return true;
2534 default:
2535 return false;
2536 }
2537
2538 return false;
2539 }
2540
CISA_create_svm_scatter_instruction(VISA_opnd * pred,SVMSubOpcode subopcode,VISA_EMask_Ctrl emask,unsigned exec_size,unsigned blockSize,unsigned numBlocks,VISA_opnd * addresses,VISA_opnd * srcDst,int lineNum)2541 bool CISA_IR_Builder::CISA_create_svm_scatter_instruction(
2542 VISA_opnd* pred,
2543 SVMSubOpcode subopcode,
2544 VISA_EMask_Ctrl emask,
2545 unsigned exec_size,
2546 unsigned blockSize,
2547 unsigned numBlocks,
2548 VISA_opnd* addresses,
2549 VISA_opnd* srcDst,
2550 int lineNum)
2551 {
2552 VISA_SVM_Block_Type blockType = valueToVISASVMBlockType(blockSize);
2553 VISA_SVM_Block_Num blockNum = valueToVISASVMBlockNum(numBlocks);
2554 switch (subopcode)
2555 {
2556 case SVM_SCATTER:
2557 VISA_CALL_TO_BOOL(AppendVISASvmScatterInst,
2558 (VISA_PredOpnd*)pred, emask, Get_VISA_Exec_Size_From_Raw_Size(exec_size),
2559 blockType, blockNum, (VISA_RawOpnd*)addresses, (VISA_RawOpnd*)srcDst);
2560 return true;
2561 case SVM_GATHER:
2562 VISA_CALL_TO_BOOL(AppendVISASvmGatherInst,
2563 (VISA_PredOpnd*)pred, emask, Get_VISA_Exec_Size_From_Raw_Size(exec_size),
2564 blockType, blockNum, (VISA_RawOpnd*)addresses, (VISA_RawOpnd*)srcDst);
2565 return true;
2566 default:
2567 return false;
2568 }
2569
2570
2571 return false;
2572 }
2573
2574 bool
CISA_create_svm_gather4_scaled(VISA_opnd * pred,VISA_EMask_Ctrl eMask,unsigned execSize,ChannelMask chMask,VISA_opnd * address,VISA_opnd * offsets,VISA_opnd * dst,int lineNum)2575 CISA_IR_Builder::CISA_create_svm_gather4_scaled(
2576 VISA_opnd *pred,
2577 VISA_EMask_Ctrl eMask,
2578 unsigned execSize,
2579 ChannelMask chMask,
2580 VISA_opnd *address,
2581 VISA_opnd *offsets,
2582 VISA_opnd *dst,
2583 int lineNum)
2584 {
2585 VISA_CALL_TO_BOOL(AppendVISASvmGather4ScaledInst,
2586 static_cast<VISA_PredOpnd *>(pred),
2587 eMask,
2588 Get_VISA_Exec_Size_From_Raw_Size(execSize),
2589 chMask.getAPI(),
2590 static_cast<VISA_VectorOpnd *>(address),
2591 static_cast<VISA_RawOpnd *>(offsets),
2592 static_cast<VISA_RawOpnd *>(dst));
2593
2594 return true;
2595 }
2596
CISA_create_svm_scatter4_scaled(VISA_opnd * pred,VISA_EMask_Ctrl eMask,unsigned execSize,ChannelMask chMask,VISA_opnd * address,VISA_opnd * offsets,VISA_opnd * src,int lineNum)2597 bool CISA_IR_Builder::CISA_create_svm_scatter4_scaled(
2598 VISA_opnd *pred,
2599 VISA_EMask_Ctrl eMask,
2600 unsigned execSize,
2601 ChannelMask chMask,
2602 VISA_opnd *address,
2603 VISA_opnd *offsets,
2604 VISA_opnd *src,
2605 int lineNum)
2606 {
2607 VISA_CALL_TO_BOOL(AppendVISASvmScatter4ScaledInst,
2608 static_cast<VISA_PredOpnd *>(pred),
2609 eMask,
2610 Get_VISA_Exec_Size_From_Raw_Size(execSize),
2611 chMask.getAPI(),
2612 static_cast<VISA_VectorOpnd *>(address),
2613 static_cast<VISA_RawOpnd *>(offsets),
2614 static_cast<VISA_RawOpnd *>(src));
2615
2616 return true;
2617 }
2618
CISA_create_svm_atomic_instruction(VISA_opnd * pred,VISA_EMask_Ctrl emask,unsigned exec_size,VISAAtomicOps op,unsigned short bitwidth,VISA_opnd * addresses,VISA_opnd * src0,VISA_opnd * src1,VISA_opnd * dst,int lineNum)2619 bool CISA_IR_Builder::CISA_create_svm_atomic_instruction(
2620 VISA_opnd* pred,
2621 VISA_EMask_Ctrl emask,
2622 unsigned exec_size,
2623 VISAAtomicOps op,
2624 unsigned short bitwidth,
2625 VISA_opnd* addresses,
2626 VISA_opnd* src0,
2627 VISA_opnd* src1,
2628 VISA_opnd* dst,
2629 int lineNum)
2630 {
2631 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2632 VISA_CALL_TO_BOOL(AppendVISASvmAtomicInst,
2633 (VISA_PredOpnd *)pred, emask, executionSize, op, bitwidth,
2634 (VISA_RawOpnd *)addresses, (VISA_RawOpnd *)src0, (VISA_RawOpnd *)src1,
2635 (VISA_RawOpnd *)dst);
2636 return true;
2637 }
2638
CISA_create_address_instruction(ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2639 bool CISA_IR_Builder::CISA_create_address_instruction(ISA_Opcode opcode,
2640 VISA_EMask_Ctrl emask,
2641 unsigned exec_size,
2642 VISA_opnd *dst,
2643 VISA_opnd *src0,
2644 VISA_opnd *src1,
2645 int lineNum)
2646 {
2647 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2648 VISA_CALL_TO_BOOL(AppendVISAAddrAddInst,
2649 emask, executionSize,
2650 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1);
2651 return true;
2652 }
2653
CISA_create_logic_instruction(VISA_opnd * pred,ISA_Opcode opcode,bool sat,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,VISA_opnd * src2,VISA_opnd * src3,int lineNum)2654 bool CISA_IR_Builder::CISA_create_logic_instruction(
2655 VISA_opnd *pred,
2656 ISA_Opcode opcode,
2657 bool sat,
2658 VISA_EMask_Ctrl emask,
2659 unsigned exec_size,
2660 VISA_opnd *dst,
2661 VISA_opnd *src0,
2662 VISA_opnd *src1,
2663 VISA_opnd *src2,
2664 VISA_opnd *src3,
2665 int lineNum)
2666 {
2667 if (opcode != ISA_SHR &&
2668 opcode != ISA_SHL &&
2669 opcode != ISA_ASR)
2670 {
2671 if (sat) {
2672 RecordParseError(lineNum, "saturation is not supported on this op");
2673 }
2674 sat = false;
2675 // fallthrough
2676 }
2677
2678 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2679 VISA_CALL_TO_BOOL(AppendVISALogicOrShiftInst,
2680 opcode, (VISA_PredOpnd *)pred, sat, emask, executionSize,
2681 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1,
2682 (VISA_VectorOpnd *)src2, (VISA_VectorOpnd *)src3);
2683 return true;
2684 }
2685
CISA_create_logic_instruction(ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,CISA_GEN_VAR * dst,CISA_GEN_VAR * src0,CISA_GEN_VAR * src1,int lineNum)2686 bool CISA_IR_Builder::CISA_create_logic_instruction(
2687 ISA_Opcode opcode,
2688 VISA_EMask_Ctrl emask,
2689 unsigned exec_size,
2690 CISA_GEN_VAR *dst,
2691 CISA_GEN_VAR *src0,
2692 CISA_GEN_VAR *src1,
2693 int lineNum)
2694 {
2695 if (opcode != ISA_AND &&
2696 opcode != ISA_OR &&
2697 opcode != ISA_NOT &&
2698 opcode != ISA_XOR)
2699 {
2700 RecordParseError(lineNum, "prediate variables are not supported for this op");
2701 return false;
2702 }
2703 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2704 if (!dst) {
2705 RecordParseError(lineNum, "null dst in logic op");
2706 }
2707 if (!src0) {
2708 RecordParseError(lineNum, "null src0 in logic op");
2709 }
2710 if (opcode != ISA_NOT)
2711 {
2712 if (!src1) {
2713 RecordParseError(lineNum, "null src1 in logic op");
2714 }
2715 }
2716 VISA_CALL_TO_BOOL(AppendVISALogicOrShiftInst,
2717 opcode, emask, executionSize,
2718 (VISA_PredVar *)dst, (VISA_PredVar *)src0, (VISA_PredVar *)src1);
2719 return true;
2720 }
2721
CISA_create_math_instruction(VISA_opnd * pred,ISA_Opcode opcode,bool sat,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2722 bool CISA_IR_Builder::CISA_create_math_instruction(
2723 VISA_opnd *pred,
2724 ISA_Opcode opcode,
2725 bool sat,
2726 VISA_EMask_Ctrl emask,
2727 unsigned exec_size,
2728 VISA_opnd *dst,
2729 VISA_opnd *src0,
2730 VISA_opnd *src1,
2731 int lineNum)
2732 {
2733 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2734 VISA_CALL_TO_BOOL(AppendVISAArithmeticInst,
2735 opcode, (VISA_PredOpnd *)pred, sat, emask, executionSize,
2736 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1, NULL);
2737 return true;
2738 }
2739
CISA_create_setp_instruction(ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,CISA_GEN_VAR * dst,VISA_opnd * src0,int lineNum)2740 bool CISA_IR_Builder::CISA_create_setp_instruction(
2741 ISA_Opcode opcode,
2742 VISA_EMask_Ctrl emask,
2743 unsigned exec_size,
2744 CISA_GEN_VAR * dst,
2745 VISA_opnd *src0,
2746 int lineNum)
2747 {
2748 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2749 VISA_CALL_TO_BOOL(AppendVISASetP,
2750 emask, executionSize, (VISA_PredVar *)dst, (VISA_VectorOpnd *)src0);
2751 return true;
2752 }
2753
CISA_create_sel_instruction(ISA_Opcode opcode,bool sat,VISA_opnd * pred,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2754 bool CISA_IR_Builder::CISA_create_sel_instruction(
2755 ISA_Opcode opcode,
2756 bool sat,
2757 VISA_opnd *pred,
2758 VISA_EMask_Ctrl emask,
2759 unsigned exec_size,
2760 VISA_opnd *dst,
2761 VISA_opnd *src0,
2762 VISA_opnd *src1,
2763 int lineNum)
2764 {
2765 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2766 VISA_CALL_TO_BOOL(AppendVISADataMovementInst,
2767 opcode, (VISA_PredOpnd*)pred, sat, emask, executionSize,
2768 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1);
2769 return true;
2770 }
2771
CISA_create_fminmax_instruction(bool minmax,ISA_Opcode opcode,bool sat,VISA_opnd * pred,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,VISA_opnd * src1,int lineNum)2772 bool CISA_IR_Builder::CISA_create_fminmax_instruction(
2773 bool minmax,
2774 ISA_Opcode opcode,
2775 bool sat,
2776 VISA_opnd *pred,
2777 VISA_EMask_Ctrl emask,
2778 unsigned exec_size,
2779 VISA_opnd *dst,
2780 VISA_opnd *src0,
2781 VISA_opnd *src1,
2782 int lineNum)
2783 {
2784 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2785 VISA_CALL_TO_BOOL(AppendVISAMinMaxInst,
2786 (minmax ? CISA_DM_FMAX : CISA_DM_FMIN), sat, emask, executionSize,
2787 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1);
2788 return true;
2789 }
2790
CISA_create_scatter_instruction(ISA_Opcode opcode,int elt_size,VISA_EMask_Ctrl emask,unsigned elemNum,bool modifier,const char * surfaceName,VISA_opnd * global_offset,VISA_opnd * element_offset,VISA_opnd * raw_dst_src,int lineNum)2791 bool CISA_IR_Builder::CISA_create_scatter_instruction(
2792 ISA_Opcode opcode,
2793 int elt_size,
2794 VISA_EMask_Ctrl emask,
2795 unsigned elemNum,
2796 bool modifier,
2797 const char *surfaceName,
2798 VISA_opnd *global_offset, //global_offset
2799 VISA_opnd *element_offset, //element_offset
2800 VISA_opnd *raw_dst_src, //dst/src
2801 int lineNum)
2802 {
2803 // GATHER 0x39 (GATHER) Elt_size Is_modified Num_elts Surface Global_Offset Element_Offset Dst
2804 // SCATTER 0x3A (SCATTER) Elt_size Num_elts Surface Global_Offset Element_Offset Src
2805 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2806 if (!surface)
2807 return false; // error recorded
2808
2809 if (elemNum != 16 && elemNum != 8 && elemNum != 1) {
2810 RecordParseError(lineNum,
2811 "unsupported number of elements for gather/scatter instruction.");
2812 }
2813
2814 VISA_Exec_Size executionSize = EXEC_SIZE_16;
2815 if (elemNum == 16)
2816 {
2817 executionSize = EXEC_SIZE_16;
2818 }
2819 else if (elemNum == 8)
2820 {
2821 executionSize = EXEC_SIZE_8;
2822 }
2823 else if (elemNum == 1)
2824 {
2825 executionSize = EXEC_SIZE_1;
2826 }
2827
2828 GATHER_SCATTER_ELEMENT_SIZE elementSize = GATHER_SCATTER_BYTE_UNDEF;
2829 if (elt_size == 1)
2830 {
2831 elementSize = GATHER_SCATTER_BYTE;
2832 }else if (elt_size == 2)
2833 {
2834 elementSize = GATHER_SCATTER_WORD;
2835 }else if (elt_size == 4)
2836 {
2837 elementSize = GATHER_SCATTER_DWORD;
2838 }
2839
2840 VISA_CALL_TO_BOOL(AppendVISASurfAccessGatherScatterInst,
2841 opcode, emask, elementSize, executionSize, surface,
2842 (VISA_VectorOpnd *)global_offset, (VISA_RawOpnd *)element_offset,
2843 (VISA_RawOpnd *)raw_dst_src);
2844 return true;
2845 }
2846
CISA_create_scatter4_typed_instruction(ISA_Opcode opcode,VISA_opnd * pred,ChannelMask ch_mask,VISA_EMask_Ctrl emask,unsigned execSize,const char * surfaceName,VISA_opnd * uOffset,VISA_opnd * vOffset,VISA_opnd * rOffset,VISA_opnd * lod,VISA_opnd * dst,int lineNum)2847 bool CISA_IR_Builder::CISA_create_scatter4_typed_instruction(
2848 ISA_Opcode opcode,
2849 VISA_opnd *pred,
2850 ChannelMask ch_mask,
2851 VISA_EMask_Ctrl emask,
2852 unsigned execSize,
2853 const char* surfaceName,
2854 VISA_opnd *uOffset,
2855 VISA_opnd *vOffset,
2856 VISA_opnd *rOffset,
2857 VISA_opnd *lod,
2858 VISA_opnd *dst,
2859 int lineNum)
2860 {
2861 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2862 if (!surface)
2863 return false; // error recorded
2864
2865 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(execSize);
2866 VISA_CALL_TO_BOOL(AppendVISASurfAccessGather4Scatter4TypedInst,
2867 opcode, (VISA_PredOpnd *)pred, ch_mask.getAPI(), emask, executionSize, surface,
2868 (VISA_RawOpnd *)uOffset, (VISA_RawOpnd *)vOffset, (VISA_RawOpnd *)rOffset,
2869 (VISA_RawOpnd *)lod, (VISA_RawOpnd*)dst);
2870 return true;
2871 }
2872
CISA_create_scatter4_scaled_instruction(ISA_Opcode opcode,VISA_opnd * pred,VISA_EMask_Ctrl eMask,unsigned execSize,ChannelMask chMask,const char * surfaceName,VISA_opnd * globalOffset,VISA_opnd * offsets,VISA_opnd * dstSrc,int lineNum)2873 bool CISA_IR_Builder::CISA_create_scatter4_scaled_instruction(
2874 ISA_Opcode opcode,
2875 VISA_opnd *pred,
2876 VISA_EMask_Ctrl eMask,
2877 unsigned execSize,
2878 ChannelMask chMask,
2879 const char *surfaceName,
2880 VISA_opnd *globalOffset,
2881 VISA_opnd *offsets,
2882 VISA_opnd *dstSrc,
2883 int lineNum)
2884 {
2885 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2886 if (!surface)
2887 return false; // error recorded
2888
2889 VISA_CALL_TO_BOOL(AppendVISASurfAccessGather4Scatter4ScaledInst,
2890 opcode, static_cast<VISA_PredOpnd *>(pred),
2891 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
2892 chMask.getAPI(),
2893 surface,
2894 static_cast<VISA_VectorOpnd *>(globalOffset),
2895 static_cast<VISA_RawOpnd *>(offsets),
2896 static_cast<VISA_RawOpnd *>(dstSrc));
2897
2898 return true;
2899 }
2900
CISA_create_scatter_scaled_instruction(ISA_Opcode opcode,VISA_opnd * pred,VISA_EMask_Ctrl eMask,unsigned execSize,unsigned numBlocks,const char * surfaceName,VISA_opnd * globalOffset,VISA_opnd * offsets,VISA_opnd * dstSrc,int lineNum)2901 bool CISA_IR_Builder::CISA_create_scatter_scaled_instruction(
2902 ISA_Opcode opcode,
2903 VISA_opnd *pred,
2904 VISA_EMask_Ctrl eMask,
2905 unsigned execSize,
2906 unsigned numBlocks,
2907 const char *surfaceName,
2908 VISA_opnd *globalOffset,
2909 VISA_opnd *offsets,
2910 VISA_opnd *dstSrc,
2911 int lineNum)
2912 {
2913 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
2914 if (!surface)
2915 return false; // error recorded
2916
2917 VISA_CALL_TO_BOOL(AppendVISASurfAccessScatterScaledInst,
2918 opcode, static_cast<VISA_PredOpnd *>(pred),
2919 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
2920 valueToVISASVMBlockNum(numBlocks),
2921 surface,
2922 static_cast<VISA_VectorOpnd *>(globalOffset),
2923 static_cast<VISA_RawOpnd *>(offsets),
2924 static_cast<VISA_RawOpnd *>(dstSrc));
2925
2926 return true;
2927 }
2928
CISA_create_sync_instruction(ISA_Opcode opcode,int lineNum)2929 bool CISA_IR_Builder::CISA_create_sync_instruction(ISA_Opcode opcode, int lineNum)
2930 {
2931 VISA_CALL_TO_BOOL(AppendVISASyncInst, opcode);
2932 return true;
2933 }
2934
CISA_create_sbarrier_instruction(bool isSignal,int lineNum)2935 bool CISA_IR_Builder::CISA_create_sbarrier_instruction(bool isSignal, int lineNum)
2936 {
2937 VISA_CALL_TO_BOOL(AppendVISASplitBarrierInst, isSignal);
2938 return true;
2939 }
2940
CISA_create_FILE_instruction(ISA_Opcode opcode,const char * file_name,int lineNum)2941 bool CISA_IR_Builder::CISA_create_FILE_instruction(
2942 ISA_Opcode opcode, const char * file_name, int lineNum)
2943 {
2944 VISA_CALL_TO_BOOL(AppendVISAMiscFileInst, file_name);
2945 return true;
2946 }
2947
CISA_create_LOC_instruction(ISA_Opcode opcode,unsigned int loc,int lineNum)2948 bool CISA_IR_Builder::CISA_create_LOC_instruction(
2949 ISA_Opcode opcode, unsigned int loc, int lineNum)
2950 {
2951 VISA_CALL_TO_BOOL(AppendVISAMiscLOC, loc);
2952 return true;
2953 }
2954
CISA_create_invtri_inst(VISA_opnd * pred,ISA_Opcode opcode,bool sat,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,int lineNum)2955 bool CISA_IR_Builder::CISA_create_invtri_inst(
2956 VISA_opnd *pred,
2957 ISA_Opcode opcode,
2958 bool sat,
2959 VISA_EMask_Ctrl emask,
2960 unsigned exec_size,
2961 VISA_opnd *dst,
2962 VISA_opnd *src0,
2963 int lineNum)
2964 {
2965 int num_operands = 0;
2966 VISA_INST_Desc *inst_desc = NULL;
2967 VISA_opnd *opnd[4];
2968 inst_desc = &CISA_INST_table[opcode];
2969 VISA_Modifier mod = MODIFIER_NONE;
2970
2971 if (sat)
2972 mod = MODIFIER_SAT;
2973
2974 if (dst != NULL)
2975 {
2976 dst->_opnd.v_opnd.tag += mod<<3;
2977 opnd[num_operands] = dst;
2978 num_operands ++;
2979 }
2980
2981 if (src0 != NULL)
2982 {
2983 opnd[num_operands] = src0;
2984 num_operands ++;
2985 }
2986
2987 PredicateOpnd predOpnd = pred ? pred->convertToPred() : PredicateOpnd::getNullPred();
2988 CisaFramework::CisaInst * inst = new(m_mem)CisaFramework::CisaInst(m_mem);
2989
2990 unsigned char size = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
2991 size += emask << 4;
2992 inst->createCisaInstruction(opcode, size, 0, predOpnd, opnd, num_operands, inst_desc);
2993 m_kernel->addInstructionToEnd(inst);
2994
2995 return true;
2996 }
2997
CISA_create_dword_atomic_instruction(VISA_opnd * pred,VISAAtomicOps subOpc,bool is16Bit,VISA_EMask_Ctrl eMask,unsigned execSize,const char * surfaceName,VISA_opnd * offsets,VISA_opnd * src0,VISA_opnd * src1,VISA_opnd * dst,int lineNum)2998 bool CISA_IR_Builder::CISA_create_dword_atomic_instruction(
2999 VISA_opnd *pred,
3000 VISAAtomicOps subOpc,
3001 bool is16Bit,
3002 VISA_EMask_Ctrl eMask,
3003 unsigned execSize,
3004 const char *surfaceName,
3005 VISA_opnd *offsets,
3006 VISA_opnd *src0,
3007 VISA_opnd *src1,
3008 VISA_opnd *dst,
3009 int lineNum)
3010 {
3011 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3012 if (!surface)
3013 return false; // error recorded
3014
3015 VISA_CALL_TO_BOOL(AppendVISASurfAccessDwordAtomicInst,
3016 static_cast<VISA_PredOpnd *>(pred),
3017 subOpc,
3018 is16Bit,
3019 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
3020 surface,
3021 static_cast<VISA_RawOpnd *>(offsets),
3022 static_cast<VISA_RawOpnd *>(src0),
3023 static_cast<VISA_RawOpnd *>(src1),
3024 static_cast<VISA_RawOpnd *>(dst));
3025
3026 return true;
3027 }
3028
CISA_create_typed_atomic_instruction(VISA_opnd * pred,VISAAtomicOps subOpc,bool is16Bit,VISA_EMask_Ctrl eMask,unsigned execSize,const char * surfaceName,VISA_opnd * u,VISA_opnd * v,VISA_opnd * r,VISA_opnd * lod,VISA_opnd * src0,VISA_opnd * src1,VISA_opnd * dst,int lineNum)3029 bool CISA_IR_Builder::CISA_create_typed_atomic_instruction(
3030 VISA_opnd *pred,
3031 VISAAtomicOps subOpc,
3032 bool is16Bit,
3033 VISA_EMask_Ctrl eMask,
3034 unsigned execSize,
3035 const char *surfaceName,
3036 VISA_opnd *u,
3037 VISA_opnd *v,
3038 VISA_opnd *r,
3039 VISA_opnd *lod,
3040 VISA_opnd *src0,
3041 VISA_opnd *src1,
3042 VISA_opnd *dst,
3043 int lineNum)
3044 {
3045 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3046 if (!surface)
3047 return false; // error recorded
3048
3049 VISA_CALL_TO_BOOL(AppendVISA3dTypedAtomic,
3050 subOpc,
3051 is16Bit,
3052 static_cast<VISA_PredOpnd *>(pred),
3053 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
3054 surface,
3055 static_cast<VISA_RawOpnd *>(u),
3056 static_cast<VISA_RawOpnd *>(v),
3057 static_cast<VISA_RawOpnd *>(r),
3058 static_cast<VISA_RawOpnd *>(lod),
3059 static_cast<VISA_RawOpnd *>(src0),
3060 static_cast<VISA_RawOpnd *>(src1),
3061 static_cast<VISA_RawOpnd *>(dst));
3062
3063 return true;
3064 }
3065
CISA_create_avs_instruction(ChannelMask channel,const char * surfaceName,const char * samplerName,VISA_opnd * u_offset,VISA_opnd * v_offset,VISA_opnd * deltaU,VISA_opnd * deltaV,VISA_opnd * u2d,VISA_opnd * groupID,VISA_opnd * verticalBlockNumber,OutputFormatControl cntrl,VISA_opnd * v2d,AVSExecMode execMode,VISA_opnd * iefbypass,VISA_opnd * dst,int lineNum)3066 bool CISA_IR_Builder::CISA_create_avs_instruction(
3067 ChannelMask channel,
3068 const char* surfaceName,
3069 const char* samplerName,
3070 VISA_opnd *u_offset,
3071 VISA_opnd *v_offset,
3072 VISA_opnd *deltaU,
3073 VISA_opnd *deltaV,
3074 VISA_opnd *u2d,
3075 VISA_opnd *groupID,
3076 VISA_opnd *verticalBlockNumber,
3077 OutputFormatControl cntrl,
3078 VISA_opnd *v2d,
3079 AVSExecMode execMode,
3080 VISA_opnd *iefbypass,
3081 VISA_opnd *dst,
3082 int lineNum)
3083 {
3084 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3085 if (!surface)
3086 return false; // error recorded
3087
3088 VISA_StateOpndHandle *sampler = CISA_get_sampler_variable(samplerName, lineNum);
3089 if (!sampler)
3090 return false; // error already reported
3091
3092 VISA_CALL_TO_BOOL(AppendVISAMEAVS,
3093 surface, sampler, channel.getAPI(),
3094 (VISA_VectorOpnd *)u_offset, (VISA_VectorOpnd *)v_offset, (VISA_VectorOpnd *)deltaU,
3095 (VISA_VectorOpnd *)deltaV, (VISA_VectorOpnd *)u2d, (VISA_VectorOpnd *)v2d,
3096 (VISA_VectorOpnd *)groupID, (VISA_VectorOpnd *)verticalBlockNumber, cntrl,
3097 execMode, (VISA_VectorOpnd *)iefbypass, (VISA_RawOpnd *)dst);
3098 return true;
3099 }
3100
CISA_create_urb_write_3d_instruction(VISA_opnd * pred,VISA_EMask_Ctrl emask,unsigned exec_size,unsigned int num_out,unsigned int global_offset,VISA_opnd * channel_mask,VISA_opnd * urb_handle,VISA_opnd * per_slot_offset,VISA_opnd * vertex_data,int lineNum)3101 bool CISA_IR_Builder::CISA_create_urb_write_3d_instruction(
3102 VISA_opnd* pred,
3103 VISA_EMask_Ctrl emask,
3104 unsigned exec_size,
3105 unsigned int num_out,
3106 unsigned int global_offset,
3107 VISA_opnd* channel_mask,
3108 VISA_opnd* urb_handle,
3109 VISA_opnd* per_slot_offset,
3110 VISA_opnd* vertex_data,
3111 int lineNum)
3112 {
3113 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3114 VISA_CALL_TO_BOOL(AppendVISA3dURBWrite,
3115 (VISA_PredOpnd*)pred, emask, executionSize, (unsigned char)num_out,
3116 (VISA_RawOpnd*) channel_mask, (unsigned short)global_offset,
3117 (VISA_RawOpnd*)urb_handle, (VISA_RawOpnd*)per_slot_offset, (VISA_RawOpnd*)vertex_data);
3118 return true;
3119 }
3120
CISA_create_rtwrite_3d_instruction(VISA_opnd * pred,const char * mode,VISA_EMask_Ctrl emask,unsigned exec_size,const char * surfaceName,const std::vector<VISA_opnd * > & operands,int lineNum)3121 bool CISA_IR_Builder::CISA_create_rtwrite_3d_instruction(
3122 VISA_opnd* pred,
3123 const char* mode,
3124 VISA_EMask_Ctrl emask,
3125 unsigned exec_size,
3126 const char* surfaceName,
3127 const std::vector<VISA_opnd*> &operands,
3128 int lineNum)
3129 {
3130 vISA_RT_CONTROLS cntrls;
3131
3132 memset(&cntrls, 0, sizeof(vISA_RT_CONTROLS));
3133
3134 VISA_opnd* s0a = NULL;
3135 VISA_opnd* oM = NULL;
3136 VISA_opnd* R = NULL;
3137 VISA_opnd* G = NULL;
3138 VISA_opnd* B = NULL;
3139 VISA_opnd* A = NULL;
3140 VISA_opnd* Z = NULL;
3141 VISA_opnd* Stencil = NULL;
3142 VISA_opnd *CPSCounter = NULL;
3143 VISA_opnd *SamplerIndex = NULL;
3144 VISA_opnd *r1Header = NULL;
3145 VISA_opnd *rti = NULL;
3146 uint8_t counter = 0;
3147
3148 r1Header = operands[counter++];
3149
3150 if (mode != NULL)
3151 {
3152 if (strstr(mode, "<SI>"))
3153 {
3154 SamplerIndex = operands[counter++];
3155 }
3156
3157 if (strstr(mode, "<CPS>"))
3158 {
3159 CPSCounter = operands[counter++];
3160 }
3161
3162 if (strstr(mode, "<RTI>"))
3163 {
3164 cntrls.RTIndexPresent = true;
3165 rti = operands[counter++];
3166 }
3167
3168 if (strstr(mode, "<A>"))
3169 {
3170 cntrls.s0aPresent = true;
3171 s0a = operands[counter++];
3172 }
3173
3174 if (strstr(mode, "<O>"))
3175 {
3176 cntrls.oMPresent = true;
3177 oM = operands[counter++];
3178 }
3179 R = operands[counter++];
3180 G = operands[counter++];
3181 B = operands[counter++];
3182 A = operands[counter++];
3183
3184 if (strstr(mode, "<Z>"))
3185 {
3186 cntrls.zPresent = true;
3187 Z = operands[counter++];
3188 }
3189
3190 if (strstr(mode, "<ST>"))
3191 {
3192 cntrls.isStencil = true;
3193 Stencil = operands[counter++];
3194 }
3195
3196 if (strstr(mode, "<LRTW>"))
3197 {
3198 cntrls.isLastWrite = true;
3199
3200 }
3201
3202 if (strstr(mode, "<PS>"))
3203 {
3204 cntrls.isPerSample = true;
3205 }
3206
3207 if (strstr(mode, "CM"))
3208 {
3209 cntrls.isCoarseMode = true;
3210 }
3211
3212 if (strstr(mode, "NULLRT"))
3213 {
3214 cntrls.isNullRT = true;
3215 }
3216 }
3217 else
3218 {
3219 R = operands[counter++];
3220 G = operands[counter++];
3221 B = operands[counter++];
3222 A = operands[counter++];
3223 }
3224
3225 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3226 if (!surface)
3227 return false; // error recorded
3228
3229 uint8_t numMsgSpecificOpnd = 0;
3230 VISA_RawOpnd* rawOpnds[20];
3231
3232 #define APPEND_NON_NULL_RAW_OPND(opnd) \
3233 if (opnd != NULL) \
3234 { \
3235 rawOpnds[numMsgSpecificOpnd++] = (VISA_RawOpnd*)opnd; \
3236 }
3237
3238 APPEND_NON_NULL_RAW_OPND(s0a);
3239 APPEND_NON_NULL_RAW_OPND(oM);
3240 APPEND_NON_NULL_RAW_OPND(R);
3241 APPEND_NON_NULL_RAW_OPND(G);
3242 APPEND_NON_NULL_RAW_OPND(B);
3243 APPEND_NON_NULL_RAW_OPND(A);
3244 APPEND_NON_NULL_RAW_OPND(Z);
3245 APPEND_NON_NULL_RAW_OPND(Stencil);
3246 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3247 VISA_CALL_TO_BOOL(AppendVISA3dRTWriteCPS,
3248 (VISA_PredOpnd*)pred, emask, executionSize, (VISA_VectorOpnd*)rti,
3249 cntrls, surface, (VISA_RawOpnd*)r1Header, (VISA_VectorOpnd*)SamplerIndex,
3250 (VISA_VectorOpnd*)CPSCounter, numMsgSpecificOpnd, rawOpnds);
3251
3252 return true;
3253 }
3254
3255
CISA_create_info_3d_instruction(VISASampler3DSubOpCode subOpcode,VISA_EMask_Ctrl emask,unsigned exec_size,ChannelMask channel,const char * surfaceName,VISA_opnd * lod,VISA_opnd * dst,int lineNum)3256 bool CISA_IR_Builder::CISA_create_info_3d_instruction(
3257 VISASampler3DSubOpCode subOpcode,
3258 VISA_EMask_Ctrl emask,
3259 unsigned exec_size,
3260 ChannelMask channel,
3261 const char* surfaceName,
3262 VISA_opnd* lod,
3263 VISA_opnd* dst,
3264 int lineNum)
3265 {
3266 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3267 if (!surface)
3268 return false; // error recorded
3269
3270 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3271 VISA_CALL_TO_BOOL(AppendVISA3dInfo,
3272 subOpcode, emask, executionSize, channel.getAPI(), surface, (VISA_RawOpnd*)lod, (VISA_RawOpnd*)dst);
3273 return true;
3274 }
3275
createSample4Instruction(VISA_opnd * pred,VISASampler3DSubOpCode subOpcode,bool pixelNullMask,ChannelMask channel,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * aoffimmi,const char * samplerName,const char * surfaceName,VISA_opnd * dst,unsigned int numParameters,VISA_RawOpnd ** params,int lineNum)3276 bool CISA_IR_Builder::createSample4Instruction(
3277 VISA_opnd* pred,
3278 VISASampler3DSubOpCode subOpcode,
3279 bool pixelNullMask,
3280 ChannelMask channel,
3281 VISA_EMask_Ctrl emask,
3282 unsigned exec_size,
3283 VISA_opnd* aoffimmi,
3284 const char* samplerName,
3285 const char* surfaceName,
3286 VISA_opnd* dst,
3287 unsigned int numParameters,
3288 VISA_RawOpnd** params,
3289 int lineNum)
3290 {
3291 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3292 if (!surface)
3293 return false; // error recorded
3294
3295 VISA_StateOpndHandle *sampler = CISA_get_sampler_variable(samplerName, lineNum);
3296 if (!sampler)
3297 return false; // error already reported
3298
3299 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3300
3301 if (channel.getNumEnabledChannels() != 1) {
3302 RecordParseError(lineNum, "one one of R,G,B,A may be specified for sample4 instruction");
3303 return false;
3304 }
3305 int status = m_kernel->AppendVISA3dGather4(
3306 subOpcode, pixelNullMask, (VISA_PredOpnd*)pred, emask,
3307 executionSize, channel.getSingleChannel(), (VISA_VectorOpnd*) aoffimmi,
3308 sampler, surface,
3309 (VISA_RawOpnd*) dst, numParameters, params);
3310 VISA_RESULT_CALL_TO_BOOL(status);
3311 return true;
3312 }
3313
3314
create3DLoadInstruction(VISA_opnd * pred,VISASampler3DSubOpCode subOpcode,bool pixelNullMask,ChannelMask channels,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * aoffimmi,const char * surfaceName,VISA_opnd * dst,unsigned int numParameters,VISA_RawOpnd ** params,int lineNum)3315 bool CISA_IR_Builder::create3DLoadInstruction(
3316 VISA_opnd* pred,
3317 VISASampler3DSubOpCode subOpcode,
3318 bool pixelNullMask,
3319 ChannelMask channels,
3320 VISA_EMask_Ctrl emask,
3321 unsigned exec_size,
3322 VISA_opnd *aoffimmi,
3323 const char* surfaceName,
3324 VISA_opnd* dst,
3325 unsigned int numParameters,
3326 VISA_RawOpnd** params,
3327 int lineNum)
3328 {
3329 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3330 if (!surface)
3331 return false; // error recorded
3332
3333 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3334 int status = m_kernel->AppendVISA3dLoad(
3335 subOpcode, pixelNullMask, (VISA_PredOpnd*)pred, emask,
3336 executionSize, channels.getAPI(), (VISA_VectorOpnd*) aoffimmi, surface,
3337 (VISA_RawOpnd*) dst, numParameters, params);
3338 VISA_RESULT_CALL_TO_BOOL(status);
3339 return true;
3340 }
3341
create3DSampleInstruction(VISA_opnd * pred,VISASampler3DSubOpCode subOpcode,bool pixelNullMask,bool cpsEnable,bool uniformSampler,ChannelMask channels,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * aoffimmi,const char * samplerName,const char * surfaceName,VISA_opnd * dst,unsigned int numParameters,VISA_RawOpnd ** params,int lineNum)3342 bool CISA_IR_Builder::create3DSampleInstruction(
3343 VISA_opnd* pred,
3344 VISASampler3DSubOpCode subOpcode,
3345 bool pixelNullMask,
3346 bool cpsEnable,
3347 bool uniformSampler,
3348 ChannelMask channels,
3349 VISA_EMask_Ctrl emask,
3350 unsigned exec_size,
3351 VISA_opnd* aoffimmi,
3352 const char* samplerName,
3353 const char* surfaceName,
3354 VISA_opnd* dst,
3355 unsigned int numParameters,
3356 VISA_RawOpnd** params,
3357 int lineNum)
3358 {
3359 VISA_StateOpndHandle *surface = CISA_get_surface_variable(surfaceName, lineNum);
3360 if (!surface) {
3361 return false; // error already reported
3362 }
3363
3364 VISA_StateOpndHandle *sampler = CISA_get_sampler_variable(samplerName, lineNum);
3365 if (!sampler) {
3366 return false; // error already reported
3367 }
3368
3369 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3370
3371 int status = m_kernel->AppendVISA3dSampler(
3372 subOpcode, pixelNullMask, cpsEnable, uniformSampler,
3373 (VISA_PredOpnd*)pred, emask, executionSize, channels.getAPI(),
3374 (VISA_VectorOpnd*)aoffimmi, sampler, surface,
3375 (VISA_RawOpnd*)dst, numParameters, params);
3376 VISA_RESULT_CALL_TO_BOOL(status);
3377 return true;
3378 }
3379
CISA_create_sample_instruction(ISA_Opcode opcode,ChannelMask channel,int simd_mode,const char * samplerName,const char * surfaceName,VISA_opnd * u_opnd,VISA_opnd * v_opnd,VISA_opnd * r_opnd,VISA_opnd * dst,int lineNum)3380 bool CISA_IR_Builder::CISA_create_sample_instruction(
3381 ISA_Opcode opcode,
3382 ChannelMask channel,
3383 int simd_mode,
3384 const char* samplerName,
3385 const char* surfaceName,
3386 VISA_opnd *u_opnd,
3387 VISA_opnd *v_opnd,
3388 VISA_opnd *r_opnd,
3389 VISA_opnd *dst,
3390 int lineNum)
3391 {
3392 VISA_StateOpndHandle* surface = CISA_get_surface_variable(surfaceName, lineNum);
3393 if (!surface)
3394 return false; // error recorded
3395
3396 if (opcode == ISA_SAMPLE)
3397 {
3398 VISA_StateOpndHandle* sampler = CISA_get_sampler_variable(samplerName, lineNum);
3399 if (!sampler)
3400 return false; // error recorded
3401
3402 VISA_CALL_TO_BOOL(AppendVISASISample,
3403 vISA_EMASK_M1, surface, sampler, channel.getAPI(), simd_mode == 16,
3404 (VISA_RawOpnd*)u_opnd, (VISA_RawOpnd*)v_opnd, (VISA_RawOpnd*)r_opnd, (VISA_RawOpnd*)dst);
3405
3406 } else if (opcode == ISA_LOAD) {
3407 VISA_CALL_TO_BOOL(AppendVISASILoad,
3408 surface, channel.getAPI(), simd_mode == 16,
3409 (VISA_RawOpnd*)u_opnd, (VISA_RawOpnd*)v_opnd,
3410 (VISA_RawOpnd*)r_opnd, (VISA_RawOpnd*)dst);
3411 } else {
3412 RecordParseError(lineNum, (int)opcode, ": unsupported sampler mnemonic");
3413 return false;
3414 }
3415
3416 return true;
3417 }
3418
CISA_create_sampleunorm_instruction(ISA_Opcode opcode,ChannelMask channel,CHANNEL_OUTPUT_FORMAT out,const char * samplerName,const char * surfaceName,VISA_opnd * src0,VISA_opnd * src1,VISA_opnd * src2,VISA_opnd * src3,VISA_opnd * dst,int lineNum)3419 bool CISA_IR_Builder::CISA_create_sampleunorm_instruction(
3420 ISA_Opcode opcode,
3421 ChannelMask channel,
3422 CHANNEL_OUTPUT_FORMAT out,
3423 const char* samplerName,
3424 const char* surfaceName,
3425 VISA_opnd *src0,
3426 VISA_opnd *src1,
3427 VISA_opnd *src2,
3428 VISA_opnd *src3,
3429 VISA_opnd *dst,
3430 int lineNum)
3431 {
3432 VISA_StateOpndHandle* surface = CISA_get_surface_variable(surfaceName, lineNum);
3433 if (!surface)
3434 return false; // error recorded
3435
3436 VISA_StateOpndHandle* sampler = CISA_get_sampler_variable(samplerName, lineNum);
3437 if (!sampler)
3438 return false; // error recorded
3439
3440 VISA_CALL_TO_BOOL(AppendVISASISampleUnorm,
3441 surface, sampler, channel.getAPI(),
3442 (VISA_VectorOpnd *)src0, (VISA_VectorOpnd *)src1, (VISA_VectorOpnd *)src2,
3443 (VISA_VectorOpnd *)src3, (VISA_RawOpnd *)dst, out);
3444
3445 return true;
3446 }
3447
CISA_create_vme_ime_instruction(ISA_Opcode opcode,unsigned char stream_mode,unsigned char searchCtrl,VISA_opnd * input_opnd,VISA_opnd * ime_input_opnd,const char * surfaceName,VISA_opnd * ref0_opnd,VISA_opnd * ref1_opnd,VISA_opnd * costCenter_opnd,VISA_opnd * dst_opnd,int lineNum)3448 bool CISA_IR_Builder::CISA_create_vme_ime_instruction(
3449 ISA_Opcode opcode,
3450 unsigned char stream_mode,
3451 unsigned char searchCtrl,
3452 VISA_opnd *input_opnd,
3453 VISA_opnd *ime_input_opnd,
3454 const char* surfaceName,
3455 VISA_opnd *ref0_opnd,
3456 VISA_opnd *ref1_opnd,
3457 VISA_opnd *costCenter_opnd,
3458 VISA_opnd *dst_opnd,
3459 int lineNum)
3460 {
3461 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3462 if (!surface)
3463 return false; // error recorded
3464
3465 VISA_CALL_TO_BOOL(AppendVISAMiscVME_IME,
3466 surface, stream_mode, searchCtrl, (VISA_RawOpnd *)input_opnd,
3467 (VISA_RawOpnd *)ime_input_opnd, (VISA_RawOpnd *)ref0_opnd,
3468 (VISA_RawOpnd *)ref1_opnd, (VISA_RawOpnd *)costCenter_opnd,
3469 (VISA_RawOpnd *)dst_opnd);
3470
3471 return true;
3472 }
3473
CISA_create_vme_sic_instruction(ISA_Opcode opcode,VISA_opnd * input_opnd,VISA_opnd * sic_input_opnd,const char * surfaceName,VISA_opnd * dst,int lineNum)3474 bool CISA_IR_Builder::CISA_create_vme_sic_instruction(
3475 ISA_Opcode opcode,
3476 VISA_opnd *input_opnd,
3477 VISA_opnd *sic_input_opnd,
3478 const char* surfaceName,
3479 VISA_opnd *dst,
3480 int lineNum)
3481 {
3482 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3483 if (!surface)
3484 return false; // error recorded
3485
3486 VISA_CALL_TO_BOOL(AppendVISAMiscVME_SIC,
3487 surface,
3488 (VISA_RawOpnd *)input_opnd,
3489 (VISA_RawOpnd *)sic_input_opnd,
3490 (VISA_RawOpnd *)dst);
3491 return true;
3492 }
3493
CISA_create_vme_fbr_instruction(ISA_Opcode opcode,VISA_opnd * input_opnd,VISA_opnd * fbr_input_opnd,const char * surfaceName,VISA_opnd * fbrMbMode,VISA_opnd * fbrSubMbShape,VISA_opnd * fbrSubPredMode,VISA_opnd * dst,int lineNum)3494 bool CISA_IR_Builder::CISA_create_vme_fbr_instruction(
3495 ISA_Opcode opcode,
3496 VISA_opnd *input_opnd,
3497 VISA_opnd *fbr_input_opnd,
3498 const char* surfaceName,
3499 VISA_opnd* fbrMbMode,
3500 VISA_opnd* fbrSubMbShape,
3501 VISA_opnd* fbrSubPredMode,
3502 VISA_opnd *dst,
3503 int lineNum)
3504 {
3505 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
3506 if (!surface)
3507 return false; // error recorded
3508
3509 VISA_CALL_TO_BOOL(AppendVISAMiscVME_FBR,
3510 surface,
3511 (VISA_RawOpnd *)input_opnd, (VISA_RawOpnd *)fbr_input_opnd,
3512 (VISA_VectorOpnd *)fbrMbMode, (VISA_VectorOpnd *)fbrSubMbShape,
3513 (VISA_VectorOpnd *)fbrSubPredMode, (VISA_RawOpnd *)dst);
3514 return true;
3515 }
3516
CISA_create_NO_OPND_instruction(ISA_Opcode opcode,int lineNum)3517 bool CISA_IR_Builder::CISA_create_NO_OPND_instruction(ISA_Opcode opcode, int lineNum)
3518 {
3519 VISA_CALL_TO_BOOL(AppendVISASyncInst, opcode);
3520 return true;
3521 }
3522
CISA_create_switch_instruction(ISA_Opcode opcode,unsigned exec_size,VISA_opnd * indexOpnd,const std::deque<const char * > & labels,int lineNum)3523 bool CISA_IR_Builder::CISA_create_switch_instruction(
3524 ISA_Opcode opcode,
3525 unsigned exec_size,
3526 VISA_opnd *indexOpnd,
3527 const std::deque<const char*>& labels,
3528 int lineNum)
3529 {
3530 int numLabels = (int) labels.size();
3531 std::vector<VISA_LabelOpnd*> jmpTargets(numLabels);
3532 for (int i = 0; i < numLabels; ++i)
3533 {
3534 auto labelOpnd = m_kernel->getLabelOpndFromLabelName(labels[i]);
3535
3536 //forward jump label: create the label optimistically
3537 if (!labelOpnd)
3538 {
3539 VISA_CALL_TO_BOOL(CreateVISALabelVar, labelOpnd, labels[i], LABEL_BLOCK);
3540 if (!m_kernel->setLabelOpndNameMap(labels[i], labelOpnd, LABEL_BLOCK))
3541 return false;
3542 }
3543 jmpTargets[i] = labelOpnd;
3544 }
3545
3546 VISA_CALL_TO_BOOL(AppendVISACFSwitchJMPInst,
3547 (VISA_VectorOpnd *)indexOpnd,
3548 (uint8_t) numLabels,
3549 jmpTargets.data());
3550
3551 return true;
3552 }
3553
CISA_create_fcall_instruction(VISA_opnd * pred_opnd,ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,const char * funcName,unsigned arg_size,unsigned return_size,int lineNum)3554 bool CISA_IR_Builder::CISA_create_fcall_instruction(
3555 VISA_opnd *pred_opnd,
3556 ISA_Opcode opcode,
3557 VISA_EMask_Ctrl emask,
3558 unsigned exec_size,
3559 const char* funcName,
3560 unsigned arg_size,
3561 unsigned return_size,
3562 int lineNum) //last index
3563 {
3564 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3565 VISA_CALL_TO_BOOL(AppendVISACFFunctionCallInst,
3566 (VISA_PredOpnd *)pred_opnd,emask, executionSize, std::string(funcName),
3567 (unsigned char)arg_size, (unsigned char)return_size);
3568 return true;
3569 }
3570
CISA_create_ifcall_instruction(VISA_opnd * pred_opnd,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * funcAddr,unsigned arg_size,unsigned return_size,int lineNum)3571 bool CISA_IR_Builder::CISA_create_ifcall_instruction(VISA_opnd *pred_opnd,
3572 VISA_EMask_Ctrl emask,
3573 unsigned exec_size,
3574 VISA_opnd* funcAddr,
3575 unsigned arg_size,
3576 unsigned return_size,
3577 int lineNum) //last index
3578 {
3579 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3580 VISA_CALL_TO_BOOL(AppendVISACFIndirectFuncCallInst,
3581 (VISA_PredOpnd *)pred_opnd, emask, executionSize,
3582 (VISA_VectorOpnd*) funcAddr, (uint8_t) arg_size, (uint8_t) return_size);
3583 return true;
3584 }
3585
CISA_create_faddr_instruction(const char * sym_name,VISA_opnd * dst,int lineNum)3586 bool CISA_IR_Builder::CISA_create_faddr_instruction(
3587 const char* sym_name, VISA_opnd* dst, int lineNum)
3588 {
3589 VISA_CALL_TO_BOOL(AppendVISACFSymbolInst, std::string(sym_name), (VISA_VectorOpnd*) dst);
3590 return true;
3591 }
3592
CISA_create_raw_send_instruction(ISA_Opcode opcode,unsigned char modifier,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * pred_opnd,unsigned int exMsgDesc,unsigned char srcSize,unsigned char dstSize,VISA_opnd * Desc,VISA_opnd * Src,VISA_opnd * Dst,int lineNum)3593 bool CISA_IR_Builder::CISA_create_raw_send_instruction(
3594 ISA_Opcode opcode,
3595 unsigned char modifier,
3596 VISA_EMask_Ctrl emask,
3597 unsigned exec_size,
3598 VISA_opnd *pred_opnd,
3599 unsigned int exMsgDesc,
3600 unsigned char srcSize,
3601 unsigned char dstSize,
3602 VISA_opnd *Desc,
3603 VISA_opnd *Src,
3604 VISA_opnd *Dst,
3605 int lineNum)
3606 {
3607 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3608 VISA_CALL_TO_BOOL(AppendVISAMiscRawSend,
3609 (VISA_PredOpnd *) pred_opnd, emask, executionSize, modifier, exMsgDesc, srcSize, dstSize,
3610 (VISA_VectorOpnd *)Desc, (VISA_RawOpnd *)Src, (VISA_RawOpnd *)Dst);
3611 return true;
3612 }
3613
CISA_create_lifetime_inst(unsigned char startOrEnd,const char * src,int lineNum)3614 bool CISA_IR_Builder::CISA_create_lifetime_inst(
3615 unsigned char startOrEnd, const char *src, int lineNum)
3616 {
3617 // src is a string representation of variable.
3618 // Scan entire symbol table to find variable whose name
3619 // corresponds to src.
3620 CISA_GEN_VAR *cisaVar = m_kernel->getDeclFromName(src);
3621 if (!cisaVar) {
3622 RecordParseError(lineNum, "lifetime operand not found");
3623 return false;
3624 }
3625
3626 VISA_opnd *var = NULL;
3627 if (cisaVar->type == GENERAL_VAR) {
3628 var = CISA_create_gen_src_operand(src, 0, 1, 0, 0, 0, MODIFIER_NONE, lineNum);
3629 }
3630 else if (cisaVar->type == ADDRESS_VAR) {
3631 var = CISA_set_address_operand(cisaVar, 0, 1, (startOrEnd == 0), lineNum);
3632 }
3633 else if (cisaVar->type == PREDICATE_VAR) {
3634 var = CISA_create_predicate_operand(cisaVar, PredState_NO_INVERSE, PRED_CTRL_NON, lineNum);
3635 } else {
3636 RecordParseError(lineNum, src, ": invalid variable type for lifetime");
3637 return false;
3638 }
3639
3640 VISA_CALL_TO_BOOL(AppendVISALifetime,
3641 (VISAVarLifetime)startOrEnd, (VISA_VectorOpnd*)var);
3642 return true;
3643 }
3644
CISA_create_raw_sends_instruction(ISA_Opcode opcode,unsigned char modifier,bool hasEOT,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * pred_opnd,VISA_opnd * exMsgDesc,unsigned char ffid,unsigned char src0Size,unsigned char src1Size,unsigned char dstSize,VISA_opnd * Desc,VISA_opnd * Src0,VISA_opnd * Src1,VISA_opnd * Dst,int lineNum)3645 bool CISA_IR_Builder::CISA_create_raw_sends_instruction(
3646 ISA_Opcode opcode,
3647 unsigned char modifier,
3648 bool hasEOT,
3649 VISA_EMask_Ctrl emask,
3650 unsigned exec_size,
3651 VISA_opnd *pred_opnd,
3652 VISA_opnd *exMsgDesc,
3653 unsigned char ffid,
3654 unsigned char src0Size,
3655 unsigned char src1Size,
3656 unsigned char dstSize,
3657 VISA_opnd *Desc,
3658 VISA_opnd *Src0,
3659 VISA_opnd *Src1,
3660 VISA_opnd *Dst,
3661 int lineNum)
3662 {
3663 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
3664
3665 VISA_CALL_TO_BOOL(AppendVISAMiscRawSends,
3666 (VISA_PredOpnd *) pred_opnd, emask, executionSize, modifier, ffid,
3667 (VISA_VectorOpnd *)exMsgDesc, src0Size, src1Size, dstSize,
3668 (VISA_VectorOpnd *)Desc, (VISA_RawOpnd *)Src0, (VISA_RawOpnd *)Src1,
3669 (VISA_RawOpnd *)Dst, hasEOT);
3670
3671 return true;
3672 }
3673 /*
3674 Should be only called from CISA 2.4+
3675 */
CISA_create_fence_instruction(ISA_Opcode opcode,unsigned char mode,int lineNum)3676 bool CISA_IR_Builder::CISA_create_fence_instruction(ISA_Opcode opcode, unsigned char mode, int lineNum)
3677 {
3678 VISA_CALL_TO_BOOL(AppendVISASyncInst, opcode, mode);
3679 return true;
3680 }
3681
CISA_create_wait_instruction(VISA_opnd * mask,int lineNum)3682 bool CISA_IR_Builder::CISA_create_wait_instruction(VISA_opnd* mask, int lineNum)
3683 {
3684 VISA_CALL_TO_BOOL(AppendVISAWaitInst, (VISA_VectorOpnd*) mask);
3685 return true;
3686 }
3687
3688
3689 /*** CISA 3.0 and later ***/
CISA_create_yield_instruction(ISA_Opcode opcode,int lineNum)3690 bool CISA_IR_Builder::CISA_create_yield_instruction(ISA_Opcode opcode, int lineNum)
3691 {
3692 VISA_CALL_TO_BOOL(AppendVISASyncInst, opcode);
3693 return true;
3694 }
3695
CISA_create_gen_src_operand(const char * var_name,short v_stride,short width,short h_stride,unsigned char row_offset,unsigned char col_offset,VISA_Modifier mod,int lineNum)3696 VISA_opnd * CISA_IR_Builder::CISA_create_gen_src_operand(
3697 const char* var_name, short v_stride, short width, short h_stride,
3698 unsigned char row_offset, unsigned char col_offset, VISA_Modifier mod, int lineNum)
3699 {
3700 auto *decl = (VISA_GenVar*)m_kernel->getDeclFromName(var_name);
3701 if (!decl) {
3702 RecordParseError(lineNum, var_name, ": unbound identifier");
3703 return nullptr;
3704 } else if (decl->type != GENERAL_VAR) {
3705 RecordParseError(lineNum, var_name, ": not a general register variable");
3706 return nullptr;
3707 }
3708
3709 VISA_VectorOpnd *cisa_opnd = nullptr;
3710 int status = m_kernel->CreateVISASrcOperand(cisa_opnd, decl, mod, v_stride, width, h_stride, row_offset, col_offset);
3711 if (status != VISA_SUCCESS)
3712 RecordParseError(lineNum, "unknown error creating src operand");
3713 return (VISA_opnd *)cisa_opnd;
3714 }
3715
CISA_dst_general_operand(const char * var_name,unsigned char roff,unsigned char sroff,unsigned short hstride,int lineNum)3716 VISA_opnd * CISA_IR_Builder::CISA_dst_general_operand(
3717 const char * var_name,
3718 unsigned char roff, unsigned char sroff,
3719 unsigned short hstride, int lineNum)
3720 {
3721 auto *decl = (VISA_GenVar *)m_kernel->getDeclFromName(var_name);
3722 if (!decl) {
3723 RecordParseError(lineNum, var_name, ": unbound identifier");
3724 return nullptr;
3725 } else if (decl->type != GENERAL_VAR) {
3726 RecordParseError(lineNum, var_name, ": not a general register variable");
3727 return nullptr;
3728 }
3729
3730 VISA_VectorOpnd *cisa_opnd = nullptr;
3731 int status = m_kernel->CreateVISADstOperand(cisa_opnd, decl, hstride, roff, sroff);
3732 if (status != VISA_SUCCESS)
3733 RecordParseError(lineNum, "unknown error creating dst operand");
3734 return (VISA_opnd *)cisa_opnd;
3735 }
3736
CISA_Create_Attr(const char * AttrName,int64_t I64Val,const char * CStrVal)3737 attr_gen_struct* CISA_IR_Builder::CISA_Create_Attr(const char* AttrName, int64_t I64Val, const char* CStrVal)
3738 {
3739 attr_gen_struct* newAttr = (attr_gen_struct*)m_mem.alloc(sizeof(attr_gen_struct));
3740 Attributes::ID aID = Attributes::getAttributeID(AttrName);
3741 MUST_BE_TRUE(Attributes::isValid(aID), "vISA: unknown attribute!");
3742 if (Attributes::isInt32(aID) || Attributes::isBool(aID))
3743 {
3744 newAttr->isInt = true;
3745 // No i64 attribute value yet
3746 newAttr->value = (int32_t)I64Val;
3747 }
3748 else if (Attributes::isCStr(aID))
3749 {
3750 newAttr->isInt = false;
3751 newAttr->string_val = CStrVal;
3752 }
3753 newAttr->name = AttrName;
3754 newAttr->attr_set = true;
3755 return newAttr;
3756 }
3757
CISA_create_immed(uint64_t value,VISA_Type type,int lineNum)3758 VISA_opnd * CISA_IR_Builder::CISA_create_immed(uint64_t value, VISA_Type type, int lineNum)
3759 {
3760 VISA_VectorOpnd *cisa_opnd = NULL;
3761
3762 VISA_CALL_TO_NULLPTR(CreateVISAImmediate, cisa_opnd, &value, type);
3763 if (type == ISA_TYPE_Q || type == ISA_TYPE_UQ)
3764 {
3765 cisa_opnd->_opnd.v_opnd.opnd_val.const_opnd._val.lval = value;
3766 }
3767 else
3768 {
3769 cisa_opnd->_opnd.v_opnd.opnd_val.const_opnd._val.ival = (uint32_t)value;
3770 }
3771 return (VISA_opnd *)cisa_opnd;
3772 }
3773
CISA_create_float_immed(double value,VISA_Type type,int lineNum)3774 VISA_opnd * CISA_IR_Builder::CISA_create_float_immed(double value, VISA_Type type, int lineNum)
3775 {
3776 VISA_VectorOpnd *cisa_opnd = nullptr;
3777 if (type == ISA_TYPE_F)
3778 {
3779 float temp = (float)value;
3780 VISA_CALL_TO_NULLPTR(CreateVISAImmediate, cisa_opnd, &temp, type);
3781 }
3782 else
3783 {
3784 VISA_CALL_TO_NULLPTR(CreateVISAImmediate, cisa_opnd, &value, type);
3785 }
3786
3787 return (VISA_opnd *)cisa_opnd;
3788 }
3789
CISA_find_decl(const char * var_name)3790 CISA_GEN_VAR * CISA_IR_Builder::CISA_find_decl(const char *var_name)
3791 {
3792 return m_kernel->getDeclFromName(var_name);
3793 }
3794
CISA_set_address_operand(CISA_GEN_VAR * cisa_decl,unsigned char offset,short width,bool isDst,int lineNum)3795 VISA_opnd * CISA_IR_Builder::CISA_set_address_operand(
3796 CISA_GEN_VAR * cisa_decl, unsigned char offset, short width, bool isDst, int lineNum)
3797 {
3798 VISA_VectorOpnd *cisa_opnd = nullptr;
3799 VISA_CALL_TO_NULLPTR(CreateVISAAddressOperand,
3800 cisa_opnd, (VISA_AddrVar *)cisa_decl, offset, width, isDst);
3801
3802 return (VISA_opnd *)cisa_opnd;
3803 }
3804
CISA_set_address_expression(CISA_GEN_VAR * cisa_decl,short offset,int lineNum)3805 VISA_opnd * CISA_IR_Builder::CISA_set_address_expression(
3806 CISA_GEN_VAR *cisa_decl, short offset, int lineNum)
3807 {
3808 VISA_VectorOpnd *cisa_opnd = NULL;
3809 VISA_CALL_TO_NULLPTR(CreateVISAAddressOfOperand,
3810 cisa_opnd, (VISA_GenVar *)cisa_decl, offset);
3811 return (VISA_opnd *)cisa_opnd;
3812 }
3813
CISA_create_indirect(CISA_GEN_VAR * cisa_decl,VISA_Modifier mod,unsigned short row_offset,unsigned char col_offset,unsigned short immedOffset,unsigned short vertical_stride,unsigned short width,unsigned short horizontal_stride,VISA_Type type,int lineNum)3814 VISA_opnd * CISA_IR_Builder::CISA_create_indirect(
3815 CISA_GEN_VAR * cisa_decl, VISA_Modifier mod, unsigned short row_offset,
3816 unsigned char col_offset, unsigned short immedOffset,
3817 unsigned short vertical_stride, unsigned short width,
3818 unsigned short horizontal_stride, VISA_Type type, int lineNum)
3819 {
3820 VISA_VectorOpnd *cisa_opnd = NULL;
3821 VISA_CALL_TO_NULLPTR(CreateVISAIndirectSrcOperand,
3822 cisa_opnd, (VISA_AddrVar*)cisa_decl, mod, col_offset,
3823 immedOffset, vertical_stride, width, horizontal_stride, type);
3824 return cisa_opnd;
3825 }
3826
CISA_create_indirect_dst(CISA_GEN_VAR * cisa_decl,VISA_Modifier mod,unsigned short row_offset,unsigned char col_offset,unsigned short immedOffset,unsigned short horizontal_stride,VISA_Type type,int lineNum)3827 VISA_opnd * CISA_IR_Builder::CISA_create_indirect_dst(
3828 CISA_GEN_VAR * cisa_decl, VISA_Modifier mod, unsigned short row_offset,
3829 unsigned char col_offset, unsigned short immedOffset,
3830 unsigned short horizontal_stride, VISA_Type type, int lineNum)
3831 {
3832 MUST_BE_TRUE(cisa_decl->type == ADDRESS_VAR, "predication variable type is wrong"); // grammar enforced
3833 VISA_VectorOpnd *cisa_opnd = nullptr;
3834 VISA_CALL_TO_NULLPTR(CreateVISAIndirectDstOperand,
3835 cisa_opnd, (VISA_AddrVar*)cisa_decl, col_offset, immedOffset, horizontal_stride, type);
3836 return (VISA_opnd *)cisa_opnd;
3837 }
3838
CISA_create_state_operand(const char * var_name,unsigned char offset,int lineNum,bool isDst)3839 VISA_opnd * CISA_IR_Builder::CISA_create_state_operand(
3840 const char * var_name, unsigned char offset, int lineNum, bool isDst)
3841 {
3842 CISA_GEN_VAR *decl = m_kernel->getDeclFromName(var_name);
3843 if (decl == nullptr) {
3844 RecordParseError(lineNum, var_name, ": undefined state operand");
3845 return nullptr;
3846 }
3847
3848 VISA_VectorOpnd * cisa_opnd = nullptr;
3849 int status = VISA_SUCCESS;
3850 switch (decl->type)
3851 {
3852 case SURFACE_VAR:
3853 status = m_kernel->CreateVISAStateOperand(cisa_opnd, (VISA_SurfaceVar *)decl, offset, isDst);
3854 break;
3855 case SAMPLER_VAR:
3856 status = m_kernel->CreateVISAStateOperand(cisa_opnd, (VISA_SamplerVar *)decl, offset, isDst);
3857 break;
3858 default:
3859 RecordParseError(lineNum, var_name, ": invalid variable type for state operand");
3860 break;
3861 }
3862
3863 if (status != VISA_SUCCESS) {
3864 RecordParseError(lineNum, "unknown error creating state operand");
3865 }
3866
3867 return (VISA_opnd *)cisa_opnd;
3868 }
3869
CISA_create_predicate_operand(CISA_GEN_VAR * decl,VISA_PREDICATE_STATE state,VISA_PREDICATE_CONTROL control,int lineNum)3870 VISA_opnd * CISA_IR_Builder::CISA_create_predicate_operand(
3871 CISA_GEN_VAR *decl, VISA_PREDICATE_STATE state,
3872 VISA_PREDICATE_CONTROL control, int lineNum)
3873 {
3874 MUST_BE_TRUE1(decl->type == PREDICATE_VAR, lineNum, "predication variable type is wrong"); // parser enforces type
3875 VISA_PredOpnd *cisa_opnd = nullptr;
3876 int status = m_kernel->CreateVISAPredicateOperand(cisa_opnd, (VISA_PredVar *)decl, state, control);
3877 MUST_BE_TRUE1((status == VISA_SUCCESS), lineNum, "Failed to create predicate operand.");
3878 if (status != VISA_SUCCESS) {
3879 RecordParseError(lineNum, "unknown error creating predicate operand");
3880 }
3881 return (VISA_opnd *)cisa_opnd;
3882 }
3883
CISA_create_RAW_NULL_operand(int lineNum)3884 VISA_opnd * CISA_IR_Builder::CISA_create_RAW_NULL_operand(int lineNum)
3885 {
3886 VISA_RawOpnd *cisa_opnd = nullptr;
3887 int status = m_kernel->CreateVISANullRawOperand(cisa_opnd, true);
3888 MUST_BE_TRUE1(status == VISA_SUCCESS, lineNum, "Was not able to create NULL RAW operand.");
3889 if (status != VISA_SUCCESS) {
3890 RecordParseError(lineNum, "unknown error creating raw null operand");
3891 }
3892 return (VISA_opnd *)cisa_opnd;
3893 }
3894
CISA_create_RAW_operand(const char * var_name,unsigned short offset,int lineNum)3895 VISA_opnd * CISA_IR_Builder::CISA_create_RAW_operand(
3896 const char * var_name, unsigned short offset, int lineNum)
3897 {
3898 VISA_RawOpnd *cisa_opnd = NULL;
3899 auto *decl = (VISA_GenVar *)m_kernel->getDeclFromName(var_name);
3900 if (decl == nullptr) {
3901 RecordParseError(lineNum, var_name, ": undefined raw operand variable");
3902 return nullptr;
3903 }
3904 int status = m_kernel->CreateVISARawOperand(cisa_opnd, decl, offset);
3905 if (status != VISA_SUCCESS) {
3906 RecordParseError(lineNum, "unknown error creating raw operand");
3907 }
3908 return (VISA_opnd *)cisa_opnd; // delay the decision of src or dst until translate stage
3909 }
3910
CISA_push_decl_scope()3911 void CISA_IR_Builder::CISA_push_decl_scope()
3912 {
3913 m_kernel->pushIndexMapScopeLevel();
3914 }
CISA_pop_decl_scope()3915 void CISA_IR_Builder::CISA_pop_decl_scope()
3916 {
3917 m_kernel->popIndexMapScopeLevel();
3918 }
3919
get_hash_key(const char * str)3920 unsigned short CISA_IR_Builder::get_hash_key(const char* str)
3921 {
3922 const char *str_pt = str;
3923 unsigned short key=0;
3924 unsigned char c;
3925 while ((c = *str_pt++) != '\0') key = (key+c)<<1;
3926
3927 return key % HASH_TABLE_SIZE;
3928 }
new_string_pool()3929 string_pool_entry** CISA_IR_Builder::new_string_pool()
3930 {
3931 string_pool_entry ** sp =
3932 (string_pool_entry**)m_mem.alloc(sizeof(string_pool_entry *) * HASH_TABLE_SIZE);
3933 memset(sp, 0, sizeof(string_pool_entry *) * HASH_TABLE_SIZE);
3934
3935 return sp;
3936 }
3937
string_pool_lookup(string_pool_entry ** spool,const char * str)3938 string_pool_entry * CISA_IR_Builder::string_pool_lookup(
3939 string_pool_entry **spool, const char *str)
3940 {
3941 unsigned short key = 0;
3942 string_pool_entry* entry;
3943 char *s;
3944
3945 key = get_hash_key(str);
3946
3947 for (entry = spool[key]; entry != NULL; entry = entry->next) {
3948 s = (char *)entry->value;
3949 if (!strcmp(s, str))
3950 return entry;
3951 }
3952
3953 return NULL;
3954 }
3955
addAllVarAttributes(CISA_GEN_VAR * GenVar,std::vector<attr_gen_struct * > & Attrs,int lineNum)3956 bool CISA_IR_Builder::addAllVarAttributes(
3957 CISA_GEN_VAR* GenVar, std::vector<attr_gen_struct*>& Attrs, int lineNum)
3958 {
3959 if (Attrs.size() > 0)
3960 {
3961 (void)m_kernel->resizeAttribute(GenVar, (uint32_t)Attrs.size());
3962 }
3963
3964 for (int i = 0, e = (int)Attrs.size(); i < e; ++i)
3965 {
3966 attr_gen_struct* pAttr = Attrs[i];
3967 Attributes::ID aID = Attributes::getAttributeID(pAttr->name);
3968 if (Attributes::isBool(aID))
3969 {
3970 m_kernel->AddAttributeToVarGeneric(GenVar, pAttr->name, 0, nullptr);
3971 }
3972 else if (Attributes::isInt32(aID))
3973 {
3974 m_kernel->AddAttributeToVarGeneric(GenVar, pAttr->name, 4, &pAttr->value);
3975 }
3976 else if (Attributes::isCStr(aID))
3977 {
3978 unsigned int sz = (unsigned)strlen(pAttr->string_val);
3979 m_kernel->AddAttributeToVarGeneric(GenVar, pAttr->name, sz, &pAttr->string_val);
3980 }
3981 else
3982 {
3983 RecordParseError(lineNum, pAttr->name, ": unknown attribute");
3984 return false;
3985 }
3986 }
3987 return true;
3988 }
3989
string_pool_lookup_and_insert(string_pool_entry ** spool,const char * str,Common_ISA_Var_Class type,VISA_Type data_type)3990 bool CISA_IR_Builder::string_pool_lookup_and_insert(
3991 string_pool_entry **spool,
3992 const char *str,
3993 Common_ISA_Var_Class type,
3994 VISA_Type data_type)
3995 {
3996 unsigned short key = 0;
3997 string_pool_entry* entry;
3998 char *s;
3999 int len = (int) strlen(str);
4000
4001 key = get_hash_key(str);
4002
4003 for (entry = spool[key]; entry != NULL; entry = entry->next) {
4004 s = (char *)entry->value;
4005 if (!strcmp(s, str))
4006 return false;
4007 }
4008
4009 s = (char*)m_mem.alloc(len + 1);
4010 memcpy_s(s, len + 1, str, len+1);
4011 s[len] = '\0';
4012
4013 entry = (string_pool_entry*)m_mem.alloc(sizeof(string_pool_entry));
4014 memset(entry, 0, sizeof(*entry));
4015 entry->value = s;
4016 entry->type = type;
4017 entry->data_type = data_type;
4018
4019 entry->next = spool[key];
4020 spool[key] = entry;
4021
4022 return true;
4023 }
4024
get_input_class(Common_ISA_Var_Class var_class)4025 Common_ISA_Input_Class CISA_IR_Builder::get_input_class(Common_ISA_Var_Class var_class)
4026 {
4027 if (var_class == GENERAL_VAR)
4028 return INPUT_GENERAL;
4029
4030 if (var_class == SAMPLER_VAR)
4031 return INPUT_SAMPLER;
4032
4033 if (var_class == SURFACE_VAR)
4034 return INPUT_SURFACE;
4035
4036 return INPUT_UNKNOWN;
4037 }
CISA_post_file_parse()4038 void CISA_IR_Builder::CISA_post_file_parse()
4039 {
4040 return;
4041 }
4042
4043 // place it here so that internal Gen_IR files don't have to include VISAKernel.h
criticalMsgStream()4044 std::stringstream& IR_Builder::criticalMsgStream()
4045 {
4046 return const_cast<CISA_IR_Builder*>(parentBuilder)->criticalMsgStream();
4047 }
4048
CISA_create_dpas_instruction(ISA_Opcode opcode,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst_cisa,VISA_opnd * src0_cisa,VISA_opnd * src1_cisa,VISA_opnd * src2_cisa,GenPrecision A,GenPrecision W,uint8_t D,uint8_t C,int lineNum)4049 bool CISA_IR_Builder::CISA_create_dpas_instruction(
4050 ISA_Opcode opcode,
4051 VISA_EMask_Ctrl emask,
4052 unsigned exec_size,
4053 VISA_opnd * dst_cisa,
4054 VISA_opnd * src0_cisa,
4055 VISA_opnd * src1_cisa,
4056 VISA_opnd * src2_cisa,
4057 GenPrecision A,
4058 GenPrecision W,
4059 uint8_t D,
4060 uint8_t C,
4061 int lineNum)
4062 {
4063 // rcount !
4064 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
4065 VISA_CALL_TO_BOOL(AppendVISADpasInst,
4066 opcode, emask, executionSize,
4067 (VISA_RawOpnd *)dst_cisa, (VISA_RawOpnd *)src0_cisa,
4068 (VISA_RawOpnd *)src1_cisa, (VISA_VectorOpnd *)src2_cisa,
4069 A, W, D, C);
4070 return true;
4071 }
4072
4073
CISA_create_bfn_instruction(VISA_opnd * pred,uint8_t func_ctrl,bool sat,VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst_cisa,VISA_opnd * src0_cisa,VISA_opnd * src1_cisa,VISA_opnd * src2_cisa,int lineNum)4074 bool CISA_IR_Builder::CISA_create_bfn_instruction(
4075 VISA_opnd * pred,
4076 uint8_t func_ctrl,
4077 bool sat,
4078 VISA_EMask_Ctrl emask,
4079 unsigned exec_size,
4080 VISA_opnd * dst_cisa,
4081 VISA_opnd * src0_cisa,
4082 VISA_opnd * src1_cisa,
4083 VISA_opnd * src2_cisa,
4084 int lineNum)
4085 {
4086 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
4087 VISA_CALL_TO_BOOL(AppendVISABfnInst,
4088 func_ctrl, (VISA_PredOpnd *)pred, sat, emask, executionSize,
4089 (VISA_VectorOpnd *)dst_cisa, (VISA_VectorOpnd *)src0_cisa,
4090 (VISA_VectorOpnd *)src1_cisa, (VISA_VectorOpnd *)src2_cisa);
4091 return true;
4092 }
4093
CISA_create_qword_scatter_instruction(ISA_Opcode opcode,VISA_opnd * pred,VISA_EMask_Ctrl eMask,unsigned execSize,unsigned numBlocks,const char * surfaceName,VISA_opnd * offsets,VISA_opnd * dstSrc,int lineNum)4094 bool CISA_IR_Builder::CISA_create_qword_scatter_instruction(
4095 ISA_Opcode opcode,
4096 VISA_opnd *pred,
4097 VISA_EMask_Ctrl eMask,
4098 unsigned execSize,
4099 unsigned numBlocks,
4100 const char *surfaceName,
4101 VISA_opnd *offsets,
4102 VISA_opnd *dstSrc,
4103 int lineNum)
4104 {
4105 VISA_StateOpndHandle * surface = CISA_get_surface_variable(surfaceName, lineNum);
4106 if (!surface)
4107 return false; // error recorded
4108
4109 if (opcode == ISA_QW_GATHER)
4110 {
4111 VISA_CALL_TO_BOOL(AppendVISAQwordGatherInst,
4112 static_cast<VISA_PredOpnd *>(pred),
4113 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
4114 valueToVISASVMBlockNum(numBlocks),
4115 surface,
4116 static_cast<VISA_RawOpnd *>(offsets),
4117 static_cast<VISA_RawOpnd *>(dstSrc));
4118 }
4119 else
4120 {
4121 VISA_CALL_TO_BOOL(AppendVISAQwordScatterInst,
4122 static_cast<VISA_PredOpnd *>(pred),
4123 eMask, Get_VISA_Exec_Size_From_Raw_Size(execSize),
4124 valueToVISASVMBlockNum(numBlocks),
4125 surface,
4126 static_cast<VISA_RawOpnd *>(offsets),
4127 static_cast<VISA_RawOpnd *>(dstSrc));
4128 }
4129 return true;
4130 }
4131
CISA_create_bf_cvt_instruction(VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,int lineNum)4132 bool CISA_IR_Builder::CISA_create_bf_cvt_instruction(
4133 VISA_EMask_Ctrl emask,
4134 unsigned exec_size,
4135 VISA_opnd *dst,
4136 VISA_opnd *src0,
4137 int lineNum)
4138 {
4139 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
4140 VISA_CALL_TO_BOOL(AppendVISADataMovementInst,
4141 ISA_BF_CVT, nullptr, false, emask, executionSize,
4142 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0);
4143 return true;
4144 }
4145
CISA_create_fcvt_instruction(VISA_EMask_Ctrl emask,unsigned exec_size,VISA_opnd * dst,VISA_opnd * src0,int lineNum)4146 bool CISA_IR_Builder::CISA_create_fcvt_instruction(
4147 VISA_EMask_Ctrl emask,
4148 unsigned exec_size,
4149 VISA_opnd *dst,
4150 VISA_opnd *src0,
4151 int lineNum)
4152 {
4153 VISA_Exec_Size executionSize = Get_VISA_Exec_Size_From_Raw_Size(exec_size);
4154 VISA_CALL_TO_BOOL(AppendVISADataMovementInst,
4155 ISA_FCVT, nullptr, false, emask, executionSize,
4156 (VISA_VectorOpnd *)dst, (VISA_VectorOpnd *)src0);
4157 return true;
4158 }
4159
CISA_create_lsc_untyped_inst(VISA_opnd * pred,LSC_OP opcode,LSC_SFID sfid,LSC_CACHE_OPTS caching,VISA_Exec_Size execSize,VISA_EMask_Ctrl emask,LSC_ADDR addr,LSC_DATA_SHAPE dataShape,VISA_opnd * surface,VISA_opnd * dstData,VISA_opnd * src0Addr,VISA_opnd * src1Data,VISA_opnd * src2Data,int lineNum)4160 bool CISA_IR_Builder::CISA_create_lsc_untyped_inst(
4161 VISA_opnd *pred,
4162 LSC_OP opcode,
4163 LSC_SFID sfid,
4164 LSC_CACHE_OPTS caching,
4165 VISA_Exec_Size execSize,
4166 VISA_EMask_Ctrl emask,
4167 LSC_ADDR addr,
4168 LSC_DATA_SHAPE dataShape,
4169 VISA_opnd *surface,
4170 VISA_opnd *dstData,
4171 VISA_opnd *src0Addr,
4172 VISA_opnd *src1Data,
4173 VISA_opnd *src2Data,
4174 int lineNum)
4175 {
4176 VISA_CALL_TO_BOOL(AppendVISALscUntypedInst,
4177 opcode,
4178 sfid,
4179 static_cast<VISA_PredOpnd *>(pred),
4180 execSize,
4181 emask,
4182 caching,
4183 addr,
4184 dataShape,
4185 static_cast<VISA_VectorOpnd *>(surface),
4186 static_cast<VISA_RawOpnd *>(dstData),
4187 static_cast<VISA_RawOpnd *>(src0Addr),
4188 static_cast<VISA_RawOpnd *>(src1Data),
4189 static_cast<VISA_RawOpnd *>(src2Data));
4190 return true;
4191 }
4192
CISA_create_lsc_untyped_strided_inst(VISA_opnd * pred,LSC_OP opcode,LSC_SFID sfid,LSC_CACHE_OPTS caching,VISA_Exec_Size execSize,VISA_EMask_Ctrl emask,LSC_ADDR addr,LSC_DATA_SHAPE dataShape,VISA_opnd * surface,VISA_opnd * dst,VISA_opnd * src0Base,VISA_opnd * src0Stride,VISA_opnd * src1Data,int lineNum)4193 bool CISA_IR_Builder::CISA_create_lsc_untyped_strided_inst(
4194 VISA_opnd *pred,
4195 LSC_OP opcode,
4196 LSC_SFID sfid,
4197 LSC_CACHE_OPTS caching,
4198 VISA_Exec_Size execSize,
4199 VISA_EMask_Ctrl emask,
4200 LSC_ADDR addr,
4201 LSC_DATA_SHAPE dataShape,
4202 VISA_opnd *surface,
4203 VISA_opnd *dst,
4204 VISA_opnd *src0Base,
4205 VISA_opnd *src0Stride,
4206 VISA_opnd *src1Data,
4207 int lineNum)
4208 {
4209 VISA_CALL_TO_BOOL(AppendVISALscUntypedStridedInst,
4210 opcode,
4211 sfid,
4212 static_cast<VISA_PredOpnd *>(pred),
4213 execSize,
4214 emask,
4215 caching,
4216 addr,
4217 dataShape,
4218 static_cast<VISA_VectorOpnd *>(surface),
4219 static_cast<VISA_RawOpnd *>(dst),
4220 static_cast<VISA_RawOpnd *>(src0Base),
4221 static_cast<VISA_VectorOpnd *>(src0Stride),
4222 static_cast<VISA_RawOpnd *>(src1Data));
4223 return true;
4224 }
4225
CISA_create_lsc_untyped_block2d_inst(VISA_opnd * pred,LSC_OP opcode,LSC_SFID sfid,LSC_CACHE_OPTS caching,VISA_Exec_Size execSize,VISA_EMask_Ctrl emask,LSC_DATA_SHAPE_BLOCK2D dataShape2d,VISA_opnd * dstData,VISA_opnd * src0AddrsOps[LSC_BLOCK2D_ADDR_PARAMS],VISA_opnd * src1Data,int lineNum)4226 bool CISA_IR_Builder::CISA_create_lsc_untyped_block2d_inst(
4227 VISA_opnd *pred,
4228 LSC_OP opcode,
4229 LSC_SFID sfid,
4230 LSC_CACHE_OPTS caching,
4231 VISA_Exec_Size execSize,
4232 VISA_EMask_Ctrl emask,
4233 LSC_DATA_SHAPE_BLOCK2D dataShape2d,
4234 VISA_opnd *dstData,
4235 VISA_opnd *src0AddrsOps[LSC_BLOCK2D_ADDR_PARAMS],
4236 VISA_opnd *src1Data,
4237 int lineNum)
4238 {
4239 VISA_VectorOpnd *src0Addrs[LSC_BLOCK2D_ADDR_PARAMS] {
4240 static_cast<VISA_VectorOpnd *>(src0AddrsOps[0]),
4241 static_cast<VISA_VectorOpnd *>(src0AddrsOps[1]),
4242 static_cast<VISA_VectorOpnd *>(src0AddrsOps[2]),
4243 static_cast<VISA_VectorOpnd *>(src0AddrsOps[3]),
4244 static_cast<VISA_VectorOpnd *>(src0AddrsOps[4]),
4245 static_cast<VISA_VectorOpnd *>(src0AddrsOps[5]),
4246 };
4247 VISA_CALL_TO_BOOL(AppendVISALscUntypedBlock2DInst,
4248 opcode,
4249 sfid,
4250 static_cast<VISA_PredOpnd *>(pred),
4251 execSize,
4252 emask,
4253 caching,
4254 dataShape2d,
4255 static_cast<VISA_RawOpnd *>(dstData),
4256 src0Addrs,
4257 static_cast<VISA_RawOpnd *>(src1Data));
4258 return true;
4259 }
4260
CISA_create_lsc_typed_inst(VISA_opnd * pred,LSC_OP opcode,LSC_SFID sfid,LSC_CACHE_OPTS caching,VISA_Exec_Size execSize,VISA_EMask_Ctrl emask,LSC_ADDR_TYPE addrModel,LSC_ADDR_SIZE addrSize,LSC_DATA_SHAPE dataShape,VISA_opnd * surface,VISA_opnd * dst_data,VISA_opnd * src0_Us,VISA_opnd * src0_Vs,VISA_opnd * src0_Rs,VISA_opnd * src0_LODs,VISA_opnd * src1_data,VISA_opnd * src2_data,int lineNum)4261 bool CISA_IR_Builder::CISA_create_lsc_typed_inst(
4262 VISA_opnd *pred,
4263 LSC_OP opcode,
4264 LSC_SFID sfid,
4265 LSC_CACHE_OPTS caching,
4266 VISA_Exec_Size execSize,
4267 VISA_EMask_Ctrl emask,
4268 LSC_ADDR_TYPE addrModel,
4269 LSC_ADDR_SIZE addrSize,
4270 LSC_DATA_SHAPE dataShape,
4271 VISA_opnd *surface,
4272 VISA_opnd *dst_data,
4273 VISA_opnd *src0_Us,
4274 VISA_opnd *src0_Vs,
4275 VISA_opnd *src0_Rs,
4276 VISA_opnd *src0_LODs,
4277 VISA_opnd *src1_data,
4278 VISA_opnd *src2_data,
4279 int lineNum)
4280 {
4281 VISA_CALL_TO_BOOL(AppendVISALscTypedInst,
4282 opcode,
4283 static_cast<VISA_PredOpnd *>(pred),
4284 execSize,
4285 emask,
4286 caching,
4287 addrModel,
4288 addrSize,
4289 dataShape,
4290 static_cast<VISA_VectorOpnd *>(surface),
4291 static_cast<VISA_RawOpnd *>(dst_data),
4292 static_cast<VISA_RawOpnd *>(src0_Us),
4293 static_cast<VISA_RawOpnd *>(src0_Vs),
4294 static_cast<VISA_RawOpnd *>(src0_Rs),
4295 static_cast<VISA_RawOpnd *>(src0_LODs),
4296 static_cast<VISA_RawOpnd *>(src1_data),
4297 static_cast<VISA_RawOpnd *>(src2_data));
4298 return true;
4299 }
4300
CISA_create_lsc_fence(LSC_SFID sfid,LSC_FENCE_OP fence,LSC_SCOPE scope,int lineNum)4301 bool CISA_IR_Builder::CISA_create_lsc_fence(
4302 LSC_SFID sfid,
4303 LSC_FENCE_OP fence,
4304 LSC_SCOPE scope,
4305 int lineNum)
4306 {
4307 VISA_CALL_TO_BOOL(AppendVISALscFence,
4308 sfid, fence, scope);
4309
4310 return true;
4311 }
4312
CISA_create_nbarrier(bool isWait,VISA_opnd * barrierId,VISA_opnd * threadCount,int lineNum)4313 bool CISA_IR_Builder::CISA_create_nbarrier(
4314 bool isWait,
4315 VISA_opnd *barrierId,
4316 VISA_opnd *threadCount,
4317 int lineNum)
4318 {
4319 if (isWait) {
4320 VISA_CALL_TO_BOOL(AppendVISANamedBarrierWait,
4321 static_cast<VISA_VectorOpnd*>(barrierId));
4322 } else {
4323 VISA_CALL_TO_BOOL(AppendVISANamedBarrierSignal,
4324 static_cast<VISA_VectorOpnd*>(barrierId),
4325 static_cast<VISA_VectorOpnd*>(threadCount));
4326 }
4327 return true;
4328 }
4329
4330
4331