2008-12-08 16:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/bin/hb-mkslib.sh
! fixed last modification
* harbour/doc/Makefile
+ harbour/doc/cmpopt.txt
+ added small description for Harbour compile time optimization
* harbour/include/hbexpra.c
+ allow to use hb_mutexCreate() as static variable initializer, f.e.:
static s_mtxarr := { "MTX1" => hb_mutexCreate(), ;
"MTX2" => hb_mutexCreate(), ;
"MTX3" => hb_mutexCreate() }
* harbour/include/hbexprb.c
% comment
* harbour/source/common/expropt2.c
+ added some missing optimizations for date constants
+ added optimization for multiple negate expressions
This commit is contained in:
@@ -8,6 +8,26 @@
|
||||
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
|
||||
*/
|
||||
|
||||
2008-12-08 16:30 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/bin/hb-mkslib.sh
|
||||
! fixed last modification
|
||||
|
||||
* harbour/doc/Makefile
|
||||
+ harbour/doc/cmpopt.txt
|
||||
+ added small description for Harbour compile time optimization
|
||||
|
||||
* harbour/include/hbexpra.c
|
||||
+ allow to use hb_mutexCreate() as static variable initializer, f.e.:
|
||||
static s_mtxarr := { "MTX1" => hb_mutexCreate(), ;
|
||||
"MTX2" => hb_mutexCreate(), ;
|
||||
"MTX3" => hb_mutexCreate() }
|
||||
* harbour/include/hbexprb.c
|
||||
% comment
|
||||
|
||||
* harbour/source/common/expropt2.c
|
||||
+ added some missing optimizations for date constants
|
||||
+ added optimization for multiple negate expressions
|
||||
|
||||
2008-12-07 22:22 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com)
|
||||
* harbour/contrib/gtwvg/makefile
|
||||
* harbour/contrib/gtwvg/common.mak
|
||||
|
||||
@@ -96,7 +96,7 @@ if [ "${SLIB_EXT}" != ".dylib" ]; then
|
||||
echo "cannot read file: ${f}"
|
||||
exit 1
|
||||
fi
|
||||
cp "${dir}/${f}" "${OTMPDIR}" || exit 1
|
||||
cp "${f}" "${OTMPDIR}" || exit 1
|
||||
;;
|
||||
*.a)
|
||||
if [ "${f#/}" == "${f}" ]; then
|
||||
@@ -110,7 +110,7 @@ if [ "${SLIB_EXT}" != ".dylib" ]; then
|
||||
d="${f##*/}"
|
||||
mkdir $d
|
||||
cd $d
|
||||
${CCPREFIX}ar -x "${dir}/${f}" || exit 1
|
||||
${CCPREFIX}ar -x "${f}" || exit 1
|
||||
cd ..
|
||||
;;
|
||||
*)
|
||||
|
||||
@@ -6,6 +6,7 @@ ROOT = ../
|
||||
|
||||
DOC_FILES=\
|
||||
c_std.txt \
|
||||
cmpopt.txt \
|
||||
class_tp.txt \
|
||||
cmdline.txt \
|
||||
codebloc.txt \
|
||||
|
||||
165
harbour/doc/cmpopt.txt
Normal file
165
harbour/doc/cmpopt.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
Harbour compile time optimizations.
|
||||
|
||||
1. Function call optimization.
|
||||
|
||||
Just like Clipper Harbour compiler can optimize few function calls if
|
||||
parameters are well known constant values. Here is the list of functions
|
||||
optimized at compile time:
|
||||
|
||||
- Clipper compatible:
|
||||
|
||||
AT( <cConst1>, <cConst2> ) // Clipper wrongly calculates
|
||||
// "" $ <cConst> as .T.
|
||||
CHR( <nConst> )
|
||||
UPPER( <cConst> ) // <cConst> cannot contain characters different then
|
||||
[0-9A-Za-z]
|
||||
|
||||
- Harbour extension:
|
||||
|
||||
INT( <cConst> )
|
||||
ASC( <cConst> [ , ... ] )
|
||||
MIN( <xConst1>, <xConst2> ) // <xConstN> is N, D or L value
|
||||
MAX( <xConst1>, <xConst2> ) // <xConstN> is N, D or L value
|
||||
EMPTY( <aConst> | <hConst> | <cConst> | <bConst> |
|
||||
<nConst> | <dConst>| <lConst> | NIL )
|
||||
LEN( <cConst> | <aConst> | <hConst> )
|
||||
CTOD( <cConst> [ , ... } )
|
||||
DTOS( <dConst> ] )
|
||||
STOD( [ <cConst> ] )
|
||||
HB_STOD( [ <cConst> ] )
|
||||
HB_BITNOT( <nConst> [, ... ] )
|
||||
HB_BITAND( <nConst1>, <nConst2> [, <nConstN> ] )
|
||||
HB_BITOR( <nConst1>, <nConst2> [, <nConstN> ] )
|
||||
HB_BITXOR( <nConst1>, <nConst2> [, <nConstN> ] )
|
||||
HB_BITTEST( <nConst1>, <nConst2> [, ... ] )
|
||||
HB_BITSET( <nConst1>, <nConst2> [, ... ] )
|
||||
HB_BITRESET( <nConst1>, <nConst2> [, ... ] )
|
||||
HB_BITSHIFT( <nConst1>, <nConst2> [, ... ] )
|
||||
|
||||
- Harbour special functions:
|
||||
|
||||
HB_I18N_GETTEXT_NOOP( <cConst1> [ , <cConst2> ] )
|
||||
HB_I18N_NGETTEXT_NOOP( <cConst1> | <acConst1> [ , <cConst2> ] )
|
||||
HB_MUTEXCREATE()
|
||||
|
||||
|
||||
2. Expresion optimization:
|
||||
|
||||
Just like Clipper Harbour compiler can optimize some expresions if
|
||||
arguments are well known and can be callculated at compile time:
|
||||
|
||||
- Clipper compatible:
|
||||
|
||||
<nConst1> + <nConst2> => <nConst>
|
||||
<nConst1> + <dConst2> => <dConst>
|
||||
<dConst1> + <nConst2> => <dConst>
|
||||
<cConst1> + <cConst2> => <cConst>
|
||||
// In Clipper neither <cConst1> nor <cConst2>
|
||||
// can contain '&' character. Harbour checks
|
||||
// if concatenation can change existing valid
|
||||
// macro expression
|
||||
<nConst1> - <nConst2> => <nConst>
|
||||
<dConst1> - <dConst2> => <dConst>
|
||||
<dConst1> - <nConst2> => <dConst>
|
||||
<cConst1> - <cConst2> => <cConst>
|
||||
// In Clipper neither <cConst1> nor <cConst2>
|
||||
// can contain '&' character. Harbour checks
|
||||
// if concatenation can change existing valid
|
||||
// macro expression
|
||||
<nConst1> * <nConst2> => <nConst>
|
||||
<nConst1> / <nConst2> => <nConst> // Clipper optimize only integers
|
||||
<nConst1> % <nConst2> => <nConst>
|
||||
<cConst1> $ <cConst2> => <lConst> // Clipper wrongly calculates
|
||||
// "" $ <cConst> as .T.
|
||||
<lConst1> == <lConst2> => <lConst>
|
||||
<nConst1> == <nConst2> => <lConst>
|
||||
<dConst1> == <dConst2> => <lConst>
|
||||
<cConst1> == <cConst2> => <lConst>
|
||||
NIL == <xConst> => <lConst>
|
||||
<xConst> == NIL => <lConst>
|
||||
<lConst1> = <lConst2> => <lConst>
|
||||
<nConst1> = <nConst2> => <lConst>
|
||||
<dConst1> = <dConst2> => <lConst>
|
||||
NIL = <xConst> => <lConst>
|
||||
<xConst> = NIL => <lConst>
|
||||
"" = "" => .T.
|
||||
<lConst1> != <lConst2> => <lConst>
|
||||
<nConst1> != <nConst2> => <lConst>
|
||||
<dConst1> != <dConst2> => <lConst>
|
||||
NIL != <xConst> => <lConst>
|
||||
<xConst> != NIL => <lConst>
|
||||
"" != "" => .F.
|
||||
<lConst1> >= <lConst2> => <lConst>
|
||||
<nConst1> >= <nConst2> => <lConst>
|
||||
<dConst1> >= <dConst2> => <lConst>
|
||||
<lConst1> <= <lConst2> => <lConst>
|
||||
<nConst1> <= <nConst2> => <lConst>
|
||||
<dConst1> <= <dConst2> => <lConst>
|
||||
<lConst1> > <lConst2> => <lConst>
|
||||
<nConst1> > <nConst2> => <lConst>
|
||||
<dConst1> > <dConst2> => <lConst>
|
||||
<lConst1> < <lConst2> => <lConst>
|
||||
<nConst1> < <nConst2> => <lConst>
|
||||
<dConst1> < <dConst2> => <lConst>
|
||||
.NOT. .T. => .F.
|
||||
.NOT. .F. => .T.
|
||||
<lConst1> .AND. <lConst2> => <lConst>
|
||||
<lConst1> .OR. <lConst2> => <lConst>
|
||||
IIF( .T., <expr1>, <expr2> ) => <expr1>
|
||||
IIF( .F., <expr1>, <expr2> ) => <expr2>
|
||||
|
||||
- optimizations disabled by -z compiler switch
|
||||
|
||||
.T. .AND. <expr> => <expr>
|
||||
<expr> .AND. .T. => <expr>
|
||||
.F. .OR. <expr> => <expr>
|
||||
<expr> .OR. .F. => <expr>
|
||||
.F. .AND. <expr> => .F.
|
||||
<expr> .AND. .F. => .F.
|
||||
.T. .OR. <expr> => .T.
|
||||
<expr> .OR. .T. => .T.
|
||||
|
||||
- Harbour extension:
|
||||
|
||||
<nConst1> ^ <nConst2> => <nConst>
|
||||
<aValue> [ <nConst> ] => <xArrayItem>
|
||||
( <expr> ) => <expr> // it allows to optimize expresions like: 1+(2)
|
||||
|
||||
- Harbour extension which may disable RT errors in wrong expressions:
|
||||
.NOT. .NOT. <expr> => <expr>
|
||||
- - <expr> => <expr>
|
||||
<expr> + 0 => <expr>
|
||||
0 + <expr> => <expr>
|
||||
<expr> + "" => <expr>
|
||||
"" + <expr> => <expr>
|
||||
|
||||
In cases when result is miningless Harbour compiler can skip code
|
||||
for operation, f.e. such line of .prg code:
|
||||
( <exp1> <op> <exp2> )
|
||||
where result of <op> operation is ignored Harbour reduced the code
|
||||
to:
|
||||
( <exp1>, <exp2> )
|
||||
|
||||
In Clipper in some places optiomization is not enabled, f.e. Clipper
|
||||
does not optimize <exp> in expressions like:
|
||||
<exp> : msg( ... )
|
||||
Unlike Clipper Harbour tries to optimize all expressions.
|
||||
|
||||
If some code needs strict Clipper behavior then it can be forced by using
|
||||
-kc Harbour compiler switch. It disabled Harbour extensions and enables
|
||||
replicating some Clipper bugs like optimizing "" $ <cConst> to .T. at
|
||||
compile time when it runtime it's .F.
|
||||
|
||||
Expressions fully optimized to constant values at compile time can be used
|
||||
to intialize static variables, f.e.:
|
||||
static s_var := ( 1 + 2 / 3 )
|
||||
|
||||
Harbour has additional optimization phase which operates on generated PCODE.
|
||||
It can also reduce expressions, joins jumps, removes death or meaningless
|
||||
code which can appear after all other optimizations and were not optimized
|
||||
by expression optimizer.
|
||||
@@ -547,10 +547,35 @@ HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR pArray, HB_EXPR_PTR pIndex, HB_CO
|
||||
/* ************************************************************************* */
|
||||
|
||||
#ifndef HB_MACRO_SUPPORT
|
||||
|
||||
/* List of functions which can be used as static initializers */
|
||||
static const char * s_szStaticFun[] = {
|
||||
"HB_MUTEXCREATE"
|
||||
};
|
||||
|
||||
#define STATIC_FUNCTIONS ( sizeof( s_szStaticFun ) / sizeof( char * ) )
|
||||
|
||||
static BOOL hb_compStaticFunction( const char * szName )
|
||||
{
|
||||
unsigned int ui;
|
||||
for( ui = 0; ui < STATIC_FUNCTIONS; ++ui )
|
||||
{
|
||||
if( strcmp( szName, s_szStaticFun[ ui ] ) == 0 )
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void hb_compExprCheckStaticInitializer( HB_EXPR_PTR pLeftExpr, HB_EXPR_PTR pRightExpr, HB_COMP_DECL )
|
||||
{
|
||||
if( pRightExpr->ExprType > HB_ET_FUNREF ||
|
||||
pRightExpr->ExprType == HB_ET_SELF )
|
||||
if( ( pRightExpr->ExprType > HB_ET_FUNREF ||
|
||||
pRightExpr->ExprType == HB_ET_SELF ) &&
|
||||
!( pRightExpr->ExprType == HB_ET_FUNCALL &&
|
||||
pRightExpr->value.asFunCall.pFunName->ExprType == HB_ET_FUNNAME &&
|
||||
hb_compStaticFunction( pRightExpr->value.asFunCall.pFunName->
|
||||
value.asSymbol ) &&
|
||||
hb_compExprParamListLen( pRightExpr->value.asFunCall.pParms ) == 0 ) )
|
||||
{
|
||||
/* Illegal initializer for static variable (not a constant value)
|
||||
*/
|
||||
|
||||
@@ -3127,6 +3127,8 @@ static HB_EXPR_FUNC( hb_compExprUseNot )
|
||||
return pSelf;
|
||||
}
|
||||
|
||||
/* handler for = operator
|
||||
*/
|
||||
static HB_EXPR_FUNC( hb_compExprUseEqual )
|
||||
{
|
||||
switch( iMessage )
|
||||
|
||||
@@ -756,6 +756,16 @@ HB_EXPR_PTR hb_compExprReduceNegate( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
HB_COMP_EXPR_FREE( pSelf );
|
||||
pSelf = pExpr;
|
||||
}
|
||||
else if( pExpr->ExprType == HB_EO_NEGATE && HB_SUPPORT_HARBOUR )
|
||||
{
|
||||
/* NOTE: This will not generate a runtime error if incompatible
|
||||
* data type is used
|
||||
*/
|
||||
pExpr->ExprType = HB_ET_NONE; /* suppress deletion of operator components */
|
||||
pExpr = pExpr->value.asOperator.pLeft;
|
||||
HB_COMP_EXPR_FREE( pSelf );
|
||||
pSelf = pExpr;
|
||||
}
|
||||
|
||||
return pSelf;
|
||||
}
|
||||
@@ -875,6 +885,17 @@ HB_EXPR_PTR hb_compExprReduceNE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l != pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_NIL:
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
@@ -972,6 +993,17 @@ HB_EXPR_PTR hb_compExprReduceGE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l >= pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
else
|
||||
@@ -1036,6 +1068,17 @@ HB_EXPR_PTR hb_compExprReduceLE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l <= pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
else
|
||||
@@ -1100,6 +1143,17 @@ HB_EXPR_PTR hb_compExprReduceGT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l > pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
else
|
||||
@@ -1164,8 +1218,17 @@ HB_EXPR_PTR hb_compExprReduceLT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l < pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
else
|
||||
@@ -1246,6 +1309,17 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_DATE:
|
||||
{
|
||||
BOOL bResult = pLeft->value.asNum.val.l == pRight->value.asNum.val.l;
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_NIL:
|
||||
HB_COMP_EXPR_FREE( pLeft );
|
||||
HB_COMP_EXPR_FREE( pRight );
|
||||
|
||||
Reference in New Issue
Block a user