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-13 22:44:48 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      445933 : OPTconstantsImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
      37             :                                                    InstrPtr pci)
      38             : {
      39      445933 :         int i, j, k = 1, n = 0, fnd = 0, actions = 0, limit = 0;
      40      445933 :         int *alias = NULL, *index = NULL, *cand = NULL;
      41      445933 :         VarPtr x, y, *cst = NULL;
      42      445933 :         str msg = MAL_SUCCEED;
      43      445933 :         InstrPtr p, q;
      44             : 
      45      445933 :         if (isSimpleSQL(mb)) {
      46      283633 :                 goto wrapup;
      47             :         }
      48      162300 :         alias = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      49      162300 :         cand = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      50      162299 :         cst = (VarPtr *) GDKzalloc(sizeof(VarPtr) * mb->vtop);
      51      162297 :         index = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      52             : 
      53      162299 :         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    13270948 :         for (i = 0; i < mb->stop; i++) {
      63    13108666 :                 q = getInstrPtr(mb, i);
      64    13108666 :                 if (!q) {
      65           0 :                         continue;
      66             :                 }
      67    13108666 :                 if (getModuleId(q) == sqlRef && getFunctionId(q) != tidRef) {
      68     2131897 :                         continue;
      69             :                 }
      70    10976769 :                 if (hasSideEffects(mb, q, 1))
      71     4597893 :                         continue;
      72    23343102 :                 for (k = q->retc; k < q->argc; k++) {
      73    16964243 :                         j = getArg(q, k);
      74    16964243 :                         if (cand[j] == 0) {
      75    13704441 :                                 cand[j] = isVarConstant(mb, j) && isVarFixed(mb, j)
      76    13704441 :                                                 && getVarType(mb, j) != TYPE_ptr;
      77             :                         }
      78             :                 }
      79             :         }
      80             : 
      81    26648942 :         for (i = 0; i < mb->vtop; i++)
      82    26486660 :                 alias[i] = i;
      83    26649075 :         for (i = 0; i < mb->vtop; i++)
      84    26486776 :                 if (cand[i]) {
      85     2486421 :                         x = getVar(mb, i);
      86     2486421 :                         fnd = 0;
      87     2486421 :                         limit = n - 128;        // don't look to far back
      88     2486421 :                         if (x->type && x->value.vtype)
      89    67333034 :                                 for (k = n - 1; k >= 0 && k > limit; k--) {
      90    65768539 :                                         y = cst[k];
      91    65768539 :                                         if (x->type == y->type && x->rowcnt == y->rowcnt
      92    34792498 :                                                 && x->value.vtype == y->value.vtype
      93    34791133 :                                                 && (x->value.vtype == TYPE_any
      94    34790883 :                                                 || ATOMcmp(x->value.vtype, VALptr(&x->value),
      95             :                                                                    VALptr(&y->value)) == 0)) {
      96             : 
      97             :                                                 /* reuse a constant */
      98      529780 :                                                 alias[i] = index[k];
      99      529780 :                                                 fnd = 1;
     100      529780 :                                                 actions++;
     101      529780 :                                                 break;
     102             :                                         }
     103             :                                 }
     104      529780 :                         if (fnd == 0) {
     105     1956658 :                                 cst[n] = x;
     106     1956658 :                                 index[n] = i;
     107     1956658 :                                 n++;
     108             :                         }
     109             :                 }
     110             : 
     111      162299 :         if (actions)
     112     9375150 :                 for (i = 0; i < mb->stop; i++) {
     113     9321551 :                         p = getInstrPtr(mb, i);
     114    47210446 :                         for (k = 0; k < p->argc; k++)
     115    37888895 :                                 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      162299 :   wrapup:
     127             :         /* keep actions taken as a fake argument */
     128      445932 :         (void) pushInt(mb, pci, actions);
     129             : 
     130      445925 :         if (cand)
     131      162292 :                 GDKfree(cand);
     132      445933 :         if (alias)
     133      162300 :                 GDKfree(alias);
     134      445933 :         if (cst)
     135      162300 :                 GDKfree(cst);
     136      445932 :         if (index)
     137      162299 :                 GDKfree(index);
     138      445933 :         return msg;
     139             : }

Generated by: LCOV version 1.14