@@ -404,13 +404,20 @@ int CISA_IR_Builder::AddFunction(VISAFunction *& function, const char* functionN
404404void restoreFCallState (
405405 G4_Kernel* kernel, const std::map<G4_BB*, G4_INST*>& savedFCallState)
406406{
407- // Iterate over all BBs in kernel and clean up the edges.
408- // FIXME: do we need to do this still?
407+ // Iterate over all BBs in kernel and fix all fcalls converted
408+ // to calls by reconverting them to fcall. This is required
409+ // because we want to reuse IR of function for next kernel.
410+
409411 for (auto && iter : savedFCallState)
410412 {
411413 auto curBB = iter.first ;
414+ auto genOffset = curBB->back ()->getGenOffset ();
415+ curBB->pop_back ();
412416 auto origInst = iter.second ;
413417 assert (origInst->isFCall () || origInst->isFReturn ());
418+ curBB->push_back (origInst);
419+ // set the genOffset in case of GenOffset being used when creating symbol table
420+ origInst->setGenOffset (genOffset);
414421
415422 if (origInst->isFCall () && !origInst->asCFInst ()->isIndirectCall ())
416423 {
@@ -440,6 +447,7 @@ void restoreFCallState(
440447
441448// Stitch the FG of subFunctions to mainFunc
442449// mainFunc could be a kernel or a non-kernel function.
450+ // It also modifies pseudo_fcall/fret in to call/ret opcodes.
443451// ToDo: may consider stitching only functions that may be called by this kernel/function
444452static void Stitch_Compiled_Units (
445453 G4_Kernel* mainFunc, std::map<std::string, G4_Kernel*>& subFuncs,
@@ -463,7 +471,8 @@ static void Stitch_Compiled_Units(
463471 mainFunc->fg .reassignBlockIDs ();
464472 mainFunc->fg .setPhysicalPredSucc (); // this is to locate the next BB after an fcall
465473
466- // setup caller/callee edges
474+ auto builder = mainFunc->fg .builder ;
475+ // Change fcall/fret to call/ret and setup caller/callee edges
467476 for (G4_BB* cur : mainFunc->fg )
468477 {
469478 if (cur->isEndWithFCall ())
@@ -491,11 +500,47 @@ static void Stitch_Compiled_Units(
491500 // Connect new fg
492501 mainFunc->fg .addPredSuccEdges (cur, callee->fg .getEntryBB ());
493502 mainFunc->fg .addPredSuccEdges (callee->fg .getUniqueReturnBlock (), retBlock);
503+
504+ G4_INST* calleeLabel = callee->fg .getEntryBB ()->front ();
505+ ASSERT_USER (calleeLabel->isLabel () == true , " Entry inst is not label" );
506+
507+ auto callInst = builder->createInternalInst (
508+ fcall->getPredicate (), G4_call, nullptr , g4::NOSAT, fcall->getExecSize (),
509+ fcall->getDst (), calleeLabel->getSrc (0 ), fcall->getSrc (0 ), fcall->getOption ());
510+ callInst->inheritDIFrom (fcall);
511+ cur->pop_back ();
512+ cur->push_back (callInst);
513+ }
514+ else
515+ {
516+ // src0 is dont care for indirect call as long it's not a label
517+ auto callInst = builder->createInternalInst (
518+ fcall->getPredicate (), G4_call, nullptr , g4::NOSAT, fcall->getExecSize (),
519+ fcall->getDst (), fcall->getSrc (0 ), fcall->getSrc (0 ), fcall->getOption ());
520+ callInst->inheritDIFrom (fcall);
521+ cur->pop_back ();
522+ cur->push_back (callInst);
494523 }
495524 FCallRetMap[cur] = fcall;
496525 }
497526 }
498527
528+ // Change fret to ret
529+ for (G4_BB* cur : mainFunc->fg )
530+ {
531+ if (cur->isEndWithFRet ())
532+ {
533+ G4_INST* fret = cur->back ();
534+ auto retInst = builder->createInternalInst (
535+ fret->getPredicate (), G4_return, nullptr , g4::NOSAT, fret->getExecSize (),
536+ builder->createNullDst (Type_UD), fret->getSrc (0 ), fret->getSrc (1 ), fret->getOption ());
537+ retInst->inheritDIFrom (fret);
538+ cur->pop_back ();
539+ cur->push_back (retInst);
540+ FCallRetMap[cur] = fret;
541+ }
542+ }
543+
499544 // Append declarations and color attributes from all callees to mainFunc
500545 for (auto iter : subFuncs)
501546 {
0 commit comments