@@ -924,6 +924,143 @@ void CustomSafeOptPass::visitExtractElementInst(ExtractElementInst &I)
924
924
}
925
925
}
926
926
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
+
927
1064
// Register pass to igc-opt
928
1065
#define PASS_FLAG2 " igc-gen-specific-pattern"
929
1066
#define PASS_DESCRIPTION2 " LastPatternMatch Pass"
@@ -3471,6 +3608,8 @@ bool FlattenSmallSwitch::runOnFunction(Function &F)
3471
3608
IGC_INITIALIZE_PASS_BEGIN (FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
3472
3609
IGC_INITIALIZE_PASS_END(FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
3473
3610
3611
+
3612
+
3474
3613
// //////////////////////////////////////////////////////////////////////
3475
3614
// LogicalAndToBranch trying to find logical AND like below:
3476
3615
// res = simpleCond0 && complexCond1
0 commit comments