LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_deadcode.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 60 91.7 %
Date: 2021-10-13 02:24:04 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.14