LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_constants.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 62 65 95.4 %
Date: 2024-04-25 20:03:45 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      467668 : OPTconstantsImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
      37             :                                                    InstrPtr pci)
      38             : {
      39      467668 :         int i, j, k = 1, n = 0, fnd = 0, actions = 0, limit = 0;
      40      467668 :         int *alias = NULL, *index = NULL, *cand = NULL;
      41      467668 :         VarPtr x, y, *cst = NULL;
      42      467668 :         str msg = MAL_SUCCEED;
      43      467668 :         InstrPtr p, q;
      44             : 
      45      467668 :         if (isSimpleSQL(mb)) {
      46      266907 :                 goto wrapup;
      47             :         }
      48      200761 :         alias = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      49      200761 :         cand = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      50      200760 :         cst = (VarPtr *) GDKzalloc(sizeof(VarPtr) * mb->vtop);
      51      200762 :         index = (int *) GDKzalloc(sizeof(int) * mb->vtop);
      52             : 
      53      200760 :         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    15020232 :         for (i = 0; i < mb->stop; i++) {
      63    14819494 :                 q = getInstrPtr(mb, i);
      64    14819494 :                 if (!q) {
      65           0 :                         continue;
      66             :                 }
      67    14819494 :                 if (getModuleId(q) == sqlRef && getFunctionId(q) != tidRef) {
      68     2742867 :                         continue;
      69             :                 }
      70    12076627 :                 if (hasSideEffects(mb, q, 1))
      71     5797969 :                         continue;
      72    22741959 :                 for (k = q->retc; k < q->argc; k++) {
      73    16463323 :                         j = getArg(q, k);
      74    16463323 :                         if (cand[j] == 0) {
      75    13354749 :                                 cand[j] = isVarConstant(mb, j) && isVarFixed(mb, j)
      76    13354749 :                                                 && getVarType(mb, j) != TYPE_ptr;
      77             :                         }
      78             :                 }
      79             :         }
      80             : 
      81    30345487 :         for (i = 0; i < mb->vtop; i++)
      82    30144749 :                 alias[i] = i;
      83    30345649 :         for (i = 0; i < mb->vtop; i++)
      84    30144888 :                 if (cand[i]) {
      85     2359065 :                         x = getVar(mb, i);
      86     2359065 :                         fnd = 0;
      87     2359065 :                         limit = n - 128;        // don't look to far back
      88     2359065 :                         if (x->type && x->value.vtype)
      89    58538466 :                                 for (k = n - 1; k >= 0 && k > limit; k--) {
      90    56940492 :                                         y = cst[k];
      91    56940492 :                                         if (x->type == y->type && x->rowcnt == y->rowcnt
      92    36275865 :                                                 && x->value.vtype == y->value.vtype
      93    36275867 :                                                 && ATOMcmp(x->value.vtype, VALptr(&x->value),
      94             :                                                                    VALptr(&y->value)) == 0) {
      95             : 
      96             :                                                 /* re-use a constant */
      97      761119 :                                                 alias[i] = index[k];
      98      761119 :                                                 fnd = 1;
      99      761119 :                                                 actions++;
     100      761119 :                                                 break;
     101             :                                         }
     102             :                                 }
     103      761119 :                         if (fnd == 0) {
     104     1597969 :                                 cst[n] = x;
     105     1597969 :                                 index[n] = i;
     106     1597969 :                                 n++;
     107             :                         }
     108             :                 }
     109             : 
     110      200761 :         if (actions)
     111     9594495 :                 for (i = 0; i < mb->stop; i++) {
     112     9536616 :                         p = getInstrPtr(mb, i);
     113    48213857 :                         for (k = 0; k < p->argc; k++)
     114    38677241 :                                 getArg(p, k) = alias[getArg(p, k)];
     115             :                 }
     116             : 
     117             :         /* Defense line against incorrect plans */
     118             :         /* Plan remains unaffected */
     119             :         // msg = chkTypes(cntxt->usermodule, mb, FALSE);
     120             :         // if (!msg)
     121             :         //      msg = chkFlow(mb);
     122             :         // if(!msg)
     123             :         //      msg = chkDeclarations(mb);
     124             :         /* keep all actions taken as a post block comment */
     125      200761 :   wrapup:
     126             :         /* keep actions taken as a fake argument */
     127      467668 :         (void) pushInt(mb, pci, actions);
     128             : 
     129      467662 :         if (cand)
     130      200755 :                 GDKfree(cand);
     131      467669 :         if (alias)
     132      200762 :                 GDKfree(alias);
     133      467669 :         if (cst)
     134      200762 :                 GDKfree(cst);
     135      467669 :         if (index)
     136      200762 :                 GDKfree(index);
     137      467668 :         return msg;
     138             : }

Generated by: LCOV version 1.14