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