home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Dag.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  28.9 KB  |  949 lines

  1. #include "c.h"
  2. #define iscall(p) (generic((p)->op) == CALL \
  3.     || IR->mulops_calls \
  4.     && ((p)->op==DIV+I || (p)->op==MOD+I || (p)->op==MUL+I \
  5.     ||  (p)->op==DIV+U || (p)->op==MOD+U || (p)->op==MUL+U))
  6. static Node     forest;
  7. static struct dag {
  8.     struct node     node;
  9.     struct dag     *hlink;
  10. }              *buckets[16];
  11. int             nodecount;
  12. static int      depth = 0;
  13. static Tree     firstarg;
  14. static Node    *tail;
  15.  
  16. static Node asgnnode ARGS((Symbol, Node));
  17. static struct dag *dagnode ARGS((int, Node, Node, Symbol));
  18. static void fixup ARGS((Node));
  19. static void labelnode ARGS((int));
  20. static void list ARGS((Node));
  21. static void kill ARGS((Symbol));
  22. static Node node ARGS((int, Node, Node, Symbol));
  23. static void printdag1 ARGS((Node, int, int));
  24. static void printnode ARGS((Node, int, int));
  25. void reset ARGS((void));
  26. static Node tmpnode ARGS((Node));
  27. static void Dagtypestab ARGS((Symbol, void *));
  28. static Node undag ARGS((Node));
  29. static Node visit ARGS((Node, int));
  30. static void unlist ARGS((void));
  31. Symbol   equated(Symbol p);
  32.  
  33. void            walk(Tree tp, int tlab, int flab)
  34. {
  35.     listnodes(tp, tlab, flab);
  36.     if (forest) {
  37.         code(Gen)->u.forest = forest->link;
  38.         forest->link = NULL;
  39.         forest = NULL;
  40.     }
  41.     reset();
  42.     deallocate(STMT);
  43. }
  44.  
  45. static Node     node(int op,Node l,Node r,Symbol sym)
  46. {
  47.     int             i;
  48.     struct dag     *p;
  49.  
  50.     i = (opindex(op) ^ ((unsigned) sym >> 2)) & (NELEMS(buckets) - 1);
  51.     for (p = buckets[i]; p; p = p->hlink)
  52.         if (p->node.op == op && p->node.syms[0] == sym
  53.                 && p->node.kids[0] == l && p->node.kids[1] == r)
  54.             return &p->node;
  55.     p = dagnode(op, l, r, sym);
  56.     p->hlink = buckets[i];
  57.     buckets[i] = p;
  58.     ++nodecount;
  59.     return &p->node;
  60. }
  61.  
  62. static struct dag *dagnode(int op,Node l,Node r,Symbol sym)
  63. {
  64.     struct dag     *p;
  65.  
  66.     NEW0(p, FUNC);
  67.     p->node.op = (short)op;
  68.     if ((p->node.kids[0] = l) != NULL)
  69.         ++l->count;
  70.     if ((p->node.kids[1] = r) != NULL)
  71.         ++r->count;
  72.     p->node.syms[0] = sym;
  73.     return p;
  74. }
  75.  
  76. Node            newnode(int op,Node l,Node r,Symbol sym)
  77. {
  78.     return &dagnode(op, l, r, sym)->node;
  79. }
  80. static void     kill(Symbol p)
  81. {
  82.     int             i;
  83.     struct dag    **q;
  84.  
  85.     for (i = 0; i < NELEMS(buckets); i++)
  86.         for (q = &buckets[i]; *q;)
  87.             if (generic((*q)->node.op) == INDIR &&
  88.                     (!isaddrop((*q)->node.kids[0]->op)
  89.                      || (*q)->node.kids[0]->syms[0] == p)) {
  90.                 *q = (*q)->hlink;
  91.                 --nodecount;
  92.             }
  93.             else
  94.                 q = &(*q)->hlink;
  95. }
  96. void     reset(void)
  97. {
  98.     if (nodecount > 0)
  99.         memset(buckets, 0, sizeof buckets);
  100.     nodecount = 0;
  101. }
  102.  
  103. int hasArgs =0;
  104. Node            listnodes(Tree tp, int tlab, int flab)
  105. {
  106.     Node            p = NULL, l, r;
  107.  
  108.     assert(tlab || flab || tlab == 0 && flab == 0);
  109.     if (tp == NULL)
  110.         return NULL;
  111.     if (tp->node)
  112.         return tp->node;
  113.     switch (generic(tp->op)) {
  114.     case AND:{
  115.             if (depth++ == 0)
  116.                 reset();
  117.             if (flab) {
  118.                 listnodes(tp->kids[0], 0, flab);
  119.                 listnodes(tp->kids[1], 0, flab);
  120.             }
  121.             else {
  122.                 flab = genlabel(1);
  123.                 listnodes(tp->kids[0], 0, flab);
  124.                 listnodes(tp->kids[1], tlab, 0);
  125.                 labelnode(flab);
  126.             }
  127.             depth--;
  128.         } break;
  129.     case OR:{
  130.             if (depth++ == 0)
  131.                 reset();
  132.             if (tlab) {
  133.                 listnodes(tp->kids[0], tlab, 0);
  134.                 listnodes(tp->kids[1], tlab, 0);
  135.             }
  136.             else {
  137.                 tlab = genlabel(1);
  138.                 listnodes(tp->kids[0], tlab, 0);
  139.                 listnodes(tp->kids[1], 0, flab);
  140.                 labelnode(tlab);
  141.             }
  142.             depth--;
  143.         } break;
  144.     case NOT:{
  145.             return listnodes(tp->kids[0], flab, tlab);
  146.         }
  147.     case COND:{
  148.             Tree            q = tp->kids[1];
  149.             assert(tlab == 0 && flab == 0);
  150.             if (tp->u.sym)
  151.                 addlocal(tp->u.sym);
  152.             flab = genlabel(2);
  153.             listnodes(tp->kids[0], 0, flab);
  154.             assert(q && q->op == RIGHT);
  155.             reset();
  156.             listnodes(q->kids[0], 0, 0);
  157.             if (forest->op == LABELV) {
  158.                 equatelab(forest->syms[0], findlabel(flab + 1));
  159.                 unlist();
  160.             }
  161.             list(jump(flab + 1));
  162.             labelnode(flab);
  163.             listnodes(q->kids[1], 0, 0);
  164.             if (forest->op == LABELV) {
  165.                 equatelab(forest->syms[0], findlabel(flab + 1));
  166.                 unlist();
  167.             }
  168.             labelnode(flab + 1);
  169.  
  170.             if (tp->u.sym)
  171.                 p = listnodes(idtree(tp->u.sym), 0, 0);
  172.         } break;
  173.     case CNST:{
  174.             Type            ty = unqual(tp->type);
  175.             assert(ty->u.sym);
  176.             if (tlab || flab) {
  177.                 assert(ty == inttype);
  178.                 if (tlab && tp->u.v.i != 0)
  179.                     list(jump(tlab));
  180.                 else if (flab && tp->u.v.i == 0)
  181.                     list(jump(flab));
  182.             }
  183.             else if (ty->u.sym->addressed) {
  184.                 if ((tp->op == CNST+D) &&
  185.                     (tp->u.v.d == 0.0 || tp->u.v.d == 1.0)) {
  186.                     p = node(tp->op,NULL,NULL,constant(ty,tp->u.v));
  187.                 }
  188.                 else if (tp->op == CNST+F &&
  189.                     (tp->u.v.f == 0.0 || tp->u.v.f == 1.0)) {
  190.                     p = node(tp->op,NULL,NULL,constant(ty,tp->u.v));
  191.                 }
  192.                 else
  193.                 p = listnodes(cvtconst(tp), 0, 0);
  194.             }
  195.             else
  196.                 p = node(tp->op, NULL, NULL, constant(ty, tp->u.v));
  197.         } break;
  198.     case RIGHT:{
  199.             if (tp->kids[0] && tp->kids[1]
  200.                     && generic(tp->kids[1]->op) == ASGN
  201.                     && (generic(tp->kids[0]->op) == INDIR
  202.                         && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]
  203.                         || (tp->kids[0]->op == FIELD
  204.                             && tp->kids[0] == tp->kids[1]->kids[0]))) {
  205.                 assert(tlab == 0 && flab == 0);
  206.                 if (generic(tp->kids[0]->op) == INDIR) {
  207.                     p = listnodes(tp->kids[0], 0, 0);
  208.                     list(p);
  209.                     listnodes(tp->kids[1], 0, 0);
  210.                 }
  211.                 else {
  212.                     assert(generic(tp->kids[0]->kids[0]->op) == INDIR);
  213.                     list(listnodes(tp->kids[0]->kids[0], 0, 0));
  214.                     p = listnodes(tp->kids[0], 0, 0);
  215.                     listnodes(tp->kids[1], 0, 0);
  216.                 }
  217.             }
  218.             else if (tp->kids[1]) {
  219.                 listnodes(tp->kids[0], 0, 0);
  220.                 p = listnodes(tp->kids[1], tlab, flab);
  221.             }
  222.             else
  223.                 p = listnodes(tp->kids[0], tlab, flab);
  224.         } break;
  225.     case JUMP:{
  226.             assert(tlab == 0 && flab == 0);
  227.             assert(tp->u.sym == 0);
  228.             assert(tp->kids[0]);
  229.             l = listnodes(tp->kids[0], 0, 0);
  230.             list(newnode(JUMPV, l, NULL, NULL));
  231.             reset();
  232.         } break;
  233.     case CALL:{
  234.             Tree            save = firstarg;
  235.             if (hasArgs) 
  236.                 FunctionInfo.NestedCalls = 1;
  237.             firstarg = NULL;
  238.             assert(tlab == 0 && flab == 0);
  239.             if (tp->op == CALL + B && !IR->wants_callb) {
  240.                 Tree            arg0 = tree(ARG + P, tp->kids[1]->type,
  241.                                             tp->kids[1], NULL);
  242.                 if (IR->left_to_right)
  243.                     firstarg = arg0;
  244.                 l = listnodes(tp->kids[0], 0, 0);
  245.                 if (!IR->left_to_right || firstarg) {
  246.                     firstarg = NULL;
  247.                     listnodes(arg0, 0, 0);
  248.                 }
  249.                 p = newnode(CALLV, l, NULL, NULL);
  250.             }
  251.             else {
  252.                 l = listnodes(tp->kids[0], 0, 0);
  253.                 r = listnodes(tp->kids[1], 0, 0);
  254.                 p = newnode(tp->op, l, r, NULL);
  255.             }
  256.             if (tp->Flags) {
  257.                 p->x.Flags = 1;
  258.                 if (tp->intrinsic) {
  259.                     p->x.intrinsic = tp->intrinsic;
  260.                     p->x.nestedCall = tp->nestedCall;
  261.                 }
  262.             }
  263.             list(p);
  264.             reset();
  265.             firstarg = save;
  266.             if (tp->intrinsic == 0) {
  267.                 cfunc->u.f.ncalls++;
  268.                 FunctionInfo.hasCalls = 1;
  269.             }
  270.         } break;
  271.     case ARG:{
  272.         int oldhasArgs = hasArgs;
  273.         hasArgs = 1;
  274.             assert(tlab == 0 && flab == 0);
  275.             if (IR->left_to_right)
  276.                 listnodes(tp->kids[1], 0, 0);
  277.             if (firstarg) {
  278.                 Tree            arg = firstarg;
  279.                 firstarg = NULL;
  280.                 listnodes(arg, 0, 0);
  281.             }
  282.             l = listnodes(tp->kids[0], 0, 0);
  283.             if (tp->intrinsicArg ) {
  284.                 if (tp->nestedCall == 0 || nrOfIntrinsicArgs(tp->intrinsicArg) < 2)
  285.                     r = newnode(LOAD+optype(tp->op),l,NULL,NULL);
  286.                 else
  287.                     r = newnode(tp->op, l, NULL, NULL);
  288.                 r->x.intrinsicArg = tp->intrinsicArg;
  289.                 r->x.nestedCall = tp->nestedCall;
  290.                 list(r);
  291.             }
  292.             else list(newnode(tp->op, l, NULL, NULL));
  293.             forest->syms[0] = intconst(tp->type->size);
  294.             forest->syms[1] = intconst(tp->type->align);
  295.             if (!IR->left_to_right)
  296.                 listnodes(tp->kids[1], 0, 0);
  297.             if (tp->intrinsicArg == 0)
  298.                 FunctionInfo.hasCalls = 1;
  299.             if (tp->op == ARGB)
  300.                 FunctionInfo.hasBlockMove = 1;
  301.             hasArgs = oldhasArgs;
  302.         } break;
  303.     case EQ:
  304.     case NE:
  305.     case GT:
  306.     case GE:
  307.     case LE:
  308.     case LT:{
  309.             assert(tp->u.sym == 0);
  310.             assert(errcnt || tlab || flab);
  311.             l = listnodes(tp->kids[0], 0, 0);
  312.             r = listnodes(tp->kids[1], 0, 0);
  313.  
  314.             if (tlab)
  315. #ifndef NDEBUG
  316.                 assert(flab == 0),
  317. #endif
  318.                     list(newnode(tp->op, l, r, findlabel(tlab)));
  319.             else if (flab) {
  320.                 int             op = generic(tp->op);
  321.                 switch (generic(op)) {
  322.                 case EQ:
  323.                     op = NE + optype(tp->op);
  324.                     break;
  325.                 case NE:
  326.                     op = EQ + optype(tp->op);
  327.                     break;
  328.                 case GT:
  329.                     op = LE + optype(tp->op);
  330.                     break;
  331.                 case LT:
  332.                     op = GE + optype(tp->op);
  333.                     break;
  334.                 case GE:
  335.                     op = LT + optype(tp->op);
  336.                     break;
  337.                 case LE:
  338.                     op = GT + optype(tp->op);
  339.                     break;
  340.                 default:
  341.                     assert(0);
  342.                 }
  343.                 list(newnode(op, l, r, findlabel(flab)));
  344.             }
  345.             if (forest && forest->syms[0]) {
  346.                 IncrementReferences(forest->syms[0]);
  347.             }
  348.         } break;
  349.     case ASGN:{
  350.             int kidsidx;
  351.             assert(tlab == 0 && flab == 0);
  352.             if (tp->kids[0]->op == FIELD) {
  353.                 Tree            x = tp->kids[0]->kids[0];
  354.                 Field           f = tp->kids[0]->u.field;
  355.                 assert(generic(x->op) == INDIR);
  356.                 reset();
  357.                 l = listnodes(lvalue(x), 0, 0);
  358.                 if (fieldsize(f) < 8 * f->type->size) {
  359.                     unsigned int    fmask = fieldmask(f);
  360.                     unsigned int    mask = fmask << fieldright(f);
  361.                     Tree            q = tp->kids[1];
  362.                     if (q->op == CNST + I && q->u.v.i == 0
  363.                             || q->op == CNST + U && q->u.v.u == 0)
  364.                         q = bittree(BAND, x, consttree(~mask, unsignedtype));
  365.                     else if (q->op == CNST + I && (q->u.v.i & fmask) == fmask
  366.                         || q->op == CNST + U && (q->u.v.u & fmask) == fmask)
  367.                         q = bittree(BOR, x, consttree(mask, unsignedtype));
  368.                     else {
  369.                         listnodes(q, 0, 0);
  370.                         q = bittree(BOR,
  371.                                     bittree(BAND, rvalue(lvalue(x)),
  372.                                             consttree(~mask, unsignedtype)),
  373.                             bittree(BAND, shtree(LSH, cast(q, unsignedtype),
  374.                                          consttree(fieldright(f), inttype)),
  375.                                     consttree(mask, unsignedtype)));
  376.                     }
  377.                     r = listnodes(q, 0, 0);
  378.                 }
  379.                 else
  380.                     r = listnodes(tp->kids[1], 0, 0);
  381.             }
  382.             else {
  383.                 l = listnodes(tp->kids[0], 0, 0);
  384.                 r = listnodes(tp->kids[1], 0, 0);
  385.             }
  386.             if (l->syms[0]) {
  387.                 l->syms[0]->assigned = 1;
  388.             }
  389.             for (kidsidx=0; kidsidx < 2; kidsidx++) {
  390.                 Node kid = r->kids[kidsidx];
  391.                 if (kid) {
  392.                     Symbol sy = (kid)? kid->syms[0] : NULL;
  393.                     if (sy && sy->assigned == 0 
  394.                         && sy->scope == LOCAL && sy->sclass != EXTERN) {
  395.                         if (sy->type && sy->type->op != ARRAY && sy->temporary == 0) {
  396.                             warning(" possible usage of %s before definition\n",sy->name);
  397.                             sy->assigned = 1;
  398.                         }
  399.                     }
  400.                 }
  401.             }
  402.             list(newnode(tp->op, l, r, NULL));
  403.             forest->syms[0] = intconst(tp->kids[1]->type->size);
  404.             forest->syms[1] = intconst(tp->kids[1]->type->align);
  405.             if (isaddrop(tp->kids[0]->op)
  406.                     && !tp->kids[0]->u.sym->computed)
  407.                 kill(tp->kids[0]->u.sym);
  408.             else
  409.                 reset();
  410.             p = listnodes(tp->kids[1], 0, 0);
  411.             if (tp->op == ASGNB)
  412.                 FunctionInfo.hasBlockMove = 1;
  413.         } break;
  414.     case BOR:
  415.     case BAND:
  416.     case BXOR:
  417.     case ADD:
  418.     case SUB:
  419.     case RSH:
  420.     case LSH:{
  421.             assert(tlab == 0 && flab == 0);
  422.             l = listnodes(tp->kids[0], 0, 0);
  423.             r = listnodes(tp->kids[1], 0, 0);
  424.             p = node(tp->op, l, r, NULL);
  425.         } break;
  426.     case DIV:
  427.     case MUL:
  428.     case MOD:{
  429.             assert(tlab == 0 && flab == 0);
  430.             l = listnodes(tp->kids[0], 0, 0);
  431.             r = listnodes(tp->kids[1], 0, 0);
  432.             p = node(tp->op, l, r, NULL);
  433.             if (IR->mulops_calls && isint(tp->type))
  434.                 list(p);
  435.             if (generic(tp->op) == DIV || generic(tp->op) == MOD)
  436.                 FunctionInfo.hasDiv = 1;
  437.         } break;
  438.     case RET:{
  439.             assert(tlab == 0 && flab == 0);
  440.             l = listnodes(tp->kids[0], 0, 0);
  441. #if 0
  442.             if (generic(l->op) == INDIR &&
  443.                 l->kids[0] && l->kids[0]->op == ADDRLP) {
  444.                 FunctionInfo.returnSymbol = l->kids[0]->syms[0];
  445.             }
  446. #endif
  447.             if (tp->kids[0]->op != CALLI)
  448.             list(newnode(tp->op, l, NULL, NULL));
  449.         } break;
  450.     case CVC:
  451.     case CVD:
  452.     case CVF:
  453.     case CVI:
  454.     case CVP:
  455.     case CVS:
  456.     case CVU:
  457.     case CVL:
  458.     case BCOM:
  459.     case NEG:{
  460.             assert(tlab == 0 && flab == 0);
  461.             l = listnodes(tp->kids[0], 0, 0);
  462.             if ((tp->op == CVUI || tp->op == CVIU || tp->op == CVPU || tp->op == CVUP ))
  463.                 p = l;
  464.             else p = node(tp->op, l, NULL, NULL);
  465.         } break;
  466.     case INDIR:{
  467.             Type            ty = tp->kids[0]->type;
  468.             Symbol            sym;
  469.  
  470.             if (tp->kids[0]->op != (CNST+P)) {
  471.                 sym = tp->kids[0]->u.sym;
  472.                 if (sym == NULL) {
  473.                     if (tp->kids[0] && tp->kids[0]->kids[0])
  474.                         sym = tp->kids[0]->kids[0]->u.sym;
  475.                 }
  476.             }
  477.             else sym = NULL;
  478. #if 1
  479.             if (sym && !sym->generated && sym->name) {
  480.                 if (sym->scope == LOCAL &&
  481.                     sym->sclass == AUTO &&
  482.                     sym->type->op == POINTER &&
  483.                     
  484.                     sym->assigned == 0) {
  485.                     warning("possible usage of %s before definition\n",sym->name);
  486.                     sym->assigned = 1;
  487.                     }
  488.             }
  489. #endif
  490.             assert(tlab == 0 && flab == 0);
  491.             l = listnodes(tp->kids[0], 0, 0);
  492.             if (isptr(ty))
  493.                 ty = unqual(ty)->type;
  494.             if (isvolatile(ty)
  495.                     || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
  496.                 p = newnode(tp->op, l, NULL, NULL);
  497.             else
  498.                 p = node(tp->op, l, NULL, NULL);
  499.         } break;
  500.     case FIELD:{
  501.             Tree            q = shtree(RSH,
  502.                                        shtree(LSH, tp->kids[0],
  503.                                 consttree(fieldleft(tp->u.field), inttype)),
  504.                       consttree(8 * tp->type->size - fieldsize(tp->u.field),
  505.                                 inttype));
  506.             assert(tlab == 0 && flab == 0);
  507.             p = listnodes(q, 0, 0);
  508.         } break;
  509.     case ADDRG:
  510.     case ADDRF:{
  511.             assert(tlab == 0 && flab == 0);
  512.             p = node(tp->op, NULL, NULL, tp->u.sym);
  513.         } break;
  514.     case ADDRL:{
  515.             assert(tlab == 0 && flab == 0);
  516.             if (tp->u.sym->temporary)
  517.                 addlocal(tp->u.sym);
  518.             p = node(tp->op, NULL, NULL, tp->u.sym);
  519.         } break;
  520.     default:
  521.         assert(0);
  522.     }
  523.     tp->node = p;
  524.     return p;
  525. }
  526. static void     list(Node p)
  527. {
  528.     if (p && p->link == NULL) {
  529.         if (forest) {
  530.             p->link = forest->link;
  531.             forest->link = p;
  532.         }
  533.         else
  534.             p->link = p;
  535.         forest = p;
  536.     }
  537. }
  538. static void     labelnode(int lab)
  539. {
  540.     assert(lab);
  541.     if (forest && forest->op == LABELV)
  542.         equatelab(findlabel(lab), forest->syms[0]);
  543.     else
  544.         list(newnode(LABELV, NULL, NULL, findlabel(lab)));
  545.     reset();
  546. }
  547. static void     unlist(void)
  548. {
  549.     Node            p;
  550.  
  551.     assert(forest);
  552.     assert(forest != forest->link);
  553.     p = forest->link;
  554.     while (p->link != forest)
  555.         p = p->link;
  556.     p->link = forest->link;
  557.     forest = p;
  558. }
  559. Tree            cvtconst(Tree p)
  560. {
  561.     Symbol          q = constant(p->type, p->u.v);
  562.     Tree            e;
  563.  
  564.     if (q->u.c.loc == NULL)
  565.         q->u.c.loc = genident(STATIC, p->type, GLOBAL);
  566.     if (isarray(p->type)) {
  567.         e = tree(ADDRG + P, atop(p->type), NULL, NULL);
  568.         e->u.sym = q->u.c.loc;
  569.     }
  570.     else
  571.         e = idtree(q->u.c.loc);
  572.     return e;
  573. }
  574.  
  575. extern void GenBlockDebugInfo(Code cp);
  576.  
  577. void            gencode(Symbol caller[],Symbol callee[])
  578. {
  579.     Code            cp;
  580.     Coordinate      save;
  581.  
  582.     save = src;
  583.     {
  584.         int             i;
  585.         Symbol          p, q;
  586.         cp = codehead.next->next;
  587.         codelist = codehead.next;
  588.         for (i = 0; (p = callee[i]) != NULL
  589.                 && (q = caller[i]) != NULL; i++) {
  590.             if (p->sclass != q->sclass || p->type != q->type) {
  591.                 if (p->sclass == q->sclass && q->type->op == INT &&
  592.                     p->type->op == ENUM)
  593.                     ;
  594.                 else
  595.                 if (p->sclass == q->sclass && q->type->op == INT &&
  596.                     p->type->op == CHAR)
  597.                     ;
  598.                 else
  599.                     walk(asgn(p, idtree(q)), 0, 0);
  600.             }
  601.         }
  602.         codelist->next = cp;
  603.         cp->prev = codelist;
  604.     }
  605.     if (/*glevel &&*/ IR->stabsym) {
  606.         int             i;
  607.         Symbol          p, q;
  608.         for (i = 0; (p = callee[i]) != NULL
  609.                 && (q = caller[i]) != NULL; i++) {
  610.             (*IR->stabsym) (p);
  611.             if (p->sclass != q->sclass || p->type != q->type)
  612.                 (*IR->stabsym) (q);
  613.         }
  614.         swtoseg(CODE);
  615.     }
  616.     cp = codehead.next;
  617.     for (; errcnt <= 0 && cp; cp = cp->next)
  618.         switch (cp->kind) {
  619.         case Address:
  620.             (*IR->address) (cp->u.addr.sym, cp->u.addr.base,
  621.                             cp->u.addr.offset);
  622.             break;
  623.         case Blockbeg:{
  624.                 Symbol         *p = cp->u.block.locals;
  625.                 (*IR->blockbeg) (&cp->u.block.x);
  626.                 for (; *p; p++) {
  627.                     if ((*p)->ref != 0.0)
  628.                         (*IR->local) (*p);
  629.                     else if (1/*glevel*/)
  630.                         (*IR->local) (*p);
  631.  
  632.                 }
  633.                 if (glevel) GenBlockDebugInfo(cp);
  634.             }
  635.             break;
  636.         case Blockend:
  637.             (*IR->blockend) (&cp->u.begin->u.block.x);
  638.             break;
  639.         case Defpoint:
  640.             src = cp->u.point.src;
  641.             break;
  642.         case Gen:
  643.         case Jump:
  644.         case Label:
  645.             if (!IR->wants_dag)
  646.                 cp->u.forest = undag(cp->u.forest);
  647.             fixup(cp->u.forest);
  648.             cp->u.forest = (*IR->gen) (cp->u.forest);
  649. //            AddCodeBlock(cp->kind,src,cp->u.forest);
  650.  
  651.             break;
  652.         case Local:
  653.             (*IR->local) (cp->u.var);
  654.             break;
  655.         case Switch:
  656. //            AddCodeBlock(cp->kind,src,(Node)cp);
  657.             break;
  658. #ifdef BUILTIN_ASM
  659.         case Start:
  660.         case Asm:
  661.             break;
  662. #endif
  663.         default:
  664.             assert(0);
  665.         }
  666.     src = save;
  667.     }
  668.  
  669. static void     fixup(Node p)
  670. {
  671.     for (; p; p = p->link)
  672.         switch (generic(p->op)) {
  673.         case JUMP:
  674.             if (p->kids[0]->op == ADDRG + P)
  675.                 p->kids[0]->syms[0] =
  676.                     equated(p->kids[0]->syms[0]);
  677.             break;
  678.         case LABEL:
  679.             assert(p->syms[0] == equated(p->syms[0]));
  680.             break;
  681.         case EQ:
  682.         case GE:
  683.         case GT:
  684.         case LE:
  685.         case LT:
  686.         case NE:
  687.             assert(p->syms[0]);
  688.             p->syms[0] = equated(p->syms[0]);
  689.         }
  690. }
  691. Symbol   equated(Symbol p)
  692. {
  693.     {
  694.         Symbol          q;
  695.         for (q = p->u.l.equatedto; q; q = q->u.l.equatedto)
  696.             assert(p != q);
  697.     }
  698.     while (p->u.l.equatedto)
  699.         p = p->u.l.equatedto;
  700.     return p;
  701. }
  702. void            emitcode(void)
  703. {
  704.     Code            cp;
  705.     Coordinate      save;
  706.  
  707.     save = src;
  708.     cp = codehead.next;
  709.     for (; errcnt <= 0 && cp; cp = cp->next)
  710.         switch (cp->kind) {
  711. #ifdef BUILTIN_ASM
  712.         case Start:
  713.             break;
  714.         case Asm:
  715.             asmcode(cp->u.acode.code, cp->u.acode.argv);
  716.             break;
  717. #endif
  718.         case Address:
  719.             break;
  720.         case Blockbeg:
  721.             if (/*glevel &&*/ IR->stabblock) {
  722.                 (*IR->stabblock) ('{', cp->u.block.level - LOCAL, cp->u.block.locals);
  723.                 swtoseg(CODE);
  724.             }
  725.             break;
  726.         case Blockend:
  727.             if (/*glevel &&*/ IR->stabblock) {
  728.                 Code            bp = cp->u.begin;
  729.                 foreach(bp->u.block.identifiers, bp->u.block.level, Dagtypestab, NULL);
  730.                 foreach(bp->u.block.types, bp->u.block.level, Dagtypestab, NULL);
  731.                 (*IR->stabblock) ('}', bp->u.block.level - LOCAL, bp->u.block.locals);
  732.                 swtoseg(CODE);
  733.             }
  734.             break;
  735.         case Defpoint:
  736.             src = cp->u.point.src;
  737.             if (IntermediateLanguageFile) {
  738.                 fprintf(ilFile,"; Line %d\n",src.y);
  739.             }
  740.             if (/*glevel > 0 &&*/ IR->stabline) {
  741.                 (*IR->stabline) (&cp->u.point.src);
  742.                 swtoseg(CODE);
  743.             } break;
  744.         case Gen:
  745.         case Jump:
  746.         case Label:
  747.             if (cp->u.forest)
  748.                 (*IR->emit) (cp->u.forest);
  749.             break;
  750.         case Local:
  751.             if (/*glevel &&*/ IR->stabsym) {
  752.                 (*IR->stabsym) (cp->u.var);
  753.                 swtoseg(CODE);
  754.             } break;
  755.         case Switch:{
  756.                 int             i;
  757.                 int        k = cp->u.swtch.values[0];
  758.                 defglobal(cp->u.swtch.table, LIT);
  759.                 for (i = 0; i < cp->u.swtch.size; i++, k++) {
  760.                     for (; k < cp->u.swtch.values[i]; k++)
  761.                         (*IR->defaddress) (equated(cp->u.swtch.deflab));
  762.                     (*IR->defaddress) (equated(cp->u.swtch.labels[i]));
  763.                 }
  764.                 swtoseg(CODE);
  765.             } break;
  766.         default:
  767.             assert(0);
  768.         }
  769.     src = save;
  770. }
  771.  
  772. static Node     undag(Node forest)
  773. {
  774.     Node            p;
  775.  
  776.     tail = &forest;
  777.     for (p = forest; p; p = p->link)
  778.         if (generic(p->op) == INDIR
  779.                 || iscall(p) && p->count >= 1)
  780. #ifndef NDEBUG
  781.             assert(p->count >= 1),
  782. #endif
  783.                 visit(p, 1);
  784.         else {
  785. #ifndef NDEBUG
  786.             assert(p->count == 0),
  787. #endif
  788.                 visit(p, 1);
  789.             *tail = p;
  790.             tail = &p->link;
  791.         }
  792.     *tail = NULL;
  793.     return forest;
  794. }
  795. static Node     visit(Node p,int listed)
  796. {
  797.     if (p)
  798.         if (p->syms[2])
  799.             p = tmpnode(p);
  800.         else if (p->count <= 1 && !iscall(p)
  801.                  || p->count == 0 && iscall(p)) {
  802.             p->kids[0] = visit(p->kids[0], 0);
  803.             p->kids[1] = visit(p->kids[1], 0);
  804.         }
  805.  
  806.         else if (p->op == ADDRLP || p->op == ADDRFP) {
  807.             assert(!listed);
  808.             p = newnode(p->op, NULL, NULL, p->syms[0]);
  809.             p->count = 1;
  810.         }
  811.         else if (p->op == CNSTI /*|| p->op == CNSTD*/) {
  812.             assert(!listed);
  813.             p = newnode(p->op, NULL, NULL, p->syms[0]);
  814.             p->count = 1;
  815.         }
  816.         else if (generic(p->op) == INDIR && !listed
  817.                  && (p->kids[0]->op == ADDRLP || p->kids[0]->op == ADDRFP)
  818.                  && p->kids[0]->syms[0]->sclass == REGISTER) {
  819.             p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL,
  820.                                        p->kids[0]->syms[0]), NULL, NULL);
  821.             p->count = 1;
  822.         }
  823.         else if (p->op == INDIRB || 
  824.             (p->op == INDIRD) ||
  825.             (p->op == INDIRL)) {
  826.             --p->count;
  827.             p = newnode(p->op, p->kids[0], NULL, NULL);
  828.             p->count = 1;
  829.             p->kids[0] = visit(p->kids[0], 0);
  830.             p->kids[1] = visit(p->kids[1], 0);
  831.         }
  832. #if 0
  833.         else if (p->op == ADDP && !listed &&
  834.             p->kids[0]->op == INDIRP &&
  835.             p->kids[1]->op == CNSTI &&
  836.             (p->kids[0]->kids[0]->op == ADDRFP ||
  837.             p->kids[0]->kids[0]->op == ADDRLP)
  838.         ) {
  839.         Node q = p->kids[0];
  840.         q = newnode(q->op,newnode(q->kids[0]->op,NULL,NULL,
  841.             q->kids[0]->syms[0]),NULL,q->syms[0]);
  842.         q->count = 1;
  843.             p = newnode(p->op, q, 
  844.             newnode(CNSTI,p->kids[1],NULL,p->kids[1]->syms[0]),
  845.          p->syms[0]);
  846.             p->count = 1;
  847.         }
  848. #endif
  849.         else {
  850.             p->kids[0] = visit(p->kids[0], 0);
  851.             p->kids[1] = visit(p->kids[1], 0);
  852.             p->syms[2] = temporary(REGISTER, btot(p->op), LOCAL);
  853.             assert(!p->syms[2]->defined);
  854.             p->syms[2]->ref = (float)1.0;
  855.             Initreferences(p->syms[2]);
  856.             p->syms[2]->u.t.cse = p;
  857.             (*IR->local) (p->syms[2]);
  858.             p->syms[2]->defined = 1;
  859.  
  860.             *tail = asgnnode(p->syms[2], p);
  861.             tail = &(*tail)->link;
  862.             if (!listed)
  863.                 p = tmpnode(p);
  864.         };
  865.     return p;
  866. }
  867. static Node     tmpnode(Node p)
  868. {
  869.     Symbol          tmp = p->syms[2];
  870.  
  871.     assert(tmp);
  872.     if (--p->count == 0)
  873.         p->syms[2] = NULL;
  874.     p = newnode(INDIR + (isunsigned(tmp->type) ? I : ttob(tmp->type)),
  875.                 newnode(ADDRLP, NULL, NULL, tmp), NULL, NULL);
  876.     p->count = 1;
  877.     return p;
  878. }
  879.  
  880. static Node     asgnnode(Symbol tmp,Node p)
  881. {
  882.     p = newnode(ASGN + (isunsigned(tmp->type) ? I : ttob(tmp->type)),
  883.                 newnode(ADDRLP, NULL, NULL, tmp), p, NULL);
  884.     p->syms[0] = intconst(tmp->type->size);
  885.     p->syms[1] = intconst(tmp->type->align);
  886.     return p;
  887. }
  888. /* printdag - print dag p on fd, or the node list if p == 0 */
  889. void            printdag(Node p,int fd)
  890. {
  891.     printed(0);
  892.     if (p == 0) {
  893.         if ((p = forest) != NULL)
  894.             do {
  895.                 p = p->link;
  896.                 printdag1(p, fd, 0);
  897.             } while (p != forest);
  898.     }
  899.     else if (*printed(nodeid((Tree) p)))
  900.         fprint(fd, "node'%d printed above\n", nodeid((Tree) p));
  901.     else
  902.         printdag1(p, fd, 0);
  903. }
  904.  
  905. /* printdag1 - recursively print dag p */
  906. static void     printdag1(Node p,int fd,int lev)
  907. {
  908.     int             id, i;
  909.  
  910.     if (p == 0 || *printed(id = nodeid((Tree) p)))
  911.         return;
  912.     *printed(id) = 1;
  913.     for (i = 0; i < NELEMS(p->kids); i++)
  914.         printdag1(p->kids[i], fd, lev + 1);
  915.     printnode(p, fd, lev);
  916. }
  917.  
  918. /* printnode - print fields of dag p */
  919. static void     printnode(Node p,int fd,int lev)
  920. {
  921.     if (p) {
  922.         int             i, id = nodeid((Tree) p);
  923.         fprint(fd, "%c%d%s", lev == 0 ? '\'' : '#', id,
  924.                &"   "[id < 10 ? 0 : id < 100 ? 1 : 2]);
  925.         fprint(fd, "%s count=%d", opname(p->op), p->count);
  926.         for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
  927.             fprint(fd, " #%d", nodeid((Tree) p->kids[i]));
  928.         for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++)
  929.             fprint(fd, " %s", p->syms[i]->name);
  930.         fprint(fd, "\n");
  931.     }
  932. }
  933.  
  934. /* typestab - emit stab entries for p */
  935. static void     Dagtypestab(Symbol p,void *cl)
  936. {
  937.     if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym)
  938.         (*IR->stabsym) (p);
  939.     else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype && xrefFile)
  940.         (*IR->stabtype) (p);
  941. }
  942.  
  943. int SetForestFlags(int f)
  944. {
  945.     forest->x.Flags = f;
  946.     return(1);
  947. }
  948.  
  949.