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-10-03 20:03:20 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      483202 : OPTconstantsImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
      37             :                                                    InstrPtr pci)
      38             : {
      39      483202 :         int i, j, k = 1, n = 0, fnd = 0, actions = 0, limit = 0;
      40      483202 :         int *alias = NULL, *index = NULL, *cand = NULL;
      41      483202 :         VarPtr x, y, *cst = NULL;
      42      483202 :         str msg = MAL_SUCCEED;
      43      483202 :         InstrPtr p, q;
      44             : 
      45      483202 :         if (isSimpleSQL(mb)) {
      46      283824 :                 goto wrapup;
      47             :         }
      48      199379 :         alias = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      49      199377 :         cand = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      50      199379 :         cst = (VarPtr *) GDKzalloc(sizeof(VarPtr) * mb->vtop);
      51      199379 :         index = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      52             : 
      53      199379 :         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    15169996 :         for (i = 0; i < mb->stop; i++) {
      63    14970640 :                 q = getInstrPtr(mb, i);
      64    14970640 :                 if (!q) {
      65           0 :                         continue;
      66             :                 }
      67    14970640 :                 if (getModuleId(q) == sqlRef && getFunctionId(q) != tidRef) {
      68     2795074 :                         continue;
      69             :                 }
      70    12175566 :                 if (hasSideEffects(mb, q, 1))
      71     5742966 :                         continue;
      72    23447316 :                 for (k = q->retc; k < q->argc; k++) {
      73    17014739 :                         j = getArg(q, k);
      74    17014739 :                         if (cand[j] == 0) {
      75    13979632 :                                 cand[j] = isVarConstant(mb, j) && isVarFixed(mb, j)
      76    13979632 :                                                 && getVarType(mb, j) != TYPE_ptr;
      77             :                         }
      78             :                 }
      79             :         }
      80             : 
      81    30904961 :         for (i = 0; i < mb->vtop; i++)
      82    30705605 :                 alias[i] = i;
      83    30904122 :         for (i = 0; i < mb->vtop; i++)
      84    30704744 :                 if (cand[i]) {
      85     2626848 :                         x = getVar(mb, i);
      86     2626848 :                         fnd = 0;
      87     2626848 :                         limit = n - 128;        // don't look to far back
      88     2626848 :                         if (x->type && x->value.vtype)
      89    69358344 :                                 for (k = n - 1; k >= 0 && k > limit; k--) {
      90    67729543 :                                         y = cst[k];
      91    67729543 :                                         if (x->type == y->type && x->rowcnt == y->rowcnt
      92    35575429 :                                                 && x->value.vtype == y->value.vtype
      93    35574840 :                                                 && (x->value.vtype == TYPE_any
      94    35574754 :                                                 || ATOMcmp(x->value.vtype, VALptr(&x->value),
      95             :                                                                    VALptr(&y->value)) == 0)) {
      96             : 
      97             :                                                 /* reuse a constant */
      98      591043 :                                                 alias[i] = index[k];
      99      591043 :                                                 fnd = 1;
     100      591043 :                                                 actions++;
     101      591043 :                                                 break;
     102             :                                         }
     103             :                                 }
     104      591043 :                         if (fnd == 0) {
     105     2035827 :                                 cst[n] = x;
     106     2035827 :                                 index[n] = i;
     107     2035827 :                                 n++;
     108             :                         }
     109             :                 }
     110             : 
     111      199378 :         if (actions)
     112     9700858 :                 for (i = 0; i < mb->stop; i++) {
     113     9643265 :                         p = getInstrPtr(mb, i);
     114    49011818 :                         for (k = 0; k < p->argc; k++)
     115    39368553 :                                 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      199378 :   wrapup:
     127             :         /* keep actions taken as a fake argument */
     128      483202 :         (void) pushInt(mb, pci, actions);
     129             : 
     130      483201 :         if (cand)
     131      199377 :                 GDKfree(cand);
     132      483204 :         if (alias)
     133      199380 :                 GDKfree(alias);
     134      483203 :         if (cst)
     135      199379 :                 GDKfree(cst);
     136      483204 :         if (index)
     137      199380 :                 GDKfree(index);
     138      483203 :         return msg;
     139             : }

Generated by: LCOV version 1.14