"Fossies" - the Fresh Open Source Software Archive

Member "dmd-2.089.0/src/dmd/backend/cod5.d" (2 Nov 2019, 5152 Bytes) of package /linux/misc/dmd-2.089.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) D source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "cod5.d": 2.086.1_vs_2.087.0.

    1 /**
    2  * Compiler implementation of the
    3  * $(LINK2 http://www.dlang.org, D programming language).
    4  *
    5  * Copyright:   Copyright (C) 1995-1998 by Symantec
    6  *              Copyright (C) 2000-2019 by The D Language Foundation, All Rights Reserved
    7  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
    8  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
    9  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/cod5.d, backend/cod5.d)
   10  */
   11 module dmd.backend.cod5;
   12 
   13 version (SCPP)
   14     version = COMPILE;
   15 version (MARS)
   16     version = COMPILE;
   17 
   18 version (COMPILE)
   19 {
   20 
   21 import core.stdc.stdio;
   22 import core.stdc.string;
   23 import core.stdc.time;
   24 import dmd.backend.cc;
   25 import dmd.backend.el;
   26 import dmd.backend.oper;
   27 import dmd.backend.code;
   28 import dmd.backend.global;
   29 import dmd.backend.type;
   30 
   31 import dmd.backend.cdef;
   32 import dmd.backend.dlist;
   33 import dmd.backend.ty;
   34 
   35 extern(C++):
   36 
   37 nothrow:
   38 
   39 private void pe_add(block *b);
   40 private int need_prolog(block *b);
   41 
   42 /********************************************************
   43  * Determine which blocks get the function prolog and epilog
   44  * attached to them.
   45  */
   46 
   47 void cod5_prol_epi()
   48 {
   49 static if(1)
   50 {
   51     cod5_noprol();
   52 }
   53 else
   54 {
   55     tym_t tym;
   56     tym_t tyf;
   57     block *b;
   58     block *bp;
   59     int nepis;
   60 
   61     tyf = funcsym_p.ty();
   62     tym = tybasic(tyf);
   63 
   64     if (!(config.flags4 & CFG4optimized) ||
   65         anyiasm ||
   66         Alloca.size ||
   67         usednteh ||
   68         calledFinally ||
   69         tyf & (mTYnaked | mTYloadds) ||
   70         tym == TYifunc ||
   71         tym == TYmfunc ||       // can't yet handle ECX passed as parameter
   72         tym == TYjfunc ||       // can't yet handle EAX passed as parameter
   73         config.flags & (CFGalwaysframe | CFGtrace) ||
   74 //      config.fulltypes ||
   75         (config.wflags & WFwindows && tyfarfunc(tym)) ||
   76         need_prolog(startblock)
   77        )
   78     {   // First block gets the prolog, all return blocks
   79         // get the epilog.
   80         //printf("not even a candidate\n");
   81         cod5_noprol();
   82         return;
   83     }
   84 
   85     // Turn on BFLoutsideprolog for all blocks outside the ones needing the prolog.
   86 
   87     for (b = startblock; b; b = b.Bnext)
   88         b.Bflags &= ~BFLoutsideprolog;                 // start with them all off
   89 
   90     pe_add(startblock);
   91 
   92     // Look for only one block (bp) that will hold the prolog
   93     bp = null;
   94     nepis = 0;
   95     for (b = startblock; b; b = b.Bnext)
   96     {   int mark;
   97 
   98         if (b.Bflags & BFLoutsideprolog)
   99             continue;
  100 
  101         // If all predecessors are marked
  102         mark = 0;
  103         assert(b.Bpred);
  104         foreach (bl; ListRange(b.Bpred))
  105         {
  106             if (list_block(bl).Bflags & BFLoutsideprolog)
  107             {
  108                 if (mark == 2)
  109                     goto L1;
  110                 mark = 1;
  111             }
  112             else
  113             {
  114                 if (mark == 1)
  115                     goto L1;
  116                 mark = 2;
  117             }
  118         }
  119         if (mark == 1)
  120         {
  121             if (bp)             // if already have one
  122                 goto L1;
  123             bp = b;
  124         }
  125 
  126         // See if b is an epilog
  127         mark = 0;
  128         foreach (bl; ListRange(b.Bsucc))
  129         {
  130             if (list_block(bl).Bflags & BFLoutsideprolog)
  131             {
  132                 if (mark == 2)
  133                     goto L1;
  134                 mark = 1;
  135             }
  136             else
  137             {
  138                 if (mark == 1)
  139                     goto L1;
  140                 mark = 2;
  141             }
  142         }
  143         if (mark == 1 || b.BC == BCret || b.BC == BCretexp)
  144         {   b.Bflags |= BFLepilog;
  145             nepis++;
  146             if (nepis > 1 && config.flags4 & CFG4space)
  147                 goto L1;
  148         }
  149     }
  150     if (bp)
  151     {   bp.Bflags |= BFLprolog;
  152         //printf("=============== prolog opt\n");
  153     }
  154 }
  155 }
  156 
  157 /**********************************************
  158  * No prolog/epilog optimization.
  159  */
  160 
  161 void cod5_noprol()
  162 {
  163     block *b;
  164 
  165     //printf("no prolog optimization\n");
  166     startblock.Bflags |= BFLprolog;
  167     for (b = startblock; b; b = b.Bnext)
  168     {
  169         b.Bflags &= ~BFLoutsideprolog;
  170         switch (b.BC)
  171         {   case BCret:
  172             case BCretexp:
  173                 b.Bflags |= BFLepilog;
  174                 break;
  175             default:
  176                 b.Bflags &= ~BFLepilog;
  177         }
  178     }
  179 }
  180 
  181 /*********************************************
  182  * Add block b, and its successors, to those blocks outside those requiring
  183  * the function prolog.
  184  */
  185 
  186 private void pe_add(block *b)
  187 {
  188     if (b.Bflags & BFLoutsideprolog ||
  189         need_prolog(b))
  190         return;
  191 
  192     b.Bflags |= BFLoutsideprolog;
  193     foreach (bl; ListRange(b.Bsucc))
  194         pe_add(list_block(bl));
  195 }
  196 
  197 /**********************************************
  198  * Determine if block needs the function prolog to be set up.
  199  */
  200 
  201 private int need_prolog(block *b)
  202 {
  203     if (b.Bregcon.used & fregsaved)
  204         goto Lneed;
  205 
  206     // If block referenced a param in 16 bit code
  207     if (!I32 && b.Bflags & BFLrefparam)
  208         goto Lneed;
  209 
  210     // If block referenced a stack local
  211     if (b.Bflags & BFLreflocal)
  212         goto Lneed;
  213 
  214     return 0;
  215 
  216 Lneed:
  217     return 1;
  218 }
  219 
  220 }