diff options
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroSubable.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/Optimizer/IroSubable.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/Optimizer/IroSubable.c b/compiler_and_linker/FrontEnd/Optimizer/IroSubable.c new file mode 100644 index 0000000..513ac6c --- /dev/null +++ b/compiler_and_linker/FrontEnd/Optimizer/IroSubable.c @@ -0,0 +1,160 @@ +#include "IroSubable.h" +#include "IroLinearForm.h" +#include "IroPropagate.h" +#include "IroUtil.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +static Boolean IsSubableOp[MAXEXPR]; + +void IRO_InitializeIsSubableOpArray(void) { + int i; + + for (i = 0; i < MAXEXPR; i++) + IsSubableOp[i] = 0; + + IsSubableOp[EPOSTINC] = 0; + IsSubableOp[EPOSTDEC] = 0; + IsSubableOp[EPREINC] = 0; + IsSubableOp[EPREDEC] = 0; + IsSubableOp[EINDIRECT] = 0; + IsSubableOp[EMONMIN] = 1; + IsSubableOp[EBINNOT] = 1; + IsSubableOp[ELOGNOT] = 1; + IsSubableOp[EFORCELOAD] = 0; + IsSubableOp[EMUL] = 1; + IsSubableOp[EMULV] = 1; + IsSubableOp[EDIV] = 1; + IsSubableOp[EMODULO] = 1; + IsSubableOp[EADDV] = 1; + IsSubableOp[ESUBV] = 1; + IsSubableOp[EADD] = 1; + IsSubableOp[ESUB] = 1; + IsSubableOp[ESHL] = 1; + IsSubableOp[ESHR] = 1; + IsSubableOp[ELESS] = 0; + IsSubableOp[EGREATER] = 0; + IsSubableOp[ELESSEQU] = 0; + IsSubableOp[EGREATEREQU] = 0; + IsSubableOp[EEQU] = 0; + IsSubableOp[ENOTEQU] = 0; + IsSubableOp[EAND] = 1; + IsSubableOp[EXOR] = 1; + IsSubableOp[EOR] = 1; + IsSubableOp[ELAND] = 0; + IsSubableOp[ELOR] = 0; + IsSubableOp[EASS] = 0; + IsSubableOp[EMULASS] = 0; + IsSubableOp[EDIVASS] = 0; + IsSubableOp[EMODASS] = 0; + IsSubableOp[EADDASS] = 0; + IsSubableOp[ESUBASS] = 0; + IsSubableOp[ESHLASS] = 0; + IsSubableOp[ESHRASS] = 0; + IsSubableOp[EANDASS] = 0; + IsSubableOp[EXORASS] = 0; + IsSubableOp[EORASS] = 0; + IsSubableOp[ECOMMA] = 0; + IsSubableOp[EPMODULO] = 0; + IsSubableOp[EROTL] = 0; + IsSubableOp[EROTR] = 0; + IsSubableOp[EBCLR] = 0; + IsSubableOp[EBTST] = 0; + IsSubableOp[EBSET] = 0; + IsSubableOp[ETYPCON] = 0; + IsSubableOp[EBITFIELD] = 0; + IsSubableOp[EINTCONST] = 0; + IsSubableOp[EFLOATCONST] = 0; + IsSubableOp[ESTRINGCONST] = 0; + IsSubableOp[ECOND] = 0; + IsSubableOp[EFUNCCALL] = 0; + IsSubableOp[EFUNCCALLP] = 0; + IsSubableOp[EOBJREF] = 0; + IsSubableOp[EMFPOINTER] = 0; + IsSubableOp[ENULLCHECK] = 0; + IsSubableOp[EPRECOMP] = 0; + IsSubableOp[ETEMP] = 0; + IsSubableOp[EARGOBJ] = 0; + IsSubableOp[ELOCOBJ] = 0; + IsSubableOp[ELABEL] = 0; + IsSubableOp[ESETCONST] = 0; + IsSubableOp[ENEWEXCEPTION] = 0; + IsSubableOp[ENEWEXCEPTIONARRAY] = 0; + IsSubableOp[EOBJLIST] = 0; + IsSubableOp[EMEMBER] = 0; + IsSubableOp[ETEMPLDEP] = 0; + IsSubableOp[EINSTRUCTION] = 0; + IsSubableOp[EDEFINE] = 0; + IsSubableOp[EREUSE] = 0; + IsSubableOp[EASSBLK] = 0; + IsSubableOp[EVECTOR128CONST] = 0; + IsSubableOp[ECONDASS] = 0; +} + +static int IsSubscript(IROLinear *nd) { + return 0; +} + +Boolean IRO_IsSubableExpression(IROLinear *nd) { + Object *varobj; + Boolean result; + + switch (nd->type) { + case IROLinearOp2Arg: + if (nd->nodetype == EADD || nd->nodetype == ESUB) { + if ( + IRO_IsConstant(nd->u.diadic.right) && + (varobj = IRO_IsVariable(nd->u.diadic.left)) && + varobj->datatype == DLOCAL && + varobj->u.var.info && + !varobj->u.var.info->noregister) + return 0; + + } + result = IsSubableOp[nd->nodetype] && !IsSubscript(nd); + return result; + case IROLinearOp1Arg: + if (IsSubableOp[nd->nodetype] && !IsSubscript(nd)) + return 1; + + if (nd->nodetype == EINDIRECT && !(nd->flags & IROLF_Assigned)) { + if (nd->flags & IROLF_Ind) { + nd = nd->u.monadic; + if (nd->type == IROLinearOperand && + nd->u.node->type == EOBJREF && + nd->u.node->data.objref->datatype == DLOCAL && + nd->u.node->data.objref->u.var.info && + !nd->u.node->data.objref->u.var.info->noregister + ) + return 0; + return 1; + } + + if (IRO_IsVariable(nd) && IRO_IsRegable(nd->u.monadic->u.node->data.objref)) + return 0; + return 1; + } else if (nd->nodetype == ETYPCON && IS_TYPE_INT(nd->rtype) && nd->rtype->size >= nd->u.monadic->rtype->size) { + return 1; + } else { + return 0; + } + case IROLinearOperand: + default: + return 0; + } +} + +Boolean IRO_IsVectorTempCandidate(IROLinear *nd) { + return + ( + nd->type == IROLinearOp1Arg || + nd->type == IROLinearOp2Arg || + nd->type == IROLinearOp3Arg || + nd->type == IROLinearOperand || + nd->type == IROLinearFunccall + ) && ( + (nd->flags & IROLF_LoopInvariant) && + !(nd->flags & IROLF_Ind) + ); +} |