@@ -924,6 +924,146 @@ 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
+ if (Inst->use_empty ())
959
+ {
960
+ Inst->eraseFromParent ();
961
+ change = true ;
962
+ }
963
+ }
964
+
965
+ for (CallInst *Inst : m_LocalFencesBariersToRemove)
966
+ {
967
+ Inst->eraseFromParent ();
968
+ change = true ;
969
+ }
970
+ }
971
+
972
+ return change;
973
+ }
974
+
975
+ /*
976
+ OCL instruction barrier(CLK_LOCAL_MEM_FENCE); is translate to two instructions
977
+ call void @llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
978
+ call void @llvm.genx.GenISA.threadgroupbarrier()
979
+
980
+ if we remove call void @llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
981
+ we must remove next instruction if it is call void @llvm.genx.GenISA.threadgroupbarrier()
982
+ */
983
+ void TrivialLocalMemoryOpsElimination::findNextThreadGroupBarrierInst (Instruction &I)
984
+ {
985
+ auto nextInst = I.getNextNonDebugInstruction ();
986
+ if (isa<GenIntrinsicInst>(nextInst))
987
+ {
988
+ GenIntrinsicInst *II = dyn_cast<GenIntrinsicInst>(nextInst);
989
+ if (II->getIntrinsicID () == GenISAIntrinsic::GenISA_threadgroupbarrier)
990
+ {
991
+ m_LocalFencesBariersToRemove.push_back (dyn_cast<CallInst>(nextInst));
992
+ }
993
+ }
994
+ }
995
+
996
+ void TrivialLocalMemoryOpsElimination::visitLoadInst (LoadInst &I)
997
+ {
998
+ if (I.getPointerAddressSpace () == ADDRESS_SPACE_LOCAL)
999
+ {
1000
+ m_LocalLoadsToRemove.push_back (&I);
1001
+ }
1002
+ }
1003
+
1004
+ void TrivialLocalMemoryOpsElimination::visitStoreInst (StoreInst &I)
1005
+ {
1006
+ if (I.getPointerAddressSpace () == ADDRESS_SPACE_LOCAL)
1007
+ {
1008
+ m_LocalStoresToRemove.push_back (&I);
1009
+ }
1010
+ }
1011
+
1012
+ bool TrivialLocalMemoryOpsElimination::isLocalBarrier (CallInst &I)
1013
+ {
1014
+ // 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
1015
+ // (i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true) it is local barrier
1016
+ std::vector<bool > argumentsOfMemoryBarrier;
1017
+
1018
+ for (auto arg = I.arg_begin (); arg != I.arg_end (); ++arg)
1019
+ {
1020
+ ConstantInt* ci = dyn_cast<ConstantInt>(arg);
1021
+ argumentsOfMemoryBarrier.push_back (ci->getValue ().getBoolValue ());
1022
+ }
1023
+
1024
+ return argumentsOfMemoryBarrier == m_argumentsOfLocalMemoryBarrier;
1025
+ }
1026
+
1027
+ // If any call instruction use pointer to local memory abort pass execution
1028
+ void TrivialLocalMemoryOpsElimination::anyCallInstUseLocalMemory (CallInst &I)
1029
+ {
1030
+ Function* fn = I.getCalledFunction ();
1031
+
1032
+ if (fn != NULL )
1033
+ {
1034
+ for (auto arg = fn->arg_begin (); arg != fn->arg_end (); ++arg)
1035
+ {
1036
+ if (arg->getType ()->isPointerTy ())
1037
+ {
1038
+ if (arg->getType ()->getPointerAddressSpace () == ADDRESS_SPACE_LOCAL || arg->getType ()->getPointerAddressSpace () == ADDRESS_SPACE_GENERIC) abortPass = true ;
1039
+ }
1040
+ }
1041
+ }
1042
+ }
1043
+
1044
+ void TrivialLocalMemoryOpsElimination::visitCallInst (CallInst &I)
1045
+ {
1046
+ // detect only: llvm.genx.GenISA.memoryfence(i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 true)
1047
+ // (note: the first and last arguments are true)
1048
+ // and add them with immediately following barriers to m_LocalFencesBariersToRemove
1049
+ anyCallInstUseLocalMemory (I);
1050
+
1051
+ if (isa<GenIntrinsicInst>(I))
1052
+ {
1053
+ GenIntrinsicInst *II = dyn_cast<GenIntrinsicInst>(&I);
1054
+ if (II->getIntrinsicID () == GenISAIntrinsic::GenISA_memoryfence)
1055
+ {
1056
+ if (isLocalBarrier (I))
1057
+ {
1058
+ m_LocalFencesBariersToRemove.push_back (&I);
1059
+ findNextThreadGroupBarrierInst (I);
1060
+ }
1061
+ }
1062
+ }
1063
+
1064
+ }
1065
+ #endif
1066
+
927
1067
// Register pass to igc-opt
928
1068
#define PASS_FLAG2 " igc-gen-specific-pattern"
929
1069
#define PASS_DESCRIPTION2 " LastPatternMatch Pass"
@@ -3471,6 +3611,8 @@ bool FlattenSmallSwitch::runOnFunction(Function &F)
3471
3611
IGC_INITIALIZE_PASS_BEGIN (FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
3472
3612
IGC_INITIALIZE_PASS_END(FlattenSmallSwitch, " flattenSmallSwitch" , " flattenSmallSwitch" , false , false )
3473
3613
3614
+
3615
+
3474
3616
// //////////////////////////////////////////////////////////////////////
3475
3617
// LogicalAndToBranch trying to find logical AND like below:
3476
3618
// res = simpleCond0 && complexCond1
0 commit comments