@@ -25,6 +25,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
25
======================= end_copyright_notice ==================================*/
26
26
27
27
#include " FlowGraph.h"
28
+ #include < unordered_set>
29
+ #include < unordered_map>
28
30
#include < string>
29
31
#include < set>
30
32
#include < iostream>
@@ -6005,3 +6007,198 @@ void FuncInfo::dump() const
6005
6007
}
6006
6008
std::cerr << " \n " ;
6007
6009
}
6010
+
6011
+ PostDom::PostDom (G4_Kernel& k) : kernel(k)
6012
+ {
6013
+ auto numBBs = k.fg .BBs .size ();
6014
+ postDoms.resize (numBBs);
6015
+ immPostDoms.resize (numBBs);
6016
+ }
6017
+
6018
+ void PostDom::run ()
6019
+ {
6020
+ exitBB = nullptr ;
6021
+ for (auto bb_rit = kernel.fg .BBs .rbegin (); bb_rit != kernel.fg .BBs .rend (); bb_rit++)
6022
+ {
6023
+ auto bb = *bb_rit;
6024
+ if (bb->size () > 0 )
6025
+ {
6026
+ auto lastInst = bb->back ();
6027
+ if (lastInst->isEOT ())
6028
+ {
6029
+ exitBB = bb;
6030
+ break ;
6031
+ }
6032
+ }
6033
+ }
6034
+
6035
+ MUST_BE_TRUE (exitBB != nullptr , " Exit BB not found!" );
6036
+
6037
+ postDoms[exitBB->getId ()] = { exitBB };
6038
+ std::unordered_set<G4_BB*> allBBs;
6039
+ for (auto bb : kernel.fg .BBs )
6040
+ {
6041
+ allBBs.insert (bb);
6042
+ }
6043
+
6044
+ for (auto bb : kernel.fg .BBs )
6045
+ {
6046
+ if (bb != exitBB)
6047
+ {
6048
+ postDoms[bb->getId ()] = allBBs;
6049
+ }
6050
+ }
6051
+
6052
+ // Actual post dom computation
6053
+ bool change = true ;
6054
+ while (change)
6055
+ {
6056
+ change = false ;
6057
+ for (auto bb : kernel.fg .BBs )
6058
+ {
6059
+ if (bb == exitBB)
6060
+ continue ;
6061
+
6062
+ std::unordered_set<G4_BB*> tmp = { bb };
6063
+ // Compute intersection of pdom of successors
6064
+ std::unordered_map<G4_BB*, unsigned int > numInstances;
6065
+ for (auto succs : bb->Succs )
6066
+ {
6067
+ auto & pdomSucc = postDoms[succs->getId ()];
6068
+ for (auto pdomSuccBB : pdomSucc)
6069
+ {
6070
+ auto it = numInstances.find (pdomSuccBB);
6071
+ if (it == numInstances.end ())
6072
+ numInstances.insert (std::make_pair (pdomSuccBB, 1 ));
6073
+ else
6074
+ it->second = it->second + 1 ;
6075
+ }
6076
+ }
6077
+
6078
+ // Common BBs appear in numInstances map with second value == bb->Succs count
6079
+ for (auto commonBBs : numInstances)
6080
+ {
6081
+ if (commonBBs.second == bb->Succs .size ())
6082
+ tmp.insert (commonBBs.first );
6083
+ }
6084
+
6085
+ // Check if postDom set changed for bb in current iter
6086
+ if (tmp.size () != postDoms[bb->getId ()].size ())
6087
+ {
6088
+ postDoms[bb->getId ()] = tmp;
6089
+ change = true ;
6090
+ continue ;
6091
+ }
6092
+ else
6093
+ {
6094
+ auto & pdomBB = postDoms[bb->getId ()];
6095
+ for (auto tmpBB : tmp)
6096
+ {
6097
+ if (pdomBB.find (tmpBB) == pdomBB.end ())
6098
+ {
6099
+ postDoms[bb->getId ()] = tmp;
6100
+ change = true ;
6101
+ break ;
6102
+ }
6103
+ if (change)
6104
+ break ;
6105
+ }
6106
+ }
6107
+ }
6108
+ }
6109
+
6110
+ updateImmPostDom ();
6111
+ }
6112
+
6113
+ std::unordered_set<G4_BB*>& PostDom::getPostDom (G4_BB* bb)
6114
+ {
6115
+ return postDoms[bb->getId ()];
6116
+ }
6117
+
6118
+ void PostDom::dumpImmDom ()
6119
+ {
6120
+ for (auto bb : kernel.fg .BBs )
6121
+ {
6122
+ printf (" BB%d - " , bb->getId ());
6123
+ auto & pdomBBs = immPostDoms[bb->getId ()];
6124
+ for (auto pdomBB : pdomBBs)
6125
+ {
6126
+ printf (" BB%d" , pdomBB->getId ());
6127
+ if (pdomBB->getLabel ())
6128
+ {
6129
+ printf (" (%s)" , pdomBB->getLabel ()->getLabel ());
6130
+ }
6131
+ printf (" , " );
6132
+ }
6133
+ printf (" \n " );
6134
+ }
6135
+ }
6136
+
6137
+ std::vector<G4_BB*>& PostDom::getImmPostDom (G4_BB* bb)
6138
+ {
6139
+ return immPostDoms[bb->getId ()];
6140
+ }
6141
+
6142
+ void PostDom::updateImmPostDom ()
6143
+ {
6144
+ // Update immPostDom vector with correct ordering
6145
+ for (auto bb : kernel.fg .BBs )
6146
+ {
6147
+ {
6148
+ auto & postDomBBs = postDoms[bb->getId ()];
6149
+ auto & immPostDomBB = immPostDoms[bb->getId ()];
6150
+ immPostDomBB.resize (postDomBBs.size ());
6151
+ immPostDomBB[0 ] = bb;
6152
+
6153
+ for (auto pdomBB : postDomBBs)
6154
+ {
6155
+ if (pdomBB == bb)
6156
+ continue ;
6157
+
6158
+ immPostDomBB[postDomBBs.size () - postDoms[pdomBB->getId ()].size ()] = pdomBB;
6159
+ }
6160
+ }
6161
+ }
6162
+ }
6163
+
6164
+ G4_BB* PostDom::getCommonImmDom (std::unordered_set<G4_BB*>& bbs)
6165
+ {
6166
+ if (bbs.size () == 0 )
6167
+ return nullptr ;
6168
+
6169
+ unsigned int maxId = (*bbs.begin ())->getId ();
6170
+
6171
+ auto commonImmDoms = getImmPostDom (*bbs.begin ());
6172
+ for (auto bb : bbs)
6173
+ {
6174
+ if (bb->getId () > maxId)
6175
+ maxId = bb->getId ();
6176
+
6177
+ auto & postDomBB = postDoms[bb->getId ()];
6178
+ for (unsigned int i = 0 ; i != commonImmDoms.size (); i++)
6179
+ {
6180
+ if (commonImmDoms[i])
6181
+ {
6182
+ if (postDomBB.find (commonImmDoms[i]) == postDomBB.end ())
6183
+ {
6184
+ commonImmDoms[i] = nullptr ;
6185
+ }
6186
+ }
6187
+ }
6188
+ }
6189
+
6190
+ // Return first imm dom that is not a BB from bbs set
6191
+ for (unsigned int i = 0 ; i != commonImmDoms.size (); i++)
6192
+ {
6193
+ if (commonImmDoms[i] &&
6194
+ // Common imm pdom must be lexically last BB
6195
+ commonImmDoms[i]->getId () >= maxId &&
6196
+ ((commonImmDoms[i]->size () > 1 && commonImmDoms[i]->front ()->isLabel ()) ||
6197
+ (commonImmDoms[i]->size () > 0 && !commonImmDoms[i]->front ()->isLabel ())))
6198
+ {
6199
+ return commonImmDoms[i];
6200
+ }
6201
+ }
6202
+
6203
+ return exitBB;
6204
+ }
0 commit comments