From 9bde313bb8db4b2234cd8f8d25670b6fb9214147 Mon Sep 17 00:00:00 2001 From: Eric Smith Date: Sat, 6 Jan 2024 21:36:59 -0400 Subject: [PATCH] more robust detection of duplicate functions --- backends/asm/optimize_ir.c | 57 +++++++++++++++++++++++++++++++++----- backends/asm/outasm.c | 15 +++++++--- instr.h | 1 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/backends/asm/optimize_ir.c b/backends/asm/optimize_ir.c index ba3d685a4..3d042d0a9 100644 --- a/backends/asm/optimize_ir.c +++ b/backends/asm/optimize_ir.c @@ -5739,17 +5739,28 @@ OptimizeFcache(IRList *irl) } static void -HashOperand(SHA256_CTX *ctx, Operand *op) +HashOperand(SHA256_CTX *ctx, Operand *op, Function *f) { if (!op) return; sha256_update(ctx, (unsigned char *)&op->kind, sizeof(op->kind)); - sha256_update(ctx, (unsigned char *)op->name, strlen(op->name)); sha256_update(ctx, (unsigned char *)&op->val, sizeof(op->val)); + if (op->origsym) { + Symbol *sym = (Symbol *)op->origsym; + int offset = sym->offset; + int kind = (int) sym->kind; + sha256_update(ctx, (unsigned char *)&kind, sizeof(kind)); + sha256_update(ctx, (unsigned char *)&offset, sizeof(offset)); + } else { + sha256_update(ctx, (unsigned char *)op->name, strlen(op->name)); + } } static void -HashIR(SHA256_CTX *ctx, IR *ir) +HashIR(SHA256_CTX *ctx, IR *ir, Function *f) { + Operand *dst, *src, *src2; + int addr; + if (IsDummy(ir)) { return; } @@ -5758,10 +5769,42 @@ HashIR(SHA256_CTX *ctx, IR *ir) sha256_update(ctx, (unsigned char *)&ir->flags, sizeof(ir->flags)); sha256_update(ctx, (unsigned char *)&ir->srceffect, sizeof(ir->srceffect)); sha256_update(ctx, (unsigned char *)&ir->dsteffect, sizeof(ir->dsteffect)); + + dst = ir->dst; + src = ir->src; + src2 = ir->src2; + + // handle some special cases here + switch (ir->opc) { + case OPC_LABEL: + addr = ir->addr; + sha256_update(ctx, (unsigned char *)&addr, sizeof(addr)); + dst = 0; + break; + case OPC_JUMP: + if (ir->aux) { + IR *dest = (IR *)ir->aux; + addr = dest->addr; + sha256_update(ctx, (unsigned char *)&addr, sizeof(addr)); + dst = 0; + } + break; + case OPC_DJNZ: + if (ir->aux) { + IR *dest = (IR *)ir->aux; + addr = dest->addr; + sha256_update(ctx, (unsigned char *)&addr, sizeof(addr)); + src = 0; + } + break; + default: + /* do nothing */ + break; + } - HashOperand(ctx, ir->dst); - HashOperand(ctx, ir->src); - HashOperand(ctx, ir->src2); + HashOperand(ctx, dst, f); + HashOperand(ctx, src, f); + HashOperand(ctx, src2, f); } static FunctionList *funchash[256]; @@ -5800,7 +5843,7 @@ HashFuncIRL(Function *f) sha256_update(&ctx, flags, sizeof(flags)); for (ir = irl->head; ir; ir = ir->next) { - HashIR(&ctx, ir); + HashIR(&ctx, ir, f); } sha256_final(&ctx, hash); fl = funchash[hash[0]]; diff --git a/backends/asm/outasm.c b/backends/asm/outasm.c index dcf3a0c88..036ab58ec 100644 --- a/backends/asm/outasm.c +++ b/backends/asm/outasm.c @@ -1309,14 +1309,17 @@ CompileSymbolForFunc(IRList *irl, Symbol *sym, Function *func, AST *ast) } ValidateObjbase(); exprtype = (AST *)sym->v.ptr; + Operand *op; if (COG_DATA) { // COG memory size = TypeSize(exprtype); - return GetSizedGlobal(REG_REG, IdentifierModuleName(P, sym->our_name), 0, size); + op = GetSizedGlobal(REG_REG, IdentifierModuleName(P, sym->our_name), 0, size); } else { // HUB memory - return TypedHubMemRef(exprtype, objbase, (int)sym->offset); + op = TypedHubMemRef(exprtype, objbase, (int)sym->offset); } + op->origsym = (void *)sym; + return op; case SYM_FUNCTION: { Function *calledf = (Function *)sym->v.ptr; @@ -1358,10 +1361,14 @@ CompileSymbolForFunc(IRList *irl, Symbol *sym, Function *func, AST *ast) return FrameRef(offset, size); } } - return GetSizedGlobal(REG_LOCAL, IdentifierLocalName(func, sym->our_name), 0, size); + op = GetSizedGlobal(REG_LOCAL, IdentifierLocalName(func, sym->our_name), 0, size); + op->origsym = (void *)sym; + return op; case SYM_TEMPVAR: size = TypeSize((AST *)sym->v.ptr); - return GetSizedGlobal(REG_TEMP, IdentifierLocalName(func, sym->our_name), 0, size); + op = GetSizedGlobal(REG_TEMP, IdentifierLocalName(func, sym->our_name), 0, size); + op->origsym = (void *)sym; + return op; case SYM_LABEL: return LabelRef(irl, sym); case SYM_ALIAS: diff --git a/instr.h b/instr.h index 98acaafba..42fefabe2 100644 --- a/instr.h +++ b/instr.h @@ -370,6 +370,7 @@ struct Operand { intptr_t val; int size; // only really used for MEMREFs int used; + void *origsym; // original symbol }; typedef struct OperandList {