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 - 2019 MonetDB B.V.
7 */
8
9/* author M.Kersten
10 * This optimizer can be used for JIT optimization and moves
11 * candidate lists into MAL operations where possible.
12 * It should be ran after the candidates optimizer.
13 * Specific snippets to be replaced
14 * C_1:bat[:oid] := sql.tid(X_0,"sys","t");
15 * X_4:bat[:int] := sql.bind(X_0,"sys","t","i",0);
16 * X_13 := algebra.projection(C_1,X_4);
17 * projection can be avoided
18 *
19 * A candidate list can be pushed into the calculations
20 */
21#include "monetdb_config.h"
22#include "mal_builder.h"
23#include "opt_jit.h"
24
25str
26OPTjitImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
27{
28 int i,actions = 0;
29 int limit = mb->stop;
30 InstrPtr p, q, *old = mb->stmt;
31 char buf[256];
32 lng usec = GDKusec();
33 str msg = MAL_SUCCEED;
34
35 (void) stk;
36 (void) cntxt;
37 (void) pci;
38
39 if( OPTdebug & OPTjit){
40 fprintf(stderr, "#Optimize JIT\n");
41 fprintFunction(stderr, mb, 0, LIST_MAL_ALL);
42 }
43
44 setVariableScope(mb);
45 if ( newMalBlkStmt(mb, mb->ssize) < 0)
46 throw(MAL,"optimizer.jit", SQLSTATE(HY001) MAL_MALLOC_FAIL);
47
48 /* peephole optimization */
49 for (i = 0; i < limit; i++) {
50 p = old[i];
51
52 if (p->token == ENDsymbol){
53 for(; i<limit; i++)
54 if (old[i])
55 pushInstruction(mb,old[i]);
56 break;
57 }
58 /* case 1
59 * X_527 := algebra.projection(C_353, X_329);
60 * X_535 := batcalc.-(100:lng, X_527);
61 */
62 if( getModuleId(p) == batcalcRef && *getFunctionId(p) == '-' && p->argc == 3 && isVarConstant(mb, getArg(p,1)) ){
63 q= getInstrPtr(mb, getVar(mb,getArg(p,2))->updated);
64 if ( q == 0)
65 q= getInstrPtr(mb, getVar(mb,getArg(p,2))->declared);
66 if( q && getArg(q,0) == getArg(p,2) && getModuleId(q) == algebraRef && getFunctionId(q) == projectionRef ){
67 getArg(p,2)= getArg(q,2);
68 p= pushArgument(mb,p, getArg(q,1));
69 if( OPTdebug & OPTjit){
70 fprintf(stderr, "#Optimize JIT case 1\n");
71 fprintInstruction(stderr, mb,0,p,LIST_MAL_ALL);
72 }
73 }
74 }
75 pushInstruction(mb,p);
76 }
77
78 GDKfree(old);
79 /* Defense line against incorrect plans */
80 chkTypes(cntxt->usermodule, mb, FALSE);
81 chkFlow(mb);
82 chkDeclarations(mb);
83 /* keep all actions taken as a post block comment */
84 usec = GDKusec()- usec;
85 snprintf(buf,256,"%-20s actions=%2d time=" LLFMT " usec","jit",actions, usec);
86 newComment(mb,buf);
87 if( actions >= 0)
88 addtoMalBlkHistory(mb);
89
90 if( OPTdebug & OPTjit){
91 fprintf(stderr, "#JIT optimizer exit\n");
92 fprintFunction(stderr, mb, 0, LIST_MAL_ALL);
93 }
94 return msg;
95}
96