diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/IroCSE.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-main.tar.gz MWCC-main.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/IroCSE.c')
-rw-r--r-- | compiler_and_linker/unsorted/IroCSE.c | 1038 |
1 files changed, 0 insertions, 1038 deletions
diff --git a/compiler_and_linker/unsorted/IroCSE.c b/compiler_and_linker/unsorted/IroCSE.c deleted file mode 100644 index 5fa9849..0000000 --- a/compiler_and_linker/unsorted/IroCSE.c +++ /dev/null @@ -1,1038 +0,0 @@ -#include "compiler/IroCSE.h" -#include "compiler/IroDump.h" -#include "compiler/IroFlowgraph.h" -#include "compiler/IroLinearForm.h" -#include "compiler/IroMalloc.h" -#include "compiler/IroPointerAnalysis.h" -#include "compiler/IroSubable.h" -#include "compiler/IROUseDef.h" -#include "compiler/IroUtil.h" -#include "compiler/IroVars.h" -#include "compiler/CError.h" -#include "compiler/CExpr.h" -#include "compiler/CInt64.h" -#include "compiler/CParser.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" - -BitVector *IRO_Depends; -Boolean IRO_NotSubable; -Boolean IRO_IsVolatile; -Boolean IRO_CouldError; -IROExpr *IRO_FirstExpr; -IROExpr *IRO_LastExpr; -SInt32 IRO_NumExprs; -static Boolean HasVectorOperand; - -// forward decls -static void IRO_DependsOnForDataFlow(IROLinear *linear, Boolean flag); - -static void GetDependsOfIndirect(IROLinear *nd) { - IROListNode *resultList; - IROListNode *next; - IROListNode *list; - IROListNode *scan; - IROLinear *scannd; - Object *obj; - VarRecord *var; - int index; - Boolean result; - Boolean foundObjRef; - - result = 0; - - if (nd && copts.opt_pointer_analysis && nd->pointsToFunction && FunctionName) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, nd, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 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) { - result = 1; - break; - } - } - - if (!result) { - while (list) { - 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(119, obj != NULL); - var = IRO_FindVar(obj, 1, 1); - CError_ASSERT(121, var != NULL); - index = var->index; - CError_ASSERT(123, index != 0); - - if (is_volatile_object(obj)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - Bv_SetBit(index, IRO_Depends); - } - } - list = list->nextList; - } - } - - while (resultList) { - next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) { - nd = nd->u.monadic; - if (nd->type == IROLinearOp1Arg && nd->nodetype == EBITFIELD) - nd = nd->u.monadic; - - if (nd->type == IROLinearOp2Arg && nd->nodetype == EADD) { - IRO_BaseTerms = 0; - IRO_VarTerms = 0; - IRO_DecomposeAddressExpression_Cheap(nd); - if (IRO_BaseTerms != 1) { - IRO_CouldError = 1; - Bv_SetBit(0, IRO_Depends); - Bv_Or(IRO_FuncKills, IRO_Depends); - } - if (IRO_VarTerms) - IRO_CouldError = 1; - } else { - IRO_CouldError = 1; - Bv_SetBit(0, IRO_Depends); - Bv_Or(IRO_FuncKills, IRO_Depends); - } - } -} - -static void GetDependsOfFunctionCallForDataFlow(IROLinear *nd) { - IROLinear *innernd; - IROListNode *resultList; - IROListNode *next; - IROListNode *list; - IROListNode *scan; - IROLinear *scannd; - Object *obj; - VarRecord *var; - int index; - Boolean result; - Boolean foundObjRef; - ObjectList *olist; - ObjectList *depsList; - - result = 0; - innernd = nd->u.funccall.linear8; - - if (innernd && copts.opt_pointer_analysis && innernd->pointsToFunction && FunctionName) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, innernd, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 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(234, obj != NULL); - - depsList = NULL; - PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList); - - for (olist = depsList; olist; olist = olist->next) { - if (!olist->object) { - result = 1; - break; - } - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - - if (result) - break; - } - } - - if (!foundObjRef) - result = 1; - if (result) - break; - } - - if (!result) { - 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; - - depsList = NULL; - PointerAnalysis_GetFunctionDependencies(obj, nd, &depsList); - - for (olist = depsList; olist; olist = olist->next) { - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(285, var != NULL); - index = var->index; - CError_ASSERT(287, index != 0); - - if (is_volatile_object(olist->object)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - Bv_SetBit(index, IRO_Depends); - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - } - } - } - } - - while (resultList) { - next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) { - IRO_DependsOnForDataFlow(nd->u.funccall.linear8, 0); - Bv_Or(IRO_FuncKills, IRO_Depends); - - for (index = nd->u.funccall.argCount - 1; index >= 0; index--) - IRO_DependsOnForDataFlow(nd->u.funccall.args[index], 0); - } -} - -static void IRO_DependsOn(IROLinear *linear, Boolean flag) { - VarRecord *var; - IROLinear *inner; - - if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - - if (!IRO_NotSubable) { - switch (linear->type) { - case IROLinearOperand: - if (flag && linear->u.node->type == EOBJREF) { - if ((var = IRO_FindVar(linear->u.node->data.objref, 0, 1))) { - if (is_volatile_object(var->object)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - Bv_SetBit(var->index, IRO_Depends); - } else { - IRO_NotSubable = 1; - } - } - break; - case IROLinearOp1Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - IRO_NotSubable = 1; - } else { - inner = linear->u.monadic; - if (linear->nodetype == EINDIRECT) { - if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD) - inner = inner->u.monadic; - if (inner->type != IROLinearOperand || inner->u.node->type != EOBJREF) - GetDependsOfIndirect(linear); - } - - IRO_DependsOn(inner, linear->nodetype == EINDIRECT); - } - break; - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - IRO_NotSubable = 1; - } else { - if (linear->nodetype == EDIV || linear->nodetype == EMODULO) { - if (IRO_IsIntConstant(linear->u.diadic.right)) { - if (CInt64_Equal(linear->u.diadic.right->u.node->data.intval, cint64_zero)) - IRO_CouldError = 1; - } else { - IRO_CouldError = 1; - } - } - - IRO_DependsOn(linear->u.diadic.left, flag); - IRO_DependsOn(linear->u.diadic.right, flag); - } - break; - case IROLinearOp3Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - IRO_NotSubable = 1; - } else { - IRO_DependsOn(linear->u.args3.a, flag); - IRO_DependsOn(linear->u.args3.b, flag); - IRO_DependsOn(linear->u.args3.c, flag); - } - break; - case IROLinearFunccall: - IRO_NotSubable = 1; - break; - default: - CError_FATAL(479); - } - } -} - -static void IRO_DependsOnForDataFlow(IROLinear *linear, Boolean flag) { - VarRecord *var; - IROLinear *inner; - - if (linear->rtype && CParser_IsVolatile(linear->rtype, linear->nodeflags & ENODE_FLAG_QUALS)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - - switch (linear->type) { - case IROLinearOperand: - if (flag && linear->u.node->type == EOBJREF) { - if ((var = IRO_FindVar(linear->u.node->data.objref, 0, 1))) { - if (is_volatile_object(var->object)) { - IRO_IsVolatile = 1; - IRO_NotSubable = 1; - } - Bv_SetBit(var->index, IRO_Depends); - } else { - IRO_NotSubable = 1; - } - } - break; - case IROLinearOp1Arg: - if (IRO_IsAssignOp[linear->nodetype]) - IRO_NotSubable = 1; - - inner = linear->u.monadic; - if (linear->nodetype == EINDIRECT) { - if (inner->type == IROLinearOp1Arg && inner->nodetype == EBITFIELD) - inner = inner->u.monadic; - if (inner->type != IROLinearOperand || inner->u.node->type != EOBJREF) - GetDependsOfIndirect(linear); - } - - IRO_DependsOnForDataFlow(inner, linear->nodetype == EINDIRECT); - break; - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) - IRO_NotSubable = 1; - - if (linear->nodetype == EDIV || linear->nodetype == EMODULO) { - if (IRO_IsIntConstant(linear->u.diadic.right)) { - if (CInt64_Equal(linear->u.diadic.right->u.node->data.intval, cint64_zero)) - IRO_CouldError = 1; - } else { - IRO_CouldError = 1; - } - } - - IRO_DependsOnForDataFlow(linear->u.diadic.left, flag); - IRO_DependsOnForDataFlow(linear->u.diadic.right, flag); - break; - case IROLinearOp3Arg: - if (IRO_IsAssignOp[linear->nodetype]) - IRO_NotSubable = 1; - - IRO_DependsOnForDataFlow(linear->u.args3.a, flag); - IRO_DependsOnForDataFlow(linear->u.args3.b, flag); - IRO_DependsOnForDataFlow(linear->u.args3.c, flag); - break; - case IROLinearFunccall: - IRO_NotSubable = 1; - GetDependsOfFunctionCallForDataFlow(linear); - break; - default: - CError_FATAL(650); - } -} - -void IRO_FindDepends_NoAlloc(IROLinear *linear) { - Bv_Clear(IRO_Depends); - IRO_CouldError = 0; - IRO_NotSubable = 0; - IRO_IsVolatile = 0; - IRO_DependsOnForDataFlow(linear, 0); -} - -void IRO_FindDepends(IROLinear *linear) { - Bv_AllocVector(&IRO_Depends, IRO_NumVars + 1); - IRO_CouldError = 0; - IRO_NotSubable = 0; - IRO_DependsOn(linear, 0); -} - -static void VecAct(IROLinear *linear, Boolean isFirst) { - if (!isFirst && (linear->flags & IROLF_VecOpBase)) - HasVectorOperand = 1; -} - -static Boolean IRO_DoesNotHaveVectorOperand(IROLinear *linear) { - HasVectorOperand = 0; - IRO_WalkTree(linear, VecAct); - return HasVectorOperand == 0; -} - -static void IRO_AddExpression(IROLinear *linear, IRONode *node, Boolean flag) { - IROExpr *expr; - - if ((linear->flags & IROLF_Reffed) && IRO_IsSubableExpression(linear) && IRO_DoesNotHaveVectorOperand(linear)) { - expr = oalloc(sizeof(IROExpr)); - expr->x0 = 0; - expr->index = ++IRO_NumExprs; - expr->linear = linear; - expr->x8 = NULL; - expr->node = node; - IRO_FindDepends(linear); - expr->depends = IRO_Depends; - expr->notSubable = IRO_NotSubable; - expr->couldError = IRO_CouldError; - expr->next = NULL; - expr->x14 = NULL; - if (IRO_FirstExpr) - IRO_LastExpr->next = expr; - else - IRO_FirstExpr = expr; - IRO_LastExpr = expr; - linear->expr = expr; - } -} - -void IRO_FindExpressions(BitVector *bv, Boolean flag) { - IROLinear *nd; - IRONode *fnode; - - IRO_FirstExpr = IRO_LastExpr = NULL; - IRO_NumExprs = 0; - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - if (!bv || Bv_IsBitSet(fnode->index, bv)) { - for (nd = fnode->first; nd; nd = nd->next) { - nd->expr = NULL; - IRO_AddExpression(nd, fnode, flag); - if (nd == fnode->last) - break; - } - } else { - for (nd = fnode->first; nd; nd = nd->next) { - nd->expr = NULL; - if (nd == fnode->last) - break; - } - } - } - - IRO_CheckForUserBreak(); -} - -void IRO_RemoveExpr(IROExpr *expr) { - IROExpr *prev; - IROExpr *scan; - - scan = IRO_FirstExpr; - prev = NULL; - while (scan != expr) { - prev = scan; - scan = scan->next; - CError_ASSERT(809, scan); - } - - expr->linear->expr = NULL; - if (prev) - prev->next = expr->next; - else - IRO_FirstExpr = expr->next; -} - -static void GetExprKillsByIndirectAssignment(IROLinear *linear) { - IROLinear *inner; - IROListNode *resultList; - IROListNode *next; - IROListNode *list; - IROListNode *scan; - IROLinear *scannd; - Object *obj; - VarRecord *var; - int index; - Boolean result; - Boolean foundObjRef; - IROExpr *expr; - - result = 0; - if (linear->type == IROLinearOp2Arg) - linear = linear->u.diadic.left; - else - linear = linear->u.monadic; - - if ( - linear && - linear->type == IROLinearOp1Arg && - linear->nodetype == EINDIRECT && - (inner = linear->u.monadic) && - copts.opt_pointer_analysis && - inner->pointsToFunction && - FunctionName - ) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, inner, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 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) { - result = 1; - break; - } - } - - if (!result) { - while (list) { - 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(893, obj != NULL); - var = IRO_FindVar(obj, 1, 1); - CError_ASSERT(895, var != NULL); - index = var->index; - - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_IsBitSet(index, expr->depends)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - } - } - list = list->nextList; - } - } - - while (resultList) { - next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) { - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_BitsInCommon(expr->depends, IRO_FuncKills)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - } -} - -static void GetExprKillsByFunctionCall(IROLinear *funccall) { - IROLinear *innernd; - IROListNode *resultList; - IROListNode *next; - IROListNode *list; - IROListNode *scan; - IROLinear *scannd; - Object *obj; - VarRecord *var; - int index; - Boolean result; - Boolean foundObjRef; - ObjectList *olist; - ObjectList *depsList; - IROExpr *expr; - - result = 0; - innernd = funccall->u.funccall.linear8; - - if (innernd && copts.opt_pointer_analysis && innernd->pointsToFunction && FunctionName) { - resultList = NULL; - PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, innernd, &resultList); - if ((list = resultList)) { - for (scan = list; scan; scan = scan->nextList) { - if (!scan->list.head || !scan->list.tail) { - result = 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(991, obj != NULL); - - depsList = NULL; - PointerAnalysis_GetFunctionKills(obj, funccall, &depsList); - - for (olist = depsList; olist; olist = olist->next) { - if (!olist->object) { - result = 1; - break; - } - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - - if (result) - break; - } - } - - if (!foundObjRef) - result = 1; - if (result) - break; - } - - if (!result) { - 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; - - depsList = NULL; - PointerAnalysis_GetFunctionKills(obj, funccall, &depsList); - - for (olist = depsList; olist; olist = olist->next) { - var = IRO_FindVar(olist->object, 1, 1); - CError_ASSERT(1042, var != NULL); - index = var->index; - CError_ASSERT(1044, index != 0); - - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_IsBitSet(index, expr->depends)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - } - - while (depsList) { - olist = depsList->next; - IRO_free(depsList); - depsList = olist; - } - } - } - } - } - - while (resultList) { - next = resultList->nextList; - IRO_free(resultList); - resultList = next; - } - } else { - result = 1; - } - } else { - result = 1; - } - - if (result) { - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_BitsInCommon(expr->depends, IRO_FuncKills)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - } -} - -static void IRO_GetExprKills(IROLinear *linear) { - Bv_Clear(IRO_ExprKills); - switch (linear->type) { - case IROLinearOp1Arg: - case IROLinearOp2Arg: - if (IRO_IsAssignOp[linear->nodetype]) { - VarRecord *var; - int index; - - var = IRO_FindAssigned(linear); - index = 0; - if (var) - index = var->index; - if (!index) { - GetExprKillsByIndirectAssignment(linear); - } else { - IROExpr *expr; - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_IsBitSet(index, expr->depends)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - } - } - break; - case IROLinearAsm: { - IROExpr *expr; - IRO_GetKills(linear); - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (Bv_BitsInCommon(expr->depends, IRO_VarKills)) - Bv_SetBit(expr->index, IRO_ExprKills); - } - break; - } - case IROLinearFunccall: - GetExprKillsByFunctionCall(linear); - break; - } -} - -void IRO_ComputeAvail(void) { - IRONode *node; - IROLinear *linear; - SInt32 counter; - BitVector *bv; - Boolean flag; - - counter = 0; - node = IRO_FirstNode; - Bv_AllocVector(&IRO_VarKills, IRO_NumVars + 1); - Bv_AllocVector(&IRO_ExprKills, IRO_NumExprs + 1); - - while (node) { - Bv_AllocVector(&node->x16, IRO_NumExprs); - if (node->numpred) - Bv_Set(node->x16); - Bv_AllocVector(&node->x22, IRO_NumExprs); - Bv_AllocVector(&node->x1E, IRO_NumExprs); - Bv_AllocVector(&node->x1A, IRO_NumExprs); - - for (linear = node->first; linear; linear = linear->next) { - if (linear->expr) - Bv_SetBit(linear->expr->index, node->x1E); - IRO_GetExprKills(linear); - Bv_Or(IRO_ExprKills, node->x22); - Bv_Minus(IRO_ExprKills, node->x1E); - if (linear == node->last) - break; - - if (counter > 250) { - IRO_CheckForUserBreak(); - counter = 0; - } else { - counter++; - } - } - - Bv_Copy(node->x16, node->x1A); - Bv_Minus(node->x22, node->x1A); - Bv_Or(node->x1E, node->x1A); - node = node->nextnode; - } - - IRO_CheckForUserBreak(); - - Bv_AllocVector(&bv, IRO_NumExprs); - do { - flag = 0; - for (node = IRO_FirstNode; node; node = node->nextnode) { - if (!node->numpred) { - Bv_Clear(bv); - } else { - UInt16 i; - Bv_Set(bv); - for (i = 0; i < node->numpred; i++) - Bv_And(IRO_NodeTable[node->pred[i]]->x1A, bv); - } - - if (!Bv_Compare(bv, node->x16)) { - flag = 1; - Bv_Copy(bv, node->x16); - } - - Bv_Copy(node->x16, node->x1A); - Bv_Minus(node->x22, node->x1A); - Bv_Or(node->x1E, node->x1A); - } - IRO_CheckForUserBreak(); - } while (flag); -} - -static void IRO_MakeReplacementEmbedded(IROExpr *expr) { - IROLinear *opnd; - IROLinear *ind; - IROLinear *ass; - - IRO_GetTemp(expr); - - opnd = IRO_NewLinear(IROLinearOperand); - opnd->u.node = create_objectrefnode(expr->x8); - opnd->rtype = opnd->u.node->data.objref->type; - opnd->index = ++IRO_NumLinear; - opnd->flags |= IROLF_Reffed | IROLF_Assigned | IROLF_Ind; - - ind = IRO_NewLinear(IROLinearOp1Arg); - ind->nodetype = EINDIRECT; - ind->rtype = expr->linear->rtype; - ind->u.monadic = opnd; - ind->index = ++IRO_NumLinear; - ind->flags |= IROLF_Reffed | IROLF_Assigned; - - ass = IRO_NewLinear(IROLinearOp2Arg); - ass->nodetype = EASS; - ass->u.diadic.left = ind; - ass->u.diadic.right = expr->linear; - ass->rtype = expr->linear->rtype; - ass->index = ++IRO_NumLinear; - - opnd->next = ind; - ind->next = ass; - IRO_ReplaceReferenceWithNode(expr->linear, ass); - IRO_PasteAfter(opnd, ass, expr->linear); -} - -static void IRO_ActUnmarkSubExpressions(IROLinear *linear, Boolean isFirst) { - if (isFirst) - linear->flags &= ~IROLF_8; -} - -static void CheckCommonSub(IROLinear *linear) { - IROExpr *expr; - - for (expr = IRO_FirstExpr; expr; expr = expr->next) { - if (expr->linear != linear && !expr->x14) { - if (Bv_IsBitSet(expr->index, IRO_Avail) && !expr->notSubable && IRO_ExprsSame(linear, expr->linear)) { - IRO_WalkTree(linear, IRO_ActUnmarkSubExpressions); - linear->flags |= IROLF_8; - linear->expr->x14 = expr; - break; - } - } - } -} - -static void MoveCommonSub(IROExpr *expr) { - SInt32 best; - SInt32 sz1; - SInt32 sz2; - SInt32 i1; - SInt32 i2; - IROLinear *scan; - IROLinear *array1[64]; - IROLinear *array2[64]; - IROExpr *scanexpr; - - sz1 = 0; - scan = expr->linear; - do { - scan = IRO_LocateFather(scan); - if (scan) { - if (sz1 == 64) - return; - array1[sz1++] = scan; - } - } while (scan); - - best = -1; - for (scanexpr = IRO_FirstExpr; scanexpr; scanexpr = scanexpr->next) { - if (scanexpr->x14 == expr) { - sz2 = 0; - scan = scanexpr->linear; - do { - scan = IRO_LocateFather(scan); - if (scan) { - if (sz2 == 64) - return; - array2[sz2++] = scan; - } - } while (scan); - - i1 = sz1; - i2 = sz2; - while (i1 && i2 && array1[i1 - 1] == array2[i2 - 1]) { - i1--; - i2--; - } - - if (i1 != sz1 && i1 > best) - best = i1; - } - } - - if (best < 0) { - IRO_MakeReplacementEmbedded(expr); - } else { - IROLinear *start; - IROLinear *comma; - IRO_Dump("Moving common sub from node %d to %d\n", expr->linear->index, array1[best]->index); - start = IRO_FindStart(array1[best]); - IRO_GetTemp(expr); - IRO_ReplaceReference(expr->linear, expr->x8, expr->linear); - IRO_MoveExpression(expr, start); - - comma = IRO_NewLinear(IROLinearOp2Arg); - comma->nodetype = ECOMMA; - comma->rtype = array1[best]->rtype; - comma->u.diadic.left = IRO_AssignToTemp(expr); - comma->u.diadic.right = array1[best]; - comma->stmt = array1[best]->stmt; - IRO_ReplaceReferenceWithNode(array1[best], comma); - IRO_PasteAfter(comma, comma, array1[best]); - } -} - -static void ReplaceCommonSub(IROLinear *linear) { - IROExpr *expr = linear->expr->x14; - if (!expr->x8) { - MoveCommonSub(expr); - if (!expr->x8) - return; - } - - IRO_Dump("Replacing common sub at %d with %d\n", linear->index, expr->linear->index); - IRO_ReplaceReference(linear, expr->x8, linear); - IRO_RemoveExpr(linear->expr); - IRO_NopOut(linear); -} - -void IRO_CommonSubs(void) { - IRONode *node; - IROLinear *linear; - SInt32 counter; - - counter = 0; - for (node = IRO_FirstNode; node; node = node->nextnode) { - IRO_Avail = node->x16; - linear = node->first; - while (1) { - if (!linear) - break; - if (linear->expr && !linear->expr->notSubable) - CheckCommonSub(linear); - if (linear->expr) - Bv_SetBit(linear->expr->index, IRO_Avail); - IRO_GetExprKills(linear); - Bv_Minus(IRO_ExprKills, IRO_Avail); - if (linear == node->last) - break; - if (counter > 250) { - IRO_CheckForUserBreak(); - counter = 0; - } else { - counter++; - } - linear = linear->next; - } - } - - for (node = IRO_FirstNode; node; node = node->nextnode) { - for (linear = node->first; linear; linear = linear->next) { - if (linear->expr && (linear->flags & IROLF_8) && !IRO_HasSideEffect(linear)) - ReplaceCommonSub(linear); - if (linear == node->last) - break; - if (counter > 250) { - IRO_CheckForUserBreak(); - counter = 0; - } else { - counter++; - } - } - } - - IRO_CheckForUserBreak(); -} - -static Boolean CountThisSubableOperandUse(IROUse *use) { - return use->x1C != 0; -} - -static int GetSubableOperandUseCount(VarRecord *var) { - int count = 0; - IROUse *use; - - if (var->uses) { - for (use = var->uses; use; use = use->varnext) { - if (CountThisSubableOperandUse(use)) - count++; - } - } - - return count; -} - -static void IRO_MakeTopLevelExprForSubableOperand(IROLinear *linear) { - IROLinear *copy = IRO_NewLinear(IROLinearOperand); - memcpy(copy, linear, sizeof(IROLinear)); - copy->index = ++IRO_NumLinear; - - if (IRO_FirstLinear && IRO_FirstLinear->type == IROLinearNop) - IRO_PasteAfter(copy, copy, IRO_FirstLinear); - else - IRO_Paste(copy, copy, IRO_FirstLinear); -} - -void IRO_GenerateTopLevelExprsForSubableOperands(void) { - IROLinear *nd; - IRONode *fnode; - VarRecord *var; - BitVector *bv; - - Bv_AllocVector(&bv, IRO_NumVars + 1); - - for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { - for (nd = fnode->first; nd; nd = nd->next) { - nd->expr = NULL; - if ((nd->flags & IROLF_Reffed) && IRO_IsSubableExpression(nd) && IRO_DoesNotHaveVectorOperand(nd)) { - if (nd->type == IROLinearOperand && nd->u.node && nd->u.node->type == EOBJREF) { - if ((var = IRO_FindVar(nd->u.node->data.objref, 0, 1))) { - if (!Bv_IsBitSet(var->index, bv)) { - IRO_MakeTopLevelExprForSubableOperand(nd); - Bv_SetBit(var->index, bv); - } - } - } - } - - if (nd == fnode->last) - break; - } - } -} |