@@ -107,10 +107,11 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
107107 return std::move (analysis.map );
108108}
109109
110- std::unordered_map<Function*, std::unordered_set<Function*>>
111- buildCallGraph (const Module& module ,
112- const std::map<Function*, FuncInfo>& funcInfos) {
113- std::unordered_map<Function*, std::unordered_set<Function*>> callGraph;
110+ using CallGraph = std::unordered_map<Function*, std::unordered_set<Function*>>;
111+
112+ CallGraph buildCallGraph (const Module& module ,
113+ const std::map<Function*, FuncInfo>& funcInfos) {
114+ CallGraph callGraph;
114115 for (const auto & [func, info] : funcInfos) {
115116 for (Name callee : info.calledFunctions ) {
116117 callGraph[func].insert (module .getFunction (callee));
@@ -120,6 +121,19 @@ buildCallGraph(const Module& module,
120121 return callGraph;
121122}
122123
124+ void mergeMaybeEffects (std::optional<EffectAnalyzer>& dest,
125+ const std::optional<EffectAnalyzer>& src) {
126+ if (dest == UnknownEffects) {
127+ return ;
128+ }
129+ if (src == UnknownEffects) {
130+ dest = UnknownEffects;
131+ return ;
132+ }
133+
134+ dest->mergeIn (*src);
135+ }
136+
123137// Propagate effects from callees to callers transitively
124138// e.g. if A -> B -> C (A calls B which calls C)
125139// Then B inherits effects from C and A inherits effects from both B and C.
@@ -129,12 +143,10 @@ buildCallGraph(const Module& module,
129143// - Merge all of the effects of functions within the CC
130144// - Also merge the (already computed) effects of each callee CC
131145// - Add trap effects for potentially recursive call chains
132- void propagateEffects (
133- const Module& module ,
134- const PassOptions& passOptions,
135- std::map<Function*, FuncInfo>& funcInfos,
136- const std::unordered_map<Function*, std::unordered_set<Function*>>
137- callGraph) {
146+ void propagateEffects (const Module& module ,
147+ const PassOptions& passOptions,
148+ std::map<Function*, FuncInfo>& funcInfos,
149+ const CallGraph& callGraph) {
138150 struct CallGraphSCCs
139151 : SCCs<std::vector<Function*>::const_iterator, CallGraphSCCs> {
140152 const std::map<Function*, FuncInfo>& funcInfos;
@@ -170,19 +182,17 @@ void propagateEffects(
170182 }
171183 CallGraphSCCs sccs (allFuncs, funcInfos, callGraph, module );
172184
173- std::unordered_map<Function*, int > sccMembers ;
174- std::unordered_map< int , std::optional<EffectAnalyzer>> componentEffects;
185+ std::unordered_map<Function*, Index> funcComponents ;
186+ std::vector< std::optional<EffectAnalyzer>> componentEffects;
175187
176- int ccIndex = 0 ;
177188 for (auto ccIterator : sccs) {
178- ccIndex++;
179- std::optional<EffectAnalyzer>& ccEffects = componentEffects[ccIndex];
180- std::vector<Function*> ccFuncs (ccIterator.begin (), ccIterator.end ());
189+ std::optional<EffectAnalyzer>& ccEffects =
190+ componentEffects.emplace_back (std::in_place, passOptions, module );
181191
182- ccEffects. emplace (passOptions, module );
192+ std::vector<Function*> ccFuncs (ccIterator. begin (), ccIterator. end () );
183193
184194 for (Function* f : ccFuncs) {
185- sccMembers .emplace (f, ccIndex );
195+ funcComponents .emplace (f, componentEffects. size () - 1 );
186196 }
187197
188198 std::unordered_set<int > calleeSccs;
@@ -192,21 +202,14 @@ void propagateEffects(
192202 continue ;
193203 }
194204 for (auto * callee : callees->second ) {
195- calleeSccs.insert (sccMembers .at (callee));
205+ calleeSccs.insert (funcComponents .at (callee));
196206 }
197207 }
198208
199209 // Merge in effects from callees
200210 for (int calleeScc : calleeSccs) {
201211 const auto & calleeComponentEffects = componentEffects.at (calleeScc);
202- if (calleeComponentEffects == UnknownEffects) {
203- ccEffects = UnknownEffects;
204- break ;
205- }
206-
207- else if (ccEffects != UnknownEffects) {
208- ccEffects->mergeIn (*calleeComponentEffects);
209- }
212+ mergeMaybeEffects (ccEffects, calleeComponentEffects);
210213 }
211214
212215 // Add trap effects for potential cycles.
@@ -227,12 +230,7 @@ void propagateEffects(
227230 if (ccEffects) {
228231 for (Function* f : ccFuncs) {
229232 const auto & effects = funcInfos.at (f).effects ;
230- if (effects == UnknownEffects) {
231- ccEffects = UnknownEffects;
232- break ;
233- }
234-
235- ccEffects->mergeIn (*effects);
233+ mergeMaybeEffects (ccEffects, effects);
236234 }
237235 }
238236
@@ -247,7 +245,7 @@ void propagateEffects(
247245 }
248246}
249247
250- void copyEffectsToFunctions (const std::map<Function*, FuncInfo> funcInfos) {
248+ void copyEffectsToFunctions (const std::map<Function*, FuncInfo>& funcInfos) {
251249 for (auto & [func, info] : funcInfos) {
252250 func->effects .reset ();
253251 if (!info.effects ) {
0 commit comments