Skip to content

Commit 041afa0

Browse files
dlei6gsys_zuul
authored andcommitted
Functions groups with indirect calls can by rebuilt in FGA pass, without having to rerun the entire pass.
Also fixed a bug where we only need to generate a single relocation instruction, instead of one per use. Change-Id: I9c46171c6ea87e03717b2d047eba3595c9b74411
1 parent b3558fc commit 041afa0

File tree

4 files changed

+80
-33
lines changed

4 files changed

+80
-33
lines changed

IGC/AdaptorCommon/AddImplicitArgs.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,10 @@ void AddImplicitArgs::FixIndirectCalls(Module& M)
557557
Value* funcPtr = call->getCalledValue();
558558
PointerType* funcTy = PointerType::get(FunctionType::get(call->getType(), argTys, false), 0);
559559
funcPtr = builder.CreatePointerBitCastOrAddrSpaceCast(funcPtr, funcTy);
560-
Value* newCall = builder.CreateCall(funcPtr, args);
560+
CallInst* newCall = builder.CreateCall(funcPtr, args);
561561

562562
call->replaceAllUsesWith(newCall);
563+
newCall->copyMetadata(*call);
563564
list_delete.push_back(call);
564565
}
565566
}

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ bool EmitPass::runOnFunction(llvm::Function& F)
453453

454454
if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer))
455455
{
456+
SmallSet<Function*, 8> funcAddrSymbols;
456457
Module* pModule = F.getParent();
457458
for (auto& FI : pModule->getFunctionList())
458459
{
@@ -467,15 +468,21 @@ bool EmitPass::runOnFunction(llvm::Function& F)
467468
{
468469
if (inst->getParent()->getParent() == &F)
469470
{
470-
m_currShader->CreateFunctionSymbol(&FI);
471+
funcAddrSymbols.insert(&FI);
471472
}
472473
}
473474
}
474475
}
475476
}
477+
for (auto pFunc : funcAddrSymbols)
478+
{
479+
m_currShader->CreateFunctionSymbol(pFunc);
480+
}
476481
}
482+
477483
if (m_moduleMD->compOpt.EnableGlobalRelocation)
478484
{
485+
SmallSet<GlobalVariable*, 8> globalAddrSymbols;
479486
Module* pModule = F.getParent();
480487
for (auto gi = pModule->global_begin(), ge = pModule->global_end(); gi != ge; gi++)
481488
{
@@ -492,13 +499,17 @@ bool EmitPass::runOnFunction(llvm::Function& F)
492499
{
493500
if (inst->getParent()->getParent() == &F)
494501
{
495-
m_currShader->CreateGlobalSymbol(pGlobal);
502+
globalAddrSymbols.insert(pGlobal);
496503
}
497504
}
498505
}
499506
}
500507
}
501508
}
509+
for (auto pGlobal : globalAddrSymbols)
510+
{
511+
m_currShader->CreateGlobalSymbol(pGlobal);
512+
}
502513
}
503514

