dataflow.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. /*****************************************************************************
  2. * Project: dcc
  3. * File: dataflow.c
  4. * Purpose: Data flow analysis module.
  5. * (C) Cristina Cifuentes
  6. ****************************************************************************/
  7. #include "dcc.h"
  8. #include <boost/range.hpp>
  9. #include <boost/range/adaptors.hpp>
  10. #include <boost/range/algorithm.hpp>
  11. #include <boost/assign.hpp>
  12. #include <string.h>
  13. #include <iostream>
  14. #include <iomanip>
  15. #include <stdio.h>
  16. using namespace boost;
  17. using namespace boost::adaptors;
  18. struct ExpStack
  19. {
  20. typedef std::list<COND_EXPR *> EXP_STK;
  21. EXP_STK expStk; /* local expression stack */
  22. void init();
  23. void push(COND_EXPR *);
  24. COND_EXPR * pop();
  25. int numElem();
  26. boolT empty();
  27. void processExpPush(int &numHlIcodes, iICODE picode)
  28. {
  29. push(picode->hl()->expr());
  30. picode->invalidate();
  31. numHlIcodes--;
  32. }
  33. };
  34. /***************************************************************************
  35. * Expression stack functions
  36. **************************************************************************/
  37. /* Reinitalizes the expression stack (expStk) to NULL, by freeing all the
  38. * space allocated (if any). */
  39. void ExpStack::init()
  40. {
  41. expStk.clear();
  42. }
  43. /* Pushes the given expression onto the local stack (expStk). */
  44. void ExpStack::push(COND_EXPR *expr)
  45. {
  46. expStk.push_back(expr);
  47. }
  48. /* Returns the element on the top of the local expression stack (expStk),
  49. * and deallocates the space allocated by this node.
  50. * If there are no elements on the stack, returns NULL. */
  51. COND_EXPR *ExpStack::pop()
  52. {
  53. if(expStk.empty())
  54. return 0;
  55. COND_EXPR *topExp = expStk.back();
  56. expStk.pop_back();
  57. return topExp;
  58. }
  59. /* Returns the number of elements available in the expression stack */
  60. int ExpStack::numElem()
  61. {
  62. return expStk.size();
  63. }
  64. /* Returns whether the expression stack is empty or not */
  65. boolT ExpStack::empty()
  66. {
  67. return expStk.empty();
  68. }
  69. using namespace std;
  70. ExpStack g_exp_stk;
  71. /* Returns the index of the local variable or parameter at offset off, if it
  72. * is in the stack frame provided. */
  73. size_t STKFRAME::getLocVar(int off)
  74. {
  75. auto iter=findByLabel(off);
  76. return distance(begin(),iter);
  77. }
  78. /* Returns a string with the source operand of Icode */
  79. static COND_EXPR *srcIdent (const LLInst &ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
  80. {
  81. if (ll_insn.testFlags(I)) /* immediate operand */
  82. {
  83. if (ll_insn.testFlags(B))
  84. return COND_EXPR::idKte (ll_insn.src().getImm2(), 1);
  85. return COND_EXPR::idKte (ll_insn.src().getImm2(), 2);
  86. }
  87. // otherwise
  88. return COND_EXPR::id (ll_insn, SRC, pProc, i, duIcode, du);
  89. }
  90. /* Returns the destination operand */
  91. static COND_EXPR *dstIdent (const LLInst & ll_insn, Function * pProc, iICODE i, ICODE & duIcode, operDu du)
  92. {
  93. COND_EXPR *n;
  94. n = COND_EXPR::id (ll_insn, DST, pProc, i, duIcode, du);
  95. /** Is it needed? (pIcode->ll()->flg) & NO_SRC_B **/
  96. return (n);
  97. }
  98. /* Eliminates all condition codes and generates new hlIcode instructions */
  99. void Function::elimCondCodes ()
  100. {
  101. // int i;
  102. uint8_t use; /* Used flags bit vector */
  103. uint8_t def; /* Defined flags bit vector */
  104. boolT notSup; /* Use/def combination not supported */
  105. COND_EXPR *rhs; /* Source operand */
  106. COND_EXPR *lhs; /* Destination operand */
  107. COND_EXPR *_expr; /* Boolean expression */
  108. //BB * pBB; /* Pointer to BBs in dfs last ordering */
  109. riICODE useAt; /* Instruction that used flag */
  110. riICODE defAt; /* Instruction that defined flag */
  111. //lhs=rhs=_expr=0;
  112. auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
  113. for( BB * pBB : valid_reversed_bbs)
  114. {
  115. // for (size_t i = 0; i < numBBs; i++)
  116. // {
  117. // pBB = m_dfsLast[i];
  118. // if (pBB->flg & INVALID_BB)
  119. // continue; /* Do not process invalid BBs */
  120. // auto v(pBB | boost::adaptors::reversed);
  121. // for (const ICODE &useAt : v)
  122. // {}
  123. for (useAt = pBB->rbegin(); useAt != pBB->rend(); useAt++)
  124. {
  125. llIcode useAtOp = llIcode(useAt->ll()->getOpcode());
  126. use = useAt->ll()->flagDU.u;
  127. if ((useAt->type != LOW_LEVEL) || ( ! useAt->valid() ) || ( 0 == use ))
  128. continue;
  129. /* Find definition within the same basic block */
  130. defAt=useAt;
  131. ++defAt;
  132. for (; defAt != pBB->rend(); defAt++)
  133. {
  134. def = defAt->ll()->flagDU.d;
  135. if ((use & def) != use)
  136. continue;
  137. notSup = false;
  138. if ((useAtOp >= iJB) && (useAtOp <= iJNS))
  139. {
  140. iICODE befDefAt = (++riICODE(defAt)).base();
  141. switch (defAt->ll()->getOpcode())
  142. {
  143. case iCMP:
  144. rhs = srcIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE);
  145. lhs = dstIdent (*defAt->ll(), this, befDefAt,*useAt, eUSE);
  146. break;
  147. case iOR:
  148. lhs = defAt->hl()->asgn.lhs->clone();
  149. useAt->copyDU(*defAt, eUSE, eDEF);
  150. if (defAt->ll()->testFlags(B))
  151. rhs = COND_EXPR::idKte (0, 1);
  152. else
  153. rhs = COND_EXPR::idKte (0, 2);
  154. break;
  155. case iTEST:
  156. rhs = srcIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE);
  157. lhs = dstIdent (*defAt->ll(),this, befDefAt,*useAt, eUSE);
  158. lhs = COND_EXPR::boolOp (lhs, rhs, AND);
  159. if (defAt->ll()->testFlags(B))
  160. rhs = COND_EXPR::idKte (0, 1);
  161. else
  162. rhs = COND_EXPR::idKte (0, 2);
  163. break;
  164. default:
  165. notSup = true;
  166. std::cout << hex<<defAt->loc_ip;
  167. reportError (JX_NOT_DEF, defAt->ll()->getOpcode());
  168. flg |= PROC_ASM; /* generate asm */
  169. }
  170. if (! notSup)
  171. {
  172. assert(lhs);
  173. assert(rhs);
  174. _expr = COND_EXPR::boolOp (lhs, rhs,condOpJCond[useAtOp-iJB]);
  175. useAt->setJCond(_expr);
  176. }
  177. }
  178. else if (useAtOp == iJCXZ)
  179. {
  180. lhs = COND_EXPR::idReg (rCX, 0, &localId);
  181. useAt->setRegDU (rCX, eUSE);
  182. rhs = COND_EXPR::idKte (0, 2);
  183. _expr = COND_EXPR::boolOp (lhs, rhs, EQUAL);
  184. useAt->setJCond(_expr);
  185. }
  186. // else if (useAt->getOpcode() == iRCL)
  187. // {
  188. // }
  189. else
  190. {
  191. ICODE &a(*defAt);
  192. ICODE &b(*useAt);
  193. reportError (NOT_DEF_USE,a.ll()->getOpcode(),b.ll()->getOpcode());
  194. flg |= PROC_ASM; /* generate asm */
  195. }
  196. break;
  197. }
  198. /* Check for extended basic block */
  199. if ((pBB->size() == 1) &&(useAtOp >= iJB) && (useAtOp <= iJNS))
  200. {
  201. ICODE & _prev(pBB->back()); /* For extended basic blocks - previous icode inst */
  202. if (_prev.hl()->opcode == HLI_JCOND)
  203. {
  204. _expr = _prev.hl()->expr()->clone();
  205. _expr->changeBoolOp (condOpJCond[useAtOp-iJB]);
  206. useAt->copyDU(_prev, eUSE, eUSE);
  207. useAt->setJCond(_expr);
  208. }
  209. }
  210. /* Error - definition not found for use of a cond code */
  211. else if (defAt == pBB->rend())
  212. {
  213. reportError(DEF_NOT_FOUND,useAtOp);
  214. //fatalError (DEF_NOT_FOUND, Icode.getOpcode(useAt-1));
  215. }
  216. }
  217. }
  218. }
  219. /** Generates the LiveUse() and Def() sets for each basic block in the graph.
  220. * Note: these sets are constant and could have been constructed during
  221. * the construction of the graph, but since the code hasn't been
  222. * analyzed yet for idioms, the procedure preamble misleads the
  223. * analysis (eg: push si, would include si in LiveUse; although it
  224. * is not really meant to be a register that is used before defined). */
  225. void Function::genLiveKtes ()
  226. {
  227. BB * pbb;
  228. bitset<32> liveUse, def;
  229. for (size_t i = 0; i < numBBs; i++)
  230. {
  231. liveUse.reset();
  232. def.reset();
  233. pbb = m_dfsLast[i];
  234. if (pbb->flg & INVALID_BB)
  235. continue; // skip invalid BBs
  236. for(ICODE &insn : *pbb)
  237. {
  238. if ((insn.type == HIGH_LEVEL) && ( insn.valid() ))
  239. {
  240. liveUse |= (insn.du.use & ~def);
  241. def |= insn.du.def;
  242. }
  243. }
  244. pbb->liveUse = liveUse;
  245. pbb->def = def;
  246. }
  247. }
  248. /* Generates the liveIn() and liveOut() sets for each basic block via an
  249. * iterative approach.
  250. * Propagates register usage information to the procedure call. */
  251. void Function::liveRegAnalysis (std::bitset<32> &in_liveOut)
  252. {
  253. using namespace boost::adaptors;
  254. using namespace boost::assign;
  255. BB * pbb=0; /* pointer to current basic block */
  256. Function * pcallee; /* invoked subroutine */
  257. //ICODE *ticode /* icode that invokes a subroutine */
  258. ;
  259. std::bitset<32> prevLiveOut, /* previous live out */
  260. prevLiveIn; /* previous live in */
  261. boolT change; /* is there change in the live sets?*/
  262. /* liveOut for this procedure */
  263. liveOut = in_liveOut;
  264. change = true;
  265. while (change)
  266. {
  267. /* Process nodes in reverse postorder order */
  268. change = false;
  269. auto valid_reversed_bbs = (m_dfsLast | reversed | filtered(BB::ValidFunctor()) );
  270. for( BB * _pbb : valid_reversed_bbs)
  271. {
  272. pbb = _pbb;//*iBB;//m_dfsLast[i-1];
  273. /* Get current liveIn() and liveOut() sets */
  274. prevLiveIn = pbb->liveIn;
  275. prevLiveOut = pbb->liveOut;
  276. /* liveOut(b) = U LiveIn(s); where s is successor(b)
  277. * liveOut(b) = {liveOut}; when b is a HLI_RET node */
  278. if (pbb->edges.empty()) /* HLI_RET node */
  279. {
  280. pbb->liveOut = in_liveOut;
  281. /* Get return expression of function */
  282. if (flg & PROC_IS_FUNC)
  283. {
  284. auto picode = pbb->rbegin(); /* icode of function return */
  285. if (picode->hl()->opcode == HLI_RET)
  286. {
  287. picode->hl()->expr(COND_EXPR::idID (&retVal, &localId, (++pbb->rbegin()).base()));
  288. picode->du.use = in_liveOut;
  289. }
  290. }
  291. }
  292. else /* Check successors */
  293. {
  294. for(TYPEADR_TYPE &e : pbb->edges)
  295. {
  296. pbb->liveOut |= e.BBptr->liveIn;
  297. }
  298. /* propagate to invoked procedure */
  299. if (pbb->nodeType == CALL_NODE)
  300. {
  301. ICODE &ticode(pbb->back());
  302. pcallee = ticode.hl()->call.proc;
  303. /* user/runtime routine */
  304. if (! (pcallee->flg & PROC_ISLIB))
  305. {
  306. if (pcallee->liveAnal == false) /* hasn't been processed */
  307. pcallee->dataFlow (pbb->liveOut);
  308. pbb->liveOut = pcallee->liveIn;
  309. }
  310. else /* library routine */
  311. {
  312. if ( (pcallee->flg & PROC_IS_FUNC) && /* returns a value */
  313. (pcallee->liveOut & pbb->edges[0].BBptr->liveIn).any()
  314. )
  315. pbb->liveOut = pcallee->liveOut;
  316. else
  317. pbb->liveOut = 0;
  318. }
  319. if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0))
  320. {
  321. switch (pcallee->retVal.type) {
  322. case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
  323. ticode.du1.numRegsDef = 2;
  324. break;
  325. case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
  326. case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
  327. ticode.du1.numRegsDef = 1;
  328. break;
  329. default:
  330. ticode.du1.numRegsDef = 0;
  331. //fprintf(stderr,"Function::liveRegAnalysis : Unknown return type %d, assume 0\n",pcallee->retVal.type);
  332. } /*eos*/
  333. /* Propagate def/use results to calling icode */
  334. ticode.du.use = pcallee->liveIn;
  335. ticode.du.def = pcallee->liveOut;
  336. }
  337. }
  338. }
  339. /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
  340. pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def);
  341. /* Check if live sets have been modified */
  342. if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
  343. change = true;
  344. }
  345. }
  346. /* Propagate liveIn(b) to procedure header */
  347. if (pbb->liveIn != 0) /* uses registers */
  348. liveIn = pbb->liveIn;
  349. /* Remove any references to register variables */
  350. if (flg & SI_REGVAR)
  351. {
  352. liveIn &= maskDuReg[rSI];
  353. pbb->liveIn &= maskDuReg[rSI];
  354. }
  355. if (flg & DI_REGVAR)
  356. {
  357. liveIn &= maskDuReg[rDI];
  358. pbb->liveIn &= maskDuReg[rDI];
  359. }
  360. }
  361. /* Check remaining instructions of the BB for all uses
  362. * of register regi, before any definitions of the
  363. * register */
  364. bool BB::FindUseBeforeDef(eReg regi, int defRegIdx, iICODE start_at)
  365. {
  366. if ((regi == rDI) && (flg & DI_REGVAR))
  367. return true;
  368. if ((regi == rSI) && (flg & SI_REGVAR))
  369. return true;
  370. if (distance(start_at,end())>1) /* several instructions */
  371. {
  372. iICODE ticode=end();
  373. auto hl_range=make_iterator_range(start_at,end()) | filtered(ICODE::select_high_level);
  374. auto checked_icode=hl_range.begin();
  375. ++checked_icode;
  376. for (; checked_icode != hl_range.end(); checked_icode++)
  377. {
  378. if (checked_icode->type != HIGH_LEVEL) // Only check uses of HIGH_LEVEL icodes
  379. continue;
  380. /* if used, get icode index */
  381. if ((checked_icode->du.use & duReg[regi]).any())
  382. start_at->du1.recordUse(defRegIdx,checked_icode.base());
  383. /* if defined, stop finding uses for this reg */
  384. if ((checked_icode->du.def & duReg[regi]).any())
  385. {
  386. ticode=checked_icode.base();
  387. break;
  388. }
  389. }
  390. if(ticode==end())
  391. ticode=(++riICODE(rbegin())).base();
  392. /* Check if last definition of this register */
  393. if ((not (ticode->du.def & duReg[regi]).any()) and (liveOut & duReg[regi]).any())
  394. start_at->du.lastDefRegi |= duReg[regi];
  395. }
  396. else /* only 1 instruction in this basic block */
  397. {
  398. /* Check if last definition of this register */
  399. if ((liveOut & duReg[regi]).any())
  400. start_at->du.lastDefRegi |= duReg[regi];
  401. }
  402. return false;
  403. }
  404. /* Find target icode for HLI_CALL icodes to procedures
  405. * that are functions. The target icode is in the
  406. * next basic block (unoptimized code) or somewhere else
  407. * on optimized code. */
  408. void BB::ProcessUseDefForFunc(eReg regi, int defRegIdx, iICODE picode)
  409. {
  410. if ((picode->hl()->opcode == HLI_CALL) &&
  411. (picode->hl()->call.proc->flg & PROC_IS_FUNC))
  412. {
  413. BB *tbb = this->edges[0].BBptr;
  414. auto target_instructions = tbb->instructions | filtered(ICODE::select_high_level);
  415. for (auto iter=target_instructions.begin(); iter!=target_instructions.end(); ++iter)
  416. {
  417. /* if used, get icode index */
  418. if ((iter->du.use & duReg[regi]).any())
  419. picode->du1.recordUse(defRegIdx,iter.base());
  420. /* if defined, stop finding uses for this reg */
  421. if ((iter->du.def & duReg[regi]).any())
  422. break;
  423. }
  424. /* if not used in this basic block, check if the
  425. * register is live out, if so, make it the last
  426. * definition of this register */
  427. if ( picode->du1.used(defRegIdx) && (tbb->liveOut & duReg[regi]).any())
  428. picode->du.lastDefRegi |= duReg[regi];
  429. }
  430. }
  431. /* If not used within this bb or in successors of this
  432. * bb (ie. not in liveOut), then register is useless,
  433. * thus remove it. Also check that this is not a return
  434. * from a library function (routines such as printf
  435. * return an integer, which is normally not taken into
  436. * account by the programmer). */
  437. void BB::RemoveUnusedDefs(eReg regi, int defRegIdx, iICODE picode)
  438. {
  439. if (picode->valid() and not picode->du1.used(defRegIdx) and
  440. (not (picode->du.lastDefRegi & duReg[regi]).any()) &&
  441. (not ((picode->hl()->opcode == HLI_CALL) &&
  442. (picode->hl()->call.proc->flg & PROC_ISLIB))))
  443. {
  444. if (! (this->liveOut & duReg[regi]).any()) /* not liveOut */
  445. {
  446. bool res = picode->removeDefRegi (regi, defRegIdx+1,&Parent->localId);
  447. if (res == true)
  448. {
  449. /* Backpatch any uses of this instruction, within
  450. * the same BB, if the instruction was invalidated */
  451. rICODE the_rest(begin(),picode);
  452. for ( ICODE &back_patch_at : the_rest|reversed)
  453. {
  454. back_patch_at.du1.remove(0,picode);
  455. }
  456. }
  457. }
  458. else /* liveOut */
  459. picode->du.lastDefRegi |= duReg[regi];
  460. }
  461. }
  462. void BB::genDU1()
  463. {
  464. /* Process each register definition of a HIGH_LEVEL icode instruction.
  465. * Note that register variables should not be considered registers.
  466. */
  467. assert(0!=Parent);
  468. ICODE::TypeFilter<HIGH_LEVEL> select_high_level;
  469. auto all_high_levels = instructions | filtered(select_high_level);
  470. printf("\n");
  471. for (auto picode=all_high_levels.begin(); picode!=all_high_levels.end(); ++picode)
  472. {
  473. int defRegIdx = 0;
  474. // foreach defined register
  475. for (int k = 0; k < INDEX_BX_SI; k++)
  476. {
  477. if (not picode->du.def.test(k))
  478. continue;
  479. eReg regi = (eReg)(k + 1); /* Register that was defined */
  480. picode->du1.regi[defRegIdx] = regi;
  481. if(FindUseBeforeDef(regi,defRegIdx, picode.base()))
  482. continue;
  483. ProcessUseDefForFunc(regi, defRegIdx,picode.base());
  484. RemoveUnusedDefs(regi, defRegIdx, picode.base());
  485. defRegIdx++;
  486. /* Check if all defined registers have been processed */
  487. if ((defRegIdx >= picode->du1.numRegsDef) || (defRegIdx == MAX_REGS_DEF))
  488. break;
  489. }
  490. }
  491. }
  492. /* Generates the du chain of each instruction in a basic block */
  493. void Function::genDU1 ()
  494. {
  495. /* Traverse tree in dfsLast order */
  496. assert(m_dfsLast.size()==numBBs);
  497. for(BB *pbb : m_dfsLast | filtered(BB::ValidFunctor()))
  498. {
  499. pbb->genDU1();
  500. }
  501. }
  502. /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
  503. * of picode. */
  504. void LOCAL_ID::forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, iICODE picode, iICODE ticode, int &numHlIcodes) const
  505. {
  506. bool res;
  507. if (rhs == NULL) /* In case expression popped is NULL */
  508. return;
  509. /* Insert on rhs of ticode, if possible */
  510. res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.rhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
  511. if (res)
  512. {
  513. picode->invalidate();
  514. numHlIcodes--;
  515. }
  516. else
  517. {
  518. /* Try to insert it on lhs of ticode*/
  519. res = COND_EXPR::insertSubTreeReg (ticode->hl()->asgn.lhs,rhs, id_arr[lhs->expr.ident.idNode.regiIdx].id.regi, this);
  520. if (res)
  521. {
  522. picode->invalidate();
  523. numHlIcodes--;
  524. }
  525. }
  526. }
  527. /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the
  528. * expression exp given */
  529. static void forwardSubsLong (int longIdx, COND_EXPR *_exp, iICODE picode, iICODE ticode, int *numHlIcodes)
  530. {
  531. bool res;
  532. if (_exp == NULL) /* In case expression popped is NULL */
  533. return;
  534. /* Insert on rhs of ticode, if possible */
  535. res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.rhs, longIdx);
  536. if (res)
  537. {
  538. picode->invalidate();
  539. (*numHlIcodes)--;
  540. }
  541. else
  542. {
  543. /* Try to insert it on lhs of ticode*/
  544. res = COND_EXPR::insertSubTreeLongReg (_exp, &ticode->hl()->asgn.lhs, longIdx);
  545. if (res)
  546. {
  547. picode->invalidate();
  548. (*numHlIcodes)--;
  549. }
  550. }
  551. }
  552. /* Returns whether the elements of the expression rhs are all x-clear from
  553. * instruction f up to instruction t. */
  554. bool COND_EXPR::xClear (rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID & locId)
  555. {
  556. iICODE i;
  557. boolT res;
  558. uint8_t regi;
  559. switch (m_type)
  560. {
  561. case IDENTIFIER:
  562. if (expr.ident.idType == REGISTER)
  563. {
  564. regi= locId.id_arr[expr.ident.idNode.regiIdx].id.regi;
  565. range_to_check.advance_begin(1);
  566. auto all_valid_and_high_level_after_start = range_to_check | filtered(ICODE::select_valid_high_level);
  567. for (ICODE &i : all_valid_and_high_level_after_start)
  568. if ((i.du.def & duReg[regi]).any())
  569. return false;
  570. if (all_valid_and_high_level_after_start.end().base() != lastBBinst)
  571. return true;
  572. return false;
  573. }
  574. else
  575. return true;
  576. /* else if (rhs->expr.ident.idType == LONG_VAR)
  577. {
  578. missing all other identifiers ****
  579. } */
  580. case BOOLEAN_OP:
  581. if(0==rhs())
  582. return false;
  583. res = rhs()->xClear ( range_to_check, lastBBinst, locId);
  584. if (res == false)
  585. return false;
  586. if(0==lhs())
  587. return false;
  588. return lhs()->xClear ( range_to_check, lastBBinst, locId);
  589. case NEGATION:
  590. case ADDRESSOF:
  591. case DEREFERENCE:
  592. if(0==expr.unaryExp)
  593. return false;
  594. return expr.unaryExp->xClear ( range_to_check, lastBBinst, locId);
  595. default:
  596. fprintf(stderr,"COND_EXPR::xClear unhandled type %d\n",m_type);
  597. } /* eos */
  598. return false;
  599. }
  600. bool UnaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
  601. {
  602. if(0==unaryExp)
  603. return false;
  604. return unaryExp->xClear ( range_to_check, lastBBinst, locs);
  605. }
  606. bool BinaryOperator::xClear(rICODE range_to_check, iICODE lastBBinst, const LOCAL_ID &locs)
  607. {
  608. if(0==m_rhs)
  609. return false;
  610. if ( ! m_rhs->xClear (range_to_check, lastBBinst, locs) )
  611. return false;
  612. if(0==m_lhs)
  613. return false;
  614. return m_lhs->xClear (range_to_check, lastBBinst, locs);
  615. }
  616. /* Checks the type of the formal argument as against to the actual argument,
  617. * whenever possible, and then places the actual argument on the procedure's
  618. * argument list. */
  619. /// @returns the type size of the stored Arg
  620. static int processCArg (Function * pp, Function * pProc, ICODE * picode, size_t numArgs)
  621. {
  622. COND_EXPR *_exp;
  623. bool res;
  624. /* if (numArgs == 0)
  625. return; */
  626. _exp = g_exp_stk.pop();
  627. if (pp->flg & PROC_ISLIB) /* library function */
  628. {
  629. if (pp->args.numArgs > 0)
  630. {
  631. if (pp->flg & PROC_VARARG)
  632. {
  633. if (numArgs < pp->args.size())
  634. adjustActArgType (_exp, pp->args[numArgs].type, pProc);
  635. }
  636. else
  637. adjustActArgType (_exp, pp->args[numArgs].type, pProc);
  638. }
  639. }
  640. else /* user function */
  641. {
  642. if (pp->args.numArgs > 0)
  643. {
  644. if(_exp==NULL)
  645. fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
  646. else
  647. pp->args.adjustForArgType (numArgs, _exp->expType (pProc));
  648. }
  649. }
  650. res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), pProc);
  651. /* Do not update the size of k if the expression was a segment register
  652. * in a near call */
  653. if (res == false)
  654. return hlTypeSize (_exp, pProc);
  655. return 0; // be default we do not know the size of the argument
  656. }
  657. /** Eliminates extraneous intermediate icode instructions when finding
  658. * expressions. Generates new hlIcodes in the form of expression trees.
  659. * For HLI_CALL hlIcodes, places the arguments in the argument list. */
  660. void LOCAL_ID::processTargetIcode(iICODE picode, int &numHlIcodes, iICODE ticode,bool isLong) const
  661. {
  662. boolT res;
  663. HLTYPE &p_hl(*picode->hl());
  664. HLTYPE &t_hl(*ticode->hl());
  665. switch (t_hl.opcode)
  666. {
  667. case HLI_ASSIGN:
  668. if(isLong)
  669. {
  670. forwardSubsLong (p_hl.asgn.lhs->expr.ident.idNode.longIdx,
  671. p_hl.asgn.rhs, picode,ticode,
  672. &numHlIcodes);
  673. }
  674. else
  675. this->forwardSubs (p_hl.asgn.lhs, p_hl.asgn.rhs, picode, ticode, numHlIcodes);
  676. break;
  677. case HLI_JCOND: case HLI_PUSH: case HLI_RET:
  678. if(isLong)
  679. {
  680. res = COND_EXPR::insertSubTreeLongReg (
  681. p_hl.asgn.rhs,
  682. &t_hl.exp.v,
  683. p_hl.asgn.lhs->expr.ident.idNode.longIdx);
  684. }
  685. else
  686. {
  687. res = COND_EXPR::insertSubTreeReg (
  688. t_hl.exp.v,
  689. p_hl.asgn.rhs,
  690. id_arr[p_hl.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
  691. this);
  692. }
  693. if (res)
  694. {
  695. picode->invalidate();
  696. numHlIcodes--;
  697. }
  698. break;
  699. case HLI_CALL: /* register arguments */
  700. newRegArg ( picode, ticode);
  701. picode->invalidate();
  702. numHlIcodes--;
  703. break;
  704. default:
  705. fprintf(stderr,"unhandled LOCAL_ID::processTargetIcode opcode %d\n",t_hl.opcode);
  706. }
  707. }
  708. void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
  709. {
  710. Function * pp;
  711. int cb, numArgs;
  712. boolT res;
  713. int k;
  714. pp = picode->hl()->call.proc;
  715. if (pp->flg & CALL_PASCAL)
  716. {
  717. cb = pp->cbParam; /* fixed # arguments */
  718. k = 0;
  719. numArgs = 0;
  720. while(k<cb)
  721. {
  722. _exp = g_exp_stk.pop();
  723. if (pp->flg & PROC_ISLIB) /* library function */
  724. {
  725. if (pp->args.numArgs > 0)
  726. adjustActArgType(_exp, pp->args[numArgs].type, this);
  727. res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
  728. }
  729. else /* user function */
  730. {
  731. if (pp->args.numArgs >0)
  732. {
  733. if(_exp==NULL)
  734. {
  735. fprintf(stderr,"Would try to adjustForArgType with null _exp\n");
  736. }
  737. pp->args.adjustForArgType (numArgs,_exp->expType (this));
  738. }
  739. res = picode->newStkArg (_exp,(llIcode)picode->ll()->getOpcode(), this);
  740. }
  741. if (res == false)
  742. k += hlTypeSize (_exp, this);
  743. numArgs++;
  744. }
  745. }
  746. else /* CALL_C */
  747. {
  748. cb = picode->hl()->call.args->cb;
  749. numArgs = 0;
  750. k = 0;
  751. if (cb)
  752. {
  753. while ( k < cb )
  754. {
  755. k+=processCArg (pp, this, &(*picode), numArgs);
  756. numArgs++;
  757. }
  758. }
  759. else if ((cb == 0) && picode->ll()->testFlags(REST_STK))
  760. {
  761. while (! g_exp_stk.empty())
  762. {
  763. k+=processCArg (pp, this, &(*picode), numArgs);
  764. numArgs++;
  765. }
  766. }
  767. }
  768. }
  769. void BB::findBBExps(LOCAL_ID &locals,Function *fnc)
  770. {
  771. bool res;
  772. ID *_retVal; // function return value
  773. COND_EXPR *_exp, // expression pointer - for HLI_POP and HLI_CALL */
  774. *lhs; // exp ptr for return value of a HLI_CALL */
  775. iICODE ticode; // Target icode */
  776. HLTYPE *ti_hl=0;
  777. uint8_t regi;
  778. numHlIcodes = 0;
  779. // register(s) to be forward substituted */
  780. auto valid_and_highlevel = instructions | filtered(ICODE::TypeAndValidFilter<HIGH_LEVEL>());
  781. for (auto picode = valid_and_highlevel.begin(); picode != valid_and_highlevel.end(); picode++)
  782. {
  783. // if ((picode->type != HIGH_LEVEL) || ( ! picode->valid() ))
  784. // continue;
  785. HLTYPE &_icHl(*picode->hl());
  786. numHlIcodes++;
  787. if (picode->du1.numRegsDef == 1) /* uint8_t/uint16_t regs */
  788. {
  789. /* Check for only one use of this register. If this is
  790. * the last definition of the register in this BB, check
  791. * that it is not liveOut from this basic block */
  792. if (picode->du1.numUses(0)==1)
  793. {
  794. /* Check that this register is not liveOut, if it
  795. * is the last definition of the register */
  796. regi = picode->du1.regi[0];
  797. /* Check if we can forward substitute this register */
  798. switch (_icHl.opcode)
  799. {
  800. case HLI_ASSIGN:
  801. /* Replace rhs of current icode into target
  802. * icode expression */
  803. ticode = picode->du1.idx[0].uses.front();
  804. if ((picode->du.lastDefRegi & duReg[regi]).any() &&
  805. ((ticode->hl()->opcode != HLI_CALL) &&
  806. (ticode->hl()->opcode != HLI_RET)))
  807. continue;
  808. if (_icHl.asgn.rhs->xClear (make_iterator_range(picode.base(),picode->du1.idx[0].uses[0]),
  809. end(), locals))
  810. {
  811. locals.processTargetIcode(picode.base(), numHlIcodes, ticode,false);
  812. }
  813. break;
  814. case HLI_POP:
  815. ticode = picode->du1.idx[0].uses.front();
  816. ti_hl = ticode->hl();
  817. if ((picode->du.lastDefRegi & duReg[regi]).any() &&
  818. ((ti_hl->opcode != HLI_CALL) &&
  819. (ti_hl->opcode != HLI_RET)))
  820. continue;
  821. _exp = g_exp_stk.pop(); /* pop last exp pushed */
  822. switch (ticode->hl()->opcode) {
  823. case HLI_ASSIGN:
  824. locals.forwardSubs(_icHl.expr(), _exp, picode.base(), ticode, numHlIcodes);
  825. break;
  826. case HLI_JCOND: case HLI_PUSH: case HLI_RET:
  827. res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v,
  828. _exp,
  829. locals.id_arr[_icHl.expr()->expr.ident.idNode.regiIdx].id.regi,
  830. &locals);
  831. if (res)
  832. {
  833. picode->invalidate();
  834. numHlIcodes--;
  835. }
  836. break;
  837. /****case HLI_CALL: // register arguments
  838. newRegArg (pProc, picode, ticode);
  839. picode->invalidate();
  840. numHlIcodes--;
  841. break; */
  842. default:
  843. fprintf(stderr,"unhandled BB::findBBExps target opcode %d\n",ticode->hl()->opcode);
  844. } // eos
  845. break;
  846. case HLI_CALL:
  847. ticode = picode->du1.idx[0].uses.front();
  848. ti_hl = ticode->hl();
  849. _retVal = &_icHl.call.proc->retVal;
  850. switch (ti_hl->opcode)
  851. {
  852. case HLI_ASSIGN:
  853. assert(ti_hl->asgn.rhs);
  854. _exp = _icHl.call.toId();
  855. res = COND_EXPR::insertSubTreeReg (ti_hl->asgn.rhs,_exp, _retVal->id.regi, &locals);
  856. if (! res)
  857. COND_EXPR::insertSubTreeReg (ti_hl->asgn.lhs, _exp,_retVal->id.regi, &locals);
  858. //TODO: HERE missing: 2 regs
  859. picode->invalidate();
  860. numHlIcodes--;
  861. break;
  862. case HLI_PUSH: case HLI_RET:
  863. ti_hl->expr( _icHl.call.toId() );
  864. picode->invalidate();
  865. numHlIcodes--;
  866. break;
  867. case HLI_JCOND:
  868. _exp = _icHl.call.toId();
  869. res = COND_EXPR::insertSubTreeReg (ti_hl->exp.v, _exp, _retVal->id.regi, &locals);
  870. if (res) /* was substituted */
  871. {
  872. picode->invalidate();
  873. numHlIcodes--;
  874. }
  875. else /* cannot substitute function */
  876. {
  877. //picode->loc_ip
  878. lhs = COND_EXPR::idID(_retVal,&locals,picode.base());
  879. picode->setAsgn(lhs, _exp);
  880. }
  881. break;
  882. default:
  883. fprintf(stderr,"unhandled BB::findBBExps HLI_CALL target opcode %d\n",ti_hl->opcode);
  884. } /* eos */
  885. break;
  886. default:
  887. fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode);
  888. } /* eos */
  889. }
  890. }
  891. else if (picode->du1.numRegsDef == 2) /* long regs */
  892. {
  893. /* Check for only one use of these registers */
  894. if ((picode->du1.numUses(0) == 1) and (picode->du1.numUses(1) == 1))
  895. {
  896. regi = picode->du1.regi[0]; //TODO: verify that regi actually should be assigned this
  897. switch (_icHl.opcode)
  898. {
  899. case HLI_ASSIGN:
  900. /* Replace rhs of current icode into target
  901. * icode expression */
  902. if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
  903. {
  904. ticode = picode->du1.idx[0].uses.front();
  905. if ((picode->du.lastDefRegi & duReg[regi]).any() &&
  906. ((ticode->hl()->opcode != HLI_CALL) &&
  907. (ticode->hl()->opcode != HLI_RET)))
  908. continue;
  909. locals.processTargetIcode(picode.base(), numHlIcodes, ticode,true);
  910. }
  911. break;
  912. case HLI_POP:
  913. if (picode->du1.idx[0].uses[0] == picode->du1.idx[1].uses[0])
  914. {
  915. ticode = picode->du1.idx[0].uses.front();
  916. if ((picode->du.lastDefRegi & duReg[regi]).any() &&
  917. ((ticode->hl()->opcode != HLI_CALL) &&
  918. (ticode->hl()->opcode != HLI_RET)))
  919. continue;
  920. _exp = g_exp_stk.pop(); /* pop last exp pushed */
  921. switch (ticode->hl()->opcode) {
  922. case HLI_ASSIGN:
  923. forwardSubsLong (_icHl.expr()->expr.ident.idNode.longIdx,
  924. _exp, picode.base(), ticode, &numHlIcodes);
  925. break;
  926. case HLI_JCOND: case HLI_PUSH:
  927. res = COND_EXPR::insertSubTreeLongReg (_exp,
  928. &ticode->hl()->exp.v,
  929. _icHl.asgn.lhs->expr.ident.idNode.longIdx);
  930. if (res)
  931. {
  932. picode->invalidate();
  933. numHlIcodes--;
  934. }
  935. break;
  936. case HLI_CALL: /*** missing ***/
  937. break;
  938. default:
  939. fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode);
  940. } /* eos */
  941. }
  942. break;
  943. case HLI_CALL: /* check for function return */
  944. ticode = picode->du1.idx[0].uses.front();
  945. switch (ticode->hl()->opcode)
  946. {
  947. case HLI_ASSIGN:
  948. _exp = _icHl.call.toId();
  949. ticode->hl()->asgn.lhs =
  950. COND_EXPR::idLong(&locals, DST,
  951. ticode,HIGH_FIRST, picode.base(),
  952. eDEF, *(++iICODE(ticode))->ll());
  953. ticode->hl()->asgn.rhs = _exp;
  954. picode->invalidate();
  955. numHlIcodes--;
  956. break;
  957. case HLI_PUSH: case HLI_RET:
  958. ticode->hl()->expr( _icHl.call.toId() );
  959. picode->invalidate();
  960. numHlIcodes--;
  961. break;
  962. case HLI_JCOND:
  963. _exp = _icHl.call.toId();
  964. _retVal = &picode->hl()->call.proc->retVal;
  965. res = COND_EXPR::insertSubTreeLongReg (_exp,
  966. &ticode->hl()->exp.v,
  967. locals.newLongReg ( _retVal->type, _retVal->id.longId.h,
  968. _retVal->id.longId.l, picode.base()));
  969. if (res) /* was substituted */
  970. {
  971. picode->invalidate();
  972. numHlIcodes--;
  973. }
  974. else /* cannot substitute function */
  975. {
  976. lhs = locals.createId(_retVal,picode.base());
  977. picode->setAsgn(lhs, _exp);
  978. }
  979. break;
  980. default:
  981. fprintf(stderr,"BB::findBBExps Unhandled target op %d\n",ticode->hl()->opcode);
  982. } /* eos */
  983. break;
  984. default:
  985. fprintf(stderr,"BB::findBBExps Unhandled HLI %d\n",_icHl.opcode);
  986. } /* eos */
  987. }
  988. }
  989. /* HLI_PUSH doesn't define any registers, only uses registers.
  990. * Push the associated expression to the register on the local
  991. * expression stack */
  992. else if (_icHl.opcode == HLI_PUSH)
  993. {
  994. g_exp_stk.processExpPush(numHlIcodes, picode.base());
  995. }
  996. else if(picode->du1.numRegsDef!=0)
  997. printf("Num def %d\n",picode->du1.numRegsDef);
  998. /* For HLI_CALL instructions that use arguments from the stack,
  999. * pop them from the expression stack and place them on the
  1000. * procedure's argument list */
  1001. if(_icHl.opcode == HLI_CALL)
  1002. {
  1003. if ( not _icHl.call.proc->hasRegArgs())
  1004. {
  1005. fnc->processHliCall(_exp, picode.base());
  1006. }
  1007. /* If we could not substitute the result of a function,
  1008. * assign it to the corresponding registers */
  1009. if ( not _icHl.call.proc->isLibrary() and (not picode->du1.used(0)) and (picode->du1.numRegsDef > 0))
  1010. {
  1011. _exp = COND_EXPR::idFunc (_icHl.call.proc, _icHl.call.args);
  1012. lhs = COND_EXPR::idID (&_icHl.call.proc->retVal, &locals, picode.base());
  1013. picode->setAsgn(lhs, _exp);
  1014. }
  1015. }
  1016. }
  1017. /* Store number of high-level icodes in current basic block */
  1018. }
  1019. void Function::findExps()
  1020. {
  1021. //int i, numHlIcodes;
  1022. //STKFRAME * args; // pointer to arguments - for HLI_CALL */
  1023. /* Initialize expression stack */
  1024. g_exp_stk.init();
  1025. /* Traverse tree in dfsLast order */
  1026. // for (i = 0; i < numBBs; i++)
  1027. for(BB *pbb : m_dfsLast)
  1028. {
  1029. /* Process one BB */
  1030. // pbb = m_dfsLast[i];
  1031. if (not pbb->valid())
  1032. continue;
  1033. pbb->findBBExps( this->localId, this);
  1034. }
  1035. }
  1036. void Function::preprocessReturnDU(std::bitset<32> &_liveOut)
  1037. {
  1038. if (_liveOut.any())
  1039. {
  1040. // int idx;
  1041. bool isAx, isBx, isCx, isDx;
  1042. flg |= PROC_IS_FUNC;
  1043. isAx = _liveOut.test(rAX - rAX);
  1044. isBx = _liveOut.test(rBX - rAX);
  1045. isCx = _liveOut.test(rCX - rAX);
  1046. isDx = _liveOut.test(rDX - rAX);
  1047. bool isAL = !isAx && _liveOut.test(rAL - rAX);
  1048. bool isAH = !isAx && _liveOut.test(rAH - rAX);
  1049. bool isBL = !isBx && _liveOut.test(rBL - rAX);
  1050. bool isBH = !isBx && _liveOut.test(rBH - rAX);
  1051. bool isCL = !isCx && _liveOut.test(rCL - rAX);
  1052. bool isCH = !isCx && _liveOut.test(rCH - rAX);
  1053. bool isDL = !isDx && _liveOut.test(rDL - rAX);
  1054. bool isDH = !isDx && _liveOut.test(rDH - rAX);
  1055. if(isAL && isAH)
  1056. {
  1057. isAx = true;
  1058. isAH=isAL=false;
  1059. }
  1060. if(isDL && isDH)
  1061. {
  1062. isDx = true;
  1063. isDH=isDL=false;
  1064. }
  1065. if(isBL && isBH)
  1066. {
  1067. isBx = true;
  1068. isBH=isBL=false;
  1069. }
  1070. if(isCL && isCH)
  1071. {
  1072. isCx = true;
  1073. isCH=isCL=false;
  1074. }
  1075. if (isAx && isDx) /* long or pointer */
  1076. {
  1077. retVal.type = TYPE_LONG_SIGN;
  1078. retVal.loc = REG_FRAME;
  1079. retVal.id.longId.h = rDX;
  1080. retVal.id.longId.l = rAX;
  1081. /*idx = */localId.newLongReg(TYPE_LONG_SIGN, rDX, rAX, Icode.begin()/*0*/);
  1082. localId.propLongId (rAX, rDX, "\0");
  1083. }
  1084. else if (isAx || isBx || isCx || isDx) /* uint16_t */
  1085. {
  1086. retVal.type = TYPE_WORD_SIGN;
  1087. retVal.loc = REG_FRAME;
  1088. if (isAx)
  1089. retVal.id.regi = rAX;
  1090. else if (isBx)
  1091. retVal.id.regi = rBX;
  1092. else if (isCx)
  1093. retVal.id.regi = rCX;
  1094. else
  1095. retVal.id.regi = rDX;
  1096. /*idx = */localId.newByteWordReg(TYPE_WORD_SIGN,retVal.id.regi);
  1097. }
  1098. else if(isAL||isBL||isCL||isDL)
  1099. {
  1100. retVal.type = TYPE_BYTE_SIGN;
  1101. retVal.loc = REG_FRAME;
  1102. if (isAL)
  1103. retVal.id.regi = rAL;
  1104. else if (isBL)
  1105. retVal.id.regi = rBL;
  1106. else if (isCL)
  1107. retVal.id.regi = rCL;
  1108. else
  1109. retVal.id.regi = rDL;
  1110. /*idx = */localId.newByteWordReg(TYPE_BYTE_SIGN,retVal.id.regi);
  1111. }
  1112. }
  1113. }
  1114. /** Invokes procedures related with data flow analysis. Works on a procedure
  1115. * at a time basis.
  1116. * Note: indirect recursion in liveRegAnalysis is possible. */
  1117. void Function::dataFlow(std::bitset<32> &_liveOut)
  1118. {
  1119. /* Remove references to register variables */
  1120. if (flg & SI_REGVAR)
  1121. _liveOut &= maskDuReg[rSI];
  1122. if (flg & DI_REGVAR)
  1123. _liveOut &= maskDuReg[rDI];
  1124. /* Function - return value register(s) */
  1125. preprocessReturnDU(_liveOut);
  1126. /* Data flow analysis */
  1127. liveAnal = true;
  1128. elimCondCodes();
  1129. genLiveKtes();
  1130. liveRegAnalysis (_liveOut); /* calls dataFlow() recursively */
  1131. if (! (flg & PROC_ASM)) /* can generate C for pProc */
  1132. {
  1133. genDU1 (); /* generate def/use level 1 chain */
  1134. findExps (); /* forward substitution algorithm */
  1135. }
  1136. }