proplong.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. /**************************************************************************
  2. * File : propLong.c
  3. * Purpose: propagate the value of long variables (local variables and
  4. * registers) along the graph. Structure the graph in this way.
  5. * (C) Cristina Cifuentes
  6. **************************************************************************/
  7. #include <string.h>
  8. #include <memory.h>
  9. #include <cassert>
  10. #include <algorithm>
  11. #include "dcc.h"
  12. /* Returns whether the given icode opcode is within the range of valid
  13. * high-level conditional jump icodes (iJB..iJG) */
  14. static boolT isJCond (llIcode opcode)
  15. {
  16. if ((opcode >= iJB) && (opcode <= iJG))
  17. return true;
  18. return false;
  19. }
  20. /* Returns whether the conditions for a 2-3 long variable are satisfied */
  21. static boolT isLong23 (Int i, BB * pbb, Int *off, Int *arc)
  22. {
  23. BB * t, * e, * obb2;
  24. if (pbb->nodeType != TWO_BRANCH)
  25. return false;
  26. t = pbb->edges[THEN].BBptr;
  27. e = pbb->edges[ELSE].BBptr;
  28. /* Check along the THEN path */
  29. if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
  30. {
  31. obb2 = t->edges[THEN].BBptr;
  32. if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
  33. {
  34. *off = obb2->front().loc_ip - i;
  35. *arc = THEN;
  36. return true;
  37. }
  38. }
  39. /* Check along the ELSE path */
  40. else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
  41. {
  42. obb2 = e->edges[THEN].BBptr;
  43. if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
  44. {
  45. *off = obb2->front().loc_ip - i;
  46. *arc = ELSE;
  47. return true;
  48. }
  49. }
  50. return false;
  51. }
  52. static boolT isLong23 (iICODE iter, BB * pbb, Int *off, Int *arc)
  53. {
  54. BB * t, * e, * obb2;
  55. if (pbb->nodeType != TWO_BRANCH)
  56. return false;
  57. t = pbb->edges[THEN].BBptr;
  58. e = pbb->edges[ELSE].BBptr;
  59. /* Check along the THEN path */
  60. if ((t->size() == 1) && (t->nodeType == TWO_BRANCH) && (t->inEdges.size() == 1))
  61. {
  62. obb2 = t->edges[THEN].BBptr;
  63. if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
  64. {
  65. *off = std::distance(iter,obb2->begin2());
  66. *arc = THEN;
  67. return true;
  68. }
  69. }
  70. /* Check along the ELSE path */
  71. else if ((e->size() == 1) && (e->nodeType == TWO_BRANCH) && (e->inEdges.size() == 1))
  72. {
  73. obb2 = e->edges[THEN].BBptr;
  74. if ((obb2->size() == 2) && (obb2->nodeType == TWO_BRANCH) && (obb2->front().ic.ll.opcode == iCMP))
  75. {
  76. *off = std::distance(iter,obb2->begin2());//obb2->front().loc_ip - i;
  77. *arc = ELSE;
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. /* Returns whether the conditions for a 2-2 long variable are satisfied */
  84. static boolT isLong22 (iICODE pIcode, iICODE pEnd, Int *off)
  85. {
  86. iICODE next1 = pIcode+1;
  87. iICODE next2 = pIcode+2;
  88. iICODE next3 = pIcode+3;
  89. if(next3>=pEnd)
  90. return false;
  91. if ( (next2->ic.ll.opcode == iCMP) &&
  92. (isJCond (next1->ic.ll.opcode)) &&
  93. (isJCond (next3->ic.ll.opcode)))
  94. {
  95. *off = 2;
  96. return true;
  97. }
  98. return false;
  99. }
  100. /** Creates a long conditional <=, >=, <, or > at (pIcode+1).
  101. * Removes excess nodes from the graph by flagging them, and updates
  102. * the new edges for the remaining nodes.
  103. * @return number of ICODEs to skip
  104. */
  105. static int longJCond23 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode, Int arc, Int off)
  106. {
  107. BB * pbb, * obb1, * obb2, * tbb;
  108. int skipped_insn=0;
  109. if (arc == THEN)
  110. {
  111. /* Find intermediate basic blocks and target block */
  112. pbb = pIcode->inBB;
  113. obb1 = pbb->edges[THEN].BBptr;
  114. obb2 = obb1->edges[THEN].BBptr;
  115. tbb = obb2->edges[THEN].BBptr;
  116. /* Modify out edge of header basic block */
  117. pbb->edges[THEN].BBptr = tbb;
  118. /* Modify in edges of target basic block */
  119. auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
  120. [obb1,obb2](BB *b) -> bool {
  121. return (b==obb1) || (b==obb2); });
  122. tbb->inEdges.erase(newlast,tbb->inEdges.end());
  123. tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
  124. /* Modify in edges of the ELSE basic block */
  125. tbb = pbb->edges[ELSE].BBptr;
  126. auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
  127. assert(iter!=tbb->inEdges.end());
  128. tbb->inEdges.erase(iter); /* looses 1 arc */
  129. /* Update icode index */
  130. skipped_insn = 5;
  131. }
  132. else /* ELSE arc */
  133. {
  134. /* Find intermediate basic blocks and target block */
  135. pbb = pIcode->inBB;
  136. obb1 = pbb->edges[ELSE].BBptr;
  137. obb2 = obb1->edges[THEN].BBptr;
  138. tbb = obb2->edges[THEN].BBptr;
  139. /* Modify in edges of target basic block */
  140. auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb2);
  141. assert(iter!=tbb->inEdges.end());
  142. tbb->inEdges.erase(iter); /* looses 1 arc */
  143. /* Modify in edges of the ELSE basic block */
  144. tbb = obb2->edges[ELSE].BBptr;
  145. auto newlast=std::remove_if(tbb->inEdges.begin(),tbb->inEdges.end(),
  146. [obb1,obb2](BB *b) -> bool { return (b==obb1) || (b==obb2); });
  147. tbb->inEdges.erase(newlast,tbb->inEdges.end());
  148. tbb->inEdges.push_back(pbb); /* looses 2 arcs, gains 1 arc */
  149. /* Modify out edge of header basic block */
  150. pbb->edges[ELSE].BBptr = tbb;
  151. /* Update icode index */
  152. skipped_insn = 2;
  153. }
  154. /* Create new HLI_JCOND and condition */
  155. lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+off+1)->ic.ll.opcode-iJB]);
  156. (pIcode+1)->setJCond(lhs);
  157. (pIcode+1)->copyDU(*pIcode, eUSE, eUSE);
  158. (pIcode+1)->du.use |= (pIcode+off)->du.use;
  159. /* Update statistics */
  160. obb1->flg |= INVALID_BB;
  161. obb2->flg |= INVALID_BB;
  162. stats.numBBaft -= 2;
  163. pIcode->invalidate();
  164. obb1->front().invalidate();
  165. obb2->front().invalidate();
  166. (obb2->begin2()+1)->invalidate();
  167. return skipped_insn;
  168. }
  169. /** Creates a long conditional equality or inequality at (pIcode+1).
  170. * Removes excess nodes from the graph by flagging them, and updates
  171. * the new edges for the remaining nodes.
  172. * @return number of ICODE's to skip
  173. */
  174. static int longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, iICODE pIcode)
  175. {
  176. Int j;
  177. BB * pbb, * obb1, * tbb;
  178. iICODE next1=pIcode+1;
  179. iICODE next2=pIcode+2;
  180. iICODE next3=pIcode+3;
  181. /* Form conditional expression */
  182. lhs = COND_EXPR::boolOp (lhs, rhs, condOpJCond[(pIcode+3)->ic.ll.opcode - iJB]);
  183. next1->setJCond(lhs);
  184. next1->copyDU (*pIcode, eUSE, eUSE);
  185. next1->du.use |= next2->du.use;
  186. /* Adjust outEdges[0] to the new target basic block */
  187. pbb = pIcode->inBB;
  188. if (pbb->back().loc_ip == next1->loc_ip)
  189. {
  190. /* Find intermediate and target basic blocks */
  191. obb1 = pbb->edges[THEN].BBptr;
  192. tbb = obb1->edges[THEN].BBptr;
  193. /* Modify THEN out edge of header basic block */
  194. pbb->edges[THEN].BBptr = tbb;
  195. /* Modify in edges of target basic block */
  196. auto iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
  197. assert(iter!=tbb->inEdges.end());
  198. tbb->inEdges.erase(iter);
  199. if ((pIcode+3)->ic.ll.opcode != iJE)
  200. tbb->inEdges.push_back(pbb); /* iJNE => replace arc */
  201. /* Modify ELSE out edge of header basic block */
  202. tbb = obb1->edges[ELSE].BBptr;
  203. pbb->edges[ELSE].BBptr = tbb;
  204. iter=std::find(tbb->inEdges.begin(),tbb->inEdges.end(),obb1);
  205. assert(iter!=tbb->inEdges.end());
  206. tbb->inEdges.erase(iter);
  207. if ((pIcode+3)->ic.ll.opcode == iJE) /* replace */
  208. tbb->inEdges.push_back(pbb);
  209. /* Update statistics */
  210. obb1->flg |= INVALID_BB;
  211. stats.numBBaft--;
  212. }
  213. pIcode->invalidate();
  214. next2->invalidate();
  215. next3->invalidate();
  216. return 4;
  217. }
  218. /* Propagates TYPE_LONG_(UN)SIGN icode information to the current pIcode
  219. * Pointer.
  220. * Arguments: i : index into the local identifier table
  221. * pLocId: ptr to the long local identifier
  222. * pProc : ptr to current procedure's record. */
  223. void Function::propLongStk (Int i, const ID &pLocId)
  224. {
  225. Int idx, off, arc;
  226. Assignment asgn;
  227. //COND_EXPR *lhs, *rhs; /* Pointers to left and right hand expression */
  228. iICODE pIcode, pEnd;
  229. /* Check all icodes for offHi:offLo */
  230. pEnd = Icode.end();
  231. for (idx = 0; idx < (this->Icode.size() - 1); idx++)
  232. {
  233. pIcode = Icode.begin()+idx;
  234. if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
  235. continue;
  236. if (pIcode->ic.ll.opcode == (pIcode+1)->ic.ll.opcode)
  237. {
  238. switch (pIcode->ic.ll.opcode)
  239. {
  240. case iMOV:
  241. if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE)
  242. {
  243. pIcode->setAsgn(asgn.lhs, asgn.rhs);
  244. (pIcode+1)->invalidate();
  245. idx++;
  246. }
  247. break;
  248. case iAND: case iOR: case iXOR:
  249. if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE)
  250. {
  251. switch (pIcode->ic.ll.opcode)
  252. {
  253. case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND); break;
  254. case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR); break;
  255. case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR); break;
  256. }
  257. pIcode->setAsgn(asgn.lhs, asgn.rhs);
  258. (pIcode+1)->invalidate();
  259. idx++;
  260. }
  261. break;
  262. case iPUSH:
  263. if (checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, 1) == TRUE)
  264. {
  265. pIcode->setUnary( HLI_PUSH, asgn.lhs);
  266. (pIcode+1)->invalidate();
  267. idx++;
  268. }
  269. break;
  270. } /*eos*/
  271. }
  272. /* Check long conditional (i.e. 2 CMPs and 3 branches */
  273. else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (idx, pIcode->inBB, &off, &arc)))
  274. {
  275. if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this, asgn, off) )
  276. {
  277. idx += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off); //
  278. }
  279. }
  280. /* Check for long conditional equality or inequality. This requires
  281. * 2 CMPs and 2 branches */
  282. else if ((pIcode->ic.ll.opcode == iCMP) && isLong22 (pIcode, pEnd, &off))
  283. {
  284. if ( checkLongEq (pLocId.id.longStkId, pIcode, i, this,asgn, off) )
  285. {
  286. idx += longJCond22 (asgn.rhs, asgn.lhs, pIcode); // maybe this should have -1 to offset loop autoincrement?
  287. }
  288. }
  289. }
  290. }
  291. int Function::findBackwarLongDefs(int loc_ident_idx, const ID &pLocId, iICODE beg)
  292. {
  293. Assignment asgn;
  294. LLOperand * pmH,* pmL;
  295. iICODE pIcode;
  296. riICODE rev(beg);
  297. bool forced_finish=false;
  298. for (; not forced_finish and rev!=Icode.rend();rev++) //idx = pLocId_idx - 1; idx > 0 ; idx--
  299. {
  300. ICODE &icode(*rev);
  301. ICODE &next1(*(rev-1)); // prev reverse is actually next instruction
  302. pIcode = (rev+1).base();//Icode.begin()+(idx-1);
  303. if ((icode.type == HIGH_LEVEL) || (icode.invalid == TRUE))
  304. continue;
  305. if (icode.ic.ll.opcode != next1.ic.ll.opcode)
  306. continue;
  307. switch (icode.ic.ll.opcode)
  308. {
  309. case iMOV:
  310. pmH = &icode.ic.ll.dst;
  311. pmL = &next1.ic.ll.dst;
  312. if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
  313. {
  314. localId.id_arr[loc_ident_idx].idx.push_back(pIcode);//idx-1//insert
  315. icode.setRegDU( pmL->regi, eDEF);
  316. asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
  317. asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, pIcode, eUSE, 1);
  318. icode.setAsgn(asgn.lhs, asgn.rhs);
  319. next1.invalidate();
  320. forced_finish=true; /* to exit the loop */
  321. }
  322. break;
  323. case iPOP:
  324. pmH = &next1.ic.ll.dst;
  325. pmL = &icode.ic.ll.dst;
  326. if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
  327. {
  328. asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
  329. icode.setRegDU( pmH->regi, eDEF);
  330. icode.setUnary(HLI_POP, asgn.lhs);
  331. next1.invalidate();
  332. asgn.lhs=0;
  333. forced_finish=true; /* to exit the loop */
  334. }
  335. break;
  336. // /**** others missing ***/
  337. case iAND: case iOR: case iXOR:
  338. pmL = &icode.ic.ll.dst;
  339. pmH = &next1.ic.ll.dst;
  340. if ((pLocId.id.longId.h == pmH->regi) && (pLocId.id.longId.l == pmL->regi))
  341. {
  342. asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
  343. asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, LOW_FIRST, pIcode/*idx*/, eUSE, 1);
  344. icode.setRegDU( pmH->regi, USE_DEF);
  345. switch (icode.ic.ll.opcode)
  346. {
  347. case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND);
  348. break;
  349. case iOR:
  350. asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR);
  351. break;
  352. case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
  353. break;
  354. } /* eos */
  355. icode.setAsgn(asgn.lhs, asgn.rhs);
  356. next1.invalidate();
  357. forced_finish=true; /* to exit the loop */
  358. }
  359. break;
  360. } /* eos */
  361. }
  362. return rev!=Icode.rend();
  363. }
  364. int Function::findForwardLongUses(int loc_ident_idx, const ID &pLocId, iICODE beg)
  365. {
  366. bool forced_finish=false;
  367. auto pEnd=Icode.end();
  368. Assignment asgn;
  369. for (auto pIcode=beg; not forced_finish and ((pIcode+1)!=Icode.end()); ++pIcode)
  370. {
  371. iICODE next1(pIcode+1);
  372. LLOperand * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */
  373. int off,arc;
  374. if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
  375. continue;
  376. if (pIcode->ic.ll.opcode == next1->ic.ll.opcode)
  377. switch (pIcode->ic.ll.opcode)
  378. {
  379. case iMOV:
  380. if ((pLocId.id.longId.h == pIcode->ic.ll.src.regi) &&
  381. (pLocId.id.longId.l == next1->ic.ll.src.regi))
  382. {
  383. pIcode->setRegDU( next1->ic.ll.src.regi, eUSE);
  384. asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx);
  385. asgn.lhs = COND_EXPR::idLong (&this->localId, DST, pIcode,HIGH_FIRST, pIcode, eDEF, 1);
  386. pIcode->setAsgn(asgn.lhs, asgn.rhs);
  387. next1->invalidate();
  388. forced_finish =true; /* to exit the loop */
  389. }
  390. break;
  391. case iPUSH:
  392. if ((pLocId.id.longId.h == pIcode->ic.ll.src.regi) &&
  393. (pLocId.id.longId.l == next1->ic.ll.src.regi))
  394. {
  395. asgn.rhs = COND_EXPR::idLongIdx (loc_ident_idx);
  396. pIcode->setRegDU( next1->ic.ll.src.regi, eUSE);
  397. pIcode->setUnary(HLI_PUSH, asgn.rhs);
  398. next1->invalidate();
  399. }
  400. forced_finish =true; /* to exit the loop */
  401. break;
  402. /*** others missing ****/
  403. case iAND: case iOR: case iXOR:
  404. pmL = &pIcode->ic.ll.dst;
  405. pmH = &next1->ic.ll.dst;
  406. if ((pLocId.id.longId.h == pmH->regi) &&
  407. (pLocId.id.longId.l == pmL->regi))
  408. {
  409. asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
  410. pIcode->setRegDU( pmH->regi, USE_DEF);
  411. asgn.rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode,
  412. LOW_FIRST, pIcode/*idx*/, eUSE, 1);
  413. switch (pIcode->ic.ll.opcode) {
  414. case iAND: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, AND);
  415. break;
  416. case iOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, OR);
  417. break;
  418. case iXOR: asgn.rhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, XOR);
  419. break;
  420. }
  421. pIcode->setAsgn(asgn.lhs, asgn.rhs);
  422. (pIcode+1)->invalidate();
  423. // ftw loop restart ????
  424. //idx = 0;
  425. // maybe this should end the loop instead
  426. forced_finish =true; /* to exit the loop */
  427. }
  428. break;
  429. } /* eos */
  430. /* Check long conditional (i.e. 2 CMPs and 3 branches */
  431. else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (pIcode, pIcode->inBB, &off, &arc)))
  432. {
  433. if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this, asgn.rhs, asgn.lhs, off) == TRUE)
  434. {
  435. pIcode += longJCond23 (asgn.rhs, asgn.lhs, pIcode, arc, off);
  436. }
  437. }
  438. /* Check for long conditional equality or inequality. This requires
  439. * 2 CMPs and 2 branches */
  440. else if ((pIcode->ic.ll.opcode == iCMP) &&
  441. (isLong22 (pIcode, pEnd, &off)))
  442. {
  443. if (checkLongRegEq (pLocId.id.longId, pIcode, loc_ident_idx, this,
  444. asgn.rhs, asgn.lhs, off) == TRUE)
  445. {
  446. pIcode += longJCond22 (asgn.rhs, asgn.lhs, pIcode);
  447. }
  448. }
  449. /* Check for OR regH, regL
  450. * JX lab
  451. * => HLI_JCOND (regH:regL X 0) lab
  452. * This is better code than HLI_JCOND (HI(regH:regL) | LO(regH:regL)) */
  453. else if ((pIcode->ic.ll.opcode == iOR) && (next1 < pEnd) &&
  454. (isJCond (next1->ic.ll.opcode)))
  455. {
  456. if ((pIcode->ic.ll.dst.regi == pLocId.id.longId.h) &&
  457. (pIcode->ic.ll.src.regi == pLocId.id.longId.l))
  458. {
  459. asgn.lhs = COND_EXPR::idLongIdx (loc_ident_idx);
  460. asgn.rhs = COND_EXPR::idKte (0, 4); /* long 0 */
  461. asgn.lhs = COND_EXPR::boolOp (asgn.lhs, asgn.rhs, condOpJCond[next1->ic.ll.opcode - iJB]);
  462. next1->setJCond(asgn.lhs);
  463. next1->copyDU(*pIcode, eUSE, eUSE);
  464. pIcode->invalidate();
  465. }
  466. }
  467. } /* end for */
  468. }
  469. /** Finds the definition of the long register pointed to by pLocId, and
  470. * transforms that instruction into a HIGH_LEVEL icode instruction.
  471. * @arg i index into the local identifier table
  472. * @arg pLocId ptr to the long local identifier
  473. *
  474. */
  475. void Function::propLongReg (Int loc_ident_idx, const ID &pLocId)
  476. {
  477. /* Process all definitions/uses of long registers at an icode position */
  478. // WARNING: this loop modifies the iterated-over container.
  479. size_t initial_size=pLocId.idx.size();
  480. for (int j = 0; j < pLocId.idx.size(); j++)
  481. {
  482. auto idx_iter=pLocId.idx.begin();
  483. std::advance(idx_iter,j);
  484. /* Check backwards for a definition of this long register */
  485. if (findBackwarLongDefs(loc_ident_idx,pLocId,*idx_iter))
  486. {
  487. //assert(initial_size==pLocId.idx.size());
  488. continue;
  489. }
  490. /* If no definition backwards, check forward for a use of this long reg */
  491. findForwardLongUses(loc_ident_idx,pLocId,*idx_iter);
  492. //assert(initial_size==pLocId.idx.size());
  493. } /* end for */
  494. }
  495. /* Propagates the long global address across all LOW_LEVEL icodes.
  496. * Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
  497. void Function::propLongGlb (Int i, const ID &pLocId)
  498. {
  499. printf("WARN: Function::propLongGlb not implemented");
  500. }
  501. /* Propagated identifier information, thus converting some LOW_LEVEL icodes
  502. * into HIGH_LEVEL icodes. */
  503. void Function::propLong()
  504. {
  505. Int i;
  506. /* Pointer to current local identifier */
  507. for (i = 0; i < localId.csym(); i++)
  508. {
  509. const ID &pLocId(localId.id_arr[i]);
  510. if ((pLocId.type==TYPE_LONG_SIGN) || (pLocId.type==TYPE_LONG_UNSIGN))
  511. {
  512. switch (pLocId.loc)
  513. {
  514. case STK_FRAME:
  515. propLongStk (i, pLocId);
  516. break;
  517. case REG_FRAME:
  518. propLongReg (i, pLocId);
  519. break;
  520. case GLB_FRAME:
  521. propLongGlb (i, pLocId);
  522. break;
  523. }
  524. }
  525. }
  526. }