504515
m_VRA->BeginFunction(&F, numLanes(m_SimdMode));
@@ -717,8 +728,8 @@ bool EmitPass::runOnFunction(llvm::Function& F)
717728
{
718729
destroyVISABuilder = true;
719730
// We only need one symbol table per module. If there are multiple kernels, only create a symbol
720-
// table for the default one set by FGA
721-
bool compileWithSymbolTable = !m_FGA || (m_FGA->getGroup(&F)->getHead() == m_FGA->getDefaultKernel());
731+
// table for the one with indirectly called functions attached.
732+
bool compileWithSymbolTable = !m_FGA || (m_FGA->getGroup(&F)->hasIndirectFuncs());
722733
m_encoder->Compile(compileWithSymbolTable);
723734
// if we are doing stack-call, do the following:
724735
// - Hard-code a large scratch-space for visa

IGC/Compiler/CISACodeGen/GenCodeGenModule.cpp

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,6 @@ bool GenXCodeGenModule::runOnModule(Module& M)
373373

374374
pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils();
375375
CallGraph& CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
376-
FGA->setDefaultkernel(nullptr);
377376

378377
std::vector<std::vector<CallGraphNode*>*> SCCVec;
379378
for (auto I = scc_begin(&CG), IE = scc_end(&CG); I != IE; ++I)
@@ -394,28 +393,10 @@ bool GenXCodeGenModule::runOnModule(Module& M)
394393
{
395394
FGA->setSubGroupMap(F, F);
396395
FGA->createFunctionGroup(F);
397-
// There may be multiple kernels, set one as the default
398-
if (FGA->getDefaultKernel() == nullptr)
399-
FGA->setDefaultkernel(F);
400396
}
401397
else if (F->hasFnAttribute("IndirectlyCalled"))
402398
{
403-
// Add all externally linked functions into the default kernel group
404-
Function* defaultKernel = FGA->getDefaultKernel();
405-
assert(defaultKernel && "kernel does not exist in this group");
406-
FunctionGroup* defaultFG = FGA->getGroupForHead(defaultKernel);
407-
assert(defaultFG && "default kernel group does not exist");
408-
FGA->addToFunctionGroup(F, defaultFG, F);
409-
410-
// Mark caller group if it calls or uses this function
411-
for (auto U : F->users())
412-
{
413-
if (CallInst * CI = dyn_cast<CallInst>(U))
414-
{
415-
Function* Caller = CI->getParent()->getParent();
416-
FGA->getGroup(Caller)->m_hasExternFCall = true;
417-
}
418-
}
399+
continue;
419400
}
420401
else if (SCCNodes->size() == 1)
421402
{
@@ -431,6 +412,9 @@ bool GenXCodeGenModule::runOnModule(Module& M)
431412
delete SCCNodes;
432413
}
433414

415+
// Add all indirect functions to the default kernel group
416+
FGA->addIndirectFuncsToKernelGroup(&M);
417+
434418
// By swapping, we sort the function list to ensure codegen order for
435419
// functions. This relies on llvm module pass manager's implementation detail.
436420
SmallVector<Function*, 16> OrderedList;
@@ -465,7 +449,6 @@ bool GenXCodeGenModule::runOnModule(Module& M)
465449
}
466450
}
467451

468-
469452
#if defined(_DEBUG)
470453
assert(FGA->verify());
471454
#endif
@@ -545,6 +528,50 @@ bool GenXFunctionGroupAnalysis::useStackCall(llvm::Function* F)
545528
return (F->hasFnAttribute("visaStackCall"));
546529
}
547530

