summaryrefslogtreecommitdiff
path: root/compiler_and_linker/FrontEnd/Optimizer/IroSubable.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroSubable.c')
-rw-r--r--compiler_and_linker/FrontEnd/Optimizer/IroSubable.c160
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)
+ );
+}