diff options
Diffstat (limited to 'compiler_and_linker/unsorted/IROUseDef.c')
-rw-r--r-- | compiler_and_linker/unsorted/IROUseDef.c | 1432 |
1 files changed, 0 insertions, 1432 deletions
diff --git a/compiler_and_linker/unsorted/IROUseDef.c b/compiler_and_linker/unsorted/IROUseDef.c deleted file mode 100644 index 19d39ff..0000000 --- a/compiler_and_linker/unsorted/IROUseDef.c +++ /dev/null @@ -1,1432 +0,0 @@ -#include "compiler/IROUseDef.h" -#include "compiler/IRODump.h" -#include "compiler/IROVars.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroMalloc.h" -#include "compiler/IroPointerAnalysis.h" -#include "compiler/IroTransform.h" -#include "compiler/IroUtil.h" -#include "compiler/CompilerTools.h" -#include "compiler/CError.h" -#include "compiler/CFunc.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CParser.h" -#include "compiler/objects.h" -#include "compiler/types.h" -#include "compiler/InlineAsm.h" -#include "compiler/InlineAsmPPC.h" - -ENodeType IRO_NonAssignmentOp[MAXEXPR]; -typedef CInt64 (*AssignmentFoldingFunc)(CInt64, CInt64); -static AssignmentFoldingFunc AssignmentFoldingFunction[MAXEXPR]; -static SInt32 NumDefs; -static IRODef *FirstDef; -static IRODef *LastDef; -static SInt32 NumUses; -static BitVector *Reaches; -static BitVector *MightReachAnyUse; -static BitVector *alldefs; -static BitVector *alluses; -static BitVector *defset; -static BitVector *useset; -IROUse *IRO_FirstVarUse; -IROUse *IRO_LastVarUse; - -// forward decls -static void AddDefToRange(IRODef *def); - -static void MakeDef(VarRecord *var, IROLinear *linear, IRONode *node, Boolean flag) { - IRODef *def = oalloc(sizeof(IRODef)); - - def->index = NumDefs++; - def->node = node; - def->linear = linear; - def->var = var; - def->globalnext = NULL; - def->x18 = 0; - def->x1A = Inline_IsObjectData(var->object); - def->x1B = var->xB; - def->x1C = flag; - def->x1D = 0; - - if (FirstDef) - LastDef->globalnext = def; - else - FirstDef = def; - LastDef = def; - - def->varnext = var->defs; - var->defs = def; -} - -static void MakeUse(VarRecord *var, IROLinear *linear, IRONode *node) { - IROUse *use = oalloc(sizeof(IROUse)); - - use->index = NumUses++; - use->node = node; - use->linear = linear; - use->var = var; - use->globalnext = NULL; - use->x1C = 0; - - if (IRO_FirstVarUse) - IRO_LastVarUse->globalnext = use; - else - IRO_FirstVarUse = use; - IRO_LastVarUse = use; - - use->varnext = var->uses; - var->uses = use; -} - -static void FindDefsAndUses(void) { - VarRecord *var; - IROLinear *linear; - IRONode *node; - - NumDefs = 0; - NumUses = 0; - IRO_FirstVarUse = NULL; - FirstDef = NULL; - - for (var = IRO_FirstVar; var; var = var->next) { - var->defs = NULL; - var->uses = NULL; - var->xC = 0; - } - - for (node = IRO_FirstNode; node; node = node->nextnode) { - for (linear = node->first; linear; linear = linear->next) { - if (IS_LINEAR_ENODE(linear, EOBJREF)) { - Object *obj = linear->u.node->data.objref; - if ((linear->flags & IROLF_Ind) && (!(linear->flags & IROLF_Assigned) || (linear->flags & IROLF_Used))) { - if ((var = IRO_FindVar(obj, 0, 1))) - MakeUse(var, linear, node); - } - } - - if (IRO_IsAssignment(linear) && (var = IRO_FindAssigned(linear))) { - MakeDef( - var, - linear, - node, - (linear->rtype->size == var->object->type->size) && !IRO_IsBitField - ); - } - - if (linear->type == IROLinearAsm) { - IAEffects effects; - int i; - CodeGen_GetAsmEffects(linear->u.asm_stmt, &effects); - - for (i = 0; i < effects.numoperands; i++) { - var = IRO_FindVar(effects.operands[i].object, 0, 1); - switch (effects.operands[i].type) { - case IAEffect_0: - MakeUse(var, linear, node); - break; - case IAEffect_1: - MakeDef( - var, - linear, - node, - (effects.operands[i].offset == 0) && (effects.operands[i].size == var->object->type->size) - ); - break; - case IAEffect_2: - MakeDef(var, linear, node, 0); - break; - case IAEffect_4: - MakeUse(var, linear, node); - MakeDef( - var, - linear, - node, - (effects.operands[i].offset == 0) && (effects.operands[i].size == var->object->type->size) - ); - break; - } - } - } - - if (linear == node->last) - break; - } - } - - for (var = IRO_FirstVar; var; var = var->next) - MakeDef(var, NULL, NULL, 1); -} - -static void MarkUses(Object *obj) { - VarRecord *var; - IRODef *def; - - if ((var = IRO_FindVar(obj, 0, 1))) { - for (def = var->defs; def; def = def->varnext) { - if (Bv_IsBitSet(def->index, Reaches)) { - Bv_SetBit(def->index, MightReachAnyUse); - def->x18++; - } - } - - var->xC = 1; - } -} - -static Boolean IsIncOrDec(IROLinear *linear) { - switch (linear->type) { - case IROLinearOp1Arg: - if (linear->nodetype == EPOSTINC || linear->nodetype == EPOSTDEC || linear->nodetype == EPREINC || linear->nodetype == EPREDEC) { - if (!(linear->u.monadic->flags & IROLF_BitfieldIndirect)) - return 1; - } - break; - case IROLinearOp2Arg: - if (linear->nodetype == EADDASS || linear->nodetype == ESUBASS) { - if (IRO_IsIntConstant(linear->u.diadic.right) && !(linear->u.diadic.left->flags & IROLF_BitfieldIndirect)) - return 1; - } - break; - } - - return 0; -} - -static Boolean IsOtherSelfAssignment(IROLinear *linear) { - switch (linear->type) { - case IROLinearOp2Arg: - switch (linear->nodetype) { - case EMULASS: - case EDIVASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - if (IRO_IsIntConstant(linear->u.diadic.right)) - return 1; - break; - } - break; - } - - return 0; -} - -CInt64 IRO_GetSelfAssignmentVal(IROLinear *linear) { - CInt64 result; - - if (linear->type == IROLinearOp1Arg) { - switch (linear->nodetype) { - case EPOSTINC: - case EPREINC: - CInt64_SetLong(&result, 1); - break; - case EPOSTDEC: - case EPREDEC: - CInt64_SetLong(&result, -1); - break; - default: - CError_FATAL(445); - } - - if (IS_TYPE_POINTER_ONLY(linear->rtype)) { - CInt64 mul; - CInt64_SetLong(&mul, TPTR_TARGET(linear->rtype)->size); - result = CInt64_Mul(result, mul); - } - } else if (linear->type == IROLinearOp2Arg) { - switch (linear->nodetype) { - case EMULASS: - case EDIVASS: - case EMODASS: - case EADDASS: - case ESHLASS: - case ESHRASS: - case EANDASS: - case EXORASS: - case EORASS: - result = linear->u.diadic.right->u.node->data.intval; - break; - case ESUBASS: - result = linear->u.diadic.right->u.node->data.intval; - result = CInt64_Neg(result); - break; - default: - CError_FATAL(491); - } - } else { - CError_FATAL(496); - } - - return result; -} - -static void UpdateUse(IROLinear *linear, CInt64 val, Type *type) { - IROLinear *father; - IROLinear *repl; - IROLinear *newdiadic; - - if ((father = IRO_LocateFather(linear))) { - switch (father->type) { - case IROLinearOp1Arg: - switch (father->nodetype) { - case EPOSTINC: - case EPOSTDEC: - case EPREINC: - case EPREDEC: - val = CInt64_Add(val, IRO_GetSelfAssignmentVal(father)); - father->nodetype = EADDASS; - father->type = IROLinearOp2Arg; - repl = IRO_NewIntConst(val, type); - father->u.diadic.right = repl; - IRO_PasteAfter(repl, repl, linear); - return; - } - break; - case IROLinearOp2Arg: - if (IRO_IsIntConstant(father->u.diadic.right)) { - switch (father->nodetype) { - case EADD: - case EADDASS: - father->u.diadic.right->u.node->data.intval = CInt64_Add( - father->u.diadic.right->u.node->data.intval, val); - return; - case ESUB: - case ESUBASS: - father->u.diadic.right->u.node->data.intval = CInt64_Sub( - father->u.diadic.right->u.node->data.intval, val); - return; - } - } - break; - } - } - - repl = IRO_NewIntConst(val, type); - newdiadic = IRO_NewLinear(IROLinearOp2Arg); - newdiadic->index = ++IRO_NumLinear; - newdiadic->nodetype = EADD; - newdiadic->u.diadic.left = linear; - newdiadic->u.diadic.right = repl; - newdiadic->rtype = linear->rtype; - repl->next = newdiadic; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(linear, newdiadic); - IRO_PasteAfter(repl, newdiadic, linear); -} - -void IRO_InitializeNonAssignmentOpArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - IRO_NonAssignmentOp[i] = MAXEXPR; - - IRO_NonAssignmentOp[EPOSTINC] = MAXEXPR; - IRO_NonAssignmentOp[EPOSTDEC] = MAXEXPR; - IRO_NonAssignmentOp[EPREINC] = MAXEXPR; - IRO_NonAssignmentOp[EPREDEC] = MAXEXPR; - IRO_NonAssignmentOp[EINDIRECT] = MAXEXPR; - IRO_NonAssignmentOp[EMONMIN] = MAXEXPR; - IRO_NonAssignmentOp[EBINNOT] = MAXEXPR; - IRO_NonAssignmentOp[ELOGNOT] = MAXEXPR; - IRO_NonAssignmentOp[EFORCELOAD] = MAXEXPR; - IRO_NonAssignmentOp[EMUL] = MAXEXPR; - IRO_NonAssignmentOp[EMULV] = MAXEXPR; - IRO_NonAssignmentOp[EDIV] = MAXEXPR; - IRO_NonAssignmentOp[EMODULO] = MAXEXPR; - IRO_NonAssignmentOp[EADDV] = MAXEXPR; - IRO_NonAssignmentOp[ESUBV] = MAXEXPR; - IRO_NonAssignmentOp[EADD] = MAXEXPR; - IRO_NonAssignmentOp[ESUB] = MAXEXPR; - IRO_NonAssignmentOp[ESHL] = MAXEXPR; - IRO_NonAssignmentOp[ESHR] = MAXEXPR; - IRO_NonAssignmentOp[ELESS] = MAXEXPR; - IRO_NonAssignmentOp[EGREATER] = MAXEXPR; - IRO_NonAssignmentOp[ELESSEQU] = MAXEXPR; - IRO_NonAssignmentOp[EGREATEREQU] = MAXEXPR; - IRO_NonAssignmentOp[EEQU] = MAXEXPR; - IRO_NonAssignmentOp[ENOTEQU] = MAXEXPR; - IRO_NonAssignmentOp[EAND] = MAXEXPR; - IRO_NonAssignmentOp[EXOR] = MAXEXPR; - IRO_NonAssignmentOp[EOR] = MAXEXPR; - IRO_NonAssignmentOp[ELAND] = MAXEXPR; - IRO_NonAssignmentOp[ELOR] = MAXEXPR; - IRO_NonAssignmentOp[EASS] = MAXEXPR; - IRO_NonAssignmentOp[EMULASS] = EMUL; - IRO_NonAssignmentOp[EDIVASS] = EDIV; - IRO_NonAssignmentOp[EMODASS] = EMODULO; - IRO_NonAssignmentOp[EADDASS] = EADD; - IRO_NonAssignmentOp[ESUBASS] = ESUB; - IRO_NonAssignmentOp[ESHLASS] = ESHL; - IRO_NonAssignmentOp[ESHRASS] = ESHR; - IRO_NonAssignmentOp[EANDASS] = EAND; - IRO_NonAssignmentOp[EXORASS] = EXOR; - IRO_NonAssignmentOp[EORASS] = EOR; - IRO_NonAssignmentOp[ECOMMA] = MAXEXPR; - IRO_NonAssignmentOp[EPMODULO] = MAXEXPR; - IRO_NonAssignmentOp[EROTL] = MAXEXPR; - IRO_NonAssignmentOp[EROTR] = MAXEXPR; - IRO_NonAssignmentOp[EBCLR] = MAXEXPR; - IRO_NonAssignmentOp[EBTST] = MAXEXPR; - IRO_NonAssignmentOp[EBSET] = MAXEXPR; - IRO_NonAssignmentOp[ETYPCON] = MAXEXPR; - IRO_NonAssignmentOp[EBITFIELD] = MAXEXPR; - IRO_NonAssignmentOp[EINTCONST] = MAXEXPR; - IRO_NonAssignmentOp[EFLOATCONST] = MAXEXPR; - IRO_NonAssignmentOp[ESTRINGCONST] = MAXEXPR; - IRO_NonAssignmentOp[ECOND] = MAXEXPR; - IRO_NonAssignmentOp[EFUNCCALL] = MAXEXPR; - IRO_NonAssignmentOp[EFUNCCALLP] = MAXEXPR; - IRO_NonAssignmentOp[EOBJREF] = MAXEXPR; - IRO_NonAssignmentOp[EMFPOINTER] = MAXEXPR; - IRO_NonAssignmentOp[ENULLCHECK] = MAXEXPR; - IRO_NonAssignmentOp[EPRECOMP] = MAXEXPR; - IRO_NonAssignmentOp[ETEMP] = MAXEXPR; - IRO_NonAssignmentOp[EARGOBJ] = MAXEXPR; - IRO_NonAssignmentOp[ELOCOBJ] = MAXEXPR; - IRO_NonAssignmentOp[ELABEL] = MAXEXPR; - IRO_NonAssignmentOp[ESETCONST] = MAXEXPR; - IRO_NonAssignmentOp[ENEWEXCEPTION] = MAXEXPR; - IRO_NonAssignmentOp[ENEWEXCEPTIONARRAY] = MAXEXPR; - IRO_NonAssignmentOp[EOBJLIST] = MAXEXPR; - IRO_NonAssignmentOp[EMEMBER] = MAXEXPR; - IRO_NonAssignmentOp[ETEMPLDEP] = MAXEXPR; - IRO_NonAssignmentOp[EINSTRUCTION] = MAXEXPR; - IRO_NonAssignmentOp[EDEFINE] = MAXEXPR; - IRO_NonAssignmentOp[EREUSE] = MAXEXPR; - IRO_NonAssignmentOp[EASSBLK] = MAXEXPR; - IRO_NonAssignmentOp[EVECTOR128CONST] = MAXEXPR; - IRO_NonAssignmentOp[ECONDASS] = MAXEXPR; -} - -void IRO_InitializeAssignmentFoldingFunctionArray(void) { - int i; - - for (i = 0; i < MAXEXPR; i++) - AssignmentFoldingFunction[i] = NULL; - - AssignmentFoldingFunction[EPOSTINC] = NULL; - AssignmentFoldingFunction[EPOSTDEC] = NULL; - AssignmentFoldingFunction[EPREINC] = NULL; - AssignmentFoldingFunction[EPREDEC] = NULL; - AssignmentFoldingFunction[EINDIRECT] = NULL; - AssignmentFoldingFunction[EMONMIN] = NULL; - AssignmentFoldingFunction[EBINNOT] = NULL; - AssignmentFoldingFunction[ELOGNOT] = NULL; - AssignmentFoldingFunction[EFORCELOAD] = NULL; - AssignmentFoldingFunction[EMUL] = NULL; - AssignmentFoldingFunction[EMULV] = NULL; - AssignmentFoldingFunction[EDIV] = NULL; - AssignmentFoldingFunction[EMODULO] = NULL; - AssignmentFoldingFunction[EADDV] = NULL; - AssignmentFoldingFunction[ESUBV] = NULL; - AssignmentFoldingFunction[EADD] = NULL; - AssignmentFoldingFunction[ESUB] = NULL; - AssignmentFoldingFunction[ESHL] = NULL; - AssignmentFoldingFunction[ESHR] = NULL; - AssignmentFoldingFunction[ELESS] = NULL; - AssignmentFoldingFunction[EGREATER] = NULL; - AssignmentFoldingFunction[ELESSEQU] = NULL; - AssignmentFoldingFunction[EGREATEREQU] = NULL; - AssignmentFoldingFunction[EEQU] = NULL; - AssignmentFoldingFunction[ENOTEQU] = NULL; - AssignmentFoldingFunction[EAND] = NULL; - AssignmentFoldingFunction[EXOR] = NULL; - AssignmentFoldingFunction[EOR] = NULL; - AssignmentFoldingFunction[ELAND] = NULL; - AssignmentFoldingFunction[ELOR] = NULL; - AssignmentFoldingFunction[EASS] = NULL; - AssignmentFoldingFunction[EMULASS] = CInt64_Mul; - AssignmentFoldingFunction[EDIVASS] = CInt64_Mul; - AssignmentFoldingFunction[EMODASS] = NULL; - AssignmentFoldingFunction[EADDASS] = CInt64_Add; - AssignmentFoldingFunction[ESUBASS] = CInt64_Add; - AssignmentFoldingFunction[ESHLASS] = CInt64_Add; - AssignmentFoldingFunction[ESHRASS] = CInt64_Add; - AssignmentFoldingFunction[EANDASS] = CInt64_And; - AssignmentFoldingFunction[EXORASS] = CInt64_Xor; - AssignmentFoldingFunction[EORASS] = CInt64_Or; - AssignmentFoldingFunction[ECOMMA] = NULL; - AssignmentFoldingFunction[EPMODULO] = NULL; - AssignmentFoldingFunction[EROTL] = NULL; - AssignmentFoldingFunction[EROTR] = NULL; - AssignmentFoldingFunction[EBCLR] = NULL; - AssignmentFoldingFunction[EBTST] = NULL; - AssignmentFoldingFunction[EBSET] = NULL; - AssignmentFoldingFunction[ETYPCON] = NULL; - AssignmentFoldingFunction[EBITFIELD] = NULL; - AssignmentFoldingFunction[EINTCONST] = NULL; - AssignmentFoldingFunction[EFLOATCONST] = NULL; - AssignmentFoldingFunction[ESTRINGCONST] = NULL; - AssignmentFoldingFunction[ECOND] = NULL; - AssignmentFoldingFunction[EFUNCCALL] = NULL; - AssignmentFoldingFunction[EFUNCCALLP] = NULL; - AssignmentFoldingFunction[EOBJREF] = NULL; - AssignmentFoldingFunction[EMFPOINTER] = NULL; - AssignmentFoldingFunction[ENULLCHECK] = NULL; - AssignmentFoldingFunction[EPRECOMP] = NULL; - AssignmentFoldingFunction[ETEMP] = NULL; - AssignmentFoldingFunction[EARGOBJ] = NULL; - AssignmentFoldingFunction[ELOCOBJ] = NULL; - AssignmentFoldingFunction[ELABEL] = NULL; - AssignmentFoldingFunction[ESETCONST] = NULL; - AssignmentFoldingFunction[ENEWEXCEPTION] = NULL; - AssignmentFoldingFunction[ENEWEXCEPTIONARRAY] = NULL; - AssignmentFoldingFunction[EOBJLIST] = NULL; - AssignmentFoldingFunction[EMEMBER] = NULL; - AssignmentFoldingFunction[ETEMPLDEP] = NULL; - AssignmentFoldingFunction[EINSTRUCTION] = NULL; - AssignmentFoldingFunction[EDEFINE] = NULL; - AssignmentFoldingFunction[EREUSE] = NULL; - AssignmentFoldingFunction[EASSBLK] = NULL; - AssignmentFoldingFunction[EVECTOR128CONST] = NULL; - AssignmentFoldingFunction[ECONDASS] = NULL; -} - -static void UpdateUseForOtherSelfAssignment(IROLinear *a, IROLinear *b, Type *type) { - CInt64 val; - IROLinear *father; - IROLinear *repl; - IROLinear *newdiadic; - - val = IRO_GetSelfAssignmentVal(b); - if ((father = IRO_LocateFather(a)) && father->type == IROLinearOp2Arg && IRO_IsIntConstant(father->u.diadic.right)) { - CInt64 var_30 = father->u.diadic.right->u.node->data.intval; - if (AssignmentFoldingFunction[b->nodetype] && ((father->nodetype == b->nodetype) || (father->nodetype == IRO_NonAssignmentOp[b->nodetype]))) { - CInt64 v; - CInt64 folded; - CInt64_SetLong(&v, b->rtype->size * 8); - folded = AssignmentFoldingFunction[b->nodetype](var_30, val); - if (b->nodetype == ESHRASS && !is_unsigned(b->rtype)) { - if (CInt64_LessU(var_30, v) && CInt64_LessU(val, v)) { - if (CInt64_GreaterEqualU(folded, v)) - folded = CInt64_Sub(v, cint64_one); - father->u.diadic.right->u.node->data.intval = folded; - return; - } - } else { - father->u.diadic.right->u.node->data.intval = folded; - return; - } - } else { - switch (b->nodetype) { - case EMULASS: - if (father->nodetype == ESHL || father->nodetype == ESHLASS) { - SInt32 powvalue; - if (IRO_IsPow2(b->u.diadic.right, &powvalue)) { - if (powvalue > 0) { - CInt64 v; - CInt64_SetLong(&v, powvalue); - father->u.diadic.right->u.node->data.intval = CInt64_Add(v, var_30); - } - } else { - father->nodetype = (father->nodetype == ESHL) ? EMUL : EMULASS; - var_30 = CInt64_Shl(cint64_one, var_30); - father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val); - } - return; - } - break; - case EDIVASS: - if ((father->nodetype == ESHR || father->nodetype == ESHRASS) && is_unsigned(father->rtype)) { - SInt32 powvalue; - if (IRO_IsPow2(b->u.diadic.right, &powvalue)) { - if (powvalue > 0) { - CInt64 v; - CInt64_SetLong(&v, powvalue); - father->u.diadic.right->u.node->data.intval = CInt64_Add(v, var_30); - } - } else { - father->nodetype = (father->nodetype == ESHR) ? EDIV : EDIVASS; - var_30 = CInt64_Shl(cint64_one, var_30); - father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val); - } - return; - } - break; - case ESHLASS: - if (father->nodetype == EMUL || father->nodetype == EMULASS) { - SInt32 powvalue; - if (IRO_IsPow2(father->u.diadic.right, &powvalue)) { - if (powvalue > 0) { - CInt64 v; - father->nodetype = (father->nodetype == EMUL) ? ESHL : ESHLASS; - CInt64_SetLong(&v, powvalue); - father->u.diadic.right->u.node->data.intval = CInt64_Add(v, val); - } - } else { - val = CInt64_Shl(cint64_one, val); - father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val); - } - return; - } else if (father->nodetype == ESHR || father->nodetype == ESHRASS) { - if (CInt64_Equal(var_30, val) && is_unsigned(father->rtype)) { - father->nodetype = (father->nodetype == ESHR) ? EAND : EANDASS; - if (father->rtype->size < 8) { - CInt64 v; - CInt64_SetLong(&v, 64 - (father->rtype->size * 8)); - val = CInt64_Add(val, v); - } - father->u.diadic.right->u.node->data.intval = CInt64_ShrU(cint64_negone, val); - return; - } - } - break; - case ESHRASS: - if ((father->nodetype == EDIV || father->nodetype == EDIVASS) && is_unsigned(father->rtype)) { - SInt32 powvalue; - if (IRO_IsPow2(father->u.diadic.right, &powvalue)) { - if (powvalue > 0) { - CInt64 v; - father->nodetype = (father->nodetype == EDIV) ? ESHR : ESHRASS; - CInt64_SetLong(&v, powvalue); - father->u.diadic.right->u.node->data.intval = CInt64_Add(v, val); - } - } else { - val = CInt64_Shl(cint64_one, val); - father->u.diadic.right->u.node->data.intval = CInt64_Mul(var_30, val); - } - return; - } else if (father->nodetype == ESHL || father->nodetype == ESHLASS) { - if (CInt64_Equal(var_30, val)) { - father->nodetype = (father->nodetype == ESHL) ? EAND : EANDASS; - father->u.diadic.right->u.node->data.intval = CInt64_Shl(cint64_negone, val); - return; - } - } - break; - } - } - } - - repl = IRO_NewIntConst(val, type); - newdiadic = IRO_NewLinear(IROLinearOp2Arg); - newdiadic->index = ++IRO_NumLinear; - newdiadic->nodetype = IRO_NonAssignmentOp[b->nodetype]; - newdiadic->u.diadic.left = a; - newdiadic->u.diadic.right = repl; - newdiadic->rtype = a->rtype; - repl->next = newdiadic; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(a, newdiadic); - IRO_PasteAfter(repl, newdiadic, a); -} - -static Boolean PropagateIncsAndDecs(void) { - IRODef *def; - Boolean result; - - result = 0; - def = FirstDef; - while (def) { - if ( - def->linear && - def->x1C && - IsIncOrDec(def->linear) && - !(def->linear->flags & IROLF_Reffed) && - (IS_TYPE_INT_OR_ENUM(def->linear->rtype) || IS_TYPE_POINTER_ONLY(def->linear->rtype)) && - IRO_TypesEqual(def->linear->rtype, def->var->object->type) && - !is_volatile_object(def->var->object) - ) { - IROUse *use; - IROUse *use2; - IROLinear *father; - CInt64 val; - SInt32 i; - Type *type; - - for (use = def->var->uses, i = 0; use; use = use->varnext) { - if (Bv_IsBitSet(def->index, use->x18)) { - if ( - use->x1C == 1 && - use->linear->type == IROLinearOperand && - (father = IRO_LocateFather(use->linear)) && - IRO_IsVariable(father) && - IRO_TypesEqual(def->linear->rtype, father->rtype) - ) { - if (use->linear->flags & IROLF_Assigned) { - if (!((father = IRO_LocateFather(father)) && IsIncOrDec(father) && !(father->flags & IROLF_Reffed))) - goto nextDef; - } - i++; - } else { - goto nextDef; - } - } - } - - if (i == def->x18) { - for (use = def->var->uses; use; use = use->varnext) { - if (Bv_IsBitSet(def->index, use->x18)) { - IRO_Dump("Propagating inc/dec from %d to %d\n", def->linear->index, use->linear->index); - father = IRO_LocateFather(use->linear); - val = IRO_GetSelfAssignmentVal(def->linear); - type = def->linear->rtype; - if (IS_TYPE_POINTER_ONLY(def->linear->rtype)) - type = TYPE(&stunsignedlong); - UpdateUse(father, val, type); - - result = 1; - for (use2 = def->var->uses; use2; use2 = use2->varnext) { - if (use2->linear == def->linear->u.monadic->u.diadic.left) { - use->x1C = use2->x1C; - Bv_Copy(use2->x18, use->x18); - break; - } - } - } - } - def->x18 = 0; - IRO_NopNonSideEffects(def->linear, -1); - def->linear->type = IROLinearNop; - IRO_Dump("Removing deadddd assignment %d\n", def->linear->index); - } - } - nextDef: - def = def->globalnext; - } - - return result; -} - -static Boolean PropagateOtherSelfAssignments(void) { - IRODef *def; - Boolean result; - - result = 0; - - def = FirstDef; - while (def) { - if ( - def->linear && - def->x1C && - IsOtherSelfAssignment(def->linear) && - !(def->linear->flags & IROLF_Reffed) && - IS_TYPE_INT_OR_ENUM(def->linear->rtype) && - IRO_TypesEqual(def->linear->rtype, def->var->object->type) && - !is_volatile_object(def->var->object) - ) - { - IROUse *use; - IROUse *use2; - IROLinear *father; - SInt32 i; - Type *type; - - for (use = def->var->uses, i = 0; use; use = use->varnext) { - if (Bv_IsBitSet(def->index, use->x18)) { - if ( - use->x1C == 1 && - use->linear->type == IROLinearOperand && - (father = IRO_LocateFather(use->linear)) && - IRO_IsVariable(father) && - IRO_TypesEqual(def->linear->rtype, father->rtype) - ) { - if (use->linear->flags & IROLF_Assigned) { - if (!((father = IRO_LocateFather(father)) && IsOtherSelfAssignment(father) && (father->nodetype == def->linear->nodetype) && !(father->flags & IROLF_Reffed))) - goto nextDef; - } - i++; - } else { - goto nextDef; - } - } - } - - if (i == def->x18) { - for (use = def->var->uses; use; use = use->varnext) { - if (Bv_IsBitSet(def->index, use->x18)) { - IRO_Dump("Propagating self assignment from %d to %d\n", def->linear->index, use->linear->index); - father = IRO_LocateFather(use->linear); - UpdateUseForOtherSelfAssignment(father, def->linear, def->linear->rtype); - - result = 1; - for (use2 = def->var->uses; use2; use2 = use2->varnext) { - if (use2->linear == def->linear->u.monadic->u.diadic.left) { - use->x1C = use2->x1C; - Bv_Copy(use2->x18, use->x18); - break; - } - } - } - } - def->x18 = 0; - IRO_NopNonSideEffects(def->linear, -1); - def->linear->type = IROLinearNop; - IRO_Dump("Removing deadddd assignment %d\n", def->linear->index); - } - } - nextDef: - def = def->globalnext; - } - - return result; -} - -static void MarkUsesByIndirect(IROLinear *linear, BitVector *a, BitVector *b) { - IROListNode *list; - IROLinear *nd; - Object *obj; - VarRecord *var; - Boolean foundObjRef; - IROListNode *scan; - IRODef *def; - Boolean found; - - found = 0; - - if (linear && copts.opt_pointer_analysis && linear->pointsToFunction && FunctionName) { - IROListNode *resultList; - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, linear, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - found = 1; - break; - } - - foundObjRef = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundObjRef = 1; - break; - } - } - - if (!foundObjRef) { - found = 1; - break; - } - } - - if (!found) { - while (list) { - for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - obj = nd->u.node->data.objref; - CError_ASSERT(1422, obj != NULL); - var = IRO_FindVar(obj, 1, 1); - CError_ASSERT(1424, var != NULL); - - for (def = var->defs; def; def = def->varnext) { - if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) { - def->x18++; - Bv_SetBit(def->index, MightReachAnyUse); - } - } - } - } - list = list->nextList; - } - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - found = 1; - } - } else { - found = 1; - } - - if (found) { - Bv_Copy(Reaches, a); - Bv_And(b, a); - Bv_Or(a, MightReachAnyUse); - for (def = FirstDef; def; def = def->globalnext) { - if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) - def->x18++; - } - } -} - -static void MarkUsesByFunctionCall(IROLinear *linear, BitVector *a, BitVector *b) { - ObjectList *olist; - IROLinear *funcnd; - IROListNode *list; - IROLinear *nd; - Object *obj; - VarRecord *var; - Boolean foundObjRef; - IROListNode *scan; - IRODef *def; - Boolean found; - - found = 0; - - if ((funcnd = linear->u.funccall.linear8) && copts.opt_pointer_analysis && funcnd->pointsToFunction && FunctionName) { - IROListNode *resultList; - ObjectList *depsList; - - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, funcnd, &resultList); - if (resultList) { - for (scan = resultList; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - found = 1; - break; - } - - foundObjRef = 0; - for (nd = scan->list.head; nd != scan->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - foundObjRef = 1; - obj = nd->u.node->data.objref; - CError_ASSERT(1522, obj != NULL); - - depsList = NULL; - PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList); - for (olist = depsList; olist; olist = olist->next) { - if (!olist->object) { - found = 1; - break; - } - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - - if (found) - break; - } - } - - if (!foundObjRef) - found = 1; - if (found) - break; - } - - if (!found) { - for (list = resultList; list; list = list->nextList) { - for (nd = list->list.head; nd != list->list.tail->next; nd = nd->next) { - if (nd->type == IROLinearOperand && nd->u.node->type == EOBJREF) { - obj = nd->u.node->data.objref; - depsList = NULL; - PointerAnalysis_GetFunctionDependencies(obj, linear, &depsList); - - for (olist = depsList; olist; olist = olist->next) { - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(1573, var != NULL); - - for (def = var->defs; def; def = def->varnext) { - if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) { - def->x18++; - Bv_SetBit(def->index, MightReachAnyUse); - } - } - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - } - } - } - } - - while (resultList) { - IROListNode *next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - found = 1; - } - } else { - found = 1; - } - - if (found) { - Bv_Copy(Reaches, a); - Bv_And(b, a); - Bv_Or(a, MightReachAnyUse); - for (def = FirstDef; def; def = def->globalnext) { - if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) - def->x18++; - } - } - - if (linear->stmt && IRO_FunctionCallMightThrowException(linear)) - IRO_WalkExcActions(linear->stmt->dobjstack, MarkUses); -} - -static Boolean UseOfVarIsInsideASimpleDefOfVar(IROUse *use) { - VarRecord *var; - VarRecord *varAss; - IROLinear *nd; - IROLinear *nd2; - - if ((var = use->var)) { - if ((nd = use->linear) && (nd->flags & IROLF_4000)) - return 0; - - while (nd && (nd->flags & IROLF_Reffed)) - nd = nd->next; - - if ( - nd && - IRO_IsAssignment(nd) && - (varAss = IRO_FindAssigned(nd)) && - varAss == var && - !IRO_HasSideEffect((nd->type == IROLinearOp1Arg) ? nd->u.monadic : nd->u.diadic.left) && - (!(nd2 = (nd->type == IROLinearOp1Arg) ? NULL : nd->u.diadic.right) || !IRO_HasSideEffect(nd2)) - ) { - return 1; - } - } - - return 0; -} - -static Boolean AllLoopDefUsesAreInSimpleLoopDefs(IRODef *def) { - VarRecord *var; - IRODef *scan; - IROUse *use; - - if ((var = def->var)) { - for (scan = var->defs; scan; scan = scan->varnext) { - if (scan->node && scan->node->loopdepth) { - for (use = var->uses; use; use = use->varnext) { - if (Bv_IsBitSet(scan->index, use->x18)) { - if (!use->node || !use->node->loopdepth || !UseOfVarIsInsideASimpleDefOfVar(use)) - return 0; - } - } - } - } - return 1; - } else { - return 0; - } -} - -static void MarkRemovableLoopDefs(void) { - IRODef *def; - IRODef *scan; - - for (def = FirstDef; def; def = def->globalnext) { - if (!def->x1A && !def->x1B && def->node && def->node->loopdepth && !def->x1D && - AllLoopDefUsesAreInSimpleLoopDefs(def) && def->var) { - for (scan = def->var->defs; scan; scan = scan->varnext) { - if (scan->node && scan->node->loopdepth) - scan->x1D = 1; - } - } - } -} - -static Boolean EliminateReffedDeadStore(IRODef *def) { - Boolean isPostIncOrDec; - IROLinear *nd; - Boolean result; - - nd = def->linear; - isPostIncOrDec = (nd->type == IROLinearOp1Arg) && (nd->nodetype == EPOSTINC || nd->nodetype == EPOSTDEC); - - result = IRO_LocateFather(nd) != NULL; - if (result && IRO_IsAssignment(nd) && IRO_IsModifyOp[nd->nodetype]) - result = IRO_TransformSelfAssignmentToAssignment(nd); - result = result && (nd->type == IROLinearOp2Arg) && (nd->nodetype == EASS); - - if (result) { - def->x18 = 0; - IRO_Dump("Removing referenced dead assignment %d\n", nd->index); - - if (isPostIncOrDec) { - IRO_NopNonSideEffects(nd->u.diadic.right, 0); - nd->type = IROLinearNop; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, nd->u.diadic.left); - } else { - IRO_NopNonSideEffects(nd->u.diadic.left, 0); - nd->type = IROLinearNop; - IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, nd->u.diadic.right); - } - } - - return result; -} - -Boolean IRO_UseDef(Boolean optDeadAssignments, Boolean optPropagation) { - Boolean result; - IRODef *gdef; - IROUse *guse; - IRODef *def; - IROUse *use; - IRONode *node; - IROLinear *nd; - VarRecord *var; - Boolean flag; - BitVector *bv3; - BitVector *bv2; - BitVector *bv; - int i; - - FindDefsAndUses(); - - IRO_CheckForUserBreak(); - - for (use = IRO_FirstVarUse; use; use = use->globalnext) - Bv_AllocVector(&use->x18, NumDefs); - Bv_AllocVector(&MightReachAnyUse, NumDefs); - Bv_AllocVector(&bv, NumDefs); - - IRO_CheckForUserBreak(); - - for (def = FirstDef; def; def = def->globalnext) { - if (def->x1A || def->x1B) - Bv_SetBit(def->index, bv); - } - - Bv_AllocVector(&bv2, NumDefs); - gdef = FirstDef; - for (node = IRO_FirstNode; node; node = node->nextnode) { - Bv_AllocVector(&node->x16, NumDefs); - Bv_AllocVector(&node->x1E, NumDefs); - Bv_AllocVector(&node->x22, NumDefs); - Bv_AllocVector(&node->x1A, NumDefs); - - for (nd = node->first; nd; nd = nd->next) { - while (gdef && gdef->linear == nd) { - Bv_SetBit(gdef->index, node->x1E); - if (gdef->x1C) { - for (def = gdef->var->defs; def; def = def->varnext) { - if (def != gdef) { - Bv_SetBit(def->index, node->x22); - Bv_ClearBit(def->index, node->x1E); - } - } - } - gdef = gdef->globalnext; - } - if (nd == node->last) - break; - } - - if (node->numpred) - Bv_Set(node->x16); - Bv_Copy(node->x1E, node->x1A); - IRO_CheckForUserBreak(); - } - - Bv_AllocVector(&bv3, NumDefs); - - do { - flag = 0; - for (node = IRO_FirstNode; node; node = node->nextnode) { - Bv_Clear(node->x16); - if (node->numpred) { - for (i = 0; i < node->numpred; i++) - Bv_Or(IRO_NodeTable[node->pred[i]]->x1A, node->x16); - } else if (node == IRO_FirstNode) { - for (var = IRO_FirstVar; var; var = var->next) - Bv_SetBit(var->defs->index, node->x16); - } - Bv_Copy(node->x16, bv3); - Bv_Minus(node->x22, bv3); - Bv_Or(node->x1E, bv3); - if (!Bv_Compare(bv3, node->x1A)) { - Bv_Copy(bv3, node->x1A); - flag = 1; - } - } - - IRO_CheckForUserBreak(); - } while (flag); - - gdef = FirstDef; - guse = IRO_FirstVarUse; - Bv_AllocVector(&Reaches, NumDefs); - - for (node = IRO_FirstNode; node; node = node->nextnode) { - Bv_Copy(node->x16, Reaches); - nd = node->first; - while (1) { - while (guse && guse->linear == nd) { - for (def = guse->var->defs; def; def = def->varnext) { - if (Bv_IsBitSet(def->index, Reaches)) { - Bv_SetBit(def->index, guse->x18); - Bv_SetBit(def->index, MightReachAnyUse); - def->x18++; - guse->x1C++; - } - } - guse = guse->globalnext; - } - - if (nd->type == IROLinearFunccall) { - MarkUsesByFunctionCall(nd, bv2, bv); - } else if (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT && !IRO_IsVariable(nd)) { - MarkUsesByIndirect(nd, bv2, bv); - } else if ((nd->type == IROLinearFunccall) || - (nd->type == IROLinearOp1Arg && nd->nodetype == EINDIRECT && !IRO_IsVariable(nd))) { - Bv_Copy(Reaches, bv2); - Bv_And(bv, bv2); - Bv_Or(bv2, MightReachAnyUse); - for (def = FirstDef; def; def = def->globalnext) { - if (def->x1A || (def->x1B && Bv_IsBitSet(def->index, Reaches))) - def->x18++; - } - if (nd->type == IROLinearFunccall && nd->stmt && IRO_FunctionCallMightThrowException(nd)) - IRO_WalkExcActions(nd->stmt->dobjstack, MarkUses); - } - - if (nd->type == IROLinearAsm) { - IAEffects effects; - CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects); - if (effects.x2) { - Bv_Copy(Reaches, bv2); - Bv_And(bv, bv2); - Bv_Or(bv2, MightReachAnyUse); - } - } - - if (nd->type == IROLinearReturn || nd->type == IROLinearEnd) { - for (def = FirstDef; def; def = def->globalnext) { - if (def->x1A && Bv_IsBitSet(def->index, Reaches)) { - Bv_SetBit(def->index, MightReachAnyUse); - def->x18++; - } - } - } - - while (gdef && gdef->linear == nd) { - if (gdef->x1C) { - for (def = gdef->var->defs; def; def = def->varnext) - Bv_ClearBit(def->index, Reaches); - } - Bv_SetBit(gdef->index, Reaches); - gdef = gdef->globalnext; - } - - if (nd == node->last) - break; - nd = nd->next; - } - } - - IRO_CheckForUserBreak(); - - result = 0; - - if (optDeadAssignments) { - MarkRemovableLoopDefs(); - for (def = FirstDef; def; def = def->globalnext) { - if (def->linear && - (!Bv_IsBitSet(def->index, MightReachAnyUse) || def->x1D) && - (copts.opt_pointer_analysis || !def->x1B) && - def->linear->type != IROLinearAsm && - (!def->linear->rtype || !CParser_IsVolatile(def->linear->rtype, def->linear->nodeflags & ENODE_FLAG_QUALS)) && - !is_volatile_object(def->var->object) - ) { - if (!(def->linear->flags & IROLF_Reffed)) { - def->x18 = 0; - IRO_NopNonSideEffects(def->linear, -1); - def->linear->type = IROLinearNop; - IRO_Dump("Removing dead assignment %d\n", def->linear->index); - result = 1; - } else { - result = EliminateReffedDeadStore(def); - } - } - } - } - - IRO_CheckForUserBreak(); - - if (optPropagation) { - while (1) { - if (PropagateIncsAndDecs() || PropagateOtherSelfAssignments()) - result = 1; - else - break; - } - } - - IRO_CheckForUserBreak(); - - return result; -} - -static IROLinear *GetOperand(IROLinear *nd) { - IROLinear *inner; - - if (nd->type == IROLinearOperand) - return nd; - - if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD) { - inner = GetOperand(nd->u.diadic.left); - if (!inner) - inner = GetOperand(nd->u.diadic.right); - return inner; - } - - return NULL; -} - -static IROLinear *GetAssigned(IROLinear *nd) { - if (!nd) - return NULL; - - if (nd->type == IROLinearOp2Arg) - nd = nd->u.diadic.left; - else if (nd->type == IROLinearOp1Arg) - nd = nd->u.monadic; - else - CError_FATAL(2338); - - if (nd->type != IROLinearOp1Arg || nd->nodetype != EINDIRECT) - CError_FATAL(2351); - - nd = nd->u.monadic; - - if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD) - nd = GetOperand(nd); - - return nd; -} - -static void AddUseToRange(IROUse *use) { - IRODef *def; - - Bv_SetBit(use->index, useset); - Bv_ClearBit(use->index, alluses); - - for (def = use->var->defs; def; def = def->varnext) { - if (Bv_IsBitSet(def->index, alldefs) && (Bv_IsBitSet(def->index, use->x18) || GetAssigned(def->linear) == use->linear)) - AddDefToRange(def); - } -} - -static void AddDefToRange(IRODef *def) { - IROUse *use; - IROLinear *assigned; - - Bv_SetBit(def->index, defset); - Bv_ClearBit(def->index, alldefs); - - for (use = def->var->uses, assigned = GetAssigned(def->linear); use; use = use->varnext) { - if (Bv_IsBitSet(use->index, alluses) && (Bv_IsBitSet(def->index, use->x18) || assigned == use->linear)) - AddUseToRange(use); - } -} - -static void ReplaceAssigned(IROLinear *nd, Object *from, Object *to) { - IROLinear *assigned; - - if ( - !(assigned = GetAssigned(nd)) || - assigned->type != IROLinearOperand || - assigned->u.node->type != EOBJREF || - assigned->u.node->data.objref != from - ) - CError_FATAL(2459); - - assigned->u.node->data.objref = to; -} - -static void ReplaceUsed(IROLinear *nd, Object *from, Object *to) { - CError_ASSERT(2482, nd->type == IROLinearOperand && nd->u.node->type == EOBJREF); - - if (nd->u.node->data.objref == from) - nd->u.node->data.objref = to; - else if (nd->u.node->data.objref != to) - CError_FATAL(2494); -} - -static void SplitOffRange(VarRecord *var) { - Object *newObj; - IRODef *def; - IROUse *use; - - IRO_Dump("Splitting range for variable: %d\n", var->index); - IRO_DumpBits("Def set: ", defset); - IRO_DumpBits("Use set: ", useset); - IRO_DumpBits("All defs: ", alldefs); - IRO_DumpBits("All uses: ", alluses); - - newObj = create_temp_object(var->object->type); - IRO_FindVar(newObj, 1, 1); - - for (def = var->defs; def; def = def->varnext) { - if (Bv_IsBitSet(def->index, defset) && def->linear) - ReplaceAssigned(def->linear, var->object, newObj); - } - - for (use = var->uses; use; use = use->varnext) { - if (Bv_IsBitSet(use->index, useset)) - ReplaceUsed(use->linear, var->object, newObj); - } -} - -void IRO_SplitLifetimes(void) { - VarRecord *var; - SInt32 numVars; - IRODef *def; - IROUse *use; - Boolean flag; - - Bv_AllocVector(&alldefs, NumDefs); - Bv_AllocVector(&alluses, NumUses); - Bv_AllocVector(&defset, NumDefs); - Bv_AllocVector(&useset, NumUses); - - var = IRO_FirstVar; - numVars = IRO_NumVars; - - while (var && var->index <= numVars) { - if (var->object->datatype == DLOCAL && !is_volatile_object(var->object) && !var->xC && !var->xB && !var->x1E) { - Bv_Clear(alldefs); - Bv_Clear(alluses); - - for (def = var->defs; def; def = def->varnext) { - if (def->linear && def->linear->type == IROLinearAsm) - goto skipThisVar; - Bv_SetBit(def->index, alldefs); - } - - for (use = var->uses; use; use = use->varnext) { - if (use->linear && use->linear->type == IROLinearAsm) - goto skipThisVar; - Bv_SetBit(use->index, alluses); - } - - flag = 1; - while (1) { - Bv_Clear(defset); - Bv_Clear(useset); - - def = var->defs; - while (def && !Bv_IsBitSet(def->index, alldefs)) - def = def->varnext; - - if (!def) - break; - - AddDefToRange(def); - if (Bv_IsEmpty(alldefs)) - break; - - if (!flag) - SplitOffRange(var); - flag = 0; - } - } - - skipThisVar: - var = var->next; - } - - IRO_CheckForUserBreak(); -} |