static void split_edge(T_t &T, G_t &G, typename boost::graph_traits<G_t>::edge_descriptor e, const iCode *ic, operand *tmpop) { // Insert new iCode into chain. iCode *newic = newiCode (ic->op, IC_LEFT (ic), IC_RIGHT (ic)); IC_RESULT(newic) = tmpop; newic->filename = ic->filename; newic->lineno = ic->lineno; newic->prev = G[boost::source(e, G)].ic; newic->next = G[boost::target(e, G)].ic; G[boost::source(e, G)].ic->next = newic; G[boost::target(e, G)].ic->prev = newic; //if (ic->op != ADDRESS_OF && IC_LEFT (ic) && IS_ITEMP (IC_LEFT (ic))) // bitVectSetBit (OP_SYMBOL (IC_LEFT (ic))->uses, ic->key); //if (IC_RIGHT (ic) && IS_ITEMP (IC_RIGHT (ic))) // bitVectSetBit (OP_SYMBOL (IC_RIGHT (ic))->uses, ic->key); //bitVectSetBit (OP_SYMBOL (IC_RESULT (ic))->defs, ic->key); // Insert node into cfg. typename boost::graph_traits<G_t>::vertex_descriptor n = boost::add_vertex(G); // TODO: Exact cost. G[n].ic = newic; G[n].uses = false; boost::add_edge(boost::source(e, G), n, G[e], G); boost::add_edge(n, boost::target(e, G), 3.0, G); #ifdef DEBUG_LOSPRE std::cout << "Calculating " << OP_SYMBOL_CONST(tmpop)->name << " at ic " << newic->key << "\n"; #endif // Update tree-decomposition. // TODO: More efficiently. for(typename boost::graph_traits<T_t>::vertex_descriptor n1 = 0; n1 < boost::num_vertices(T); ++n1) { if(T[n1].bag.find(boost::source(e, G)) == T[n1].bag.end()) continue; if(T[n1].bag.find(boost::target(e, G)) == T[n1].bag.end()) continue; // Found bag that contains both endpoints of original edge. // Add new tree node with bag there. Let nicify() sort things out later. typename boost::graph_traits<T_t>::vertex_descriptor n2 = boost::add_vertex(T); T[n2].bag.insert(boost::source(e, G)); T[n2].bag.insert(boost::target(e, G)); T[n2].bag.insert(n); boost::add_edge(n1, n2, T); break; } // Remove old edge from cfg. boost::remove_edge(e, G); }
/*-----------------------------------------------------------------*/ static void convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) { symbol *func = NULL; iCode *ip = ic->next; iCode *newic; int lineno = ic->lineno; int bwd; int su; int bytesPushed=0; remiCodeFromeBBlock (ebp, ic); /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { if (compareType (type, __multypes[bwd][su]) == 1) { if (op == '*') func = __muldiv[0][bwd][su]; else if (op == '/') func = __muldiv[1][bwd][su]; else if (op == '%') func = __muldiv[2][bwd][su]; else if (op == RRC) func = __rlrr[1][bwd][su]; else if (op == RLC) func = __rlrr[0][bwd][su]; else if (op == RIGHT_OP) func = __rlrr[1][bwd][su]; else if (op == LEFT_OP) func = __rlrr[0][bwd][su]; else assert (0); goto found; } } } assert (0); found: /* if int & long support routines NOT compiled as reentrant */ if (!options.intlong_rent) { /* first one */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) newic = newiCode (SEND, IC_LEFT (ic), NULL); else { newic = newiCode ('=', NULL, IC_LEFT (ic)); IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; /* second one */ if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) newic = newiCode (SEND, IC_RIGHT (ic), NULL); else { newic = newiCode ('=', NULL, IC_RIGHT (ic)); IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } else { /* compiled as reentrant then push */ /* push right */ if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) { newic = newiCode (SEND, IC_RIGHT (ic), NULL); } else { newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); newic->parmPush = 1; bytesPushed += getSize(operandType(IC_RIGHT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; /* insert push left */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) { newic = newiCode (SEND, IC_LEFT (ic), NULL); } else { newic = newiCode (IPUSH, IC_LEFT (ic), NULL); newic->parmPush = 1; bytesPushed += getSize(operandType(IC_LEFT(ic))); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } /* for the result */ newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); newic->lineno = lineno; newic->parmBytes+=bytesPushed; // to clear the stack after the call addiCodeToeBBlock (ebp, newic, ip); }
/*-----------------------------------------------------------------*/ static void cnvToFcall (iCode * ic, eBBlock * ebp) { iCode *ip; iCode *newic; operand *left; operand *right; symbol *func = NULL; int lineno = ic->lineno; int bytesPushed=0; ip = ic->next; /* insertion point */ /* remove it from the iCode */ remiCodeFromeBBlock (ebp, ic); left = IC_LEFT (ic); right = IC_RIGHT (ic); switch (ic->op) { case '+': func = __fsadd; break; case '-': func = __fssub; break; case '/': func = __fsdiv; break; case '*': func = __fsmul; break; case EQ_OP: func = __fseq; break; case NE_OP: func = __fsneq; break; case '<': func = __fslt; break; case '>': func = __fsgt; break; case LE_OP: func = __fslteq; break; case GE_OP: func = __fsgteq; break; } /* if float support routines NOT compiled as reentrant */ if (!options.float_rent) { /* first one */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) { newic = newiCode (SEND, IC_LEFT (ic), NULL); } else { newic = newiCode ('=', NULL, IC_LEFT (ic)); IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; /* second one */ if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) { newic = newiCode (SEND, IC_LEFT (ic), NULL); } else { newic = newiCode ('=', NULL, IC_RIGHT (ic)); IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } else { /* push right */ if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype)) { newic = newiCode (SEND, right, NULL); } else { newic = newiCode (IPUSH, right, NULL); newic->parmPush = 1; bytesPushed+=4; } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; /* insert push left */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) { newic = newiCode (SEND, left, NULL); } else { newic = newiCode (IPUSH, left, NULL); newic->parmPush = 1; bytesPushed+=4; } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } /* insert the call */ newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); newic->lineno = lineno; newic->parmBytes+=bytesPushed; addiCodeToeBBlock (ebp, newic, ip); }
/*-----------------------------------------------------------------*/ static void cnvFromFloatCast (iCode * ic, eBBlock * ebp) { iCode *ip, *newic; symbol *func; sym_link *type = operandType (IC_LEFT (ic)); int lineno = ic->lineno; int bwd, su; ip = ic->next; /* remove it from the iCode */ remiCodeFromeBBlock (ebp, ic); /* depending on the type */ for (bwd = 0; bwd < 3; bwd++) { for (su = 0; su < 2; su++) { if (compareType (type, __multypes[bwd][su]) == 1) { func = __conv[1][bwd][su]; goto found; } } } assert (0); found: /* if float support routines NOT compiled as reentrant */ if (!options.float_rent) { /* first one */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) newic = newiCode (SEND, IC_RIGHT (ic), NULL); else { newic = newiCode ('=', NULL, IC_RIGHT (ic)); IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)); } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } else { /* push the left */ if (IS_REGPARM (FUNC_ARGS(func->type)->etype)) newic = newiCode (SEND, IC_RIGHT (ic), NULL); else { newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); newic->parmPush = 1; } addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; } /* make the call */ newic = newiCode (CALL, operandFromSymbol (func), NULL); IC_RESULT (newic) = IC_RESULT (ic); addiCodeToeBBlock (ebp, newic, ip); newic->lineno = lineno; }