summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/IroRangePropagation.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/IroRangePropagation.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/IroRangePropagation.c')
-rw-r--r--compiler_and_linker/unsorted/IroRangePropagation.c774
1 files changed, 0 insertions, 774 deletions
diff --git a/compiler_and_linker/unsorted/IroRangePropagation.c b/compiler_and_linker/unsorted/IroRangePropagation.c
deleted file mode 100644
index d15ef86..0000000
--- a/compiler_and_linker/unsorted/IroRangePropagation.c
+++ /dev/null
@@ -1,774 +0,0 @@
-#include "compiler/IroRangePropagation.h"
-#include "compiler/IroDump.h"
-#include "compiler/IroFlowgraph.h"
-#include "compiler/IroLinearForm.h"
-#include "compiler/IroMalloc.h"
-#include "compiler/IroPointerAnalysis.h"
-#include "compiler/IroUtil.h"
-#include "compiler/IroVars.h"
-#include "compiler/CInt64.h"
-#include "compiler/objects.h"
-#include "compiler/types.h"
-
-#ifdef __MWERKS__
-#pragma options align=mac68k
-#endif
-typedef enum ERangeType {
- ERangeType0,
- ERangeType1,
- ERangeType2,
- ERangeType3
-} ERangeType;
-
-typedef struct ERange {
- ERangeType type;
- CInt64 upper;
- CInt64 lower;
-} ERange;
-
-typedef struct ERecord {
- Object *object;
- ERange *range;
- struct ERecord *next;
-} ERecord;
-#ifdef __MWERKS__
-#pragma options align=reset
-#endif
-
-static ERecord *ERangeFirst;
-static ERecord *ERangeLast;
-
-static ERange *ERnewERange(ERangeType type) {
- ERange *range;
-
- range = oalloc(sizeof(ERange));
- range->type = type;
- return range;
-}
-
-static ERecord *ERnewRecord(Object *object, ERange *range) {
- ERecord *record;
-
- record = oalloc(sizeof(ERecord));
- record->object = object;
- record->range = range;
- record->next = ERangeFirst;
- ERangeFirst = record;
- if (!ERangeLast)
- ERangeLast = record;
- return record;
-}
-
-static ERecord *ERecordFound(Object *obj) {
- ERecord *scan;
-
- scan = ERangeFirst;
- while (scan && obj != scan->object)
- scan = scan->next;
-
- return scan;
-}
-
-static Boolean EREandHasNoUse(ERange *range, CInt64 val) {
- UInt16 i;
- CInt64 v11;
- CInt64 work;
-
- i = 0;
- work = range->upper;
- while (CInt64_NotEqual(work = CInt64_ShrU(work, cint64_one), cint64_zero))
- i++;
-
- if (CInt64_NotEqual(range->upper, cint64_zero))
- i++;
-
- CInt64_SetULong(&work, i);
- v11 = CInt64_Sub(CInt64_Shl(cint64_one, work), cint64_one);
- if (CInt64_NotEqual(cint64_zero, CInt64_And(CInt64_Inv(val), v11)))
- return 0;
- else
- return 1;
-}
-
-static void ERcheckOverflow(ERange *range, Type *type) {
- CInt64 typeSize;
- CInt64 work;
- CInt64 work2;
- CInt64 value3;
-
- if (!range)
- return;
-
- if (!IS_TYPE_INT(type)) {
- range->type = ERangeType3;
- return;
- }
-
- CInt64_SetLong(&typeSize, type->size);
- CInt64_SetLong(&value3, 3);
-
- if (IRO_IsUnsignedType(type)) {
- if (type->size < 8) {
- work = CInt64_Sub(CInt64_Shl(cint64_one, CInt64_Shl(typeSize, value3)), cint64_one);
- if (CInt64_GreaterU(range->upper, work))
- range->type = ERangeType3;
- } else {
- range->type = ERangeType3;
- }
- } else {
- if (type->size < 8) {
- work = CInt64_Sub(CInt64_Shl(cint64_one, CInt64_Sub(CInt64_Shl(typeSize, value3), cint64_one)), cint64_one);
- work2 = CInt64_Shl(cint64_negone, CInt64_Sub(CInt64_Shl(typeSize, value3), cint64_one));
- if (CInt64_Greater(range->upper, work) || CInt64_Less(range->lower, work2))
- range->type = ERangeType3;
- } else {
- range->type = ERangeType3;
- }
- }
-}
-
-static void ERinvalidAll(void) {
- ERecord *record;
-
- for (record = ERangeFirst; record; record = record->next)
- record->range->type = ERangeType3;
-}
-
-static void SetRangesForKillsByIndirectAssignment(IROLinear *nd) {
- IROListNode *list;
- IROListNode *scan;
- IROLinear *inner;
- Boolean failed;
- IROListNode *resultList;
- IROLinear *scannd;
- Boolean foundObjRef;
- ERecord *record;
- ERange *range;
- IROListNode *next;
- Object *obj;
- IROLinear *analysend;
- Object *proc;
-
- failed = 0;
- if (nd->type == IROLinearOp2Arg)
- inner = nd->u.diadic.left;
- else
- inner = nd->u.monadic;
-
- if (
- inner &&
- inner->type == IROLinearOp1Arg &&
- inner->nodetype == EINDIRECT &&
- (analysend = inner->u.monadic) &&
- copts.opt_pointer_analysis &&
- analysend->pointsToFunction &&
- (proc = FunctionName)
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(proc, analysend, &resultList);
-
- if ((list = resultList)) {
- for (scan = list; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- failed = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- break;
- }
- }
-
- if (!foundObjRef) {
- failed = 1;
- break;
- }
- }
-
- if (!failed) {
- for (; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- CError_ASSERT(302, obj != NULL);
-
- range = nd->x16;
- if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
- range = inner->x16;
-
- record = ERecordFound(obj);
- if (!record)
- ERnewRecord(obj, range);
- else
- record->range = range;
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- failed = 1;
- }
- } else {
- failed = 1;
- }
-
- if (failed) {
- ERinvalidAll();
- nd->x16 = ERnewERange(ERangeType3);
- }
-}
-
-static void InvalidateRangesForKillsByFunctionCall(IROLinear *nd) {
- IROListNode *scan;
- IROLinear *scannd;
- Boolean failed;
- Boolean foundObjRef;
- IROListNode *list;
- IROListNode *resultList;
- ERecord *record;
- IROListNode *next;
- Object *obj;
- IROLinear *analysend;
- Object *proc;
- ObjectList *olist;
- ObjectList *killList;
-
- failed = 0;
-
- if (
- (analysend = nd->u.funccall.linear8) &&
- copts.opt_pointer_analysis &&
- analysend->pointsToFunction &&
- (proc = FunctionName)
- ) {
- resultList = NULL;
- PointerAnalysis_LookupLinearNodePointerExpr(proc, analysend, &resultList);
-
- if (resultList) {
- for (scan = resultList; scan; scan = scan->nextList) {
- if (!scan->list.head || !scan->list.tail) {
- failed = 1;
- break;
- }
-
- foundObjRef = 0;
- for (scannd = scan->list.head; scannd != scan->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- foundObjRef = 1;
- obj = scannd->u.node->data.objref;
- CError_ASSERT(385, obj != NULL);
-
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, nd, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- if (!olist->object) {
- failed = 1;
- break;
- }
- }
-
- while (killList) {
- olist = killList->next;
- IRO_free(killList);
- killList = olist;
- }
-
- if (failed)
- break;
- }
- }
-
- if (!foundObjRef)
- failed = 1;
- if (failed)
- break;
- }
-
- if (!failed) {
- for (list = resultList; list; list = list->nextList) {
- for (scannd = list->list.head; scannd != list->list.tail->next; scannd = scannd->next) {
- if (scannd->type == IROLinearOperand && scannd->u.node->type == EOBJREF) {
- obj = scannd->u.node->data.objref;
- killList = NULL;
- PointerAnalysis_GetFunctionKills(obj, nd, &killList);
-
- for (olist = killList; olist; olist = olist->next) {
- if ((record = ERecordFound(olist->object)))
- record->range->type = ERangeType3;
- }
-
- while (killList) {
- olist = killList->next;
- IRO_free(killList);
- killList = olist;
- }
- }
- }
- }
- }
-
- while (resultList) {
- next = resultList->nextList;
- IRO_free(resultList);
- resultList = next;
- }
- } else {
- failed = 1;
- }
- } else {
- failed = 1;
- }
-
- if (failed)
- ERinvalidAll();
-}
-
-static void ERfoldOperand(IROLinear *nd) {
- switch (nd->u.node->type) {
- case EOBJREF:
- nd->x16 = NULL;
- break;
- case EINTCONST:
- nd->x16 = ERnewERange(ERangeType0);
- nd->x16->upper = nd->x16->lower = nd->u.node->data.intval;
- break;
- case EFLOATCONST:
- case ESTRINGCONST:
- nd->x16 = ERnewERange(ERangeType0);
- break;
- }
-}
-
-static Boolean ERfoldExpr(IROLinear *nd) {
- ERecord *record;
- ERange *range;
- IROLinear *tmp;
- IROLinear *inner;
- Object *obj;
-
- switch (nd->nodetype) {
- case EINDIRECT:
- inner = nd->u.monadic;
- if (IS_TYPE_INT(nd->rtype)) {
- if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF) {
- if (!inner->x16 && (obj = inner->u.node->data.objref)) {
- if ((record = ERecordFound(obj))) {
- inner->x16 = ERnewERange(ERangeType3);
- *inner->x16 = *record->range;
- } else {
- inner->x16 = ERnewERange(ERangeType3);
- inner->x16->upper = cint64_max;
- inner->x16->lower = cint64_min;
- ERnewRecord(obj, inner->x16);
- }
- }
- nd->x16 = inner->x16;
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- if (inner->type == IROLinearOperand && inner->u.node->type == EOBJREF && !inner->x16)
- inner->x16 = ERnewERange(ERangeType3);
- nd->x16 = ERnewERange(ERangeType3);
- }
- break;
- case EAND:
- case EANDASS:
- if (IRO_IsIntConstant(nd->u.diadic.right)) {
- CInt64 val = nd->u.diadic.right->u.node->data.intval;
- nd->x16 = ERnewERange(ERangeType1);
- nd->x16->upper = val;
- nd->x16->lower = cint64_zero;
- if (
- (range = nd->u.diadic.left->x16) &&
- range->type != ERangeType3 &&
- CInt64_LessEqualU(range->upper, val) &&
- CInt64_LessEqualU(range->lower, val) &&
- EREandHasNoUse(range, val) &&
- !IRO_HasSideEffect(nd->u.diadic.left)
- ) {
- IRO_Dump("eliminating redundant EAND %" PRId32 "; upperBound==0x%x, lowerBound==0x%x, Constant==0x%x\n",
- nd->index,
- CInt64_GetULong(&range->upper),
- CInt64_GetULong(&range->upper),
- CInt64_GetULong(&val)
- );
- IRO_NopOut(nd->u.diadic.right);
- nd->type = IROLinearNop;
- nd->expr = NULL;
- tmp = nd->u.diadic.left;
- nd->u.diadic.left = nd->u.diadic.right;
- if (!IRO_LocateFather_Cut_And_Paste(nd, tmp)) {
- tmp->flags &= ~IROLF_Reffed;
- if (IRO_IsVariable(tmp))
- IRO_NopOut(tmp);
- }
- }
- } else {
- if (nd->u.diadic.right->x16) {
- nd->x16 = ERnewERange(ERangeType3);
- *nd->x16 = *nd->u.diadic.right->x16;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ELOGNOT:
- case ELESS:
- case EGREATER:
- case ELESSEQU:
- case EGREATEREQU:
- case EEQU:
- case ENOTEQU:
- case ELAND:
- case ELOR:
- nd->x16 = ERnewERange(ERangeType1);
- nd->x16->upper = cint64_one;
- nd->x16->lower = cint64_zero;
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EBINNOT:
- case EFORCELOAD:
- case EXOR:
- case EOR:
- case EXORASS:
- case EORASS:
- case ECOMMA:
- case ETYPCON:
- case EBITFIELD:
- case ECOND:
- case ENULLCHECK:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- case EASS:
- if (IS_TYPE_INT(nd->rtype))
- nd->x16 = nd->u.diadic.right->x16;
- break;
- case EMUL:
- case EMULV:
- case EMULASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_MulU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_MulU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16->upper = CInt64_Mul(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Mul(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EDIV:
- case EDIVASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (!CInt64_IsZero(&nd->u.diadic.right->x16->lower) && !CInt64_IsZero(&nd->u.diadic.right->x16->upper)) {
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_DivU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_DivU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Div(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Div(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EMODULO:
- case EMODASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (!CInt64_IsZero(&nd->u.diadic.right->x16->lower) && !CInt64_IsZero(&nd->u.diadic.right->x16->upper)) {
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_ModU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_ModU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Mod(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Mod(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EADDV:
- case EADD:
- case EADDASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Add(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Add(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESUBV:
- case ESUB:
- case ESUBASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Sub(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Sub(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESHL:
- case ESHLASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- nd->x16->upper = CInt64_Shl(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->upper);
- nd->x16->lower = CInt64_Shl(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->lower);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case ESHR:
- case ESHRASS:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.diadic.left->x16 && nd->u.diadic.left->x16->type != ERangeType3 &&
- nd->u.diadic.right->x16 && nd->u.diadic.right->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- if (IRO_IsUnsignedType(nd->rtype)) {
- nd->x16->upper = CInt64_ShrU(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_ShrU(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- } else {
- nd->x16->upper = CInt64_Shr(nd->u.diadic.left->x16->upper, nd->u.diadic.right->x16->lower);
- nd->x16->lower = CInt64_Shr(nd->u.diadic.left->x16->lower, nd->u.diadic.right->x16->upper);
- }
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPOSTINC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- *nd->x16 = *range;
- range->upper = CInt64_Add(range->upper, cint64_one);
- range->lower = CInt64_Add(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPOSTDEC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- *nd->x16 = *range;
- range->upper = CInt64_Sub(range->upper, cint64_one);
- range->lower = CInt64_Sub(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPREINC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- nd->x16->upper = CInt64_Add(range->upper, cint64_one);
- nd->x16->lower = CInt64_Add(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EPREDEC:
- if (IS_TYPE_INT(nd->rtype)) {
- if (nd->u.monadic->x16 && nd->u.monadic->x16->type != ERangeType3) {
- nd->x16 = ERnewERange(ERangeType2);
- range = nd->u.monadic->x16;
- nd->x16->upper = CInt64_Sub(range->upper, cint64_one);
- nd->x16->lower = CInt64_Sub(range->lower, cint64_one);
- } else {
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- }
- }
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- case EMONMIN:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- case EPMODULO:
- case EROTL:
- case EROTR:
- case EBCLR:
- case EBTST:
- case EBSET:
- nd->x16 = ERnewERange(ERangeType3);
- nd->x16->upper = cint64_max;
- nd->x16->lower = cint64_min;
- break;
- default:
- ERcheckOverflow(nd->x16, nd->rtype);
- break;
- }
-
- if (
- (nd->type == IROLinearOp1Arg || nd->type == IROLinearOp2Arg) &&
- IRO_IsAssignOp[nd->nodetype] &&
- nd->x16 &&
- IS_TYPE_INT(nd->rtype)
- ) {
- IROLinear *x = NULL;
- if (nd->type == IROLinearOp2Arg)
- x = nd->u.diadic.left;
- else if (nd->type == IROLinearOp1Arg)
- x = nd->u.monadic;
-
- if (x->type == IROLinearOp1Arg &&
- x->nodetype == EINDIRECT &&
- (x->u.monadic->nodetype == EINDIRECT || x->u.monadic->nodetype == EADD)) {
- SetRangesForKillsByIndirectAssignment(nd);
- } else {
- obj = NULL;
- if (x)
- obj = IRO_IsVariable(x);
- if (!obj)
- return 0;
-
- range = nd->x16;
- if (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC)
- range = x->x16;
-
- record = ERecordFound(obj);
- if (!record)
- ERnewRecord(obj, range);
- else
- record->range = range;
- }
- }
-
- return nd->x16 != NULL;
-}
-
-static Boolean ERfoldLinear(IROLinear *nd) {
- nd->x16 = 0;
-
- switch (nd->type) {
- case IROLinearNop:
- case IROLinearEnd:
- break;
- case IROLinearOperand:
- ERfoldOperand(nd);
- break;
- case IROLinearOp1Arg:
- case IROLinearOp2Arg:
- ERfoldExpr(nd);
- break;
- case IROLinearFunccall:
- InvalidateRangesForKillsByFunctionCall(nd);
- break;
- case IROLinearAsm:
- ERinvalidAll();
- break;
- }
-
- return 0;
-}
-
-Boolean IRO_RangePropagateInFNode(void) {
- IRONode *fnode;
- IROLinear *nd;
- Boolean result;
-
- result = 0;
-
- for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) {
- ERangeFirst = ERangeLast = NULL;
- for (nd = fnode->first; nd != fnode->last; nd = nd->next)
- ERfoldLinear(nd);
- if (ERfoldLinear(nd))
- result = 1;
- }
-
- if (result) {
- IRO_ComputeSuccPred();
- IRO_ComputeDom();
- }
-
- IRO_CheckForUserBreak();
- return result;
-}