LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_constants.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 63 66 95.5 %
Date: 2024-11-12 21:42:17 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             : /*
      14             :  * Constant Duplicate Removal
      15             :  * The compilers may generate an abundance of constants on
      16             :  * the stack. This simple optimizer merges them into a single reference.
      17             :  * This makes it easier to search for statement duplicates
      18             :  * and alias their variables.
      19             :  */
      20             : /* We should not look at constants in simple, side-effect functions, because
      21             :  * they can not be removed later on.
      22             : */
      23             : /*
      24             :  * We have to keep an alias table to reorganize the program
      25             :  * after the variable stack has changed.
      26             :  * The plan may contain many constants and to check them all would be quadratic
      27             :  * in the size of the constant list.
      28             :  * The heuristic is to look back into the list only partially.
      29             :  * A hash structure could help out with further reduction.
      30             :  */
      31             : #include "monetdb_config.h"
      32             : #include "mal_instruction.h"
      33             : #include "opt_constants.h"
      34             : 
      35             : str
      36      495703 : OPTconstantsImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
      37             :                                                    InstrPtr pci)
      38             : {
      39      495703 :         int i, j, k = 1, n = 0, fnd = 0, actions = 0, limit = 0;
      40      495703 :         int *alias = NULL, *index = NULL, *cand = NULL;
      41      495703 :         VarPtr x, y, *cst = NULL;
      42      495703 :         str msg = MAL_SUCCEED;
      43      495703 :         InstrPtr p, q;
      44             : 
      45      495703 :         if (isSimpleSQL(mb)) {
      46      285183 :                 goto wrapup;
      47             :         }
      48      210521 :         alias = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      49      210520 :         cand = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      50      210520 :         cst = (VarPtr *) GDKzalloc(sizeof(VarPtr) * mb->vtop);
      51      210520 :         index = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      52             : 
      53      210521 :         if (alias == NULL || cst == NULL || index == NULL || cand == NULL) {
      54           0 :                 msg = createException(MAL, "optimizer.constants",
      55             :                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
      56           0 :                 goto wrapup;
      57             :         }
      58             : 
      59             :         (void) stk;
      60             :         (void) cntxt;
      61             : 
      62    16196202 :         for (i = 0; i < mb->stop; i++) {
      63    15985682 :                 q = getInstrPtr(mb, i);
      64    15985682 :                 if (!q) {
      65           0 :                         continue;
      66             :                 }
      67    15985682 :                 if (getModuleId(q) == sqlRef && getFunctionId(q) != tidRef) {
      68     2982940 :                         continue;
      69             :                 }
      70    13002742 :                 if (hasSideEffects(mb, q, 1))
      71     6144825 :                         continue;
      72    25131980 :                 for (k = q->retc; k < q->argc; k++) {
      73    18274064 :                         j = getArg(q, k);
      74    18274064 :                         if (cand[j] == 0) {
      75    14705688 :                                 cand[j] = isVarConstant(mb, j) && isVarFixed(mb, j)
      76    14705688 :                                                 && getVarType(mb, j) != TYPE_ptr;
      77             :                         }
      78             :                 }
      79             :         }
      80             : 
      81    32849717 :         for (i = 0; i < mb->vtop; i++)
      82    32639197 :                 alias[i] = i;
      83    32848512 :         for (i = 0; i < mb->vtop; i++)
      84    32637990 :                 if (cand[i]) {
      85     2729267 :                         x = getVar(mb, i);
      86     2729267 :                         fnd = 0;
      87     2729267 :                         limit = n - 128;        // don't look to far back
      88     2729267 :                         if (x->type && x->value.vtype)
      89    71413299 :                                 for (k = n - 1; k >= 0 && k > limit; k--) {
      90    69690661 :                                         y = cst[k];
      91    69690661 :                                         if (x->type == y->type && x->rowcnt == y->rowcnt
      92    36065468 :                                                 && x->value.vtype == y->value.vtype
      93    36064864 :                                                 && (x->value.vtype == TYPE_any
      94    36064740 :                                                 || ATOMcmp(x->value.vtype, VALptr(&x->value),
      95             :                                                                    VALptr(&y->value)) == 0)) {
      96             : 
      97             :                                                 /* reuse a constant */
      98      581617 :                                                 alias[i] = index[k];
      99      581617 :                                                 fnd = 1;
     100      581617 :                                                 actions++;
     101      581617 :                                                 break;
     102             :                                         }
     103             :                                 }
     104      581617 :                         if (fnd == 0) {
     105     2147652 :                                 cst[n] = x;
     106     2147652 :                                 index[n] = i;
     107     2147652 :                                 n++;
     108             :                         }
     109             :                 }
     110             : 
     111      210522 :         if (actions)
     112    10306921 :                 for (i = 0; i < mb->stop; i++) {
     113    10248263 :                         p = getInstrPtr(mb, i);
     114    52213207 :                         for (k = 0; k < p->argc; k++)
     115    41964944 :                                 getArg(p, k) = alias[getArg(p, k)];
     116             :                 }
     117             : 
     118             :         /* Defense line against incorrect plans */
     119             :         /* Plan remains unaffected */
     120             :         // msg = chkTypes(cntxt->usermodule, mb, FALSE);
     121             :         // if (!msg)
     122             :         //      msg = chkFlow(mb);
     123             :         // if(!msg)
     124             :         //      msg = chkDeclarations(mb);
     125             :         /* keep all actions taken as a post block comment */
     126      210522 :   wrapup:
     127             :         /* keep actions taken as a fake argument */
     128      495705 :         (void) pushInt(mb, pci, actions);
     129             : 
     130      495699 :         if (cand)
     131      210516 :                 GDKfree(cand);
     132      495705 :         if (alias)
     133      210522 :                 GDKfree(alias);
     134      495705 :         if (cst)
     135      210522 :                 GDKfree(cst);
     136      495703 :         if (index)
     137      210520 :                 GDKfree(index);
     138      495704 :         return msg;
     139             : }

Generated by: LCOV version 1.14