@@ -53,47 +53,8 @@ STATISTIC(NumOpenMPRuntimeFunctionUsesIdentified,
53
53
static constexpr auto TAG = " [" DEBUG_TYPE " ]" ;
54
54
#endif
55
55
56
- // / Helper struct to store tracked ICV values at specif instructions.
57
- struct ICVValue {
58
- Instruction *Inst;
59
- Value *TrackedValue;
60
-
61
- ICVValue (Instruction *I, Value *Val) : Inst(I), TrackedValue(Val) {}
62
- };
63
-
64
- namespace llvm {
65
-
66
- // Provide DenseMapInfo for ICVValue
67
- template <> struct DenseMapInfo <ICVValue> {
68
- using InstInfo = DenseMapInfo<Instruction *>;
69
- using ValueInfo = DenseMapInfo<Value *>;
70
-
71
- static inline ICVValue getEmptyKey () {
72
- return ICVValue (InstInfo::getEmptyKey (), ValueInfo::getEmptyKey ());
73
- };
74
-
75
- static inline ICVValue getTombstoneKey () {
76
- return ICVValue (InstInfo::getTombstoneKey (), ValueInfo::getTombstoneKey ());
77
- };
78
-
79
- static unsigned getHashValue (const ICVValue &ICVVal) {
80
- return detail::combineHashValue (
81
- InstInfo::getHashValue (ICVVal.Inst ),
82
- ValueInfo::getHashValue (ICVVal.TrackedValue ));
83
- }
84
-
85
- static bool isEqual (const ICVValue &LHS, const ICVValue &RHS) {
86
- return InstInfo::isEqual (LHS.Inst , RHS.Inst ) &&
87
- ValueInfo::isEqual (LHS.TrackedValue , RHS.TrackedValue );
88
- }
89
- };
90
-
91
- } // end namespace llvm
92
-
93
56
namespace {
94
57
95
- struct AAICVTracker ;
96
-
97
58
// / OpenMP specific information. For now, stores RFIs and ICVs also needed for
98
59
// / Attributor runs.
99
60
struct OMPInformationCache : public InformationCache {
@@ -160,9 +121,9 @@ struct OMPInformationCache : public InformationCache {
160
121
161
122
// / Return the vector of uses in function \p F.
162
123
UseVector &getOrCreateUseVector (Function *F) {
163
- std::shared_ptr <UseVector> &UV = UsesMap[F];
124
+ std::unique_ptr <UseVector> &UV = UsesMap[F];
164
125
if (!UV)
165
- UV = std::make_shared <UseVector>();
126
+ UV = std::make_unique <UseVector>();
166
127
return *UV;
167
128
}
168
129
@@ -218,7 +179,7 @@ struct OMPInformationCache : public InformationCache {
218
179
private:
219
180
// / Map from functions to all uses of this runtime function contained in
220
181
// / them.
221
- DenseMap<Function *, std::shared_ptr <UseVector>> UsesMap;
182
+ DenseMap<Function *, std::unique_ptr <UseVector>> UsesMap;
222
183
};
223
184
224
185
// / The slice of the module we are allowed to look at.
@@ -391,9 +352,9 @@ struct OpenMPOpt {
391
352
392
353
OpenMPOpt (SmallVectorImpl<Function *> &SCC, CallGraphUpdater &CGUpdater,
393
354
OptimizationRemarkGetter OREGetter,
394
- OMPInformationCache &OMPInfoCache, Attributor &A )
355
+ OMPInformationCache &OMPInfoCache)
395
356
: M(*(*SCC.begin())->getParent ()), SCC(SCC), CGUpdater(CGUpdater),
396
- OREGetter(OREGetter), OMPInfoCache(OMPInfoCache), A(A) {}
357
+ OREGetter(OREGetter), OMPInfoCache(OMPInfoCache) {}
397
358
398
359
// / Run all OpenMP optimizations on the underlying SCC/ModuleSlice.
399
360
bool run () {
@@ -424,7 +385,6 @@ struct OpenMPOpt {
424
385
}
425
386
}
426
387
427
- Changed |= runAttributor ();
428
388
Changed |= deduplicateRuntimeCalls ();
429
389
Changed |= deleteParallelRegions ();
430
390
@@ -786,206 +746,9 @@ struct OpenMPOpt {
786
746
787
747
// / OpenMP-specific information cache. Also Used for Attributor runs.
788
748
OMPInformationCache &OMPInfoCache;
789
-
790
- // / Attributor instance.
791
- Attributor &A;
792
-
793
- // / Helper function to run Attributor on SCC.
794
- bool runAttributor () {
795
- if (SCC.empty ())
796
- return false ;
797
-
798
- registerAAs ();
799
-
800
- ChangeStatus Changed = A.run ();
801
-
802
- LLVM_DEBUG (dbgs () << " [Attributor] Done with " << SCC.size ()
803
- << " functions, result: " << Changed << " .\n " );
804
-
805
- return Changed == ChangeStatus::CHANGED;
806
- }
807
-
808
- // / Populate the Attributor with abstract attribute opportunities in the
809
- // / function.
810
- void registerAAs () {
811
- for (Function *F : SCC) {
812
- if (F->isDeclaration ())
813
- continue ;
814
-
815
- A.getOrCreateAAFor <AAICVTracker>(IRPosition::function (*F));
816
- }
817
- }
818
- };
819
-
820
- // / Abstract Attribute for tracking ICV values.
821
- struct AAICVTracker : public StateWrapper <BooleanState, AbstractAttribute> {
822
- using Base = StateWrapper<BooleanState, AbstractAttribute>;
823
- AAICVTracker (const IRPosition &IRP, Attributor &A) : Base(IRP) {}
824
-
825
- // / Returns true if value is assumed to be tracked.
826
- bool isAssumedTracked () const { return getAssumed (); }
827
-
828
- // / Returns true if value is known to be tracked.
829
- bool isKnownTracked () const { return getAssumed (); }
830
-
831
- // / Create an abstract attribute biew for the position \p IRP.
832
- static AAICVTracker &createForPosition (const IRPosition &IRP, Attributor &A);
833
-
834
- // / Return the value with which \p I can be replaced for specific \p ICV.
835
- virtual Value *getReplacementValue (InternalControlVar ICV,
836
- const Instruction *I, Attributor &A) = 0;
837
-
838
- // / See AbstractAttribute::getName()
839
- const std::string getName () const override { return " AAICVTracker" ; }
840
-
841
- static const char ID;
842
- };
843
-
844
- struct AAICVTrackerFunction : public AAICVTracker {
845
- AAICVTrackerFunction (const IRPosition &IRP, Attributor &A)
846
- : AAICVTracker(IRP, A) {}
847
-
848
- // FIXME: come up with better string.
849
- const std::string getAsStr () const override { return " ICVTracker" ; }
850
-
851
- // FIXME: come up with some stats.
852
- void trackStatistics () const override {}
853
-
854
- // / TODO: decide whether to deduplicate here, or use current
855
- // / deduplicateRuntimeCalls function.
856
- ChangeStatus manifest (Attributor &A) override {
857
- ChangeStatus Changed = ChangeStatus::UNCHANGED;
858
-
859
- for (InternalControlVar &ICV : TrackableICVs)
860
- if (deduplicateICVGetters (ICV, A))
861
- Changed = ChangeStatus::CHANGED;
862
-
863
- return Changed;
864
- }
865
-
866
- bool deduplicateICVGetters (InternalControlVar &ICV, Attributor &A) {
867
- auto &OMPInfoCache = static_cast <OMPInformationCache &>(A.getInfoCache ());
868
- auto &ICVInfo = OMPInfoCache.ICVs [ICV];
869
- auto &GetterRFI = OMPInfoCache.RFIs [ICVInfo.Getter ];
870
-
871
- bool Changed = false ;
872
-
873
- auto ReplaceAndDeleteCB = [&](Use &U, Function &Caller) {
874
- CallInst *CI = OpenMPOpt::getCallIfRegularCall (U, &GetterRFI);
875
- Instruction *UserI = cast<Instruction>(U.getUser ());
876
- Value *ReplVal = getReplacementValue (ICV, UserI, A);
877
-
878
- if (!ReplVal || !CI)
879
- return false ;
880
-
881
- A.removeCallSite (CI);
882
- CI->replaceAllUsesWith (ReplVal);
883
- CI->eraseFromParent ();
884
- Changed = true ;
885
- return true ;
886
- };
887
-
888
- GetterRFI.foreachUse (ReplaceAndDeleteCB);
889
- return Changed;
890
- }
891
-
892
- // Map of ICV to their values at specific program point.
893
- EnumeratedArray<SmallSetVector<ICVValue, 4 >, InternalControlVar,
894
- InternalControlVar::ICV___last>
895
- ICVValuesMap;
896
-
897
- // Currently only nthreads is being tracked.
898
- // this array will only grow with time.
899
- InternalControlVar TrackableICVs[1 ] = {ICV_nthreads};
900
-
901
- ChangeStatus updateImpl (Attributor &A) override {
902
- ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
903
-
904
- Function *F = getAnchorScope ();
905
-
906
- auto &OMPInfoCache = static_cast <OMPInformationCache &>(A.getInfoCache ());
907
-
908
- for (InternalControlVar ICV : TrackableICVs) {
909
- auto &SetterRFI = OMPInfoCache.RFIs [OMPInfoCache.ICVs [ICV].Setter ];
910
-
911
- auto TrackValues = [&](Use &U, Function &) {
912
- CallInst *CI = OpenMPOpt::getCallIfRegularCall (U);
913
- if (!CI)
914
- return false ;
915
-
916
- // FIXME: handle setters with more that 1 arguments.
917
- // / Track new value.
918
- if (ICVValuesMap[ICV].insert (ICVValue (CI, CI->getArgOperand (0 ))))
919
- HasChanged = ChangeStatus::CHANGED;
920
-
921
- return false ;
922
- };
923
-
924
- SetterRFI.foreachUse (TrackValues, F);
925
- }
926
-
927
- return HasChanged;
928
- }
929
-
930
- // / Return the value with which \p I can be replaced for specific \p ICV.
931
- Value *getReplacementValue (InternalControlVar ICV, const Instruction *I,
932
- Attributor &A) override {
933
- const BasicBlock *CurrBB = I->getParent ();
934
-
935
- auto &ValuesSet = ICVValuesMap[ICV];
936
- auto &OMPInfoCache = static_cast <OMPInformationCache &>(A.getInfoCache ());
937
- auto &GetterRFI = OMPInfoCache.RFIs [OMPInfoCache.ICVs [ICV].Getter ];
938
-
939
- for (const auto &ICVVal : ValuesSet) {
940
- if (CurrBB == ICVVal.Inst ->getParent ()) {
941
- if (!ICVVal.Inst ->comesBefore (I))
942
- continue ;
943
-
944
- // both instructions are in the same BB and at \p I we know the ICV
945
- // value.
946
- while (I != ICVVal.Inst ) {
947
- // we don't yet know if a call might update an ICV.
948
- // TODO: check callsite AA for value.
949
- if (const auto *CB = dyn_cast<CallBase>(I))
950
- if (CB->getCalledFunction () != GetterRFI.Declaration )
951
- return nullptr ;
952
-
953
- I = I->getPrevNode ();
954
- }
955
-
956
- // No call in between, return the value.
957
- return ICVVal.TrackedValue ;
958
- }
959
- }
960
-
961
- // No value was tracked.
962
- return nullptr ;
963
- }
964
749
};
965
750
} // namespace
966
751
967
- const char AAICVTracker::ID = 0 ;
968
-
969
- AAICVTracker &AAICVTracker::createForPosition (const IRPosition &IRP,
970
- Attributor &A) {
971
- AAICVTracker *AA = nullptr ;
972
- switch (IRP.getPositionKind ()) {
973
- case IRPosition::IRP_INVALID:
974
- case IRPosition::IRP_FLOAT:
975
- case IRPosition::IRP_ARGUMENT:
976
- case IRPosition::IRP_RETURNED:
977
- case IRPosition::IRP_CALL_SITE_RETURNED:
978
- case IRPosition::IRP_CALL_SITE_ARGUMENT:
979
- case IRPosition::IRP_CALL_SITE:
980
- llvm_unreachable (" ICVTracker can only be created for function position!" );
981
- case IRPosition::IRP_FUNCTION:
982
- AA = new (A.Allocator ) AAICVTrackerFunction (IRP, A);
983
- break ;
984
- }
985
-
986
- return *AA;
987
- }
988
-
989
752
PreservedAnalyses OpenMPOptPass::run (LazyCallGraph::SCC &C,
990
753
CGSCCAnalysisManager &AM,
991
754
LazyCallGraph &CG, CGSCCUpdateResult &UR) {
@@ -1022,10 +785,8 @@ PreservedAnalyses OpenMPOptPass::run(LazyCallGraph::SCC &C,
1022
785
OMPInformationCache InfoCache (*(Functions.back ()->getParent ()), AG, Allocator,
1023
786
/* CGSCC*/ &Functions, ModuleSlice);
1024
787
1025
- Attributor A (Functions, InfoCache, CGUpdater);
1026
-
1027
788
// TODO: Compute the module slice we are allowed to look at.
1028
- OpenMPOpt OMPOpt (SCC, CGUpdater, OREGetter, InfoCache, A );
789
+ OpenMPOpt OMPOpt (SCC, CGUpdater, OREGetter, InfoCache);
1029
790
bool Changed = OMPOpt.run ();
1030
791
(void )Changed;
1031
792
return PreservedAnalyses::all ();
@@ -1089,10 +850,8 @@ struct OpenMPOptLegacyPass : public CallGraphSCCPass {
1089
850
Allocator,
1090
851
/* CGSCC*/ &Functions, ModuleSlice);
1091
852
1092
- Attributor A (Functions, InfoCache, CGUpdater);
1093
-
1094
853
// TODO: Compute the module slice we are allowed to look at.
1095
- OpenMPOpt OMPOpt (SCC, CGUpdater, OREGetter, InfoCache, A );
854
+ OpenMPOpt OMPOpt (SCC, CGUpdater, OREGetter, InfoCache);
1096
855
return OMPOpt.run ();
1097
856
}
1098
857
0 commit comments