diff options
Diffstat (limited to 'compiler_and_linker/FrontEnd/Optimizer/IroRangePropagation.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/Optimizer/IroRangePropagation.c | 774 |
1 files changed, 774 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/Optimizer/IroRangePropagation.c b/compiler_and_linker/FrontEnd/Optimizer/IroRangePropagation.c new file mode 100644 index 0000000..737035f --- /dev/null +++ b/compiler_and_linker/FrontEnd/Optimizer/IroRangePropagation.c @@ -0,0 +1,774 @@ +#include "IroRangePropagation.h" +#include "IroDump.h" +#include "IroFlowgraph.h" +#include "IroLinearForm.h" +#include "IroMalloc.h" +#include "IroPointerAnalysis.h" +#include "IroUtil.h" +#include "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; +} |