@@ -924,6 +924,143 @@ void CustomSafeOptPass::visitExtractElementInst(ExtractElementInst &I)
924924 }
925925}
926926
927+ #if LLVM_VERSION_MAJOR >= 7
928+ // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
929+ // This pass removes dead local memory loads and stores. If we remove all such loads and stores, we also
930+ // remove all local memory fences together with barriers that follow.
931+ //
932+ IGC_INITIALIZE_PASS_BEGIN (TrivialLocalMemoryOpsElimination, " TrivialLocalMemoryOpsElimination" , " TrivialLocalMemoryOpsElimination" , false , false )
933+ IGC_INITIALIZE_PASS_END(TrivialLocalMemoryOpsElimination, " TrivialLocalMemoryOpsElimination" , " TrivialLocalMemoryOpsElimination" , false , false )
934+
935+ char TrivialLocalMemoryOpsElimination::ID = 0;
936+
937+ TrivialLocalMemoryOpsElimination::TrivialLocalMemoryOpsElimination () : FunctionPass(ID)
938+ {
939+ initializeTrivialLocalMemoryOpsEliminationPass (*PassRegistry::getPassRegistry ());
940+ }
941+
942+
943+
944+ bool TrivialLocalMemoryOpsElimination::runOnFunction (Function &F)
945+ {
946+ bool change = false ;
947+ visit (F);
948+ if (!abortPass && (m_LocalLoadsToRemove.empty () || m_LocalStoresToRemove.empty ()))
949+ {
950+ for (StoreInst *Inst : m_LocalStoresToRemove)
951+ {
952+ Inst->eraseFromParent ();
953+ change = true ;
954+ }
955+
956+ for (LoadInst *Inst : m_LocalLoadsToRemove)
957+ {
958+ Inst->eraseFromParent ();
959+ change = true ;
960+ }
961+
962+ for (CallInst *Inst : m_LocalFencesBariersToRemove)
963+ {
964+ Inst->eraseFromParent ();
965+ change = true ;
966+ }
967+ }
968+
969+ return change;
970+ }
971+
972+ /*
973+ OCL instruction barrier(CLK_LOCAL_MEM_FENCE); is translate to two instructions
974+ call void @llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
975+ call void @llvm.genx.GenISA.threadgroupbarrier()
976+
977+ if we remove call void @llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
978+ we must remove next instruction if it is call void @llvm.genx.GenISA.threadgroupbarrier()
979+ */
980+ void TrivialLocalMemoryOpsElimination::findNextThreadGroupBarrierInst (Instruction &I)
981+ {
982+ auto nextInst = I.getNextNonDebugInstruction ();
983+ if (isa<GenIntrinsicInst>(nextInst))
984+ {
985+ GenIntrinsicInst *II = dyn_cast<GenIntrinsicInst>(nextInst);
986+ if (II->getIntrinsicID () == GenISAIntrinsic::GenISA_threadgroupbarrier)
987+ {
988+ m_LocalFencesBariersToRemove.push_back (dyn_cast<CallInst>(nextInst));
989+ }
990+ }
991+ }
992+
993+ void TrivialLocalMemoryOpsElimination::visitLoadInst (LoadInst &I)
994+ {
995+ if (I.getPointerAddressSpace () == ADDRESS_SPACE_LOCAL)
996+ {
997+ m_LocalLoadsToRemove.push_back (&I);
998+ }
999+ }
1000+
1001+ void TrivialLocalMemoryOpsElimination::visitStoreInst (StoreInst &I)
1002+ {
1003+ if (I.getPointerAddressSpace () == ADDRESS_SPACE_LOCAL)
1004+ {
1005+ m_LocalStoresToRemove.push_back (&I);
1006+ }
1007+ }
1008+
1009+ bool TrivialLocalMemoryOpsElimination::isLocalBarrier (CallInst &I)
1010+ {
1011+ // check arguments in call void @llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true) if match to
1012+ // (i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true) it is local barrier
1013+ std::vector<bool > argumentsOfMemoryBarrier;
1014+
1015+ for (auto arg = I.arg_begin (); arg != I.arg_end (); ++arg)
1016+ {
1017+ ConstantInt* ci = dyn_cast<ConstantInt>(arg);
1018+ argumentsOfMemoryBarrier.push_back (ci->getValue ().getBoolValue ());
1019+ }
1020+
1021+ return argumentsOfMemoryBarrier == m_argumentsOfLocalMemoryBarrier;
1022+ }
1023+
1024+ // If any call instruction use pointer to local memory abort pass execution
1025+ void TrivialLocalMemoryOpsElimination::anyCallInstUseLocalMemory (CallInst &I)
1026+ {
1027+ Function* fn = I.getCalledFunction ();
1028+
1029+ if (fn != NULL )
1030+ {
1031+ for (auto arg = fn->arg_begin (); arg != fn->arg_end (); ++arg)
1032+ {
1033+ if (arg->getType ()->isPointerTy ())
1034+ {
1035+ if (arg->getType ()->getPointerAddressSpace () == ADDRESS_SPACE_LOCAL || arg->getType ()->getPointerAddressSpace () == ADDRESS_SPACE_GENERIC) abortPass = true ;
1036+ }
1037+ }
1038+ }
1039+ }
1040+
1041+ void TrivialLocalMemoryOpsElimination::visitCallInst (CallInst &I)
1042+ {
1043+ // detect only: llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
1044+ // (note: the first and last arguments are true)
1045+ // and add them with immediately following barriers to m_LocalFencesBariersToRemove
1046+ anyCallInstUseLocalMemory (I);
1047+
1048+ if (isa<GenIntrinsicInst>(I))
1049+ {
1050+ GenIntrinsicInst *II = dyn_cast<GenIntrinsicInst>(&I);
1051+ if (II->getIntrinsicID () == GenISAIntrinsic::GenISA_memoryfence)
1052+ {
1053+ if (isLocalBarrier (I))
1054+ {
1055+ m_LocalFencesBariersToRemove.push_back (&I);
1056+ findNextThreadGroupBarrierInst (I);
1057+ }
1058+ }
1059+ }
1060+
1061+ }
1062+ #endif
1063+
9271064// Register pass to igc-opt
9281065#define PASS_FLAG2 " igc-gen-specific-pattern"
9291066#define PASS_DESCRIPTION2 " LastPatternMatch Pass"
@@ -3471,6 +3608,8 @@ bool FlattenSmallSwitch::runOnFunction(Function &F)
34713608IGC_INITIALIZE_PASS_BEGIN (FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
34723609IGC_INITIALIZE_PASS_END(FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
34733610
3611+
3612+
34743613// //////////////////////////////////////////////////////////////////////
34753614// LogicalAndToBranch trying to find logical AND like below:
34763615// res = simpleCond0 && complexCond1
0 commit comments