cgflow.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #include "cgstd.h"
  2. #include "cgflow.h"
  3. #include "cgutil.h"
  4. #include "cgdebug.h"
  5. //#define _DEBUG_FLOW
  6. static set<CGBlock*> reachable;
  7. static void findReachable( CGBlock *blk ){
  8. if( !reachable.insert(blk).second ) return;
  9. CGBlockIter it;
  10. for( it=blk->succ.begin();it!=blk->succ.end();++it ){
  11. findReachable(*it);
  12. }
  13. }
  14. //******************* Build flow ******************
  15. CGBlock *CGFlow::block( CGAsm *as,CGBlock *p ){
  16. CGBlock *b=new CGBlock;
  17. b->begin=b->end=as;
  18. blocks.push_back(b);
  19. if( !p ) return b;
  20. p->succ.push_back(b);
  21. b->pred.push_back(p);
  22. return b;
  23. }
  24. void CGFlow::buildFlow(){
  25. CGAsm *as;
  26. blocks.clear();
  27. map<CGSym*,CGBlock*> lab_map;
  28. map<CGBlock*,CGSym*> bra_map;
  29. #ifdef _DEBUG_FLOW
  30. cout<<"CGFlow::buildFlow()"<<endl;
  31. #endif
  32. //make sure there's a label at the start
  33. if( !assem.begin->stm->lab() ){
  34. assem.insert( new CGAsm(CG::lab(),""),assem.begin );
  35. }
  36. //ensure there's a LAB after each BRA/BCC/RET
  37. for( as=assem.begin;as!=assem.end;as=as->succ ){
  38. CGStm *st=as->stm;
  39. if( !st->bra() && !st->bcc() && !st->ret() ) continue;
  40. if( as->succ->stm->lab() ) continue;
  41. as=assem.insert( new CGAsm(CG::lab(),""),as->succ );
  42. }
  43. as=assem.begin;
  44. CGBlock *b=block(as,0);
  45. while( as!=assem.end ){
  46. CGStm *st=as->stm;
  47. if( CGLab *t=st->lab() ){
  48. if( as!=b->begin ){
  49. b->end=as;
  50. b=block(as,b);
  51. }
  52. lab_map[t->sym]=b;
  53. as=as->succ;
  54. }else if( CGBra *t=st->bra() ){
  55. bra_map[b]=t->sym;
  56. as=as->succ;
  57. b->end=as;
  58. b=block(as,0);
  59. }else if( CGBcc *t=st->bcc() ){
  60. bra_map[b]=t->sym;
  61. as=as->succ;
  62. b->end=as;
  63. b=block(as,b);
  64. }else if( CGRet *t=st->ret() ){
  65. as=as->succ;
  66. b->end=as;
  67. b=block(as,0);
  68. }else{
  69. as=as->succ;
  70. }
  71. }
  72. b->end=as;
  73. //patch bras
  74. map<CGBlock*,CGSym*>::iterator it;
  75. for( it=bra_map.begin();it!=bra_map.end();++it ){
  76. CGBlock *src=it->first;
  77. if( !lab_map.count(it->second) ) continue;
  78. CGBlock *dst=lab_map[it->second];
  79. src->succ.push_back( dst );
  80. dst->pred.push_back( src );
  81. }
  82. //find reachable blocks
  83. reachable.clear();
  84. findReachable( *blocks.begin() );
  85. CGBlockIter blk_it=blocks.begin();
  86. for( ++blk_it;blk_it!=blocks.end(); ){
  87. //reachable?
  88. CGBlock *blk=*blk_it;
  89. if( reachable.count(blk) ){
  90. ++blk_it;
  91. continue;
  92. }
  93. //erase assem
  94. CGAsm *as=blk->begin;
  95. while( as!=blk->end ) as=assem.erase(as);
  96. (*(blk_it-1))->end=as;
  97. //erase block
  98. blk_it=blocks.erase( blk_it );
  99. }
  100. }
  101. //***************** Loop detection ****************
  102. static void eraseDom( CGBlock *blk,CGBlock *dom ){
  103. if( blk==dom ) return;
  104. if( !blk->dom.insert(dom).second ) return;
  105. CGBlockIter it;
  106. for( it=blk->succ.begin();it!=blk->succ.end();++it ){
  107. eraseDom( *it,dom );
  108. }
  109. }
  110. static void insertLoop( CGBlock *blk,CGBlock *head ){
  111. if( !head->loops.insert( blk ).second ) return;
  112. CGBlockIter it;
  113. for( it=blk->pred.begin();it!=blk->pred.end();++it ){
  114. insertLoop( *it,head );
  115. }
  116. }
  117. void CGFlow::findLoops(){
  118. #ifdef _DEBUG_FLOW
  119. cout<<"CGFlow::findLoops() - blocks="<<blocks.size()<<endl;
  120. #endif
  121. // cout<<"findLoops blocks="<<blocks.size()<<endl;
  122. int k;
  123. for( k=0;k<blocks.size();++k ){
  124. blocks[k]->dom.clear();
  125. blocks[k]->loops.clear();
  126. blocks[k]->loop_level=0;
  127. }
  128. if( blocks.size()>1000 ) return;
  129. // cout<<"EraseDom"<<endl;
  130. for( k=0;k<blocks.size();++k ){
  131. eraseDom( blocks[0],blocks[k] );
  132. }
  133. // cout<<"Find back edges"<<endl;
  134. //find back edges
  135. for( k=0;k<blocks.size();++k ){
  136. CGBlock *blk=blocks[k];
  137. CGBlockIter it;
  138. for( it=blk->succ.begin();it!=blk->succ.end();++it ){
  139. CGBlock *head=*it;
  140. if( blk->dom.count(head) ) continue;
  141. head->loops.insert( head );
  142. insertLoop( blk,head );
  143. }
  144. }
  145. // cout<<"Creating loop_level"<<endl;
  146. //create loop_level
  147. for( k=0;k<blocks.size();++k ){
  148. CGBlock *blk=blocks[k];
  149. set<CGBlock*>::iterator it;
  150. for( it=blk->loops.begin();it!=blk->loops.end();++it ){
  151. ++(*it)->loop_level;
  152. }
  153. }
  154. }
  155. //*************** liveness analysis ***************
  156. static void liveIn( CGBlock *blk,int n ){
  157. if( !blk->live_in.insert( n ) ) return;
  158. CGBlockIter it;
  159. for( it=blk->pred.begin();it!=blk->pred.end();++it ){
  160. CGBlock *t=*it;
  161. if( t->live_out.insert(n) && !t->def.count(n) ) liveIn( t,n );
  162. }
  163. }
  164. void CGFlow::liveness(){
  165. #ifdef _DEBUG_FLOW
  166. cout<<"CGFlow::liveness()"<<endl;
  167. #endif
  168. CGBlockIter blk_it;
  169. for( blk_it=blocks.begin();blk_it!=blocks.end();++blk_it ){
  170. CGBlock *blk=*blk_it;
  171. blk->use.clear();
  172. blk->def.clear();
  173. blk->live_in.clear();
  174. blk->live_out.clear();
  175. CGAsm *as;
  176. for( as=blk->begin;as!=blk->end;as=as->succ ){
  177. blk->use.xinsert( as->use,blk->def );
  178. blk->def.xinsert( as->def,blk->use );
  179. }
  180. }
  181. for( blk_it=blocks.begin();blk_it!=blocks.end();++blk_it ){
  182. CGBlock *blk=*blk_it;
  183. CGIntCIter it;
  184. for( it=blk->use.begin();it!=blk->use.end();++it ){
  185. liveIn( blk,*it );
  186. }
  187. }
  188. }
  189. //***************** Constructor *******************
  190. static vector<CGFlow*> _flows;
  191. CGFlow::CGFlow( CGAsmSeq &t_assem ):assem(t_assem){
  192. buildFlow();
  193. findLoops();
  194. _flows.push_back( this );
  195. }
  196. CGFlow::~CGFlow(){
  197. for( int k=0;k<blocks.size();++k ){
  198. delete blocks[k];
  199. }
  200. }