📄 optimize.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
This program is derived from the cc68k complier by
Matthew Brandt (mattb@walkingdog.net)
You may contact the author of this derivative at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
/* no support for complex. Floating point currently commented out */
/*
* this module combines constants at compile time. Integer constants
* will get combined slightly better than floating point ones
*/
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
extern int stdpragmas;
extern int stdshortsize, stdintsize, stdlongsize, stdlonglongsize;
static ENODE *asidehead, **asidetail;
LLONG_TYPE reint(ENODE *node);
static unsigned LLONG_TYPE shifts[sizeof(LLONG_TYPE)*8] ;
void constoptinit(void)
{
LLONG_TYPE i;
for (i=0; i < sizeof(LLONG_TYPE) * 8; i++)
shifts[i] = (1 << i);
}
static int optimizerfloatconst(ENODE *en)
{
if (en->cflags &DF_FENV_ACCESS)
return FALSE;
return isfloatconst(en->nodetype) || isimaginaryconst(en->nodetype) || iscomplexconst(en->nodetype);
}
//-------------------------------------------------------------------------
static int isoptconst(ENODE *en)
{
if (!en)
return FALSE;
return isintconst(en->nodetype) || optimizerfloatconst(en);
}
//-------------------------------------------------------------------------
int maxinttype(ENODE *ep1, ENODE *ep2)
{
int type1 = ep1->nodetype;
int type2 = ep2->nodetype;
if (type1 == en_llucon || type2 == en_llucon)
return en_llucon;
if (type1 == en_llcon || type2 == en_llcon)
return en_llcon;
if (type1 == en_lucon || type2 == en_lucon)
return en_lucon;
if (type1 == en_lcon || type2 == en_lcon)
return en_lcon;
if (type1 == en_iucon || type2 == en_iucon)
return en_iucon;
if (type1 == en_icon || type2 == en_icon)
return en_icon;
if (type1 == en_cucon || type2 == en_cucon)
return en_cucon;
if (type1 == en_ccon || type2 == en_ccon)
return en_ccon;
return en_boolcon;
}
//-------------------------------------------------------------------------
int isunsigned(ENODE *ep1)
{
switch (ep1->nodetype)
{
case en_lucon:
case en_iucon:
case en_llucon:
return TRUE;
default:
return FALSE;
}
}
//-------------------------------------------------------------------------
int maxfloattype(ENODE *ep1, ENODE *ep2)
{
int type1 = ep1->nodetype;
int type2 = ep2->nodetype;
if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
type2 == en_lrimaginarycon)
return en_lrcon;
if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
type2 == en_rimaginarycon)
return en_rcon;
return en_fcon;
}
//-------------------------------------------------------------------------
int maximaginarytype(ENODE *ep1, ENODE *ep2)
{
int type1 = ep1->nodetype;
int type2 = ep2->nodetype;
if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
type2 == en_lrimaginarycon)
return en_lrimaginarycon;
if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
type2 == en_rimaginarycon)
return en_rimaginarycon;
return en_fimaginarycon;
}
//-------------------------------------------------------------------------
int maxcomplextype(ENODE *ep1, ENODE *ep2)
{
int type1 = ep1->nodetype;
int type2 = ep2->nodetype;
if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
type2 == en_lrimaginarycon || type1 == en_lrcomplexcon ||
type2 == en_lrcomplexcon)
return en_lrcomplexcon;
if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
type2 == en_rimaginarycon || type1 == en_rcomplexcon || type2 == en_rcomplexcon)
return en_rcomplexcon;
return en_fcomplexcon;
}
//-------------------------------------------------------------------------
int getmode(ENODE *ep1, ENODE *ep2)
/*
* get the constant mode of a pair of nodes
* 0 = Neither node is a constant
* 1 = icon,icon
* 2 = icon,rcon
* 3 = rcon,icon
* 4 = rcon,rcon
* 5 = icon,nothing
* 6 = rcon,nothing
* 7 = nothing,icon
* 8 = nothing,rcon
* 9 = rcon, ricon
* 10 = ricon, rcon
* 11 = ricon, ricon
* 12 = ricon, nothing
* 13 = nothing, ricon
* 14 = ricon, icon
* 15 = icon, ricon
* 16 = ricon, cmplxcon
* 17 = cmplxcon, ricon
* 18 = rcon, cmplxcon
* 19 = cmplxcon, rcon
* 20 = cmplxcon, cmplxcon
* 21 = cmplxcon, nothing
* 22 = nothing, cmplxcon
* 23 = cmplxcon, icon
* 24 = icon, cmplxcon
*/
{
int mode = 0;
if ((ep1->cflags &DF_FENV_ACCESS) && (isfloatconst(ep1->nodetype) ||
isimaginaryconst(ep1->nodetype) || iscomplexconst(ep1->nodetype)))
return 0;
if (ep2 && (ep2->cflags &DF_FENV_ACCESS) && (isfloatconst(ep2->nodetype) ||
isimaginaryconst(ep2->nodetype) || iscomplexconst(ep2->nodetype)))
return 0;
if (isintconst(ep1->nodetype))
if (ep2)
{
if (isintconst(ep2->nodetype))
mode = 1;
else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
->nodetype == en_fcon)
{
mode = 2;
}
else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
ep2->nodetype == en_lrimaginarycon)
mode = 15;
else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
ep2->nodetype == en_lrcomplexcon)
mode = 24;
else
mode = 5;
}
else
mode = 5;
else if (ep1->nodetype == en_rcon || ep1->nodetype == en_lrcon || ep1
->nodetype == en_fcon)
if (ep2)
{
if (isintconst(ep2->nodetype))
mode = 3;
else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon ||
ep2->nodetype == en_fcon)
mode = 4;
else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
ep2->nodetype == en_lrimaginarycon)
mode = 9;
else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
ep2->nodetype == en_lrcomplexcon)
mode = 18;
else
mode = 6;
}
else
mode = 6;
else if (ep1->nodetype == en_rimaginarycon || ep1->nodetype == en_fimaginarycon ||
ep1->nodetype == en_lrimaginarycon)
if (ep2)
{
if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
->nodetype == en_fcon)
mode = 10;
else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
ep2->nodetype == en_lrimaginarycon)
mode = 11;
else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
ep2->nodetype == en_lrcomplexcon)
mode = 16;
else if (isintconst(ep2->nodetype))
mode = 14;
else
mode = 12;
} else
mode = 12;
else if (ep1->nodetype == en_rcomplexcon || ep1->nodetype == en_fcomplexcon ||
ep1->nodetype == en_lrcomplexcon)
if (ep2)
{
if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
->nodetype == en_fcon)
mode = 17;
else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
ep2->nodetype == en_lrimaginarycon)
mode = 19;
else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
ep2->nodetype == en_lrcomplexcon)
mode = 20;
else if (isintconst(ep2->nodetype))
mode = 23;
else
mode = 21;
} else
mode = 21;
else if (ep2)
if (isintconst(ep2->nodetype))
mode = 7;
else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
->nodetype == en_fcon)
mode = 8;
else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
ep2->nodetype == en_lrimaginarycon)
mode = 13;
else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
ep2->nodetype == en_lrcomplexcon)
mode = 22;
return (mode);
}
//-------------------------------------------------------------------------
void dooper(ENODE **node, int mode)
/*
* dooper will execute a constant operation in a node and
* modify the node to be the result of the operation.
* It will also cast integers to floating point values when
* necessary
*/
{
ENODE *ep, *ep1, *ep2;
ep = *node;
ep1 = ep->v.p[0];
ep2 = ep->v.p[1];
if (mode == 5)
{
if (floatrecurse(ep2))
{
ep1->v.f = ep1->v.i;
ep1->nodetype = en_rcon;
}
return ;
}
else if (mode == 7)
{
if (floatrecurse(ep1))
{
ep2->v.f = ep2->v.i;
ep2->nodetype = en_rcon;
}
return ;
}
else if (mode == 6 || mode == 8 || mode == 12 || mode == 13 || mode == 21 || mode == 22)
return ;
else
switch (ep->nodetype)
{
case en_add:
case en_addstruc:
case en_array:
switch (mode)
{
case 1:
ep->nodetype = maxinttype(ep1, ep2);
ep->v.i = ep1->v.i + ep2->v.i;
ep->v.i = reint(ep);
break;
case 2:
ep->nodetype = maxfloattype(ep1, ep2);
ep->v.f = ep1->v.i + ep2->v.f;
break;
case 3:
ep->nodetype = maxfloattype(ep1, ep2);
ep->v.f = ep1->v.f + ep2->v.i;
break;
case 4:
ep->nodetype = maxfloattype(ep1, ep2);
ep->v.f = ep1->v.f + ep2->v.f;
break;
case 9:
ep->nodetype = maxcomplextype(ep1,ep2);
ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
&& (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
DF_CXLIMITED : 0;
ep->v.c.r = ep1->v.f ;
ep->v.c.i = ep2->v.f;
break ;
case 10:
ep->nodetype = maxcomplextype(ep1,ep2);
ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
&& (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
DF_CXLIMITED : 0;
ep->v.c.r = ep2->v.f ;
ep->v.c.i = ep1->v.f;
break ;
case 11:
ep->nodetype = maximaginarytype(ep1,ep2);
ep->v.f = ep1->v.f + ep2->v.f;
break ;
case 14:
ep->nodetype = maxcomplextype(ep1,ep2);
ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
&& (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
DF_CXLIMITED : 0;
ep->v.c.r = ep2->v.i ;
ep->v.c.i = ep1->v.f ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -