LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_deadcode.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 66 71 93.0 %
Date: 2024-04-26 00:35:57 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /* (c) Martin Kersten
      14             :  */
      15             : #include "monetdb_config.h"
      16             : #include "opt_deadcode.h"
      17             : 
      18             : str
      19     1502081 : OPTdeadcodeImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
      20             :                                                   InstrPtr pci)
      21             : {
      22     1502081 :         int i, k, se, limit, slimit;
      23     1502081 :         InstrPtr p = 0, *old = NULL;
      24     1502081 :         int actions = 0;
      25     1502081 :         int *varused = 0;
      26     1502081 :         str msg = MAL_SUCCEED;
      27             : 
      28     1502081 :         (void) cntxt;
      29     1502081 :         (void) stk;                                     /* to fool compilers */
      30             : 
      31     1502081 :         if (mb->inlineProp)
      32           0 :                 goto wrapup;
      33             : 
      34     1502081 :         varused = GDKzalloc(mb->vtop * sizeof(int));
      35     1503387 :         if (varused == NULL)
      36           0 :                 goto wrapup;
      37             : 
      38     1503387 :         old = mb->stmt;
      39     1503387 :         limit = mb->stop;
      40     1503387 :         slimit = mb->ssize;
      41     1503387 :         if (newMalBlkStmt(mb, mb->ssize) < 0) {
      42           0 :                 GDKfree(varused);
      43           0 :                 throw(MAL, "optimizer.deadcode", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      44             :         }
      45             :         //mnstr_printf(cntxt->fdout,"deadcode limit %d ssize %d vtop %d vsize %d\n", limit, (int)(mb->ssize), mb->vtop, (int)(mb->vsize));
      46             : 
      47             :         // Calculate the instructions in which a variable is used.
      48             :         // Variables can be used multiple times in an instruction.
      49    79805292 :         for (i = 1; i < limit; i++) {
      50    78301861 :                 p = old[i];
      51   320368593 :                 for (k = p->retc; k < p->argc; k++)
      52   242066732 :                         varused[getArg(p, k)]++;
      53    78301861 :                 if (blockCntrl(p))
      54       13351 :                         for (k = 0; k < p->retc; k++)
      55       10737 :                                 varused[getArg(p, k)]++;
      56             :         }
      57             : 
      58             :         // Consolidate the actual need for variables
      59    82858184 :         for (i = limit; i >= 0; i--) {
      60    81354913 :                 p = old[i];
      61    81354913 :                 if (p == 0)
      62     1502533 :                         continue;                       //left behind by others?
      63             : 
      64    79852380 :                 if (getModuleId(p) == batRef && isUpdateInstruction(p) && !p->barrier) {
      65             :                         /* bat.append and friends are intermediates that need not be retained
      66             :                          * unless they are not used outside of an update */
      67      628749 :                         if (varused[getArg(p, 1)] > 1)
      68         850 :                                 varused[getArg(p, 0)]++;        // force keeping it
      69    79223742 :                 } else if (hasSideEffects(mb, p, FALSE) || !isLinearFlow(p)
      70    30465516 :                                    || (p->retc == 1 && mb->unsafeProp)
      71    30402430 :                                    || p->barrier /* ==side-effect */ ) {
      72    48821235 :                         varused[getArg(p, 0)]++;        // force keeping it
      73    48821235 :                         continue;
      74             :                 }
      75             :                 // The results should be used somewhere
      76    31030985 :                 se = 0;
      77    63557400 :                 for (k = 0; k < p->retc; k++)
      78    32526415 :                         se += varused[getArg(p, k)] > 0;
      79             : 
      80             :                 // Reduce input variable count when garbage is detected
      81    31030985 :                 if (se == 0)
      82    90618129 :                         for (k = p->retc; k < p->argc; k++)
      83    81472203 :                                 varused[getArg(p, k)]--;
      84             :         }
      85             : 
      86             :         // Now we can simply copy the intructions and discard useless ones.
      87     1503271 :         pushInstruction(mb, old[0]);
      88    39592359 :         for (i = 1; i < limit; i++) {
      89    38089285 :                 if ((p = old[i]) != NULL) {
      90    38087737 :                         if (p->token == ENDsymbol) {
      91     1503180 :                                 pushInstruction(mb, p);
      92             :                                 // Also copy the optimizer trace information
      93    41772472 :                                 for (i++; i < limit; i++)
      94    40269243 :                                         if (old[i])
      95    40269243 :                                                 pushInstruction(mb, old[i]);
      96             :                                 break;
      97             :                         }
      98             :                         // Is the instruction still relevant?
      99             :                         se = 0;
     100    76464577 :                         for (k = 0; k < p->retc; k++)
     101    39880020 :                                 se += varused[getArg(p, k)] > 0;
     102             : 
     103    36584557 :                         if (se)
     104    28941715 :                                 pushInstruction(mb, p);
     105             :                         else {
     106     7642842 :                                 freeInstruction(p);
     107     7643027 :                                 actions++;
     108             :                         }
     109             :                 }
     110             :         }
     111             :         /* save the free instructions records for later */
     112   337748070 :         for (; i < slimit; i++)
     113   336244695 :                 if (old[i]) {
     114           0 :                         pushInstruction(mb, old[i]);
     115             :                 }
     116             :         /* Defense line against incorrect plans */
     117             :         /* we don't create or change existing structures */
     118             :         // no type change msg = chkTypes(cntxt->usermodule, mb, FALSE);
     119     1503375 :         if (actions > 0) {
     120      495476 :                 msg = chkFlow(mb);
     121      495427 :                 if (!msg)
     122      495427 :                         msg = chkDeclarations(mb);
     123             :         }
     124     1007899 :   wrapup:
     125             :         /* keep actions taken as a fake argument */
     126     1503344 :         (void) pushInt(mb, pci, actions);
     127             : 
     128     1503048 :         if (old)
     129     1503048 :                 GDKfree(old);
     130     1503421 :         if (varused)
     131     1503421 :                 GDKfree(varused);
     132             :         return msg;
     133             : }

Generated by: LCOV version 1.14