531+
void GenXFunctionGroupAnalysis::addIndirectFuncsToKernelGroup(llvm::Module* pModule)
532+
{
533+
auto pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils();
534+
535+
Function* defaultKernel = nullptr;
536+
// Set the first kernel as the default
537+
for (auto I = pModule->begin(), E = pModule->end(); I != E; ++I)
538+
{
539+
Function* F = &(*I);
540+
if (isEntryFunc(pMdUtils, F))
541+
{
542+
defaultKernel = F;
543+
break;
544+
}
545+
}
546+
assert(defaultKernel && "kernel does not exist in this group");
547+
548+
FunctionGroup* defaultFG = getGroupForHead(defaultKernel);
549+
assert(defaultFG && "default kernel group does not exist");
550+
551+
// Add all externally linked functions into the default kernel group
552+
for (auto I = pModule->begin(), E = pModule->end(); I != E; ++I)
553+
{
554+
Function* F = &(*I);
555+
if (F->isDeclaration() || isEntryFunc(pMdUtils, F)) continue;
556+
557+
if (F->hasFnAttribute("IndirectlyCalled"))
558+
{
559+
addToFunctionGroup(F, defaultFG, F);
560+
defaultFG->m_hasIndirectFuncs = true;
561+
562+
// Mark caller group if it calls or uses this function
563+
for (auto U : F->users())
564+
{
565+
if (CallInst * CI = dyn_cast<CallInst>(U))
566+
{
567+
Function* Caller = CI->getParent()->getParent();
568+
getGroup(Caller)->m_hasExternFCall = true;
569+
}
570+
}
571+
}
572+
}
573+
}
574+
548575
bool GenXFunctionGroupAnalysis::rebuild(llvm::Module* Mod) {
549576
clear();
550577
auto pMdUtils = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils();
@@ -570,6 +597,10 @@ bool GenXFunctionGroupAnalysis::rebuild(llvm::Module* Mod) {
570597
CurFG = createFunctionGroup(F);
571598
CurSubGrpH = F;
572599
}
600+
else if (F->hasFnAttribute("IndirectlyCalled"))
601+
{
602+
continue;
603+
}
573604
else
574605
{
575606
if (useStackCall(F))
@@ -584,6 +615,9 @@ bool GenXFunctionGroupAnalysis::rebuild(llvm::Module* Mod) {
584615
}
585616
}
586617

618+
// Re-add all indirect functions to the default kernel group
619+
addIndirectFuncsToKernelGroup(Mod);
620+
587621
// Verification.
588622
if (!verify())
589623
{

IGC/Compiler/CISACodeGen/GenCodeGenModule.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ namespace IGC {
7171
/// \brief A collection of functions that are reachable from a kernel.
7272
class FunctionGroup {
7373
public:
74-
friend class GenXCodeGenModule;
74+
friend class GenXFunctionGroupAnalysis;
7575
/// \brief use 2-d vector of Functions to represent FunctionGroup.
7676
/// Each sub-vector is a subgroup led by a kernel or a stack-call function.
7777
/// Element [0][0] is the group head. Element[i][0] is the sub-group head.
@@ -100,6 +100,9 @@ namespace IGC {
100100
/// \brief Indicate if any function in this group directly calls an externally linked function
101101
bool hasExternFCall() { return m_hasExternFCall; }
102102

103+
/// \brief Indicate if there are indirectly functions attached to this group
104+
bool hasIndirectFuncs() { return m_hasIndirectFuncs; }
105+
103106
void replaceGroupHead(llvm::Function* OH, llvm::Function* NH) {
104107
auto headSG = Functions[0];
105108
llvm::AssertingVH<llvm::Function>& HVH = (*headSG)[0];
@@ -109,6 +112,7 @@ namespace IGC {
109112

110113
private:
111114
bool m_hasExternFCall = false;
115+
bool m_hasIndirectFuncs = false;
112116
};
113117

114118
class GenXFunctionGroupAnalysis : public llvm::ImmutablePass {
@@ -124,9 +128,6 @@ namespace IGC {
124128
/// \brief Each function also belongs to a uniquely defined sub-group of a stack-call entry
125129
llvm::DenseMap<llvm::Function*, llvm::Function*> SubGroupMap;
126130

127-
/// \brief the main kernel in this module
128-
llvm::Function* DefaultKernel = nullptr;
129-
130131
public:
131132
static char ID;
132133
explicit GenXFunctionGroupAnalysis();
@@ -146,6 +147,9 @@ namespace IGC {
146147
///
147148
bool rebuild(llvm::Module* Mod);
148149

150+
// Attach all indirectly called functions to a single kernel group
151+
void addIndirectFuncsToKernelGroup(llvm::Module* pModule);
152+
149153
// Replace OF with NF in Groups and GroupMap
150154
void replaceEntryFunc(llvm::Function* OF, llvm::Function* NF);
151155

@@ -175,9 +179,6 @@ namespace IGC {
175179
return I->second;
176180
}
177181

178-
llvm::Function* getDefaultKernel() { return DefaultKernel; }
179-
void setDefaultkernel(llvm::Function* F) { DefaultKernel = F; }
180-
181182
void setSubGroupMap(llvm::Function* F, llvm::Function* SubGroupHead) {
182183
SubGroupMap[F] = SubGroupHead;
183184
}

0 commit comments

Comments
 (0)