cgallocregs.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. #include "cgstd.h"
  2. #include "cgallocregs.h"
  3. #include "cgdebug.h"
  4. #include "cgutil.h"
  5. #include <float.h>
  6. //quick debug
  7. //#define _DEBUG_ALLOCREGS
  8. //BIG debug!
  9. //#define _DEBUG_REGALLOC
  10. using namespace CG;
  11. using namespace std;
  12. static CGFlow *flow;
  13. static CGFrame *frame;
  14. struct Node;
  15. typedef set<Node*> NodeSet;
  16. typedef NodeSet::iterator NodeIter;
  17. static int reg_colors[4];
  18. static int n_passes,n_spills,max_spill_id;
  19. struct Node{
  20. Node *succ,*pred,*_list;
  21. CGReg *reg;
  22. Node *alias;
  23. int bank,color,degree;
  24. float usage;
  25. int block_count;
  26. NodeSet edges,moves;
  27. bool cant_spill;
  28. Node():reg(0),alias(0),bank(-1),color(-1),degree(0),usage(0),block_count(1),cant_spill(false){
  29. clear();
  30. }
  31. void setReg( CGReg *r ){
  32. reg=r;
  33. color=reg->color;
  34. bank=frame->reg_banks[reg->type];
  35. }
  36. Node *unAlias(){
  37. return alias ? alias->unAlias() : this;
  38. }
  39. void clear(){
  40. _list=0;
  41. succ=pred=this;
  42. }
  43. bool empty(){
  44. return succ==this;
  45. }
  46. void insert( Node *t_list ){
  47. if( _list==t_list ) return;
  48. pred->succ=succ;
  49. succ->pred=pred;
  50. succ=t_list;
  51. pred=succ->pred;
  52. succ->pred=pred->succ=this;
  53. _list=t_list;
  54. }
  55. int colors(){
  56. return reg_colors[bank];
  57. }
  58. bool sigDegree(){
  59. return degree>=colors();
  60. }
  61. bool colored(){
  62. return color!=-1;
  63. }
  64. bool moveRelated(){
  65. return moves.size()>0;
  66. }
  67. };
  68. //node per enumerated tmp
  69. static vector<Node> nodes;
  70. //nodes not yet removed from graph
  71. static Node *_simplify,*_coalesce,*_freeze,*_spill;
  72. //nodes removed from graph
  73. static Node *_selected,*_coalesced,*_spilled,*_colored;
  74. static void freezeNode( Node *node );
  75. static void createNodes(){
  76. nodes.clear();
  77. nodes.resize( frame->regs.size() );
  78. int k;
  79. for( k=0;k<frame->regs.size();++k ){
  80. CGReg *r=frame->regs[k];
  81. nodes[k].setReg( r );
  82. if( r->id!=k ) nodes[k].alias=&nodes[r->id];
  83. }
  84. for( k=0;k<nodes.size();++k ){
  85. if( nodes[k].alias ){
  86. CGReg *r=nodes[k].unAlias()->reg;
  87. assert( frame->regs[r->id]->id==r->id );
  88. }
  89. }
  90. }
  91. static void createGraph(){
  92. CGAsm *as;
  93. CGBlockCIter blk_it;
  94. //build interference edges
  95. for( blk_it=flow->blocks.begin();blk_it!=flow->blocks.end();++blk_it ){
  96. CGBlock *blk=*blk_it;
  97. float use_cost=pow((double)10,(double)blk->loop_level);
  98. //Increase usage for regs that are live_in and live_out
  99. CGIntCIter int_it;
  100. for( int_it=blk->live_in.begin();int_it!=blk->live_in.end();++int_it ){
  101. if( blk->live_out.count(*int_it) ) nodes[*int_it].block_count+=1;
  102. }
  103. CGIntSet live=blk->live_out;
  104. CGAsm *as=blk->end;
  105. while( as!=blk->begin ){
  106. as=as->pred;
  107. Node *copy_src=0;
  108. if( CGMov *t=as->stm->mov() ){
  109. if( CGReg *lhs=t->lhs->reg() ){
  110. if( CGReg *rhs=t->rhs->reg() ){
  111. copy_src=&nodes[rhs->id];
  112. }
  113. }
  114. }
  115. CGIntCIter def_it;
  116. for( def_it=as->def.begin();def_it!=as->def.end();++def_it ){
  117. Node *x=&nodes[*def_it];
  118. x->usage+=use_cost;
  119. CGIntCIter live_it;
  120. for( live_it=live.begin();live_it!=live.end();++live_it ){
  121. Node *y=&nodes[*live_it];
  122. if( (x!=y) && (y!=copy_src) && (x->bank==y->bank) ){
  123. x->edges.insert( y );
  124. y->edges.insert( x );
  125. }
  126. }
  127. }
  128. CGIntCIter use_it;
  129. for( use_it=as->use.begin();use_it!=as->use.end();++use_it ){
  130. Node *y=&nodes[*use_it];
  131. y->usage+=use_cost;
  132. }
  133. live.erase( as->def );
  134. live.insert( as->use );
  135. }
  136. }
  137. //build 'move' edges
  138. for( as=flow->assem.begin;as!=flow->assem.end;as=as->succ ){
  139. if( CGMov *t=as->stm->mov() ){
  140. if( CGReg *lhs=t->lhs->reg() ){
  141. if( CGReg *rhs=t->rhs->reg() ){
  142. Node *x=&nodes[lhs->id];
  143. Node *y=&nodes[rhs->id];
  144. if( x!=y && !x->edges.count(y) ){
  145. x->moves.insert(y);
  146. y->moves.insert(x);
  147. }
  148. }
  149. }
  150. }
  151. }
  152. //initial node degrees
  153. int k;
  154. for( k=0;k<nodes.size();++k ){
  155. Node *node=&nodes[k];
  156. node->degree=node->colored() ? 0x7fffffff : node->edges.size();
  157. }
  158. #ifdef _DEBUG_REGALLOC
  159. cout<<endl<<";--- Flow ---;"<<endl;
  160. cout<<flow;
  161. cout<<endl<<";--- Interference graph ---;"<<endl;
  162. for( k=0;k<nodes.size();++k ){
  163. Node *node=&nodes[k];
  164. cout<<node->reg->id<<' ';
  165. cout<<"(usage="<<node->usage;
  166. cout<<" moves="<<node->moves.size();
  167. cout<<" degree="<<node->degree;
  168. if( node->degree ) cout<<" spill="<<(float)node->usage/(float)node->degree;
  169. cout<<"):";
  170. NodeIter it;
  171. for( it=node->edges.begin();it!=node->edges.end();++it ){
  172. cout<<' '<<(*it)->reg->id;
  173. }
  174. cout<<endl;
  175. }
  176. #endif
  177. }
  178. static void createLists(){
  179. //initialize lists
  180. if( !_simplify ){
  181. _simplify=new Node;
  182. _coalesce=new Node;
  183. _freeze=new Node;
  184. _spill=new Node;
  185. _selected=new Node;
  186. _coalesced=new Node;
  187. _spilled=new Node;
  188. _colored=new Node;
  189. }
  190. _simplify->clear();
  191. _coalesce->clear();
  192. _freeze->clear();
  193. _spill->clear();
  194. _selected->clear();
  195. _coalesced->clear();
  196. _spilled->clear();
  197. _colored->clear();
  198. for( int k=0;k<nodes.size();++k ){
  199. Node *node=&nodes[k];
  200. if( node->alias ) node->insert( _coalesced );
  201. else if( node->moveRelated() ) node->insert( _coalesce );
  202. else freezeNode( node );
  203. }
  204. }
  205. //decrement degree of a node.
  206. static void decDegree( Node *node ){
  207. //dec degree
  208. if( --node->degree!=node->colors()-1 ) return;
  209. //OK node transitioned from sig to insig...
  210. //move frozen neighbors to coalesce
  211. NodeIter it;
  212. for( it=node->edges.begin();it!=node->edges.end();++it ){
  213. Node *t=(*it);
  214. if( t->_list==_freeze ) t->insert( _coalesce );
  215. }
  216. //simplify if in spill
  217. if( node->_list==_spill ) node->insert( _simplify );
  218. }
  219. //node has become non-move related
  220. //(node in coalesce or frozen)
  221. static void freezeNode( Node *node ){
  222. assert( !node->moveRelated() );
  223. if( node->colored() ) node->insert( _colored );
  224. else if( node->sigDegree() ) node->insert( _spill );
  225. else node->insert( _simplify );
  226. }
  227. //move node to select stack
  228. //decrement degree of neighboring nodes
  229. //(node is insig degree )
  230. static void selectNode( Node *node ){
  231. assert( node->_list==_simplify || node->_list==_spill );
  232. node->degree=0;
  233. node->insert( _selected );
  234. NodeIter it;
  235. for( it=node->edges.begin();it!=node->edges.end();++it ){
  236. Node *t=(*it);
  237. decDegree( t );
  238. }
  239. }
  240. //combine nodes a,b to node a
  241. //(a in coalesce, b in coalesce or frozen)
  242. static void combine( Node *a,Node *b ){
  243. assert( a->_list==_coalesce && (b->_list==_coalesce||b->_list==_freeze) );
  244. a->cant_spill=true;
  245. b->alias=a;
  246. b->insert( _coalesced );
  247. NodeIter it;
  248. //fix moves
  249. for( it=b->moves.begin();it!=b->moves.end();++it ){
  250. Node *t=*it;
  251. t->moves.erase(b);
  252. if( t==a ) continue;
  253. if( !a->edges.count(t) ){
  254. t->moves.insert(a);
  255. a->moves.insert(t);
  256. }else if( !t->moveRelated() ){
  257. freezeNode(t);
  258. }
  259. }
  260. //fix edges
  261. for( it=b->edges.begin();it!=b->edges.end();++it ){
  262. Node *t=(*it);
  263. t->edges.erase(b);
  264. if( a->edges.count(t) ){
  265. decDegree(t);
  266. continue;
  267. }
  268. t->edges.insert(a);
  269. a->edges.insert(t);
  270. if( t->_list==_selected ) continue;
  271. if( !a->colored() ) ++a->degree;
  272. if( !t->moves.count(a) ) continue;
  273. t->moves.erase(a);
  274. a->moves.erase(t);
  275. if( !t->moveRelated() ) freezeNode(t);
  276. }
  277. a->usage+=b->usage;
  278. if( !a->moveRelated() ) freezeNode( a );
  279. }
  280. //Briggs:
  281. //can we coalesce these 2 nodes?
  282. //(a in coalesce, b in coalesce or frozen)
  283. static bool canCoalesce( Node *a,Node *b ){
  284. assert( a->_list==_coalesce && (b->_list==_coalesce||b->_list==_freeze||b->_list==_colored) );
  285. if( b->colored() ) return false;
  286. NodeIter it;
  287. bool briggs;
  288. //Briggs...
  289. int n=0;
  290. for( it=a->edges.begin();it!=a->edges.end();++it ){
  291. Node *t=(*it);
  292. if( t->sigDegree() ) ++n;
  293. }
  294. for( it=b->edges.begin();it!=b->edges.end();++it ){
  295. Node *t=(*it);
  296. if( t->sigDegree() && !t->edges.count(a) ) ++n;
  297. }
  298. briggs=n<a->colors();
  299. return briggs;
  300. }
  301. static void simplify(){
  302. Node *node=_simplify->succ;
  303. #ifdef _DEBUG_REGALLOC
  304. cout<<"Simplifying:\t"<<node->reg->id<<endl;
  305. #endif
  306. selectNode( node );
  307. }
  308. static void coalesce(){
  309. Node *node=_coalesce->succ;
  310. NodeIter it;
  311. for( it=node->moves.begin();it!=node->moves.end();++it ){
  312. Node *t=*it;
  313. if( !canCoalesce(node,t) ) continue;
  314. #ifdef _DEBUG_REGALLOC
  315. cout<<"Coalescing:\t"<<t->reg->id<<"->"<<node->reg->id<<endl;
  316. #endif
  317. combine(node,t);
  318. return;
  319. }
  320. if( node->colored() ) node->insert( _colored );
  321. else node->insert( _freeze );
  322. }
  323. //freeze heuristic:
  324. //pick non-sig degree node with lowest move count
  325. //
  326. static void freeze(){
  327. int min=0x7fffffff;
  328. Node *node=0;
  329. for( Node *t=_freeze->succ;t!=_freeze;t=t->succ ){
  330. if( t->degree<min ){
  331. node=t;
  332. min=t->degree;
  333. }
  334. }
  335. #ifdef _DEBUG_REGALLOC
  336. cout<<"Freezing:\t"<<node->reg->id<<endl;
  337. #endif
  338. NodeIter it;
  339. for( it=node->moves.begin();it!=node->moves.end();++it ){
  340. Node *t=*it;
  341. t->moves.erase(node);
  342. if( !t->moveRelated() ) freezeNode( t );
  343. }
  344. node->moves.clear();
  345. freezeNode( node );
  346. }
  347. static void spill(){
  348. Node *node=0;
  349. float min=FLT_MAX;
  350. for( int pass=0;pass<2;++pass ){
  351. for( Node *t=_spill->succ;t!=_spill;t=t->succ ){
  352. if( t->cant_spill ) cout<<"Shouldn't spill:"<<t->reg->id<<endl;
  353. //don't spill reg generated by prior spill
  354. if( !pass && t->reg->id>=max_spill_id ) continue;
  355. //No idea...!
  356. // if( !pass && t->reg->owner ) continue;
  357. // float cost=(float)t->usage/(float)t->degree;
  358. //***** Munged cost *****//
  359. float cost=(float)t->usage/((float)t->degree*(float)t->block_count);
  360. if( cost<min ){
  361. node=t;
  362. min=cost;
  363. }
  364. }
  365. if( node ) break;
  366. cout<<"Pass "<<n_passes<<": trouble finding spill candidate\n"<<endl;
  367. }
  368. if( !node ) fail( "Unable to find spill candidate" );
  369. #ifdef _DEBUG_REGALLOC
  370. cout<<"Spilling:\t"<<node->reg->id<<endl;
  371. #endif
  372. selectNode( node );
  373. }
  374. static bool selectRegs(){
  375. #ifdef _DEBUG_REGALLOC
  376. cout<<endl<<";--- Popping stack ---;"<<endl;
  377. #endif
  378. while( !_selected->empty() ){
  379. Node *node=_selected->pred;
  380. //find color;
  381. NodeIter it;
  382. unsigned avail=frame->reg_masks[node->bank];
  383. for( it=node->edges.begin();it!=node->edges.end();++it ){
  384. Node *t=(*it);
  385. if( t->color>=0 ) avail&=~(1<<t->color);
  386. }
  387. if( avail ){
  388. int color=0;
  389. for( ;!(avail&1);avail>>=1 ) ++color;
  390. node->color=color;
  391. node->insert( _colored );
  392. #ifdef _DEBUG_REGALLOC
  393. cout<<"Colored:\t"<<node->reg->id<<"->"<<color<<endl;
  394. #endif
  395. }else{
  396. node->insert( _spilled );
  397. #ifdef _DEBUG_REGALLOC
  398. cout<<"Spilled:\t"<<node->reg->id<<endl;
  399. #endif
  400. }
  401. }
  402. if( _spilled->empty() ){
  403. int k;
  404. for( k=0;k<nodes.size();++k ){
  405. Node *x=&nodes[k];
  406. Node *y=x->unAlias();
  407. assert( y->color>=0 );
  408. x->reg->color=y->color;
  409. }
  410. return true;
  411. }
  412. // max_spill_id=nodes.size();
  413. for( Node *node=_spilled->succ;node!=_spilled;node=node->succ ){
  414. frame->spillReg( node->reg,0 );
  415. ++n_spills;
  416. }
  417. flow->liveness();
  418. return false;
  419. }
  420. static int countBits( unsigned n ){
  421. int c=0;
  422. for( ;n;n>>=1 ) c+=(n&1);
  423. return c;
  424. }
  425. static bool allocRegs(){
  426. createNodes();
  427. createGraph();
  428. createLists();
  429. if( !max_spill_id ) max_spill_id=nodes.size();
  430. for(;;){
  431. if( !_simplify->empty() ){
  432. simplify();
  433. }else if( !_coalesce->empty() ){
  434. coalesce();
  435. }else if( !_freeze->empty() ){
  436. freeze();
  437. }else if( !_spill->empty() ){
  438. spill();
  439. }else{
  440. break;
  441. }
  442. }
  443. return selectRegs();
  444. }
  445. void cgAllocRegs( CGFrame *t_frame ){
  446. frame=t_frame;
  447. flow=frame->flow;
  448. for( int k=0;k<4;++k ){
  449. reg_colors[k]=countBits( frame->reg_masks[k] );
  450. }
  451. nodes.clear();
  452. max_spill_id=0;//0x7fffffff;
  453. n_passes=0;
  454. n_spills=0;
  455. for(;;){
  456. if( ++n_passes==100 ){
  457. cout<<"INTERNAL ERROR! Register allocator terminally confused!"<<endl;
  458. abort();
  459. }
  460. if( allocRegs() ) break;
  461. }
  462. #ifdef _DEBUG_ALLOCREGS
  463. if( n_spills ){
  464. cout<<frame->fun->sym->value<<" passes="<<n_passes<<" spills="<<n_spills<<endl;
  465. }
  466. #endif
  467. }