@@ -14,6 +14,8 @@ SPDX-License-Identifier: MIT
14
14
15
15
#include " common/LLVMWarningsPush.hpp"
16
16
#include < llvm/ADT/STLExtras.h>
17
+ #include < llvm/ADT/DenseMapInfo.h>
18
+ #include < llvm/ADT/Hashing.h>
17
19
#include < llvm/Analysis/LoopInfo.h>
18
20
#include < llvm/IR/Dominators.h>
19
21
#include < llvm/IR/InstIterator.h>
@@ -25,6 +27,29 @@ SPDX-License-Identifier: MIT
25
27
using namespace IGC ;
26
28
using namespace llvm ;
27
29
30
+ namespace llvm {
31
+ template <>
32
+ struct DenseMapInfo <IGC::AllocationLivenessAnalyzer::LivenessData::Edge> {
33
+ using Edge = IGC::AllocationLivenessAnalyzer::LivenessData::Edge;
34
+
35
+ static inline Edge getEmptyKey () {
36
+ return Edge{ DenseMapInfo<BasicBlock *>::getEmptyKey (), DenseMapInfo<BasicBlock *>::getEmptyKey () };
37
+ }
38
+
39
+ static inline Edge getTombstoneKey () {
40
+ return Edge{ DenseMapInfo<BasicBlock *>::getTombstoneKey (), DenseMapInfo<BasicBlock *>::getTombstoneKey () };
41
+ }
42
+
43
+ static unsigned getHashValue (const Edge &E) {
44
+ return (unsigned )hash_combine (E.from , E.to );
45
+ }
46
+
47
+ static bool isEqual (const Edge &LHS, const Edge &RHS) {
48
+ return LHS == RHS;
49
+ }
50
+ };
51
+ } // namespace llvm
52
+
28
53
void InlineRaytracing::getAdditionalAnalysisUsage (AnalysisUsage &AU) const { AU.addRequired <CodeGenContextWrapper>(); }
29
54
30
55
bool InlineRaytracing::LowerAllocations (Function &F) {
@@ -771,8 +796,7 @@ void InlineRaytracing::StopAndStartRayquery(RTBuilder &IRB, Instruction *I, Valu
771
796
}
772
797
}
773
798
774
- void InlineRaytracing::HandleOptimizationsAndSpills (llvm::Function &F, LivenessDataMap &livenessDataMap,
775
- DominatorTree &DT, LoopInfo &LI) {
799
+ void InlineRaytracing::HandleOptimizationsAndSpills (llvm::Function &F, LivenessDataMap &livenessDataMap) {
776
800
RTBuilder IRB (&*F.getEntryBlock ().begin (), *m_pCGCtx);
777
801
778
802
SmallVector<Instruction *> continuationInstructions;
@@ -800,108 +824,122 @@ void InlineRaytracing::HandleOptimizationsAndSpills(llvm::Function &F, LivenessD
800
824
m_pCGCtx->platform .enableRayQueryThrottling (m_pCGCtx->getModuleMetaData ()->compOpt .EnableDynamicRQManagement ) &&
801
825
m_numSlotsUsed == 1 ;
802
826
827
+ MapVector<Instruction *, SmallVector<std::function<void (RTBuilder &)>>> instructionClosures;
828
+ MapVector<LivenessData::Edge, SmallVector<std::function<void (RTBuilder &)>>> edgeClosures;
829
+
803
830
for (auto &entry : livenessDataMap) {
804
- bool cfgChanged = false ;
805
831
806
832
auto *rqObject = entry.first ;
807
833
auto *LD = &entry.second ;
808
834
809
835
// process the allocation acquire point
810
836
// handle rayquery check
811
- if ( doRQCheckRelease) {
812
- // check before the allocation is acquired
813
- IRB. SetInsertPoint (LD-> lifetimeStart );
814
- IRB.CreateRayQueryCheckIntrinsic ();
815
- }
837
+ instructionClosures[LD-> lifetimeStart ]. push_back ([ this , doRQCheckRelease](RTBuilder &IRB ) {
838
+
839
+ if (doRQCheckRelease)
840
+ IRB.CreateRayQueryCheckIntrinsic ();
841
+ });
816
842
817
843
// process the allocation release points
818
844
for (auto *I : LD->lifetimeEndInstructions ) {
819
- IRB.SetInsertPoint (isa<ReturnInst>(I) ? I : I->getNextNode ());
820
845
821
- auto *stackPtr = getStackPtr (IRB, IRB.Insert (rqObject->clone ()));
846
+ instructionClosures[isa<ReturnInst>(I) ? I : I->getNextNode ()].push_back (
847
+ [this , rqObject, doRQCheckRelease](RTBuilder &IRB) {
822
848
823
- // handle cache control
824
- InsertCacheControl (IRB, stackPtr);
849
+ auto *stackPtr = getStackPtr (IRB, IRB.Insert (rqObject->clone ()));
825
850
826
- // handle rayquery release
827
- if (doRQCheckRelease)
828
- IRB.CreateRayQueryReleaseIntrinsic ();
851
+ // handle cache control
852
+ InsertCacheControl (IRB, stackPtr);
829
853
830
- IGC_ASSERT (DT.dominates (LD->lifetimeStart , I));
854
+ // handle rayquery release
855
+ if (doRQCheckRelease)
856
+ IRB.CreateRayQueryReleaseIntrinsic ();
857
+ });
831
858
}
832
859
833
- for (const auto &[from, to] : LD->lifetimeEndEdges ) {
834
- auto *succ = to;
835
- // to avoid multiple executions of rayquery release instructions,
836
- // we need to ensure that the "to" block has a single predecessor
837
- if (!to->getSinglePredecessor ()) {
838
- succ = SplitEdge (from, succ);
839
-
840
- // we invalidated other the liveness data for other instructions
841
- cfgChanged = true ;
842
- }
843
-
844
- IRB.SetInsertPoint (succ->getFirstNonPHI ());
860
+ for (const auto &edge : LD->lifetimeEndEdges ) {
845
861
846
- auto *stackPtr = getStackPtr (IRB, IRB. Insert ( rqObject-> clone ()));
862
+ edgeClosures[edge]. push_back ([ this , rqObject, doRQCheckRelease](RTBuilder &IRB) {
847
863
848
- // handle cache control
849
- InsertCacheControl (IRB, stackPtr);
864
+ auto *stackPtr = getStackPtr (IRB, IRB.Insert (rqObject->clone ()));
850
865
851
- // handle rayquery release
852
- if (doRQCheckRelease)
853
- IRB.CreateRayQueryReleaseIntrinsic ();
866
+ // handle cache control
867
+ InsertCacheControl (IRB, stackPtr);
854
868
855
- IGC_ASSERT (DT.dominates (LD->lifetimeStart , succ));
869
+ // handle rayquery release
870
+ if (doRQCheckRelease)
871
+ IRB.CreateRayQueryReleaseIntrinsic ();
872
+ });
856
873
}
857
874
858
875
// handle continuation instructions
859
876
for (auto *I : continuationInstructions) {
877
+
860
878
if (!LD->ContainsInstruction (*I))
861
879
continue ;
862
880
863
- IRB.SetInsertPoint (I);
864
- StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
881
+ instructionClosures[I].push_back ([this , rqObject, doRQCheckRelease, I](RTBuilder &IRB) {
882
+
883
+ StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
884
+ });
865
885
}
866
886
867
887
// handle indirect calls
868
888
for (auto *I : indirectCallInstructions) {
889
+
869
890
if (!LD->ContainsInstruction (*I))
870
891
continue ;
871
892
872
- IRB.SetInsertPoint (I);
873
- StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
893
+ instructionClosures[I].push_back ([this , rqObject, doRQCheckRelease, I](RTBuilder &IRB) {
894
+
895
+ StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
896
+ });
874
897
}
875
898
876
899
// handle hidden control flow instructions
877
900
for (auto *I : hiddenCFInstructions) {
901
+
878
902
if (!LD->ContainsInstruction (*I))
879
903
continue ;
880
904
881
- IRB.SetInsertPoint (I);
882
- StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
905
+ instructionClosures[I].push_back ([this , rqObject, doRQCheckRelease, I](RTBuilder &IRB) {
906
+
907
+ StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), true , doRQCheckRelease);
908
+ });
883
909
}
884
910
885
911
// handle barriers
886
912
for (auto *I : barrierInstructions) {
913
+
887
914
if (!LD->ContainsInstruction (*I))
888
915
continue ;
889
916
890
- IRB.SetInsertPoint (I);
891
- StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), false , doRQCheckRelease);
917
+ instructionClosures[I].push_back ([this , rqObject, doRQCheckRelease, I](RTBuilder &IRB) {
918
+
919
+ StopAndStartRayquery (IRB, I, IRB.Insert (rqObject->clone ()), false , doRQCheckRelease);
920
+ });
892
921
}
922
+ }
923
+
924
+ for (const auto [I, closures] : instructionClosures) {
893
925
894
- if (cfgChanged) {
895
- auto nextentry = livenessDataMap.find (rqObject);
926
+ IRB.SetInsertPoint (I);
927
+ for (const auto c : closures)
928
+ c (IRB);
929
+ }
896
930
897
- // TODO: can we incrementally update LoopInfo and DomTree?
898
- DT.recalculate (F);
931
+ for (const auto [edge, closures] : edgeClosures) {
899
932
900
- getAnalysis<LoopInfoWrapperPass>().releaseMemory ();
901
- getAnalysis<LoopInfoWrapperPass>().runOnFunction (F);
902
- while (++nextentry != livenessDataMap.end ())
903
- nextentry->second = ProcessInstruction (nextentry->first , DT, getAnalysis<LoopInfoWrapperPass>().getLoopInfo ());
904
- }
933
+ auto *succ = edge.to ;
934
+ // to avoid multiple executions of rayquery release instructions,
935
+ // we need to ensure that the "to" block has a single predecessor
936
+ if (!edge.to ->getSinglePredecessor ())
937
+ succ = SplitEdge (edge.from , succ);
938
+
939
+ IRB.SetInsertPoint (succ->getFirstNonPHI ());
940
+
941
+ for (const auto c : closures)
942
+ c (IRB);
905
943
}
906
944
}
907
945
@@ -971,7 +1009,7 @@ bool InlineRaytracing::runOnFunction(Function &F) {
971
1009
972
1010
auto livenessData = AnalyzeLiveness (F, DT, LI);
973
1011
AssignSlots (F, livenessData);
974
- HandleOptimizationsAndSpills (F, livenessData, DT, LI );
1012
+ HandleOptimizationsAndSpills (F, livenessData);
975
1013
LowerSlotAssignments (F);
976
1014
LowerStackPtrs (F);
977
1015
0 commit comments