diff --git a/BuildName.txt b/BuildName.txt index df249f93cddf80b1f063775a98de6ecdbe8f2337..5ff12ff9f271f4aea019d489930009f0961964e8 100644 --- a/BuildName.txt +++ b/BuildName.txt @@ -1 +1 @@ -49.x86fre.master.230807-2311 +50.x86fre.master.230810-1506 diff --git a/__blddate__ b/__blddate__ index 949c401a9c6a1bfe82a1e9810b85c4b2b0b70814..b6a66803d3589ddc9478decbf97910ea0d61c01c 100644 --- a/__blddate__ +++ b/__blddate__ @@ -1 +1 @@ -BUILDDATE=230807-2311 \ No newline at end of file +BUILDDATE=230810-1506 \ No newline at end of file diff --git a/__bldnum__ b/__bldnum__ index b77ef58f621d6df590042c9c8c59d987da4e211b..fffc8bd0df72b6751881ea0bbc978e561935a6dc 100644 --- a/__bldnum__ +++ b/__bldnum__ @@ -1 +1 @@ -BUILDNUMBER=49 +BUILDNUMBER=50 diff --git a/back/ARMv7/instsel.c b/back/ARMv7/instsel.c index d5a8aa2de7b57cc5c6f0ae09499dde28f8590fc9..7a2a3530de45285629e4eb4033cb26bad8730613 100644 --- a/back/ARMv7/instsel.c +++ b/back/ARMv7/instsel.c @@ -48,12 +48,6 @@ char *opCodeTab[] = { "mov", /* 数据传送指令 mov */ "ldr", /* 数据传送指令 ldr */ "str", /* 数据传送指令 str */ - "moveq", /* 数据传送指令 moveq */ - "movne", /* 数据传送指令 movne */ - "movle", /* 数据传送指令 movle */ - "movgt", /* 数据传送指令 movgt */ - "movlt", /* 数据传送指令 movlt */ - "movge", /* 数据传送指令 movge */ "vmrs", /* 数据传送指令 vmrs */ "vmov", /* 数据传送指令 vmov */ "vldr.32", /* 数据传送指令 vldr.32 */ @@ -86,12 +80,6 @@ char *opCodeTab[] = { "vcmpe.f32", /* 浮点比较指令 vcmpe.f32 */ /* 跳转指令 */ "bx", /* 跳转指令 间接跳转 */ - "beq", /* 跳转指令 == */ - "bne", /* 跳转指令 != */ - "blt", /* 跳转指令 < */ - "ble", /* 跳转指令 <= */ - "bgt", /* 跳转指令 > */ - "bge", /* 跳转指令 >= */ "b", /* 跳转指令 goto */ "bl", /* 跳转指令 bl */ /* 函数调用相关指令 */ @@ -107,6 +95,27 @@ char *opCodeTab[] = { "@DBG: ", /* 伪指令 调试 */ }; +// https://developer.arm.com/documentation/dui0801/l/Condition-Codes/Condition-code-suffixes?lang=en +char *condCodeTab[] = { + "al", /* Always (this is the default) */ + "eq", /* Equal */ + "ne", /* Not equal */ + "cs", /* Carry set (identical to HS) */ + "hs", /* Unsigned higher or same (identical to CS) */ + "cc", /* Carry clear (identical to LO) */ + "lo", /* Unsigned lower (identical to CC) */ + "mi", /* Minus or negative result */ + "pl", /* Positive or zero result */ + "vs", /* Overflow */ + "vc", /* No overflow */ + "hi", /* Unsigned higher */ + "ls", /* Unsigned lower or same */ + "ge", /* Signed greater than or equal */ + "lt", /* Signed less than */ + "gt", /* Signed greater than */ + "le", /* Signed less than or equal */ +}; + static int asm_entry(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam); static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam); static int asm_assign(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam); @@ -188,7 +197,7 @@ static void DestroyUDData(void* p, void* T) ; static PVIRTREGINFO emitstorearg (PLLI instructions, int dest, PVIRTREGINFO src); static PVIRTREGINFO expand_mult(PVIRTREGINFO op0, void* op1, int IsImm, PLLI instructions, PDYNAMIC_ARRAY virtregs); -static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, PLLI instructions, PDYNAMIC_ARRAY virtregs); +static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, int suffix, condition_code cond, PLLI instructions, PDYNAMIC_ARRAY virtregs); static PVIRTREGINFO expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instructions, PDYNAMIC_ARRAY virtregs); /* ARCompact stack frames look like: @@ -802,6 +811,8 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT if (ret2 > 2 && ret > 2) { // 两个常数相加、减、乘、除、取模,不可能出现。 internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__); + PrintInstruction(stdout, currentinstruction, 0, 1); + fprintf(stdout, " in block %lu\n", bb_GetIdent(currentinstruction->bb)); goto cleanup; } @@ -863,7 +874,7 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT switch (iop) { case IRINST_OP_PLUS: - reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvaddf32 : opadd, instructions, &pMyData->virtreg); + reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvaddf32 : opadd, 0, CONDITION_AL, instructions, &pMyData->virtreg); if (!reg3) { goto cleanup; @@ -871,7 +882,7 @@ static int asm_addexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT break; case IRINST_OP_MINUS: - reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvsubf32 : opsub, instructions, &pMyData->virtreg); + reg3 = expand_binop(reg1, ret2 > 2 ? (void*)&TheValue2.integer_val : (void*)iarg2, ret2 > 2, type == Float ? opvsubf32 : opsub, 0, CONDITION_AL, instructions, &pMyData->virtreg); if (!reg3) { goto cleanup; @@ -1390,8 +1401,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction PVIRTREGINFO reg4; int iZero = 0; int bSuccess = 0; - OPCODE iop1; - OPCODE iop2; + condition_code iop1; + condition_code iop2; INSTRUCTION *asmInstr; pMyData = (PMYDATA)lpParam; @@ -1528,33 +1539,33 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction switch (ir_getOp(currentinstruction)) { case IRINST_OPVALUE_EQUALS: - iop1 = opmoveq; - iop2 = opmovne; + iop1 = CONDITION_EQ; + iop2 = CONDITION_NE; break ; case IRINST_OPVALUE_NOTEQ: - iop1 = opmovne; - iop2 = opmoveq; + iop1 = CONDITION_NE; + iop2 = CONDITION_EQ; break ; case IRINST_OPVALUE_GT: - iop1 = opmovgt; - iop2 = opmovle; + iop1 = CONDITION_GT; + iop2 = CONDITION_LE; break ; case IRINST_OPVALUE_LT: - iop1 = opmovlt; - iop2 = opmovge; + iop1 = CONDITION_LT; + iop2 = CONDITION_GE; break ; case IRINST_OPVALUE_GTEQ: - iop1 = opmovge; - iop2 = opmovlt; + iop1 = CONDITION_GE; + iop2 = CONDITION_LT; break ; case IRINST_OPVALUE_LTEQ: - iop1 = opmovle; - iop2 = opmovgt; + iop1 = CONDITION_LE; + iop2 = CONDITION_GT; break ; @@ -1579,7 +1590,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction { return 0; } - asmInstr->iop = iop1; + asmInstr->iop = opmov; + asmInstr->cond = iop1; asmInstr->Args[0].argType = VIRTREGARG; asmInstr->Args[0].arg.virtreg = reg3; asmInstr->Args[1].argType = INTEGERARG; @@ -1595,7 +1607,8 @@ static int asm_relexp_value(PLLI instructions, IRINSTRUCTION* currentinstruction { return 0; } - asmInstr->iop = iop2; + asmInstr->iop = opmov; + asmInstr->cond = iop2; asmInstr->Args[0].argType = VIRTREGARG; asmInstr->Args[0].arg.virtreg = reg3; asmInstr->Args[1].argType = INTEGERARG; @@ -1670,7 +1683,7 @@ static int asm_relexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT PVIRTREGINFO reg1; int iZero = 0; int bSuccess = 0; - OPCODE iop; + condition_code iop; pMyData = (PMYDATA)lpParam; @@ -1807,27 +1820,27 @@ static int asm_relexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMT switch (ir_getOp(currentinstruction)) { case IRINST_OP_EQUALS: - iop = opbeq; + iop = CONDITION_EQ; break ; case IRINST_OP_NOTEQ: - iop = opbne; + iop = CONDITION_NE; break ; case IRINST_OP_GT: - iop = opbgt; + iop = CONDITION_GT; break ; case IRINST_OP_LT: - iop = opblt; + iop = CONDITION_LT; break ; case IRINST_OP_GTEQ: - iop = opbge; + iop = CONDITION_GE; break ; case IRINST_OP_LTEQ: - iop = opble; + iop = CONDITION_LE; break ; default: @@ -1846,7 +1859,7 @@ cleanup: static int asm_goto(PLLI instructions, IRINSTRUCTION* currentinstruction, SYMTAB *psymtab, void *lpParam) { - if (!addasmInstrbranches(instructions, opb, ir_GetBranchTarget(currentinstruction))) + if (!addasmInstrbranches(instructions, CONDITION_AL, ir_GetBranchTarget(currentinstruction))) { return 0; } @@ -2377,7 +2390,8 @@ static int asm_unaryexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SY { return 0; } - asmInstr->iop = opmoveq; + asmInstr->iop = opmov; + asmInstr->cond = CONDITION_EQ; asmInstr->Args[0].argType = VIRTREGARG; asmInstr->Args[0].arg.virtreg = reg2; asmInstr->Args[1].argType = INTEGERARG; @@ -2393,7 +2407,8 @@ static int asm_unaryexp(PLLI instructions, IRINSTRUCTION* currentinstruction, SY { return 0; } - asmInstr->iop = opmovne; + asmInstr->iop = opmov; + asmInstr->cond = CONDITION_NE; asmInstr->Args[0].argType = VIRTREGARG; asmInstr->Args[0].arg.virtreg = reg2; asmInstr->Args[1].argType = INTEGERARG; @@ -3448,7 +3463,7 @@ int addasmInstrbx(PLLI instructions, int reg) return 1; } -int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination) +int addasmInstrbranches(PLLI instructions, condition_code iop, unsigned long destination) { INSTRUCTION *asmInstr; @@ -3457,7 +3472,8 @@ int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination { return 0; } - asmInstr->iop = iop; + asmInstr->iop = opb; + asmInstr->cond = iop; asmInstr->Args[0].argType = INTEGERARG; asmInstr->Args[0].arg.int_val = destination; if (-1 == LinkListAppend(instructions, asmInstr)) @@ -5089,6 +5105,9 @@ static void PrintArg(FILE *stream, ARG *arg) void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr) { int iCount; + char szFullName[512]; + + sprintf(szFullName, "%s%s%s", opCodeTab[asmInstr->iop], asmInstr->suffix ? "s" : "", asmInstr->cond ? condCodeTab[asmInstr->cond] : ""); if (asmInstr->iop == oplabel) { @@ -5105,7 +5124,7 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr) { if (asmInstr->nargs) { - fprintf ( stream, " %-7s {", opCodeTab[asmInstr->iop]); + fprintf ( stream, " %-7s {", szFullName); for( iCount = 0; iCount < asmInstr->nargs; iCount++ ) { if (asmInstr->Args[iCount].argType != NOARG && iCount >= 1) @@ -5121,21 +5140,21 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr) } else if ((asmInstr->iop == opmovw) && (asmInstr->Args[1].argType == SYMNAMEARG)) { - fprintf ( stream, " %-7s ", opCodeTab[asmInstr->iop]); + fprintf ( stream, " %-7s ", szFullName); PrintArg(stream, &asmInstr->Args[0]); fprintf ( stream, ", #:lower16:"); PrintArg(stream, &asmInstr->Args[1]); } else if ((asmInstr->iop == opmovt) && (asmInstr->Args[1].argType == SYMNAMEARG)) { - fprintf ( stream, " %-7s ", opCodeTab[asmInstr->iop]); + fprintf ( stream, " %-7s ", szFullName); PrintArg(stream, &asmInstr->Args[0]); fprintf ( stream, ", #:upper16:"); PrintArg(stream, &asmInstr->Args[1]); } else if ((asmInstr->iop == opldr) || (asmInstr->iop == opstr) || (asmInstr->iop == opvldr32) || (asmInstr->iop == opvstr32)) { - fprintf ( stream, " %-7s ", opCodeTab[asmInstr->iop]); + fprintf ( stream, " %-7s ", szFullName); PrintArg(stream, &asmInstr->Args[0]); fprintf ( stream, ", ["); PrintArg(stream, &asmInstr->Args[1]); @@ -5162,15 +5181,9 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr) } PrintArg(stream, &asmInstr->Args[1]); } - else if ((asmInstr->iop == opb) || - (asmInstr->iop == opbeq) || - (asmInstr->iop == opbne) || - (asmInstr->iop == opbge) || - (asmInstr->iop == opbgt) || - (asmInstr->iop == opble) || - (asmInstr->iop == opblt)) + else if (asmInstr->iop == opb) { - fprintf ( stream, " %-7s .L%u", opCodeTab[asmInstr->iop], asmInstr->Args[0].arg.int_val); + fprintf ( stream, " %-7s .L%u", szFullName, asmInstr->Args[0].arg.int_val); } else if (asmInstr->iop == opDBG) { @@ -5188,7 +5201,7 @@ void PrintasmInstr(FILE *stream, INSTRUCTION *asmInstr) } else { - fprintf ( stream, " %-7s ", opCodeTab[asmInstr->iop]); + fprintf ( stream, " %-7s ", szFullName); for( iCount = 0; iCount < asmInstr->nargs; iCount++ ) { if (asmInstr->Args[iCount].argType != NOARG && iCount >= 1) @@ -5898,7 +5911,7 @@ INSTRUCTION* asmcopy(INSTRUCTION* src) return lpBuffer; } -static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, PLLI instructions, PDYNAMIC_ARRAY virtregs) +static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE op, int suffix, condition_code cond, PLLI instructions, PDYNAMIC_ARRAY virtregs) { INSTRUCTION* insn; PVIRTREGINFO target = NULL; @@ -5919,6 +5932,8 @@ static PVIRTREGINFO expand_binop(PVIRTREGINFO op0, void* op1, int IsImm, OPCODE goto cleanup; } insn->iop = op; + insn->cond = cond; + insn->suffix = suffix; insn->Args[0].argType = VIRTREGARG; insn->Args[0].arg.virtreg = target; insn->Args[1].argType = VIRTREGARG; @@ -6271,45 +6286,71 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru { /* 如果log>= 0,则通过移位来实现。 我们必须根据除数加减某个数来纠正被除数,以实现代码指定的舍入。 */ - insn = AllocasmInstr(2); - if (!insn) + if (!mod_flag) { - goto Error; - } - insn->iop = opcmp; - insn->Args[0].argType = VIRTREGARG; - insn->Args[0].arg.virtreg = op0; - insn->Args[1].argType = INTEGERARG; - insn->Args[1].arg.int_val = 0; - if (-1 == LinkListAppend(instructions, insn)) - { - free(insn); - goto Error; - } + iVal = *(int*) op1 - 1; + reg1 = expand_binop(op0, &iVal, 1, opadd, 0, CONDITION_AL, instructions, virtregs); + if (!reg1) + { + goto Error; + } - iVal = *(int*) op1 - 1; - temp = expand_binop(op0, &iVal, 1, opadd, instructions, virtregs); - if (!temp) - { - goto Error; - } + insn = AllocasmInstr(2); + if (!insn) + { + goto Error; + } + insn->iop = opcmp; + insn->Args[0].argType = VIRTREGARG; + insn->Args[0].arg.virtreg = op0; + insn->Args[1].argType = INTEGERARG; + insn->Args[1].arg.int_val = 0; + if (-1 == LinkListAppend(instructions, insn)) + { + free(insn); + goto Error; + } - insn = AllocasmInstr(2); - if (!insn) - { - goto Error; - } - insn->iop = opmovge; - insn->Args[0].argType = VIRTREGARG; - insn->Args[0].arg.virtreg = temp; - insn->Args[1].argType = VIRTREGARG; - insn->Args[1].arg.virtreg = op0; - if (-1 == LinkListAppend(instructions, insn)) - { - free(insn); - goto Error; - } + temp = getReg(virtregs, NULL, 0, NULL, 0, 0, op0->isfloat ,&IsPresent); + if (!reg1) + { + goto Error; + } + insn = AllocasmInstr(2); + if (!insn) + { + goto Error; + } + insn->iop = opmov; + insn->cond = CONDITION_LT; + insn->Args[0].argType = VIRTREGARG; + insn->Args[0].arg.virtreg = temp; + insn->Args[1].argType = VIRTREGARG; + insn->Args[1].arg.virtreg = reg1; + if (-1 == LinkListAppend(instructions, insn)) + { + free(insn); + goto Error; + } + + insn = AllocasmInstr(2); + if (!insn) + { + goto Error; + } + insn->iop = opmov; + insn->cond = CONDITION_GE; + insn->Args[0].argType = VIRTREGARG; + insn->Args[0].arg.virtreg = temp; + insn->Args[1].argType = VIRTREGARG; + insn->Args[1].arg.virtreg = op0; + if (-1 == LinkListAppend(instructions, insn)) + { + free(insn); + goto Error; + } + } } else { // 将除数放在寄存器中 @@ -6347,12 +6388,44 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru if (mod_flag && log>=0) { + iVal = 0; + temp = expand_binop(op0, &iVal, 1, oprsb, 1, CONDITION_AL, instructions, virtregs); + if (!temp) + { + goto Error; + } + iVal = *(int*) op1 - 1; - target = expand_binop(op0, &iVal, 1, opand, instructions, virtregs); + target = expand_binop(op0, &iVal, 1, opand, 0, CONDITION_AL, instructions, virtregs); if (!target) { goto Error; } + reg1 = expand_binop(temp, &iVal, 1, opand, 0, CONDITION_AL, instructions, virtregs); + if (!reg1) + { + goto Error; + } + + insn = AllocasmInstr(3); + if (!insn) + { + goto Error; + } + insn->iop = oprsb; + insn->cond = CONDITION_PL; + insn->Args[0].argType = VIRTREGARG; + insn->Args[0].arg.virtreg = target; + insn->Args[1].argType = VIRTREGARG; + insn->Args[1].arg.virtreg = reg1; + insn->Args[2].argType = INTEGERARG; + insn->Args[2].arg.int_val = 0; + if (-1 == LinkListAppend(instructions, insn)) + { + free(insn); + goto Error; + } + goto Success; } @@ -6374,7 +6447,7 @@ expand_divmod (PVIRTREGINFO op0, void* op1, int IsImm, int mod_flag, PLLI instru insn->Args[0].argType = VIRTREGARG; insn->Args[0].arg.virtreg = target; insn->Args[1].argType = VIRTREGARG; - insn->Args[1].arg.virtreg = op0; + insn->Args[1].arg.virtreg = temp; insn->Args[2].argType = INTEGERARG; insn->Args[2].arg.int_val = exact_log2 (*(int*) op1); if (-1 == LinkListAppend(instructions, insn)) diff --git a/back/ARMv7/regalloc.c b/back/ARMv7/regalloc.c index 813673f5ea2153ef6181af08466a0f91072763a0..49913dab165ea34f7d0b59baa61b1f51d0225609 100644 --- a/back/ARMv7/regalloc.c +++ b/back/ARMv7/regalloc.c @@ -441,18 +441,6 @@ static int IsInputOpr(OPCODE iop, int iarg) iResult = 1; break; - case opmoveq: - /* fall through */ - case opmovne: - /* fall through */ - case opmovle: - /* fall through */ - case opmovgt: - /* fall through */ - case opmovlt: - /* fall through */ - case opmovge: - /* fall through */ case opuxtb: if (iarg != 0) { @@ -487,18 +475,6 @@ static int IsInputOpr(OPCODE iop, int iarg) /* fall through */ case opbx: /* fall through */ - case opbeq: - /* fall through */ - case opbne: - /* fall through */ - case opblt: - /* fall through */ - case opble: - /* fall through */ - case opbgt: - /* fall through */ - case opbge: - /* fall through */ case opb: /* fall through */ case opbl: diff --git a/compiler.exe b/compiler.exe index 91f655dff35611e362856eed35d92ee058b4a974..3ea7c68a8cbeaf9ac95ded054a75d51fc0ace4cf 100644 Binary files a/compiler.exe and b/compiler.exe differ diff --git a/front/IRInst.c b/front/IRInst.c index 1a8d06a62556084e98d6fa45ffb2898b66d705bb..4b9307e7622544666aecb22f5ac25b120f434f5f 100644 --- a/front/IRInst.c +++ b/front/IRInst.c @@ -350,6 +350,15 @@ void PrintInstruction(FILE *stream, IRINSTRUCTION *inst, int fEscape, int fRenam } break; } + if (inst->iop == IRINST_OP_ARRAYASSIGN) + { + fprintf(stream, ", "); + PrintSymbol(stream, inst->iarg3); + if (fRename && inst->iarg3) + { + fprintf(stream, "'%d", ir_GetNumber(inst, 3)); + } + } } fprintf(stream, ")"); @@ -643,7 +652,6 @@ int ir_isDef(IRINSTRUCTION *inst, int iArg) iop = ir_getOp(inst); switch (iop) { - case IRINST_OP_PLUS: case IRINST_OP_MULT: case IRINST_OP_MINUS: case IRINST_OP_DIV: @@ -669,6 +677,18 @@ int ir_isDef(IRINSTRUCTION *inst, int iArg) } break; + case IRINST_OP_PLUS: + if (iArg == 2) + { + bResult = 1; + } + if (iArg == 0 && !ir_IsArgFloat(inst, 1) && !ir_IsArgInteger(inst, 1) && + !SymIsConst(ir_GetArgVoidPtr(inst, 1), NULL, NULL) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(inst, 1)))) + { + bResult = 1; + } + break; + case IRINST_OP_FUNC_CALL: if ((iArg == 2) && (ir_GetDstVoidPtr(inst) != NULL)) { @@ -709,10 +729,16 @@ int ir_GetNumber(IRINSTRUCTION *inst, int iArg) { return inst->number3; } - else + else if (iArg == 3) { return inst->number4; } + else + { + internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__); + return -1; + } + } void ir_SetNumber(IRINSTRUCTION *inst, int iArg, int number) @@ -729,10 +755,14 @@ void ir_SetNumber(IRINSTRUCTION *inst, int iArg, int number) { inst->number3 = number; } - else + else if (iArg == 3) { inst->number4 = number; } + else + { + internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__); + } } void ir_SetArgVoidPtr(IRINSTRUCTION* inst, int iArg, void* lpvoid) @@ -765,7 +795,7 @@ void ir_GetOperand(IRINSTRUCTION *inst, int iArg, ExpType *lpType, int *isImmedi if (!ir_IsArgFloat(inst, 1) && !ir_IsArgInteger(inst, 1)) { psyment = ir_GetArgVoidPtr(inst, 1); - if (!SymIsConst(psyment, lpType, lpBuffer) || DynamicArrayGetCount(Get_Dope(psyment))) + if (DynamicArrayGetCount(Get_Dope(psyment)) || !SymIsConst(psyment, lpType, lpBuffer)) { *isImmediate = 0; *(SYMENT**)lpBuffer = psyment; @@ -794,7 +824,7 @@ void ir_GetOperand(IRINSTRUCTION *inst, int iArg, ExpType *lpType, int *isImmedi if (!ir_IsArgFloat(inst, 0) && !ir_IsArgInteger(inst, 0)) { psyment = ir_GetArgVoidPtr(inst, 0); - if (!SymIsConst(psyment, lpType, lpBuffer) || DynamicArrayGetCount(Get_Dope(psyment))) + if ( DynamicArrayGetCount(Get_Dope(psyment)) || !SymIsConst(psyment, lpType, lpBuffer) ) { *isImmediate = 0; *(SYMENT**)lpBuffer = psyment; @@ -960,6 +990,7 @@ void swap_operands(InterCode *g_code) insn->fIsArg2Float = 0; } + // 警告:下面这些memcpy不再可用。它们在本地或者树莓派上不会引起崩溃,但在评测机上不总是如此。 // uiSize = (char *)&(P->fIsArg2Integer) - (char *)&(P->fIsArg1Integer); // memcpy ( &Swap.fIsArg2Integer, &insn->fIsArg1Integer, uiSize ) ; // memcpy ( &Swap.fIsArg1Integer, &insn->fIsArg2Integer, uiSize ) ; @@ -994,6 +1025,50 @@ void swap_operands(InterCode *g_code) } } +/// @brief 找到指针类型的参数所指向的数组。 +/// @param insn 一条中间代码 +SYMENT* FinddefinedArray(IRINSTRUCTION* insn) +{ + IRInstOperator iop ; + SYMENT* psyment; + + iop = ir_getOp(insn); + + if (iop != IRINST_OP_PARAM) + { + return NULL; + } + + if (ir_IsArgFloat(insn, 1) || ir_IsArgInteger(insn, 1) || SymIsConst(ir_GetArgVoidPtr(insn, 1), NULL, NULL)) + { + return NULL; + } + psyment = ir_GetArgVoidPtr(insn, 1); + return SymGetPointTo(psyment); +} + +/// @brief 找到一条参数中间指令所属的函数调用。 +/// @param insn 一条参数中间代码 +IRINSTRUCTION* FindParamFunc(IRINSTRUCTION* insn) +{ + LIST_ITERATOR iterator; + IRINSTRUCTION* inst; + int bFound = 0; + + List_TRAVERSE(bb_GetInsts(ir_GetContainer(insn)), inst, &iterator) + { + if (insn == inst) + { + bFound = 1; + } + if (bFound && ir_getOp(inst)==IRINST_OP_FUNC_CALL) + { + return inst; + } + } + return NULL; +} + #if defined( WITH_PRINTIR_NEW ) static void PrintAllDeclarations(FILE *stream, SYMTAB *SymTable) diff --git a/front/genIR.c b/front/genIR.c index dcd981266c336ac66c37eb18f606b1c54f8bc7b1..ad6c5ded6087fcf0296c88c32bcb358ec32878bd 100644 --- a/front/genIR.c +++ b/front/genIR.c @@ -3241,6 +3241,7 @@ static int ir_funccall(TreeNode * pv) return 0; } memset(&symParam, 0, sizeof(symParam)); + SymSetPointTo(psyment, Ast_GetPlace(pvisit)); if (!Ast_AddInst(pv, &g_code, &labelCount, IRINST_OP_PLUS, Ast_GetPlace(pvisit), Ast_GetOffset(pvisit), psyment)) { return 0; diff --git a/front/grammar.tab.c b/front/grammar.tab.c index ec5a915d7bef0515e6df5bcf6f0c034aa7f3b9db..ff9b133661c11ef7ac5dfe59200a6d7067a218cb 100644 --- a/front/grammar.tab.c +++ b/front/grammar.tab.c @@ -67,7 +67,7 @@ /* First part of user prologue. */ -#line 7 "./front/grammar.y" +#line 7 ".\\front\\grammar.y" #include "compiler.h" @@ -78,7 +78,7 @@ #define YYDEBUG 1 -#line 82 "./front/grammar.tab.c" +#line 82 ".\\front\\grammar.tab.c" # ifndef YY_CAST # ifdef __cplusplus @@ -1321,7 +1321,7 @@ yyreduce: switch (yyn) { case 2: /* CompUnit: FuncDef */ -#line 147 "./front/grammar.y" +#line 147 ".\\front\\grammar.y" { MyPrintf(("%d : CompUnit -> FuncDef\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1339,11 +1339,11 @@ yyreduce: } g_savedTree = (yyval.asttreenode); } -#line 1343 "./front/grammar.tab.c" +#line 1343 ".\\front\\grammar.tab.c" break; case 3: /* CompUnit: CompUnit FuncDef */ -#line 165 "./front/grammar.y" +#line 165 ".\\front\\grammar.y" { MyPrintf(("%d : CompUnit -> CompUnit FuncDef\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -1353,11 +1353,11 @@ yyreduce: MyExit(1); } } -#line 1357 "./front/grammar.tab.c" +#line 1357 ".\\front\\grammar.tab.c" break; case 4: /* CompUnit: Decl */ -#line 175 "./front/grammar.y" +#line 175 ".\\front\\grammar.y" { MyPrintf(("%d : CompUnit -> Decl\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1375,11 +1375,11 @@ yyreduce: } g_savedTree = (yyval.asttreenode); } -#line 1379 "./front/grammar.tab.c" +#line 1379 ".\\front\\grammar.tab.c" break; case 5: /* CompUnit: CompUnit Decl */ -#line 193 "./front/grammar.y" +#line 193 ".\\front\\grammar.y" { MyPrintf(("%d : CompUnit -> CompUnit Decl\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -1389,49 +1389,49 @@ yyreduce: MyExit(1); } } -#line 1393 "./front/grammar.tab.c" +#line 1393 ".\\front\\grammar.tab.c" break; case 6: /* Decl: ConstDecl */ -#line 207 "./front/grammar.y" +#line 207 ".\\front\\grammar.y" { MyPrintf(("%d : Decl -> ConstDecl\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 1402 "./front/grammar.tab.c" +#line 1402 ".\\front\\grammar.tab.c" break; case 7: /* Decl: VarDecl */ -#line 212 "./front/grammar.y" +#line 212 ".\\front\\grammar.y" { MyPrintf(("%d : Decl -> VarDecl\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 1411 "./front/grammar.tab.c" +#line 1411 ".\\front\\grammar.tab.c" break; case 8: /* Decl: FuncDecl */ -#line 217 "./front/grammar.y" +#line 217 ".\\front\\grammar.y" { MyPrintf(("%d : Decl -> FuncDecl\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 1420 "./front/grammar.tab.c" +#line 1420 ".\\front\\grammar.tab.c" break; case 9: /* ConstDecl: "const" BType ConstDefGroup ";" */ -#line 226 "./front/grammar.y" +#line 226 ".\\front\\grammar.y" { MyPrintf(("%d : ConstDecl -> \"const\" BType ConstDefGroup \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); SetBasicType((yyval.asttreenode), (yyvsp[-2].integer)); SetNodeType((yyval.asttreenode), AT_ConstDecl); } -#line 1431 "./front/grammar.tab.c" +#line 1431 ".\\front\\grammar.tab.c" break; case 10: /* ConstDefGroup: ConstDefGroup "," ConstDef */ -#line 236 "./front/grammar.y" +#line 236 ".\\front\\grammar.y" { MyPrintf(("%d : ConstDefGroup -> ConstDefGroup \",\" ConstDef\n", ++nCount)); (yyval.asttreenode)= (yyvsp[-2].asttreenode); @@ -1441,11 +1441,11 @@ yyreduce: MyExit(1); } } -#line 1445 "./front/grammar.tab.c" +#line 1445 ".\\front\\grammar.tab.c" break; case 11: /* ConstDefGroup: ConstDef */ -#line 246 "./front/grammar.y" +#line 246 ".\\front\\grammar.y" { MyPrintf(("%d : ConstDefGroup -> ConstDef\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1461,29 +1461,29 @@ yyreduce: MyExit(1); } } -#line 1465 "./front/grammar.tab.c" +#line 1465 ".\\front\\grammar.tab.c" break; case 12: /* BType: "int" */ -#line 266 "./front/grammar.y" +#line 266 ".\\front\\grammar.y" { MyPrintf(("%d : BType -> \"int\"\n", ++nCount)); (yyval.integer) = Integer; } -#line 1474 "./front/grammar.tab.c" +#line 1474 ".\\front\\grammar.tab.c" break; case 13: /* BType: "float" */ -#line 271 "./front/grammar.y" +#line 271 ".\\front\\grammar.y" { MyPrintf(("%d : BType -> \"float\"\n", ++nCount)); (yyval.integer) = Float; } -#line 1483 "./front/grammar.tab.c" +#line 1483 ".\\front\\grammar.tab.c" break; case 14: /* ConstDef: Ident ConstExpGroup "=" ConstInitVal */ -#line 280 "./front/grammar.y" +#line 280 ".\\front\\grammar.y" { MyPrintf(("%d : ConstDef -> Ident ConstExpGroup \"=\" ConstInitVal\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -1500,11 +1500,11 @@ yyreduce: MyExit(1); } } -#line 1504 "./front/grammar.tab.c" +#line 1504 ".\\front\\grammar.tab.c" break; case 15: /* ConstExpGroup: "[" ConstExp "]" ConstExpGroup */ -#line 300 "./front/grammar.y" +#line 300 ".\\front\\grammar.y" { MyPrintf(("%d : ConstExpGroup -> \"[\" ConstExp \"]\" ConstExpGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1514,11 +1514,11 @@ yyreduce: MyExit(1); } } -#line 1518 "./front/grammar.tab.c" +#line 1518 ".\\front\\grammar.tab.c" break; case 16: /* ConstExpGroup: %empty */ -#line 310 "./front/grammar.y" +#line 310 ".\\front\\grammar.y" { MyPrintf(("%d : ConstExpGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1530,11 +1530,11 @@ yyreduce: SetOriginalType((yyval.asttreenode), ConstExpGroupK); SetNodeType((yyval.asttreenode), AT_ConstExpGroup); } -#line 1534 "./front/grammar.tab.c" +#line 1534 ".\\front\\grammar.tab.c" break; case 17: /* ConstInitVal: ConstExp */ -#line 326 "./front/grammar.y" +#line 326 ".\\front\\grammar.y" { MyPrintf(("%d : ConstInitVal -> ConstExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1551,11 +1551,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_ConstInitVal); SetOriginalType((yyval.asttreenode),ConstInitValK); } -#line 1555 "./front/grammar.tab.c" +#line 1555 ".\\front\\grammar.tab.c" break; case 18: /* ConstInitVal: "{" "}" */ -#line 343 "./front/grammar.y" +#line 343 ".\\front\\grammar.y" { MyPrintf(("%d : ConstInitVal -> \"{\" \"}\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1567,22 +1567,22 @@ yyreduce: SetOriginalType((yyval.asttreenode),ConstInitValK); SetNodeType((yyval.asttreenode), AT_ConstInitVal); } -#line 1571 "./front/grammar.tab.c" +#line 1571 ".\\front\\grammar.tab.c" break; case 19: /* ConstInitVal: "{" ConstInitValGroup "}" */ -#line 355 "./front/grammar.y" +#line 355 ".\\front\\grammar.y" { MyPrintf(("%d : ConstInitVal -> \"{\" ConstInitValGroup \"}\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); SetOriginalType((yyval.asttreenode),ConstInitValK); SetNodeType((yyval.asttreenode), AT_ConstInitVal); } -#line 1582 "./front/grammar.tab.c" +#line 1582 ".\\front\\grammar.tab.c" break; case 20: /* ConstInitValGroup: ConstInitVal dummy1 */ -#line 365 "./front/grammar.y" +#line 365 ".\\front\\grammar.y" { MyPrintf(("%d : ConstInitValGroup -> ConstInitVal dummy1\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1592,11 +1592,11 @@ yyreduce: MyExit(1); } } -#line 1596 "./front/grammar.tab.c" +#line 1596 ".\\front\\grammar.tab.c" break; case 21: /* dummy1: "," ConstInitVal dummy1 */ -#line 378 "./front/grammar.y" +#line 378 ".\\front\\grammar.y" { MyPrintf(("%d : dummy1 -> \",\" ConstInitVal dummy1\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1606,11 +1606,11 @@ yyreduce: MyExit(1); } } -#line 1610 "./front/grammar.tab.c" +#line 1610 ".\\front\\grammar.tab.c" break; case 22: /* dummy1: %empty */ -#line 388 "./front/grammar.y" +#line 388 ".\\front\\grammar.y" { MyPrintf(("%d : dummy1 -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1621,11 +1621,11 @@ yyreduce: } SetOriginalType((yyval.asttreenode), ConstInitValGroupK); } -#line 1625 "./front/grammar.tab.c" +#line 1625 ".\\front\\grammar.tab.c" break; case 23: /* VarDecl: BType VarDef VarDefGroup ";" */ -#line 403 "./front/grammar.y" +#line 403 ".\\front\\grammar.y" { MyPrintf(("%d : VarDecl -> BType VarDef VarDefGroup \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -1637,11 +1637,11 @@ yyreduce: MyExit(1); } } -#line 1641 "./front/grammar.tab.c" +#line 1641 ".\\front\\grammar.tab.c" break; case 24: /* VarDefGroup: "," VarDef VarDefGroup */ -#line 418 "./front/grammar.y" +#line 418 ".\\front\\grammar.y" { MyPrintf(("%d : VarDefGroup -> \",\" VarDef VarDefGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1651,11 +1651,11 @@ yyreduce: MyExit(1); } } -#line 1655 "./front/grammar.tab.c" +#line 1655 ".\\front\\grammar.tab.c" break; case 25: /* VarDefGroup: %empty */ -#line 428 "./front/grammar.y" +#line 428 ".\\front\\grammar.y" { MyPrintf(("%d : VarDefGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1666,11 +1666,11 @@ yyreduce: } SetOriginalType((yyval.asttreenode), VarDeclK); } -#line 1670 "./front/grammar.tab.c" +#line 1670 ".\\front\\grammar.tab.c" break; case 26: /* VarDef: Ident ConstExpGroup */ -#line 443 "./front/grammar.y" +#line 443 ".\\front\\grammar.y" { MyPrintf(("%d : VarDef -> Ident ConstExpGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -1682,11 +1682,11 @@ yyreduce: MyExit(1); } } -#line 1686 "./front/grammar.tab.c" +#line 1686 ".\\front\\grammar.tab.c" break; case 27: /* VarDef: Ident ConstExpGroup "=" InitVal */ -#line 455 "./front/grammar.y" +#line 455 ".\\front\\grammar.y" { MyPrintf(("%d : VarDef -> Ident ConstExpGroup \"=\" InitVal\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -1703,11 +1703,11 @@ yyreduce: MyExit(1); } } -#line 1707 "./front/grammar.tab.c" +#line 1707 ".\\front\\grammar.tab.c" break; case 28: /* InitVal: Exp */ -#line 476 "./front/grammar.y" +#line 476 ".\\front\\grammar.y" { MyPrintf(("%d : InitVal -> Exp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1724,11 +1724,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_InitVal); SetOriginalType((yyval.asttreenode),InitValK); } -#line 1728 "./front/grammar.tab.c" +#line 1728 ".\\front\\grammar.tab.c" break; case 29: /* InitVal: "{" "}" */ -#line 493 "./front/grammar.y" +#line 493 ".\\front\\grammar.y" { MyPrintf(("%d : InitVal -> \"{\" \"}\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1740,11 +1740,11 @@ yyreduce: SetOriginalType((yyval.asttreenode),InitValK); SetNodeType((yyval.asttreenode), AT_InitVal); } -#line 1744 "./front/grammar.tab.c" +#line 1744 ".\\front\\grammar.tab.c" break; case 30: /* InitVal: "{" InitVal InitValGroup "}" */ -#line 505 "./front/grammar.y" +#line 505 ".\\front\\grammar.y" { MyPrintf(("%d : InitVal -> \"{\" InitVal InitValGroup \"}\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -1755,11 +1755,11 @@ yyreduce: } SetNodeType((yyval.asttreenode), AT_InitVal); } -#line 1759 "./front/grammar.tab.c" +#line 1759 ".\\front\\grammar.tab.c" break; case 31: /* InitValGroup: "," InitVal InitValGroup */ -#line 519 "./front/grammar.y" +#line 519 ".\\front\\grammar.y" { MyPrintf(("%d : InitValGroup -> \",\" InitVal InitValGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1769,11 +1769,11 @@ yyreduce: MyExit(1); } } -#line 1773 "./front/grammar.tab.c" +#line 1773 ".\\front\\grammar.tab.c" break; case 32: /* InitValGroup: %empty */ -#line 529 "./front/grammar.y" +#line 529 ".\\front\\grammar.y" { MyPrintf(("%d : InitValGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1784,11 +1784,11 @@ yyreduce: } SetOriginalType((yyval.asttreenode),InitValK); } -#line 1788 "./front/grammar.tab.c" +#line 1788 ".\\front\\grammar.tab.c" break; case 33: /* FuncDef: BType Ident "(" ")" Block */ -#line 544 "./front/grammar.y" +#line 544 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> BType Ident \"(\" \")\" Block\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -1814,11 +1814,11 @@ yyreduce: MyExit(1); } } -#line 1818 "./front/grammar.tab.c" +#line 1818 ".\\front\\grammar.tab.c" break; case 34: /* FuncDef: BType Ident "(" FuncFParams ")" Block */ -#line 570 "./front/grammar.y" +#line 570 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> BType Ident \"(\" FuncFParams \")\" Block\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-4].asttreenode); @@ -1836,11 +1836,11 @@ yyreduce: MyExit(1); } } -#line 1840 "./front/grammar.tab.c" +#line 1840 ".\\front\\grammar.tab.c" break; case 35: /* FuncDef: "void" Ident "(" ")" Block */ -#line 588 "./front/grammar.y" +#line 588 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" \")\" Block\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -1866,11 +1866,11 @@ yyreduce: MyExit(1); } } -#line 1870 "./front/grammar.tab.c" +#line 1870 ".\\front\\grammar.tab.c" break; case 36: /* FuncDef: "void" Ident "(" FuncFParams ")" Block */ -#line 614 "./front/grammar.y" +#line 614 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" FuncFParams \")\" Block\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-4].asttreenode); @@ -1888,11 +1888,11 @@ yyreduce: MyExit(1); } } -#line 1892 "./front/grammar.tab.c" +#line 1892 ".\\front\\grammar.tab.c" break; case 37: /* FuncFParams: FuncFParam FuncFParamGroup */ -#line 636 "./front/grammar.y" +#line 636 ".\\front\\grammar.y" { MyPrintf(("%d : FuncFParams -> FuncFParam FuncFParamGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1902,11 +1902,11 @@ yyreduce: MyExit(1); } } -#line 1906 "./front/grammar.tab.c" +#line 1906 ".\\front\\grammar.tab.c" break; case 38: /* FuncFParamGroup: "," FuncFParam FuncFParamGroup */ -#line 649 "./front/grammar.y" +#line 649 ".\\front\\grammar.y" { MyPrintf(("%d : FuncFParamGroup -> \",\" FuncFParam FuncFParamGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1916,11 +1916,11 @@ yyreduce: MyExit(1); } } -#line 1920 "./front/grammar.tab.c" +#line 1920 ".\\front\\grammar.tab.c" break; case 39: /* FuncFParamGroup: %empty */ -#line 659 "./front/grammar.y" +#line 659 ".\\front\\grammar.y" { MyPrintf(("%d : FuncFParamGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1932,11 +1932,11 @@ yyreduce: SetOriginalType((yyval.asttreenode), FuncFParamsK); SetNodeType((yyval.asttreenode), AT_FuncFParams); } -#line 1936 "./front/grammar.tab.c" +#line 1936 ".\\front\\grammar.tab.c" break; case 40: /* FuncFParam: BType */ -#line 675 "./front/grammar.y" +#line 675 ".\\front\\grammar.y" { MyPrintf(("%d : FuncFParam -> BType\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -1950,11 +1950,11 @@ yyreduce: SetLineno((yyval.asttreenode), LineNum); SetBasicType((yyval.asttreenode), (yyvsp[0].integer)); } -#line 1954 "./front/grammar.tab.c" +#line 1954 ".\\front\\grammar.tab.c" break; case 41: /* FuncFParam: BType Ident */ -#line 689 "./front/grammar.y" +#line 689 ".\\front\\grammar.y" { MyPrintf(("%d : FuncFParam -> BType Ident\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -1962,11 +1962,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_FuncFParam); SetBasicType((yyval.asttreenode), (yyvsp[-1].integer)); } -#line 1966 "./front/grammar.tab.c" +#line 1966 ".\\front\\grammar.tab.c" break; case 42: /* FuncFParam: BType Ident "[" "]" ExpGroup */ -#line 697 "./front/grammar.y" +#line 697 ".\\front\\grammar.y" { TreeNode* temp; int tempValue; @@ -2004,11 +2004,11 @@ yyreduce: MyExit(1); } } -#line 2008 "./front/grammar.tab.c" +#line 2008 ".\\front\\grammar.tab.c" break; case 43: /* ExpGroup: "[" Exp "]" ExpGroup */ -#line 738 "./front/grammar.y" +#line 738 ".\\front\\grammar.y" { MyPrintf(("%d : ExpGroup -> \"[\" Exp \"]\" ExpGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -2018,11 +2018,11 @@ yyreduce: MyExit(1); } } -#line 2022 "./front/grammar.tab.c" +#line 2022 ".\\front\\grammar.tab.c" break; case 44: /* ExpGroup: %empty */ -#line 748 "./front/grammar.y" +#line 748 ".\\front\\grammar.y" { MyPrintf(("%d : ExpGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2032,21 +2032,21 @@ yyreduce: MyExit(1); } } -#line 2036 "./front/grammar.tab.c" +#line 2036 ".\\front\\grammar.tab.c" break; case 45: /* Block: "{" BlockItemGroup "}" */ -#line 762 "./front/grammar.y" +#line 762 ".\\front\\grammar.y" { MyPrintf(("%d : Block -> \"{\" BlockItemGroup \"}\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); SetNodeType((yyval.asttreenode), AT_Block); } -#line 2046 "./front/grammar.tab.c" +#line 2046 ".\\front\\grammar.tab.c" break; case 46: /* BlockItemGroup: BlockItem BlockItemGroup */ -#line 771 "./front/grammar.y" +#line 771 ".\\front\\grammar.y" { MyPrintf(("%d : BlockItemGroup -> BlockItem BlockItemGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -2056,11 +2056,11 @@ yyreduce: MyExit(1); } } -#line 2060 "./front/grammar.tab.c" +#line 2060 ".\\front\\grammar.tab.c" break; case 47: /* BlockItemGroup: %empty */ -#line 781 "./front/grammar.y" +#line 781 ".\\front\\grammar.y" { MyPrintf(("%d : BlockItemGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2071,29 +2071,29 @@ yyreduce: } SetOriginalType((yyval.asttreenode),BlockK); } -#line 2075 "./front/grammar.tab.c" +#line 2075 ".\\front\\grammar.tab.c" break; case 48: /* BlockItem: Decl */ -#line 796 "./front/grammar.y" +#line 796 ".\\front\\grammar.y" { MyPrintf(("%d : BlockItem -> Decl\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2084 "./front/grammar.tab.c" +#line 2084 ".\\front\\grammar.tab.c" break; case 49: /* BlockItem: Stmt */ -#line 801 "./front/grammar.y" +#line 801 ".\\front\\grammar.y" { MyPrintf(("%d : BlockItem -> Stmt\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2093 "./front/grammar.tab.c" +#line 2093 ".\\front\\grammar.tab.c" break; case 50: /* Stmt: LVal "=" Exp ";" */ -#line 810 "./front/grammar.y" +#line 810 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> LVal \"=\" Exp \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2115,11 +2115,11 @@ yyreduce: MyExit(1); } } -#line 2119 "./front/grammar.tab.c" +#line 2119 ".\\front\\grammar.tab.c" break; case 51: /* Stmt: ";" */ -#line 832 "./front/grammar.y" +#line 832 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2131,30 +2131,30 @@ yyreduce: SetOriginalType((yyval.asttreenode), StmtK); SetNodeType((yyval.asttreenode), AT_EmptyStmt); } -#line 2135 "./front/grammar.tab.c" +#line 2135 ".\\front\\grammar.tab.c" break; case 52: /* Stmt: Exp ";" */ -#line 844 "./front/grammar.y" +#line 844 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> Exp \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); } -#line 2144 "./front/grammar.tab.c" +#line 2144 ".\\front\\grammar.tab.c" break; case 53: /* Stmt: Block */ -#line 849 "./front/grammar.y" +#line 849 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> Block\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); SetNodeType((yyval.asttreenode), AT_Block); } -#line 2154 "./front/grammar.tab.c" +#line 2154 ".\\front\\grammar.tab.c" break; case 54: /* Stmt: "if" "(" Cond ")" Stmt */ -#line 855 "./front/grammar.y" +#line 855 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"if\" \"(\" Cond \")\" Stmt\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2176,11 +2176,11 @@ yyreduce: MyExit(1); } } -#line 2180 "./front/grammar.tab.c" +#line 2180 ".\\front\\grammar.tab.c" break; case 55: /* Stmt: "if" "(" Cond ")" Stmt "else" Stmt */ -#line 877 "./front/grammar.y" +#line 877 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"if\" \"(\" Cond \")\" Stmt \"else\" Stmt\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2207,11 +2207,11 @@ yyreduce: MyExit(1); } } -#line 2211 "./front/grammar.tab.c" +#line 2211 ".\\front\\grammar.tab.c" break; case 56: /* Stmt: "while" "(" Cond ")" Stmt */ -#line 904 "./front/grammar.y" +#line 904 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"while\" \"(\" Cond \")\" Stmt\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2233,11 +2233,11 @@ yyreduce: MyExit(1); } } -#line 2237 "./front/grammar.tab.c" +#line 2237 ".\\front\\grammar.tab.c" break; case 57: /* Stmt: "break" ";" */ -#line 926 "./front/grammar.y" +#line 926 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"break\" \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2250,11 +2250,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_BreakStmt); SetLineno((yyval.asttreenode), LineNum); } -#line 2254 "./front/grammar.tab.c" +#line 2254 ".\\front\\grammar.tab.c" break; case 58: /* Stmt: "continue" ";" */ -#line 939 "./front/grammar.y" +#line 939 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"continue\" \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2267,11 +2267,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_ContinueStmt); SetLineno((yyval.asttreenode), LineNum); } -#line 2271 "./front/grammar.tab.c" +#line 2271 ".\\front\\grammar.tab.c" break; case 59: /* Stmt: "return" ";" */ -#line 952 "./front/grammar.y" +#line 952 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"return\" \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2284,11 +2284,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_ReturnStmt); SetLineno((yyval.asttreenode), LineNum); } -#line 2288 "./front/grammar.tab.c" +#line 2288 ".\\front\\grammar.tab.c" break; case 60: /* Stmt: "return" Exp ";" */ -#line 965 "./front/grammar.y" +#line 965 ".\\front\\grammar.y" { MyPrintf(("%d : Stmt -> \"return\" Exp \";\"\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2306,30 +2306,30 @@ yyreduce: SetOriginalType((yyval.asttreenode), StmtK); SetLineno((yyval.asttreenode), LineNum); } -#line 2310 "./front/grammar.tab.c" +#line 2310 ".\\front\\grammar.tab.c" break; case 61: /* Exp: AddExp */ -#line 987 "./front/grammar.y" +#line 987 ".\\front\\grammar.y" { MyPrintf(("%d : Exp -> AddExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2319 "./front/grammar.tab.c" +#line 2319 ".\\front\\grammar.tab.c" break; case 62: /* Cond: LOrExp */ -#line 996 "./front/grammar.y" +#line 996 ".\\front\\grammar.y" { MyPrintf(("%d : Cond -> LOrExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); SetNodeType((yyval.asttreenode), AT_Condition); } -#line 2329 "./front/grammar.tab.c" +#line 2329 ".\\front\\grammar.tab.c" break; case 63: /* LVal: Ident ExpGroup */ -#line 1006 "./front/grammar.y" +#line 1006 ".\\front\\grammar.y" { MyPrintf(("%d : LVal -> Ident ExpGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -2347,11 +2347,11 @@ yyreduce: // ************************************************************************** free((yyvsp[-1].asttreenode)); } -#line 2351 "./front/grammar.tab.c" +#line 2351 ".\\front\\grammar.tab.c" break; case 64: /* Number: IntConst */ -#line 1028 "./front/grammar.y" +#line 1028 ".\\front\\grammar.y" { MyPrintf(("%d : Number -> IntConst\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2364,11 +2364,11 @@ yyreduce: SetBasicType((yyval.asttreenode), Integer); SetLiteralContent((yyval.asttreenode), &(yyvsp[0].integer), Integer); } -#line 2368 "./front/grammar.tab.c" +#line 2368 ".\\front\\grammar.tab.c" break; case 65: /* Number: floatConst */ -#line 1041 "./front/grammar.y" +#line 1041 ".\\front\\grammar.y" { MyPrintf(("%d : Number -> floatConst\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2381,47 +2381,47 @@ yyreduce: SetBasicType((yyval.asttreenode), Float); SetLiteralContent((yyval.asttreenode), &(yyvsp[0].floatValue), Float); } -#line 2385 "./front/grammar.tab.c" +#line 2385 ".\\front\\grammar.tab.c" break; case 66: /* PrimaryExp: "(" Exp ")" */ -#line 1058 "./front/grammar.y" +#line 1058 ".\\front\\grammar.y" { MyPrintf(("%d : PrimaryExp -> \"(\" Exp \")\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); } -#line 2394 "./front/grammar.tab.c" +#line 2394 ".\\front\\grammar.tab.c" break; case 67: /* PrimaryExp: LVal */ -#line 1063 "./front/grammar.y" +#line 1063 ".\\front\\grammar.y" { MyPrintf(("%d : PrimaryExp -> LVal\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2403 "./front/grammar.tab.c" +#line 2403 ".\\front\\grammar.tab.c" break; case 68: /* PrimaryExp: Number */ -#line 1068 "./front/grammar.y" +#line 1068 ".\\front\\grammar.y" { MyPrintf(("%d : PrimaryExp -> Number\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2412 "./front/grammar.tab.c" +#line 2412 ".\\front\\grammar.tab.c" break; case 69: /* UnaryExp: PrimaryExp */ -#line 1077 "./front/grammar.y" +#line 1077 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryExp -> PrimaryExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2421 "./front/grammar.tab.c" +#line 2421 ".\\front\\grammar.tab.c" break; case 70: /* UnaryExp: Ident "(" ")" */ -#line 1082 "./front/grammar.y" +#line 1082 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryExp -> Ident \"(\" \")\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-2].asttreenode); @@ -2429,11 +2429,11 @@ yyreduce: SetNodeType((yyval.asttreenode), AT_FuncCall); Ast_SetFlag((yyval.asttreenode), FUNCCALL_SIGNATURE); } -#line 2433 "./front/grammar.tab.c" +#line 2433 ".\\front\\grammar.tab.c" break; case 71: /* UnaryExp: Ident "(" FuncRParams ")" */ -#line 1090 "./front/grammar.y" +#line 1090 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryExp -> Ident \"(\" FuncRParams \")\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-1].asttreenode); @@ -2453,11 +2453,11 @@ yyreduce: // ************************************************************************** free((yyvsp[-3].asttreenode)); } -#line 2457 "./front/grammar.tab.c" +#line 2457 ".\\front\\grammar.tab.c" break; case 72: /* UnaryExp: UnaryOp UnaryExp */ -#line 1110 "./front/grammar.y" +#line 1110 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryExp -> UnaryOp UnaryExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2474,38 +2474,38 @@ yyreduce: MyExit(1); } } -#line 2478 "./front/grammar.tab.c" +#line 2478 ".\\front\\grammar.tab.c" break; case 73: /* UnaryOp: "+" */ -#line 1131 "./front/grammar.y" +#line 1131 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryOp -> \"+\"\n", ++nCount)); (yyval.integer) = AST_UNARYOP_PLUS; } -#line 2487 "./front/grammar.tab.c" +#line 2487 ".\\front\\grammar.tab.c" break; case 74: /* UnaryOp: "-" */ -#line 1136 "./front/grammar.y" +#line 1136 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryOp -> \"-\"\n", ++nCount)); (yyval.integer) = AST_UNARYOP_MINUS; } -#line 2496 "./front/grammar.tab.c" +#line 2496 ".\\front\\grammar.tab.c" break; case 75: /* UnaryOp: "!" */ -#line 1141 "./front/grammar.y" +#line 1141 ".\\front\\grammar.y" { MyPrintf(("%d : UnaryOp -> \"!\"\n", ++nCount)); (yyval.integer) = AST_UNARYOP_EXCLAIM; } -#line 2505 "./front/grammar.tab.c" +#line 2505 ".\\front\\grammar.tab.c" break; case 76: /* FuncRParams: Exp FuncRParamsGroup */ -#line 1150 "./front/grammar.y" +#line 1150 ".\\front\\grammar.y" { MyPrintf(("%d : FuncRParams -> Exp FuncRParamsGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -2516,11 +2516,11 @@ yyreduce: } SetNodeType((yyval.asttreenode), AT_FuncRParams); } -#line 2520 "./front/grammar.tab.c" +#line 2520 ".\\front\\grammar.tab.c" break; case 77: /* FuncRParamsGroup: "," Exp FuncRParamsGroup */ -#line 1164 "./front/grammar.y" +#line 1164 ".\\front\\grammar.y" { MyPrintf(("%d : FuncRParamsGroup -> \",\" Exp FuncRParamsGroup\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); @@ -2530,11 +2530,11 @@ yyreduce: MyExit(1); } } -#line 2534 "./front/grammar.tab.c" +#line 2534 ".\\front\\grammar.tab.c" break; case 78: /* FuncRParamsGroup: %empty */ -#line 1174 "./front/grammar.y" +#line 1174 ".\\front\\grammar.y" { MyPrintf(("%d : FuncRParamsGroup -> (null)\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2545,20 +2545,20 @@ yyreduce: } SetOriginalType((yyval.asttreenode),FuncRParamsK); } -#line 2549 "./front/grammar.tab.c" +#line 2549 ".\\front\\grammar.tab.c" break; case 79: /* MulExp: UnaryExp */ -#line 1189 "./front/grammar.y" +#line 1189 ".\\front\\grammar.y" { MyPrintf(("%d : MulExp -> UnaryExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2558 "./front/grammar.tab.c" +#line 2558 ".\\front\\grammar.tab.c" break; case 80: /* MulExp: MulExp "*" UnaryExp */ -#line 1194 "./front/grammar.y" +#line 1194 ".\\front\\grammar.y" { MyPrintf(("%d : MulExp -> MulExp \"*\" UnaryExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2580,11 +2580,11 @@ yyreduce: MyExit(1); } } -#line 2584 "./front/grammar.tab.c" +#line 2584 ".\\front\\grammar.tab.c" break; case 81: /* MulExp: MulExp "/" UnaryExp */ -#line 1216 "./front/grammar.y" +#line 1216 ".\\front\\grammar.y" { MyPrintf(("%d : MulExp -> MulExp \"/\" UnaryExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2606,11 +2606,11 @@ yyreduce: MyExit(1); } } -#line 2610 "./front/grammar.tab.c" +#line 2610 ".\\front\\grammar.tab.c" break; case 82: /* MulExp: MulExp "%" UnaryExp */ -#line 1238 "./front/grammar.y" +#line 1238 ".\\front\\grammar.y" { MyPrintf(("%d : MulExp -> MulExp \"%\" UnaryExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2632,20 +2632,20 @@ yyreduce: MyExit(1); } } -#line 2636 "./front/grammar.tab.c" +#line 2636 ".\\front\\grammar.tab.c" break; case 83: /* AddExp: MulExp */ -#line 1264 "./front/grammar.y" +#line 1264 ".\\front\\grammar.y" { MyPrintf(("%d : AddExp -> MulExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2645 "./front/grammar.tab.c" +#line 2645 ".\\front\\grammar.tab.c" break; case 84: /* AddExp: AddExp "+" MulExp */ -#line 1269 "./front/grammar.y" +#line 1269 ".\\front\\grammar.y" { MyPrintf(("%d : AddExp -> AddExp \"+\" MulExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2667,11 +2667,11 @@ yyreduce: MyExit(1); } } -#line 2671 "./front/grammar.tab.c" +#line 2671 ".\\front\\grammar.tab.c" break; case 85: /* AddExp: AddExp "-" MulExp */ -#line 1291 "./front/grammar.y" +#line 1291 ".\\front\\grammar.y" { MyPrintf(("%d : AddExp -> AddExp \"-\" MulExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2693,20 +2693,20 @@ yyreduce: MyExit(1); } } -#line 2697 "./front/grammar.tab.c" +#line 2697 ".\\front\\grammar.tab.c" break; case 86: /* RelExp: AddExp */ -#line 1317 "./front/grammar.y" +#line 1317 ".\\front\\grammar.y" { MyPrintf(("%d : RelExp -> AddExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2706 "./front/grammar.tab.c" +#line 2706 ".\\front\\grammar.tab.c" break; case 87: /* RelExp: RelExp "<" AddExp */ -#line 1322 "./front/grammar.y" +#line 1322 ".\\front\\grammar.y" { MyPrintf(("%d : RelExp -> RelExp \"<\" AddExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2729,11 +2729,11 @@ yyreduce: MyExit(1); } } -#line 2733 "./front/grammar.tab.c" +#line 2733 ".\\front\\grammar.tab.c" break; case 88: /* RelExp: RelExp ">" AddExp */ -#line 1345 "./front/grammar.y" +#line 1345 ".\\front\\grammar.y" { MyPrintf(("%d : RelExp -> RelExp \">\" AddExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2756,11 +2756,11 @@ yyreduce: MyExit(1); } } -#line 2760 "./front/grammar.tab.c" +#line 2760 ".\\front\\grammar.tab.c" break; case 89: /* RelExp: RelExp "<=" AddExp */ -#line 1368 "./front/grammar.y" +#line 1368 ".\\front\\grammar.y" { MyPrintf(("%d : RelExp -> RelExp \"<=\" AddExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2783,11 +2783,11 @@ yyreduce: MyExit(1); } } -#line 2787 "./front/grammar.tab.c" +#line 2787 ".\\front\\grammar.tab.c" break; case 90: /* RelExp: RelExp ">=" AddExp */ -#line 1391 "./front/grammar.y" +#line 1391 ".\\front\\grammar.y" { MyPrintf(("%d : RelExp -> RelExp \">=\" AddExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2810,20 +2810,20 @@ yyreduce: MyExit(1); } } -#line 2814 "./front/grammar.tab.c" +#line 2814 ".\\front\\grammar.tab.c" break; case 91: /* EqExp: RelExp */ -#line 1418 "./front/grammar.y" +#line 1418 ".\\front\\grammar.y" { MyPrintf(("%d : EqExp -> RelExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2823 "./front/grammar.tab.c" +#line 2823 ".\\front\\grammar.tab.c" break; case 92: /* EqExp: EqExp "==" RelExp */ -#line 1423 "./front/grammar.y" +#line 1423 ".\\front\\grammar.y" { MyPrintf(("%d : EqExp -> EqExp \"==\" RelExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2846,11 +2846,11 @@ yyreduce: MyExit(1); } } -#line 2850 "./front/grammar.tab.c" +#line 2850 ".\\front\\grammar.tab.c" break; case 93: /* EqExp: EqExp "!=" RelExp */ -#line 1446 "./front/grammar.y" +#line 1446 ".\\front\\grammar.y" { MyPrintf(("%d : EqExp -> EqExp \"!=\" RelExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2873,20 +2873,20 @@ yyreduce: MyExit(1); } } -#line 2877 "./front/grammar.tab.c" +#line 2877 ".\\front\\grammar.tab.c" break; case 94: /* LAndExp: EqExp */ -#line 1473 "./front/grammar.y" +#line 1473 ".\\front\\grammar.y" { MyPrintf(("%d : LAndExp -> EqExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2886 "./front/grammar.tab.c" +#line 2886 ".\\front\\grammar.tab.c" break; case 95: /* LAndExp: LAndExp "&&" EqExp */ -#line 1478 "./front/grammar.y" +#line 1478 ".\\front\\grammar.y" { MyPrintf(("%d : LAndExp -> LAndExp \"&&\" EqExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2909,20 +2909,20 @@ yyreduce: MyExit(1); } } -#line 2913 "./front/grammar.tab.c" +#line 2913 ".\\front\\grammar.tab.c" break; case 96: /* LOrExp: LAndExp */ -#line 1505 "./front/grammar.y" +#line 1505 ".\\front\\grammar.y" { MyPrintf(("%d : LOrExp -> LAndExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2922 "./front/grammar.tab.c" +#line 2922 ".\\front\\grammar.tab.c" break; case 97: /* LOrExp: LOrExp "||" LAndExp */ -#line 1510 "./front/grammar.y" +#line 1510 ".\\front\\grammar.y" { MyPrintf(("%d : LOrExp -> LOrExp \"||\" LAndExp\n", ++nCount)); (yyval.asttreenode) = AllocNode(); @@ -2945,20 +2945,20 @@ yyreduce: MyExit(1); } } -#line 2949 "./front/grammar.tab.c" +#line 2949 ".\\front\\grammar.tab.c" break; case 98: /* ConstExp: AddExp */ -#line 1537 "./front/grammar.y" +#line 1537 ".\\front\\grammar.y" { MyPrintf(("%d : ConstExp -> AddExp\n", ++nCount)); (yyval.asttreenode) = (yyvsp[0].asttreenode); } -#line 2958 "./front/grammar.tab.c" +#line 2958 ".\\front\\grammar.tab.c" break; case 99: /* FuncDecl: BType Ident "(" ")" ";" */ -#line 1547 "./front/grammar.y" +#line 1547 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> BType Ident \"(\" \")\" \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -2979,11 +2979,11 @@ yyreduce: MyExit(1); } } -#line 2983 "./front/grammar.tab.c" +#line 2983 ".\\front\\grammar.tab.c" break; case 100: /* FuncDecl: BType Ident "(" FuncFParams ")" ";" */ -#line 1568 "./front/grammar.y" +#line 1568 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> BType Ident \"(\" FuncFParams \")\" \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-4].asttreenode); @@ -2996,11 +2996,11 @@ yyreduce: MyExit(1); } } -#line 3000 "./front/grammar.tab.c" +#line 3000 ".\\front\\grammar.tab.c" break; case 101: /* FuncDecl: "void" Ident "(" ")" ";" */ -#line 1581 "./front/grammar.y" +#line 1581 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" \")\" \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-3].asttreenode); @@ -3021,11 +3021,11 @@ yyreduce: MyExit(1); } } -#line 3025 "./front/grammar.tab.c" +#line 3025 ".\\front\\grammar.tab.c" break; case 102: /* FuncDecl: "void" Ident "(" FuncFParams ")" ";" */ -#line 1602 "./front/grammar.y" +#line 1602 ".\\front\\grammar.y" { MyPrintf(("%d : FuncDef -> \"void\" Ident \"(\" FuncFParams \")\" \";\"\n", ++nCount)); (yyval.asttreenode) = (yyvsp[-4].asttreenode); @@ -3038,11 +3038,11 @@ yyreduce: MyExit(1); } } -#line 3042 "./front/grammar.tab.c" +#line 3042 ".\\front\\grammar.tab.c" break; -#line 3046 "./front/grammar.tab.c" +#line 3046 ".\\front\\grammar.tab.c" default: break; } @@ -3235,6 +3235,6 @@ yyreturnlab: return yyresult; } -#line 1616 "./front/grammar.y" +#line 1616 ".\\front\\grammar.y" diff --git a/front/lex.yy.c b/front/lex.yy.c index 6f7615041d8925f602e0182804a9df61f159398c..0cba0fdbf78f0cf329efecdc266200698867e256 100644 --- a/front/lex.yy.c +++ b/front/lex.yy.c @@ -1,6 +1,6 @@ -#line 1 "./front/lex.yy.c" +#line 1 ".\\front\\lex.yy.c" -#line 3 "./front/lex.yy.c" +#line 3 ".\\front\\lex.yy.c" #define YY_INT_ALIGNED short int @@ -536,16 +536,16 @@ int yy_flex_debug = 0; #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "./front/lex.l" -#line 2 "./front/lex.l" +#line 1 ".\\front\\lex.l" +#line 2 ".\\front\\lex.l" #define YY_NO_UNISTD_H #include "compiler.h" #include <stdio.h> #include <string.h> #include "grammar.tab.h" -#line 546 "./front/lex.yy.c" +#line 546 ".\\front\\lex.yy.c" -#line 548 "./front/lex.yy.c" +#line 548 ".\\front\\lex.yy.c" #define INITIAL 0 #define COMMENT 1 @@ -764,12 +764,12 @@ YY_DECL } { -#line 19 "./front/lex.l" +#line 19 ".\\front\\lex.l" -#line 22 "./front/lex.l" +#line 22 ".\\front\\lex.l" -#line 772 "./front/lex.yy.c" +#line 772 ".\\front\\lex.yy.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -828,234 +828,234 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 23 "./front/lex.l" +#line 23 ".\\front\\lex.l" {;} //忽略空白符 YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 24 "./front/lex.l" +#line 24 ".\\front\\lex.l" {LineNum = LineNum + 1;} //匹配到换行符,行数+1 YY_BREAK case 3: YY_RULE_SETUP -#line 25 "./front/lex.l" +#line 25 ".\\front\\lex.l" {return (L_INT);} YY_BREAK case 4: YY_RULE_SETUP -#line 26 "./front/lex.l" +#line 26 ".\\front\\lex.l" {return (L_FLOAT);} YY_BREAK case 5: YY_RULE_SETUP -#line 27 "./front/lex.l" +#line 27 ".\\front\\lex.l" {return (L_CONST);} YY_BREAK case 6: YY_RULE_SETUP -#line 28 "./front/lex.l" +#line 28 ".\\front\\lex.l" {return (L_VOID);} YY_BREAK case 7: YY_RULE_SETUP -#line 29 "./front/lex.l" +#line 29 ".\\front\\lex.l" {return (L_BREAK);} YY_BREAK case 8: YY_RULE_SETUP -#line 30 "./front/lex.l" +#line 30 ".\\front\\lex.l" {return (L_CONTINUE);} YY_BREAK case 9: YY_RULE_SETUP -#line 31 "./front/lex.l" +#line 31 ".\\front\\lex.l" {return (L_RETURN);} YY_BREAK case 10: YY_RULE_SETUP -#line 32 "./front/lex.l" +#line 32 ".\\front\\lex.l" {return (L_IF);} YY_BREAK case 11: YY_RULE_SETUP -#line 33 "./front/lex.l" +#line 33 ".\\front\\lex.l" {return (L_ELSE);} YY_BREAK case 12: YY_RULE_SETUP -#line 34 "./front/lex.l" +#line 34 ".\\front\\lex.l" {return (L_WHILE);} YY_BREAK case 13: YY_RULE_SETUP -#line 35 "./front/lex.l" +#line 35 ".\\front\\lex.l" {return (L_FOR);} YY_BREAK case 14: YY_RULE_SETUP -#line 36 "./front/lex.l" +#line 36 ".\\front\\lex.l" {return (L_LT);} YY_BREAK case 15: YY_RULE_SETUP -#line 37 "./front/lex.l" +#line 37 ".\\front\\lex.l" {return (L_LTEQ);} YY_BREAK case 16: YY_RULE_SETUP -#line 38 "./front/lex.l" +#line 38 ".\\front\\lex.l" {return (L_GT);} YY_BREAK case 17: YY_RULE_SETUP -#line 39 "./front/lex.l" +#line 39 ".\\front\\lex.l" {return (L_GTEQ);} YY_BREAK case 18: YY_RULE_SETUP -#line 40 "./front/lex.l" +#line 40 ".\\front\\lex.l" {return (L_EQUALS);} YY_BREAK case 19: YY_RULE_SETUP -#line 41 "./front/lex.l" +#line 41 ".\\front\\lex.l" {return (L_NOTEQ);} YY_BREAK case 20: YY_RULE_SETUP -#line 42 "./front/lex.l" +#line 42 ".\\front\\lex.l" {return (L_ASSIGN);} YY_BREAK case 21: YY_RULE_SETUP -#line 43 "./front/lex.l" +#line 43 ".\\front\\lex.l" {return (L_PLUS);} YY_BREAK case 22: YY_RULE_SETUP -#line 44 "./front/lex.l" +#line 44 ".\\front\\lex.l" {return (L_MINUS);} YY_BREAK case 23: YY_RULE_SETUP -#line 45 "./front/lex.l" +#line 45 ".\\front\\lex.l" {return (L_MULT);} YY_BREAK case 24: YY_RULE_SETUP -#line 46 "./front/lex.l" +#line 46 ".\\front\\lex.l" {return (L_DIV);} YY_BREAK case 25: YY_RULE_SETUP -#line 47 "./front/lex.l" +#line 47 ".\\front\\lex.l" {return (L_MOD);} YY_BREAK case 26: YY_RULE_SETUP -#line 48 "./front/lex.l" +#line 48 ".\\front\\lex.l" {return (L_EXCLAIM);} YY_BREAK case 27: YY_RULE_SETUP -#line 49 "./front/lex.l" +#line 49 ".\\front\\lex.l" {return (L_ANDAND);} YY_BREAK case 28: YY_RULE_SETUP -#line 50 "./front/lex.l" +#line 50 ".\\front\\lex.l" {return (L_OROR);} YY_BREAK case 29: YY_RULE_SETUP -#line 51 "./front/lex.l" +#line 51 ".\\front\\lex.l" {return (L_SEMI);} YY_BREAK case 30: YY_RULE_SETUP -#line 52 "./front/lex.l" +#line 52 ".\\front\\lex.l" {return (L_COLON);} YY_BREAK case 31: YY_RULE_SETUP -#line 53 "./front/lex.l" +#line 53 ".\\front\\lex.l" {return (L_COMMA);} YY_BREAK case 32: YY_RULE_SETUP -#line 54 "./front/lex.l" +#line 54 ".\\front\\lex.l" {return (L_LPAREN);} YY_BREAK case 33: YY_RULE_SETUP -#line 55 "./front/lex.l" +#line 55 ".\\front\\lex.l" {return (L_RPAREN);} YY_BREAK case 34: YY_RULE_SETUP -#line 56 "./front/lex.l" +#line 56 ".\\front\\lex.l" {return (L_LCURLY);} YY_BREAK case 35: YY_RULE_SETUP -#line 57 "./front/lex.l" +#line 57 ".\\front\\lex.l" {return (L_RCURLY);} YY_BREAK case 36: YY_RULE_SETUP -#line 58 "./front/lex.l" +#line 58 ".\\front\\lex.l" {return (L_LBRACK);} YY_BREAK case 37: YY_RULE_SETUP -#line 59 "./front/lex.l" +#line 59 ".\\front\\lex.l" {return (L_RBRACK);} YY_BREAK case 38: YY_RULE_SETUP -#line 61 "./front/lex.l" +#line 61 ".\\front\\lex.l" {BEGIN(COMMENT);} YY_BREAK case 39: YY_RULE_SETUP -#line 62 "./front/lex.l" +#line 62 ".\\front\\lex.l" {BEGIN(INITIAL);} YY_BREAK case 40: /* rule 40 can match eol */ YY_RULE_SETUP -#line 63 "./front/lex.l" +#line 63 ".\\front\\lex.l" {LineNum++;} YY_BREAK case 41: YY_RULE_SETUP -#line 64 "./front/lex.l" +#line 64 ".\\front\\lex.l" {;} YY_BREAK case YY_STATE_EOF(COMMENT): -#line 65 "./front/lex.l" +#line 65 ".\\front\\lex.l" {printf("%d: Unterminated comment\n", LineNum); MyExit(1);} YY_BREAK case 42: YY_RULE_SETUP -#line 67 "./front/lex.l" +#line 67 ".\\front\\lex.l" {BEGIN(COMMENT_SINGLELINE);} YY_BREAK case 43: /* rule 43 can match eol */ YY_RULE_SETUP -#line 68 "./front/lex.l" +#line 68 ".\\front\\lex.l" {BEGIN(INITIAL);LineNum++;} YY_BREAK case 44: YY_RULE_SETUP -#line 69 "./front/lex.l" +#line 69 ".\\front\\lex.l" {;} YY_BREAK case 45: YY_RULE_SETUP -#line 71 "./front/lex.l" +#line 71 ".\\front\\lex.l" { yylval.integer = (int)strtol(yytext, NULL, 10); return (IntConst); @@ -1063,7 +1063,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 76 "./front/lex.l" +#line 76 ".\\front\\lex.l" { yylval.integer = (int)strtol(yytext, NULL, 8); return (IntConst); @@ -1071,7 +1071,7 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 81 "./front/lex.l" +#line 81 ".\\front\\lex.l" { yylval.integer = (int)strtol(yytext, NULL, 16); return (IntConst); @@ -1079,7 +1079,7 @@ YY_RULE_SETUP YY_BREAK case 48: YY_RULE_SETUP -#line 86 "./front/lex.l" +#line 86 ".\\front\\lex.l" { yylval.floatValue = (float)atof(yytext); return (floatConst); @@ -1087,7 +1087,7 @@ YY_RULE_SETUP YY_BREAK case 49: YY_RULE_SETUP -#line 91 "./front/lex.l" +#line 91 ".\\front\\lex.l" { yylval.floatValue = (float)atof(yytext); return (floatConst); @@ -1095,7 +1095,7 @@ YY_RULE_SETUP YY_BREAK case 50: YY_RULE_SETUP -#line 96 "./front/lex.l" +#line 96 ".\\front\\lex.l" { yylval.asttreenode = AllocNode(); if( yylval.asttreenode == NULL ) @@ -1115,10 +1115,10 @@ YY_RULE_SETUP YY_BREAK case 51: YY_RULE_SETUP -#line 113 "./front/lex.l" +#line 113 ".\\front\\lex.l" ECHO; YY_BREAK -#line 1121 "./front/lex.yy.c" +#line 1121 ".\\front\\lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(COMMENT_SINGLELINE): yyterminate(); @@ -2124,7 +2124,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 113 "./front/lex.l" +#line 113 ".\\front\\lex.l" int yywrap(){ //文件结束处理函数,如果返回值为1就停止解析。可以用来解析多个文件。 return 1; diff --git a/front/main.c b/front/main.c index b61f0aca4a650a48a430c8e6e6fe8ba415ee2682..38efad81b6f69928016068c0fb24a142b53f6781 100644 --- a/front/main.c +++ b/front/main.c @@ -181,21 +181,32 @@ main( goto label1; } -#if defined( WITH_OUTPUTCFG ) - if (!OutputCFG("testcase.pdf", &g_cfg, 0)) + if (!BuildPrunedSSA(&g_cfg)) { goto label1; } -#endif - - if (!BuildPrunedSSA(&g_cfg)) + +#if defined( WITH_OUTPUTCFG ) + if (!OutputCFG("testcase.pdf", &g_cfg, 0)) { goto label1; } - +#endif if (g_Options.optimize > 0) { // 有优化 + if (!PropagateConstant(&g_cfg, &g_symtab)) + { + goto label1; + } + +#if defined( WITH_OUTPUTCFG ) + if (!OutputCFG("testcase_1.pdf", &g_cfg, 0)) + { + goto label1; + } +#endif + #if defined( WITH_LOCAL_VALUE_NUMBER ) if (!Local_Value_Number(&g_cfg)) { @@ -326,7 +337,7 @@ static int ValidOptions(char *argv[], int argc) { g_Options = default_options; for( i=1; i<argc; i++ ) { - if( (argv[i][0] == '-') /*|| (argv[i][0] == '/')*/ ) { + if( argv[i][0] == '-' /*|| (argv[i][0] == '/')*/ ) { switch( argv[i][1] ) { case 'v' : g_Options.bVerbose = 1; diff --git a/front/symtab.c b/front/symtab.c index 41e0a89954f73a320e4db9ca2c91f13a0a12c884..71bd26c67fd632ef3e02664f3104b803bd82bede 100644 --- a/front/symtab.c +++ b/front/symtab.c @@ -1267,7 +1267,7 @@ int SymGetInitValueArray(SYMENT *psyment, int iIndex, void *lpValue) } else { - if (psyment->BasicType == Float) + if (psyment->BasicType == Integer) { *(int *)lpValue = result->integer_value; } @@ -1889,3 +1889,13 @@ PDYNAMIC_ARRAY SymGetDefInfo(SYMENT* psyment) { return &psyment->defs; } + +void SymSetPointTo(SYMENT* psyment, SYMENT* pointTo) +{ + psyment->pointTo = pointTo; +} + +SYMENT* SymGetPointTo(SYMENT* psyment) +{ + return psyment->pointTo; +} diff --git a/include/backend.h b/include/backend.h index 9f03b1dae21c87fe9aa908f0103cf35702495d75..7cfe12ce59f481277d58f72816de87ce775a71e4 100644 --- a/include/backend.h +++ b/include/backend.h @@ -27,12 +27,6 @@ typedef enum opmov, /* 数据传送指令 mov */ opldr, /* 数据传送指令 ldr */ opstr, /* 数据传送指令 str */ - opmoveq, /* 数据传送指令 moveq */ - opmovne, /* 数据传送指令 movne */ - opmovle, /* 数据传送指令 movle */ - opmovgt, /* 数据传送指令 movgt */ - opmovlt, /* 数据传送指令 movlt */ - opmovge, /* 数据传送指令 movge */ opvmrs, /* 数据传送指令 vmrs */ opvmov, /* 数据传送指令 vmov */ opvldr32, /* 数据传送指令 vldr.32 */ @@ -65,12 +59,6 @@ typedef enum opvcmpef32, /* 浮点数比较指令 vcmpe.f32 */ /* 跳转指令 */ opbx, /* 跳转指令 间接跳转 */ - opbeq, /* 跳转指令 beq */ - opbne, /* 跳转指令 bne */ - opblt, /* 跳转指令 blt */ - opble, /* 跳转指令 ble */ - opbgt, /* 跳转指令 bgt */ - opbge, /* 跳转指令 bge */ opb, /* 跳转指令 goto */ opbl, /* 跳转指令 函数调用 */ /* 函数调用相关指令 */ @@ -86,6 +74,28 @@ typedef enum opDBG, /* 伪指令 调试 */ } OPCODE; +typedef enum condition_code condition_code; + +enum condition_code { + CONDITION_AL, /* Always (this is the default) */ + CONDITION_EQ, /* Equal */ + CONDITION_NE, /* Not equal */ + CONDITION_CS, /* Carry set (identical to HS) */ + CONDITION_HS, /* Unsigned higher or same (identical to CS) */ + CONDITION_CC, /* Carry clear (identical to LO) */ + CONDITION_LO, /* Unsigned lower (identical to CC) */ + CONDITION_MI, /* Minus or negative result */ + CONDITION_PL, /* Positive or zero result */ + CONDITION_VS, /* Overflow */ + CONDITION_VC, /* No overflow */ + CONDITION_HI, /* Unsigned higher */ + CONDITION_LS, /* Unsigned lower or same */ + CONDITION_GE, /* Signed greater than or equal */ + CONDITION_LT, /* Signed less than */ + CONDITION_GT, /* Signed greater than */ + CONDITION_LE, /* Signed less than or equal */ + }; + struct argType { int argType; union { @@ -137,6 +147,8 @@ typedef struct argType ARG; typedef struct { unsigned long identifier; // 标识符 OPCODE iop ; + condition_code cond; + int suffix; int nargs; ARG Args[1] ; } INSTRUCTION; @@ -202,7 +214,7 @@ int addasmInstrsub(PLLI instructions, int dest, int src1, int src2); int addasmInstrsubi(PLLI instructions, PDYNAMIC_ARRAY virtregs, int dest, int src1, int src2, int isuncertain); int addasmInstrsize(PLLI instructions, SYMENT *psyment, void *pValue, int fIsNum); int addasmInstrbx(PLLI instructions, int reg); -int addasmInstrbranches(PLLI instructions, OPCODE iop, unsigned long destination); +int addasmInstrbranches(PLLI instructions, condition_code iop, unsigned long destination); int addasmInstrmovv2p(PLLI instructions, int dest, PVIRTREGINFO src); int addasmInstrbl(PLLI instructions, SYMENT *psyment); int addasmInstrstr(PLLI instructions, int idregister, int iOffset); diff --git a/include/dataflow.h b/include/dataflow.h index 8aa659a03ac5aa20cde707f9da42f0156eef30cf..3de8a8038176969f5622cbb04de9616d5fe63a2e 100644 --- a/include/dataflow.h +++ b/include/dataflow.h @@ -36,5 +36,6 @@ typedef EXPRESSION *LPEXPRESSION; int DataflowAnalysis(control_flow_graph *cfg); void PrintLive(FILE *fileOutput, control_flow_graph *cfg); +void Printdefuse(FILE *fileOutput, control_flow_graph *cfg); #endif // !defined(DATAFLOW_H) diff --git a/include/frontend.h b/include/frontend.h index e99f868505c41e4233e95daa06a9784fa28a7df3..498cbd44a07044347466eb6b802c0e5a46fc8a29 100644 --- a/include/frontend.h +++ b/include/frontend.h @@ -82,6 +82,7 @@ typedef struct _syment ValueType type; ExpType BasicType; // 'void' | 'int' | 'float' int IsPointer; // 是否是指针类型 + struct _syment* pointTo; // 若是指针类型,它指向什么? long offset; /* 相对地址 */ long width; /* 类型的宽度 */ int isConst; /* 是否是常量 */ @@ -205,9 +206,9 @@ typedef struct df_ref df_ref; struct df_ref { - IRINSTRUCTION *insn; - int count; - int iArgIndex; + IRINSTRUCTION *insn; // 中间指令 + int count; // SSA名字的数字 + int iArgIndex; // 它在三地址代码中的位置 }; /* from IRInst.c */ @@ -217,7 +218,7 @@ struct df_ref typedef enum { IRINST_OP_MAX, /* 最大指令码,也是无效指令 */ - IRINST_OP_PLUS, /* 加法指令,二元运算 ;约定:如果操作数1是数组,则相加结果是指针类型 */ + IRINST_OP_PLUS, /* 加法指令,二元运算 ;约定:如果操作数1是数组,则相加结果是指针类型,对数组既定值又使用。 */ IRINST_OP_MULT, /* 乘法指令,二元运算 */ IRINST_OP_MINUS, /* 减法指令,二元运算 */ IRINST_OP_DIV, /* 除法指令,二元运算 */ @@ -235,7 +236,7 @@ typedef enum { IRINST_OP_ARRAYASSIGN, /* x[i]=y x<-Update(x, i,y)*/ IRINST_OP_ASSIGN, /* 复制指令,一元运算 */ - IRINST_OP_PARAM, /* 参数传递 */ + IRINST_OP_PARAM, /* 参数传递,会对数组定值 */ /* 注意:参数被放在arg1中,因为参数有可能是一个字面量 */ IRINST_OP_GOTO, /* 跳转指令 */ IRINST_OP_RETURN, /* 返回指令 */ @@ -245,7 +246,7 @@ typedef enum { IRINST_UNARYOP_MINUS, /* 单目运算符- */ IRINST_UNARYOP_EXCLAIM, /* 单目运算符! */ - IRINST_OP_ENTRY, /* 函数入口指令 */ + IRINST_OP_ENTRY, /* 函数入口指令,会对所有参数定值 */ IRINST_OP_EXIT, /* 函数出口指令 */ IRINST_OP_ITR, /* 整数转换成实数 */ @@ -603,6 +604,8 @@ int SymIsPure(SYMENT* psyment); void SymSetIsPure(SYMENT* psyment, int IsPure); PDYNAMIC_ARRAY SymGetDefInfo(SYMENT* psyment); PDYNAMIC_ARRAY SymGetUseInfo(SYMENT* psyment); +SYMENT* SymGetPointTo(SYMENT* psyment); +void SymSetPointTo(SYMENT* psyment, SYMENT* pointTo); /* from IRInst.c */ IRINSTRUCTION *addInst(InterCode *code, InterCode *g_code, unsigned long *labelCount, IRInstOperator iop, void *iarg1, void *iarg2, void *iarg3); @@ -641,6 +644,8 @@ void ir_SetMark(IRINSTRUCTION* inst, int bMark); void ir_SetContainer(IRINSTRUCTION* inst, void * bb); void * ir_GetContainer(IRINSTRUCTION* inst); void swap_operands(InterCode *g_code); +SYMENT* FinddefinedArray(IRINSTRUCTION* insn); +IRINSTRUCTION* FindParamFunc(IRINSTRUCTION* insn); #if defined( WITH_PRINTIR_NEW ) int PrintIr_New(FILE *stream, InterCode *g_code, SYMTAB *SymTable); diff --git a/include/grammar.tab.h b/include/grammar.tab.h index 5f02f1135784188640ff90eb4662042a3289da72..da309c6c5eaada4a82162b54d51cf8e122132cdf 100644 --- a/include/grammar.tab.h +++ b/include/grammar.tab.h @@ -121,13 +121,13 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 22 "./front/grammar.y" +#line 22 ".\\front\\grammar.y" float floatValue; int integer; TreeNode* asttreenode; -#line 131 "./include/grammar.tab.h" +#line 131 ".\\include\\grammar.tab.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/include/ssa.h b/include/ssa.h index 399a19ffe535cc14fd53466f5e83d0d1f15b4758..fc8305aeae6cc90a80103b6824cdb26dd3a7f484 100644 --- a/include/ssa.h +++ b/include/ssa.h @@ -22,6 +22,8 @@ int Local_Value_Number(control_flow_graph* graph); int run_dce(control_flow_graph* graph); #endif +int PropagateConstant(control_flow_graph* graph, SYMTAB *g_symtab); + void phi_set_arg (phi *phi, unsigned index, SYMENT * phiarg, int iNumber); phi_arg_d *phi_arg (phi *phi_stmt, unsigned index); int phi_num_args (phi *phi_stmt); diff --git a/optimize/cfg.c b/optimize/cfg.c index 39e9f5de2eafa415fb209e81b7aca54705103c3b..ce3efd425fe88741aa1dd41fdea51f3dbcfebb26 100644 --- a/optimize/cfg.c +++ b/optimize/cfg.c @@ -361,6 +361,7 @@ void cfg_fast_deleteinst(control_flow_graph* graph, basic_block *bb, LIST_ITERAT else { ir_SetOp(List_Current(iterator), IRINST_NOP); + List_Next(iterator); fNeedPatch = 0; } @@ -519,7 +520,7 @@ int OutputCFG(char *lpszFilename, control_flow_graph *cfg, int bReverse) fprintf( fp, " struct%lu [label=\"B%lu | " ,bb_GetIdent(bb), bb_GetIdent(bb) ); instructions = bb_GetInsts(bb); - if (iCount < 90) + if (iCount <= 162) { number =0; List_TRAVERSE(instructions, pvisit, &iterator) diff --git a/optimize/dataflow.c b/optimize/dataflow.c index 96ad137582b93bfadd1e2d8873f63e07888a3a8d..4a64ec5aea54a1d1e7d837e9a4efdcd01aaadb1a 100644 --- a/optimize/dataflow.c +++ b/optimize/dataflow.c @@ -127,10 +127,83 @@ void PrintLive(FILE *fileOutput, control_flow_graph *cfg) } } -static int GetDefUses(control_flow_graph *cfg) +void Printdefuse(FILE *fileOutput, control_flow_graph *cfg) { int inumber ; // 基本块数 int i; + int count; + basic_block *bb; + CAVLTreeCursor c; + LPUDINFO lpUDData; + static const int max_nums_on_line = 10; + + inumber = cfg_GetBlockNumber(cfg); + for (i = 0; i < inumber; i++) + { + bb = DynamicArrayRetrieve(&cfg->bbs, i); + fprintf (fileOutput, " %s %lu:", " livedef:", bb_GetIdent(bb)); + count = max_nums_on_line + 1; + for (CAVLTreeSetCursor(bb_GetLiveVariablesDef(bb), POINT_TO_SMALLEST, &c, (void**)&lpUDData); lpUDData; CAVLTreeGetNext(&c, (void**)&lpUDData)) + { + if (count > max_nums_on_line) + { + fprintf (fileOutput, "\n "); + count = 0; + } + fprintf (fileOutput, " "); + PrintSymbol(fileOutput, lpUDData->lpBase); + if (lpUDData->IsArray) + { + fprintf(fileOutput, "["); + if (lpUDData->IsInteger) + { + fprintf(fileOutput, "%d", lpUDData->iOffset); + } + else + { + PrintSymbol(fileOutput, lpUDData->poffset); + } + fprintf(fileOutput, "]"); + } + count++; + } + fprintf (fileOutput, "\n\n"); + + fprintf (fileOutput, " %s %lu:", " liveuse:", bb_GetIdent(bb)); + count = max_nums_on_line + 1; + for (CAVLTreeSetCursor(bb_GetLiveVariablesUse(bb), POINT_TO_SMALLEST, &c, (void**)&lpUDData); lpUDData; CAVLTreeGetNext(&c, (void**)&lpUDData)) + { + if (count > max_nums_on_line) + { + fprintf (fileOutput, "\n "); + count = 0; + } + fprintf (fileOutput, " "); + PrintSymbol(fileOutput, lpUDData->lpBase); + if (lpUDData->IsArray) + { + fprintf(fileOutput, "["); + if (lpUDData->IsInteger) + { + fprintf(fileOutput, "%d", lpUDData->iOffset); + } + else + { + PrintSymbol(fileOutput, lpUDData->poffset); + } + fprintf(fileOutput, "]"); + } + count++; + } + fprintf (fileOutput, "\n\n"); + + } +} + +static int GetDefUses(control_flow_graph *cfg) +{ + int inumber ; // 基本块数 + int i, j; PLLI instructions; //int nInstr ; IRInstOperator iop; @@ -152,6 +225,8 @@ static int GetDefUses(control_flow_graph *cfg) ExpType type; int ret = 0; LIST_ITERATOR iterator; + DOPEVECT *expdope; + PDYNAMIC_ARRAY FieldsDopeVector; inumber = cfg_GetBlockNumber(cfg); for (i = 0; i < inumber; i++) @@ -192,7 +267,7 @@ static int GetDefUses(control_flow_graph *cfg) { // 二元运算符 if ((!ir_IsArgFloat(currentinstruction, 1)) && (!ir_IsArgInteger(currentinstruction, 1))) {// 处理第一操作数 - if (!SymIsConst(iarg1, NULL, NULL) || DynamicArrayGetCount(Get_Dope(iarg1))) + if (!SymIsConst(iarg1, NULL, NULL) && !DynamicArrayGetCount(Get_Dope(iarg1))) { memset ( &DummyData, 0, sizeof (DummyData)); DummyData.lpBase = iarg1; @@ -524,22 +599,118 @@ static int GetDefUses(control_flow_graph *cfg) if (CAVLTreeFindNode(use, &DummyData) == NULL) { needAlloc = 0; - if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) { + if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) + { needAlloc = 1; - } - if ( needAlloc && !(lpUDData = AllocUDData())) { + } + if ( needAlloc && !(lpUDData = AllocUDData())) + { return 0; - } - if ( needAlloc) { + } + if ( needAlloc) + { lpUDData->lpBase = iarg3; - } + } - if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) { + if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) + { FreeUDData (lpUDData); return 0; + } } + + if (iop == IRINST_OP_PLUS && !ir_IsArgFloat(currentinstruction, 1) && !ir_IsArgInteger(currentinstruction, 1) && + !SymIsConst(iarg1, NULL, NULL) && DynamicArrayGetCount(Get_Dope(iarg1))) + { + memset ( &DummyData, 0, sizeof (DummyData)); + DummyData.lpBase = iarg1; + + if (CAVLTreeFindNode(use, &DummyData) == NULL) + { + needAlloc = 0; + if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) + { + needAlloc = 1; + } + if ( needAlloc && !(lpUDData = AllocUDData())) + { + return 0; + } + if ( needAlloc) + { + lpUDData->lpBase = iarg1; + } + + if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) + { + FreeUDData (lpUDData); + return 0; + } + } } + } + else if (iop == IRINST_OP_MEMSET) + { + if (!ir_IsArgFloat(currentinstruction, 1) && !ir_IsArgInteger(currentinstruction, 1) && + !SymIsConst(iarg1, NULL, NULL) && DynamicArrayGetCount(Get_Dope(iarg1))) + { + memset ( &DummyData, 0, sizeof (DummyData)); + DummyData.lpBase = iarg1; + if (CAVLTreeFindNode(use, &DummyData) == NULL) + { + needAlloc = 0; + if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) + { + needAlloc = 1; + } + if ( needAlloc && !(lpUDData = AllocUDData())) + { + return 0; + } + if ( needAlloc) + { + lpUDData->lpBase = iarg1; + } + if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) + { + FreeUDData (lpUDData); + return 0; + } + } + } + } + else if (iop == IRINST_OP_ENTRY) + { + FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(currentinstruction, 1)); + for (j = (int)DynamicArrayGetCount(FieldsDopeVector) - 1; j>=0; j--) + { + expdope = DynamicArrayRetrieve(FieldsDopeVector, j); + memset ( &DummyData, 0, sizeof (DummyData)); + DummyData.lpBase = expdope->psyment; + if (DummyData.lpBase != NULL && CAVLTreeFindNode(use, &DummyData) == NULL) + { + needAlloc = 0; + if ( ! (lpUDData = CAVLTreeFindNode(def, &DummyData))) + { + needAlloc = 1; + } + if ( needAlloc && !(lpUDData = AllocUDData())) + { + return 0; + } + if ( needAlloc) + { + lpUDData->lpBase = DummyData.lpBase; + } + + if ( needAlloc && !CAVLTreeAddNode(def, lpUDData, NULL)) + { + FreeUDData (lpUDData); + return 0; + } + } + } } /* else if (iop == IRINST_OP_ARRAYASSIGN) { @@ -621,6 +792,9 @@ static int GetDefUses(control_flow_graph *cfg) } } + + // Printdefuse(stdout, cfg); + return 1; } @@ -654,6 +828,7 @@ static int computeLiveness(control_flow_graph *cfg) blkPtr = DynamicArrayRetrieve(&cfg->bbs, j); successor = bb_GetSuccessor(blkPtr); nChildren = DynamicArrayGetCount(successor); + FinalizeAVLTree(bb_GetLiveVariablesOut(blkPtr), NULL); for (k = 0; k < nChildren; k++) { // 遍历每个后继 lpChild = cfg_GetBlockByIdentifier(cfg, DynArrayItemAsLong(successor, k)); diff --git a/optimize/linklist.c b/optimize/linklist.c index d125017af5d575b08ef7b851036a295cf7ed537b..ddad3824a5b0c700d70f21d40e0825037eb7709f 100644 --- a/optimize/linklist.c +++ b/optimize/linklist.c @@ -461,5 +461,12 @@ long List_Index( LIST_ITERATOR* pit ) void *List_Current( LIST_ITERATOR* pit ) { - return pit->_current->pValue; + if (pit->_current != NULL) + { + return (void*)pit->_current->pValue; + } + else + { + return (void*)NULL; + } } diff --git a/optimize/ssa.c b/optimize/ssa.c index 2a6fb6162d311c8e7c30e777af38eb5b9f263082..dcb3d0a2c4aebfa5e3fc405fd21d052029456edf 100644 --- a/optimize/ssa.c +++ b/optimize/ssa.c @@ -1,3 +1,17 @@ +//+------------------------------------------------------------------------- +// +// 编译器 +// +// 版权所有 (C) 苗潼超, 2023 +// +// 文件: ssa.c +// +//-------------------------------------------------------------------------- + +// ssa.c : 静态单赋值及基于静态单赋值的优化 +// + + #include "compiler.h" static int CommCompare( long *arg1, long *arg2 ) @@ -10,6 +24,13 @@ static void destroy(void* p, void* T) free (p); } +//############################################################################ +//############################################################################ +// +// 静态单赋值 +// +//############################################################################ +//############################################################################ static int gendom(control_flow_graph* graph, int bReverse) { int iCount ; @@ -352,6 +373,8 @@ static int Place_Phi_Functions(control_flow_graph* graph) LIST_ITERATOR iterator; bitmap_iterator bi; unsigned int ival; + DOPEVECT *expdope; + PDYNAMIC_ARRAY FieldsDopeVector; bSuccess = 0; @@ -369,9 +392,23 @@ static int Place_Phi_Functions(control_flow_graph* graph) for (i = 0; i < iCount; i++) { blkPtr = DynamicArrayRetrieve(&graph->bbs, i); - //printf("\nB%d: ", blkPtr->identifier); + // printf("\nB%d: ", blkPtr->identifier); insts = bb_GetInsts(blkPtr); - //nInstr = LinkListGetCount(insts); + if (bb_IsEntryBlock(blkPtr)) + { // ENTRY块对参数定值。 + FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(List_First(insts, &iterator), 1)); + k = DynamicArrayGetCount(FieldsDopeVector); + for (j = 0; j < k; j++) + { + expdope =DynamicArrayRetrieve(FieldsDopeVector, j); + if ( !CAVLTreeFindNode(bb_getaOrig(blkPtr), expdope->psyment) && + !CAVLTreeAddNode(bb_getaOrig(blkPtr), expdope->psyment, NULL) ) + { + goto cleanup; + } + } + } + List_TRAVERSE(insts, currentinstruction, &iterator) //for (j = 0; j < nInstr; j++) @@ -384,7 +421,7 @@ static int Place_Phi_Functions(control_flow_graph* graph) { if ( k == 0 ) { - psyment = ir_GetArgVoidPtr(currentinstruction, 1); + psyment = ir_GetArgVoidPtr(currentinstruction, 1); } else if ( k == 1 ) { @@ -394,13 +431,14 @@ static int Place_Phi_Functions(control_flow_graph* graph) { psyment = ir_GetDstVoidPtr(currentinstruction); }// - //printf("%d ", psyment->iIdent); + // printf("%d ", psyment->iIdent); + // PrintSymbol(stdout, psyment); + // printf("\n"); if ( !CAVLTreeFindNode(bb_getaOrig(blkPtr), psyment) && !CAVLTreeAddNode(bb_getaOrig(blkPtr), psyment, NULL) ) { goto cleanup; } - } } } @@ -615,6 +653,8 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) LIST_ITERATOR iterator; df_ref *def; df_ref *use; + DOPEVECT *expdope; + PDYNAMIC_ARRAY FieldsDopeVector; bSuccess = 0; @@ -627,6 +667,33 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) insts = bb_GetInsts(blkPtr); //nInstr = LinkListGetCount(insts); + if (bb_IsEntryBlock(blkPtr)) + { + FieldsDopeVector = Get_Dope(ir_GetArgVoidPtr(List_First(insts, &iterator), 1)); + k = DynamicArrayGetCount(FieldsDopeVector); + for (j = 0; j < k; j++) + { + expdope =DynamicArrayRetrieve(FieldsDopeVector, j); + SymSetCount(expdope->psyment, SymGetCount(expdope->psyment)+1); + if ( !SymStackPush(expdope->psyment, SymGetCount(expdope->psyment)) ) + { + goto cleanup; + } + if ((def = malloc (sizeof (*def))) == NULL) + { + goto cleanup; + } + def->count = SymGetStackTop(expdope->psyment); + def->insn = List_Current(&iterator); + def->iArgIndex = -1; + if (-1 ==DynamicArrayAdd(SymGetDefInfo(expdope->psyment), def)) + { + free (def); + goto cleanup; + } + } + } + List_TRAVERSE(insts, currentinstruction, &iterator) //for (j = 0; j < nInstr; j++) { @@ -642,14 +709,24 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) !SymIsConst(psyment, NULL, NULL) && !SymIsFunction(psyment)) { - ir_SetNumber(currentinstruction, 0, SymGetStackTop(psyment)); if ((use = malloc (sizeof (*use))) == NULL) { goto cleanup; } + + if (iop==IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(psyment))) + { + ir_SetNumber(currentinstruction, 3, SymGetStackTop(psyment)); + use->iArgIndex = 3; + } + else + { + ir_SetNumber(currentinstruction, 0, SymGetStackTop(psyment)); + use->iArgIndex = 0; + } use->count = SymGetStackTop(psyment); use->insn = currentinstruction; - use->iArgIndex = 0; + if (-1 ==DynamicArrayAdd(SymGetUseInfo(psyment), use)) { free (use); @@ -704,6 +781,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) } } } + for (k=0; k < 3 ;k++ ) { if (ir_isDef(currentinstruction, k)) @@ -721,7 +799,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) psyment = ir_GetDstVoidPtr(currentinstruction); }// // printf("def : "); - // PrintSymbol(stdout, psyment); + // PrintInstruction(stdout, currentinstruction, 0, 1); PrintSymbol(stdout, psyment); // printf(" %d\n", SymGetCount(psyment)); SymSetCount(psyment, SymGetCount(psyment)+1); if ( !SymStackPush(psyment, SymGetCount(psyment)) ) @@ -744,6 +822,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) } } // for (k=0; k < 3 ;k++ ) + } // for (j = 0; j < nInstr; j++) successor = bb_GetSuccessor(blkPtr); @@ -835,7 +914,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) }// // printf("%d pop ", blkPtr->identifier); // PrintSymbol(stdout, psyment); - + if (!SymStackPop(psyment)) { internal_error(NULL, "Fatal error on line %u of %s.", __LINE__, __FILE__); @@ -844,6 +923,7 @@ static int Rename(control_flow_graph* graph, basic_block *blkPtr) // printf(" stacktop : %d\n", SymGetStackTop(psyment)); } } + } bSuccess = 1; @@ -941,6 +1021,13 @@ void phi_set_arg (phi *phi, unsigned index, SYMENT * phiarg, int iNumber) } #if defined( WITH_LOCAL_VALUE_NUMBER ) +//############################################################################ +//############################################################################ +// +// 局部值编号 +// +//############################################################################ +//############################################################################ static int cmp_Value_Number(EXPRESSION* a, EXPRESSION* b) { @@ -1012,7 +1099,7 @@ cmp_Value_Number(EXPRESSION* a, EXPRESSION* b) return ret; } - if (IRINST_OP_ARRAYASSIGN != a->iop) + if (IRINST_OP_ARRAYASSIGN != a->iop && IRINST_OP_PLUS != a->iop) { return ret; } @@ -1041,7 +1128,7 @@ cmp_hash(EXPRESSION* a, EXPRESSION* b) if (ret) return ret; ret = (a)->Value_Number[1] - (b)->Value_Number[1]; - if (IRINST_OP_ARRAYASSIGN != a->iop) + if (IRINST_OP_ARRAYASSIGN != a->iop && IRINST_OP_PLUS != a->iop) { return ret; } @@ -1177,10 +1264,11 @@ static int Value_Number(basic_block* bb) expr2.Value_Number[1] = -1; } - if (iop == IRINST_OP_ARRAYASSIGN) + if (iop == IRINST_OP_ARRAYASSIGN || + (iop == IRINST_OP_PLUS && !ir_IsArgInteger(insn, 1) && !ir_IsArgFloat(insn, 1) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1))))) { expr.arg1.symbol.num = ir_GetNumber(insn, 3); - ir_GetOperand(insn, 2, &Type, &isImmediate, &expr.arg1); + ir_GetOperand(insn, iop == IRINST_OP_PLUS ? 0 : 2, &Type, &isImmediate, &expr.arg1); expr.fIsArg1Float = 0; expr.fIsArg1Integer = 0; expr.iop = IRINST_OP_MAX; @@ -1322,6 +1410,13 @@ Cleanup: #endif #if defined( WITH_DCE ) +//############################################################################ +//############################################################################ +// +// 死代码删除 +// +//############################################################################ +//############################################################################ /* 如果insn是可以通过死代码删除删除的普通指令,则返回true。 */ static int deletable_insn(IRINSTRUCTION* insn) @@ -1397,7 +1492,7 @@ prescan_insns_for_dce(control_flow_graph* graph, CAVLTree* worklist) if (!deletable_insn(insn)) { ir_SetMark(insn, 1); - //printf("%d\n", insn->identifier); + // printf("%d\n", insn->identifier); if (CAVLTreeAddNode(worklist, insn, NULL) == 0) { goto Cleanup; @@ -1534,7 +1629,8 @@ mark_dependencies (control_flow_graph* graph, CAVLTree* worklist, IRINSTRUCTION else if (iop != IRINST_OP_ENTRY && iop != IRINST_OP_EXIT) { pSym = ir_GetArgVoidPtr(insn, 1); - if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && pSym && !SymIsConst(pSym, NULL, NULL)) + if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && pSym && !SymIsConst(pSym, NULL, NULL) && + !(iop==IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(pSym)))) { nCount = DynamicArrayGetCount(SymGetDefInfo(pSym)); for (j = 0; j<nCount; j++) @@ -1599,6 +1695,28 @@ mark_dependencies (control_flow_graph* graph, CAVLTree* worklist, IRINSTRUCTION } } + pSym = ir_GetArgVoidPtr(insn, 1); + if (iop == IRINST_OP_PLUS && !ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && DynamicArrayGetCount(Get_Dope(pSym))) + { + nCount = DynamicArrayGetCount(SymGetDefInfo(pSym)); + for (j = 0; j<nCount; j++) + { + def = DynamicArrayRetrieve(SymGetDefInfo(pSym), j); + if (def->count == ir_GetNumber(insn, 3)) + { + if (!ir_GetMark(def->insn)) + { + ir_SetMark(def->insn, 1); + if (!CAVLTreeFindNode(worklist, def->insn) && !CAVLTreeAddNode(worklist, def->insn, NULL)) + { + goto Cleanup; + } + } + break; + } + } + } + } bb = ir_GetContainer(insn); @@ -1655,7 +1773,7 @@ static int dce (control_flow_graph* graph, CAVLTree* worklist) { insn = CAVLTreeGetIndexData(worklist, 0); CAVLTreeDelNodebyidx(worklist, 0); - //printf("%d %d\n", CAVLTreeGetItemCount(worklist), insn->identifier); + // printf("%d %d\n", CAVLTreeGetItemCount(worklist), insn->identifier); if (!mark_dependencies(graph, worklist, insn)) { goto Cleanup; @@ -1680,7 +1798,7 @@ delete_unmarked_insns (control_flow_graph* graph) IRINSTRUCTION* op; basic_block* p; - // int iCounter; + int iCounter; // fprintf(stdout, "\n"); n = cfg_GetBlockNumber(graph); @@ -1689,10 +1807,11 @@ delete_unmarked_insns (control_flow_graph* graph) bb = DynamicArrayRetrieve(&graph->bbs, i); instructions = bb_GetInsts(bb); - // iCounter = 0; + iCounter = 0; - List_TRAVERSE(instructions, insn, &iterator) + for( insn=List_First(instructions, &iterator);List_Current(&iterator)!=NULL;) { + // printf("%d\n", insn->identifier); if (!ir_GetMark(insn)) { iop = ir_getOp(insn); @@ -1732,6 +1851,8 @@ delete_unmarked_insns (control_flow_graph* graph) } ir_SetOp(insn, IRINST_OP_GOTO); ir_SetBranchTarget(insn, GetIdentifier(op)); + + insn = List_Next(&iterator); // fprintf(stdout, " -> "); // PrintInstruction(stdout, insn, 0, 1); // fprintf(stdout, "\n"); @@ -1740,11 +1861,17 @@ delete_unmarked_insns (control_flow_graph* graph) { // fprintf(stdout, "deleting B%d %d", bb_GetIdent(insn->bb), iCounter); // PrintInstruction(stdout, insn, 0, 1); + // fprintf(stdout, "\n"); cfg_fast_deleteinst(graph, bb, &iterator); - List_Prev(&iterator); + insn = List_Current(&iterator); } } - // iCounter++; + else + { + insn = List_Next(&iterator); + } + + iCounter++; } } @@ -1885,3 +2012,1123 @@ Cleanup: return bSuccess; } #endif + +typedef struct value_ent { + struct ssa_name ve_valuename; + union { + int integer_val; + float real_val; + } ve_value; + int IsInteger; + int ve_type; // -1, 0, +1 +}VALENT, *PVALENT; + +static int +cmp_value_ent (PVALENT a, PVALENT b) +{ + int ret; + if (a == b) + return 0; + ret = (int)SymGetIdentifier(a->ve_valuename.var) - (int)SymGetIdentifier(b->ve_valuename.var); + if (ret) + return ret; + return (a->ve_valuename.num -b->ve_valuename.num); +} + +static int evaluate(CAVLTree *names, PVALENT value, IRINSTRUCTION *insn) +{ + int bSuccess = 0; + VALENT * opr1; + VALENT * opr2; + VALENT * opr3; + VALENT dummy; + VALENT dummy1, dummy2, dummy3; + ExpType type; + SYMENT dummy4; + IRInstOperator iop ; + phi_arg_d *lpArg; + int i, n; + + memset (&dummy, 0, sizeof (dummy)); + memset (&dummy1, 0, sizeof (dummy1)); + memset (&dummy2, 0, sizeof (dummy2)); + memset (&dummy3, 0, sizeof (dummy3)); + memset (&dummy4, 0, sizeof (dummy4)); + + iop = ir_getOp(insn); + + if (iop != IRINST_OP_PHI) + { + if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1)) + { + dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 1); + if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var)) != 0 && + iop != IRINST_OP_ARRAYASSIGN && iop != IRINST_OP_ASSIGNARRAY) + { + goto dodefault; + } + if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var)) != 0 || + !SymIsConst(dummy.ve_valuename.var, &type, &dummy.ve_value)) + { + dummy.ve_valuename.num = ir_GetNumber(insn, 0); + dummy.ve_valuename.var = dummy.ve_valuename.var ? dummy.ve_valuename.var : &dummy4; + if (IsInFilescope(SymGetScope(dummy.ve_valuename.var))) + { + goto dodefault; + } + if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) ) + { // 没找到,应该是一个全局变量。 + goto dodefault; + } + } + else if (type == Integer) + { + dummy.IsInteger =1; + opr1 = &dummy; + dummy.ve_valuename.var = &dummy4; + } + else + { + dummy.ve_valuename.var = &dummy4; + opr1 = &dummy; + } + } + else if (ir_IsArgFloat(insn, 1)) + { + dummy.ve_value.real_val = ir_GetArgFloat(insn, 1); + opr1 = &dummy; + dummy.ve_valuename.var = &dummy4; + } + else + { + dummy.ve_value.integer_val = ir_GetArgInteger(insn, 1); + dummy.IsInteger = 1; + opr1 = &dummy; + dummy.ve_valuename.var = &dummy4; + } + } + + if (iop != IRINST_OP_ASSIGN && + iop != IRINST_UNARYOP_PLUS && + iop != IRINST_UNARYOP_MINUS && + iop != IRINST_UNARYOP_EXCLAIM && + iop != IRINST_OP_ITR && + iop != IRINST_OP_RTI && + iop != IRINST_OP_PHI && + iop != IRINST_OP_PARAM) + { + if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0)) + { + dummy1.ve_valuename.var = ir_GetArgVoidPtr(insn, 0); + if (DynamicArrayGetCount(Get_Dope(dummy1.ve_valuename.var)) || !SymIsConst(dummy1.ve_valuename.var, NULL, NULL)) + { + dummy1.ve_valuename.num = ir_GetNumber(insn, 1); + dummy1.ve_valuename.var = dummy1.ve_valuename.var ? dummy1.ve_valuename.var : &dummy4; + if (IsInFilescope(SymGetScope(dummy1.ve_valuename.var))) + { + goto dodefault; + } + if ( ! ( opr2 = CAVLTreeFindNode ( names, &dummy1 ) ) ) + { // 没找到,应该是一个全局变量。 + goto dodefault; + } + } + else + { + SymIsConst(dummy1.ve_valuename.var, &type, &dummy1.ve_value); + dummy1.ve_valuename.var = &dummy4; + opr2 = &dummy1; + if (type == Integer) + { + dummy1.IsInteger =1; + } + } + } + else if (ir_IsArgFloat(insn, 0)) + { + dummy1.ve_value.real_val = ir_GetArgFloat(insn, 0); + opr2 = &dummy1; + dummy1.ve_valuename.var = &dummy4; + } + else + { + dummy1.ve_value.integer_val = ir_GetArgInteger(insn, 0); + dummy1.IsInteger = 1; + opr2 = &dummy1; + dummy1.ve_valuename.var = &dummy4; + } + } + + if (iop == IRINST_OP_ARRAYASSIGN) + { + dummy2.ve_valuename.var = ir_GetDstVoidPtr(insn); + dummy2.ve_valuename.num = ir_GetNumber(insn, 3); + if (IsInFilescope(SymGetScope(dummy2.ve_valuename.var))) + { + goto dodefault; + } + if ( ! ( opr3 = CAVLTreeFindNode ( names, &dummy2 ) ) ) + { // 没找到,应该是一个全局变量。 + goto dodefault; + } + } + + switch ( ir_getOp(insn) ) + { + case IRINST_OP_PLUS: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = opr1->ve_value.integer_val + opr2->ve_value.integer_val; + } + else + { + value->IsInteger = 0; + value->ve_value.real_val = opr1->ve_value.real_val + opr2->ve_value.real_val; + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_MULT: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = opr1->ve_value.integer_val * opr2->ve_value.integer_val; + } + else + { + value->IsInteger = 0; + value->ve_value.real_val = opr1->ve_value.real_val * opr2->ve_value.real_val; + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + if ((!opr1->ve_type && opr1->ve_value.integer_val == 0) || + (!opr2->ve_type && opr2->ve_value.integer_val == 0)) + { + value->IsInteger = opr1->IsInteger; + value->ve_value.integer_val = 0; + } + else + { + value->ve_type = -1; + } + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_MINUS: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = opr1->ve_value.integer_val - opr2->ve_value.integer_val; + } + else + { + value->IsInteger = 0; + value->ve_value.real_val = opr1->ve_value.real_val - opr2->ve_value.real_val; + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_DIV: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + if (opr2->ve_value.integer_val == 0) + { + value->ve_type = -1; + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = opr1->ve_value.integer_val / opr2->ve_value.integer_val; + } + } + else + { + value->IsInteger = 0; + value->ve_value.real_val = opr1->ve_value.real_val / opr2->ve_value.real_val; + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + if (opr2->ve_type == 0 && !opr2->IsInteger && opr2->ve_value.integer_val == 0) + { + value->IsInteger = 0; + value->ve_value.real_val = opr1->ve_value.real_val / opr2->ve_value.real_val; + } + else + { + value->ve_type = -1; + } + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_MOD: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->ve_value.integer_val == 0) + { + value->ve_type = -1; + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = opr1->ve_value.integer_val % opr2->ve_value.integer_val; + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_ASSIGN: + case IRINST_UNARYOP_PLUS: + if (!opr1->ve_type) + { + value->ve_type = 0; + value->IsInteger = opr1->IsInteger; + memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ; + } + else if (opr1->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_UNARYOP_MINUS: + if (!opr1->ve_type) + { + value->ve_type = 0; + if (opr1->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = -opr1->ve_value.integer_val; + } + else + { + value->IsInteger = 0; + value->ve_value.real_val = -opr1->ve_value.real_val; + } + } + else if (opr1->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_UNARYOP_EXCLAIM: + if (!opr1->ve_type) + { + value->ve_type = 0; + if (opr1->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = !opr1->ve_value.integer_val; + } + else + { + value->IsInteger = 1; + value->ve_value.real_val = !opr1->ve_value.real_val; + } + } + else if (opr1->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_EQUALS: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val == opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val == opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_NOTEQ: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val != opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val != opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_GT: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val > opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val > opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_LT: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val < opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val < opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_GTEQ: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val >= opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val >= opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OPVALUE_LTEQ: + if (!opr1->ve_type && !opr2->ve_type) + { + value->ve_type = 0; + if (opr2->IsInteger) + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.integer_val <= opr2->ve_value.integer_val); + } + else + { + value->IsInteger = 1; + value->ve_value.integer_val = (opr1->ve_value.real_val <= opr2->ve_value.real_val); + } + } + else if (opr1->ve_type==-1 || opr2->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_ITR: + if (!opr1->ve_type) + { + value->ve_type = 0; + value->IsInteger = 0; + value->ve_value.real_val = (float)opr1->ve_value.integer_val; + } + else if (opr1->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_RTI: + if (!opr1->ve_type) + { + value->ve_type = 0; + value->IsInteger = 1; + value->ve_value.integer_val = (int)opr1->ve_value.real_val; + } + else if (opr1->ve_type==-1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_ARRAYASSIGN: + if (opr3->ve_type >= 0 && opr1->ve_type == 0 && opr2->ve_type == 0) + { + value->ve_type = 0; + SymIsConst(opr3->ve_valuename.var, &type, NULL); + if (!SymSetInitValueArray(opr3->ve_valuename.var, opr2->ve_value.integer_val / (opr3->IsInteger ? SIZE_INTEGER : SIZE_FLOAT), &opr1->ve_value)) + { + return 0; + } + } + else if (opr3->ve_type == -1 || opr1->ve_type == -1 || opr2->ve_type == -1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_ASSIGNARRAY: + if (opr1->ve_type == 0 && opr2->ve_type==0) + { + // TODO: 对数组越界的检查.. + value->ve_type = 0; + SymIsConst(opr1->ve_valuename.var, &type, NULL); + value->IsInteger = (type==Integer); + if (!SymGetInitValueArray(opr1->ve_valuename.var, opr2->ve_value.integer_val / (type==Integer?SIZE_INTEGER:SIZE_FLOAT), &value->ve_value)) + { + return 0; + } + } + else if (opr1->ve_type == -1 || opr2->ve_type == -1) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + break; + case IRINST_OP_PHI: + n = phi_num_args(ir_GetArgVoidPtr(insn, 1)); + for (i = 0; i < n; i++) + { + lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), i); + if (i == 0) + { + dummy.ve_valuename.num = lpArg->iNumber; + dummy.ve_valuename.var = lpArg->psyment; + if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) ) + { // 没找到,应该是一个全局变量。 + goto dodefault; + } + value->IsInteger = opr1->IsInteger; + value->ve_type = opr1->ve_type; + memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ; + } + else + { + dummy.ve_valuename.num = lpArg->iNumber; + dummy.ve_valuename.var = lpArg->psyment; + if ( ! ( opr1 = CAVLTreeFindNode ( names, &dummy ) ) ) + { // 没找到,应该是一个全局变量。 + goto dodefault; + } + + if (!opr1->ve_type && !value->ve_type) + { + if (value->ve_value.integer_val != opr1->ve_value.integer_val) + { + value->ve_type = -1; + } + } + else if (opr1->ve_type==-1 || value->ve_type == -1) + { + value->ve_type = -1; + break; + } + // else if (opr1->ve_type==1 || value->ve_type == 1) + // { + // value->ve_type = 1; + // break; + // } + else if (value->ve_type==1) + { + value->IsInteger = opr1->IsInteger; + value->ve_type = opr1->ve_type; + memcpy ( &value->ve_value, &opr1->ve_value, sizeof(opr1->ve_value) ) ; + } + } + } + break; +dodefault: + default: + value->ve_type = -1; + break; + } + +// Success: + return 1; +} + +int PropagateConstant(control_flow_graph* graph, SYMTAB *g_symtab) +{ + CAVLTree names; + CAVLTree worklist; + DYNAMIC_ARRAY MyQueue, tmpqueue; + int bSuccess = 0; + int i, n, j, k; + int iEdge; + SYMTAB * pSymTable; + int nChildren = 0; + CAVLTreeCursor c; + SYMENT *psyment; + PVALENT value; + PVALENT value2; + PDYNAMIC_ARRAY defs; + PDYNAMIC_ARRAY uses; + df_ref* def; + df_ref *use; + IRInstOperator iop ; + ExpType type; + int isImmediate; + VALENT dummy; + VALENT saved; + basic_block *bb; + IRINSTRUCTION *insn; + LIST_ITERATOR iterator; + int nCount; + phi_arg_d *lpArg; + int bSkip; + + InitializeAVLTree(&names, NULL, (NODECOMPAREPROC)cmp_value_ent, destroy); + InitializeAVLTree(&worklist, NULL, (NODECOMPAREPROC)cmp_value_ent, NULL); + + DynamicArrayInit(&MyQueue, NULL); + DynamicArrayInit(&tmpqueue, NULL); + if( -1 == DynamicArrayAdd(&MyQueue, g_symtab)) + { + goto Cleanup; // sorry + } + + while ( DynamicArrayGetCount(&MyQueue) ) + { + DynamicArrayDestroy(&tmpqueue); + DynamicArrayInit(&tmpqueue, NULL); + + n = (int)DynamicArrayGetCount(&MyQueue); + for ( i = 0; i < n; i++ ) + { + if( -1 == DynamicArrayAdd(&tmpqueue, DynamicArrayRetrieve(&MyQueue, i))) + { + goto Cleanup; // sorry + } + } + DynamicArrayDestroy(&MyQueue); + DynamicArrayInit(&MyQueue, NULL); + + n = (int)DynamicArrayGetCount(&tmpqueue); + for ( iEdge = 0; iEdge < n; iEdge++ ) + { + pSymTable = DynamicArrayRetrieve(&tmpqueue, iEdge); + // 把它的孩子都加入队列。 + nChildren = (int)DynamicArrayGetCount(&pSymTable->rgsymtab); + for ( j = 0; j < nChildren; j++ ) + { + if( -1 == DynamicArrayAdd(&MyQueue, DynamicArrayRetrieve(&pSymTable->rgsymtab, j))) + { + goto Cleanup; // sorry + } + } + for ( CAVLTreeSetCursor(&pSymTable->rgsyment, POINT_TO_SMALLEST, &c, (void**)&psyment); psyment; CAVLTreeGetNext(&c, (void**)&psyment) ) + { + if (SymIsConst(psyment, NULL, NULL) && DynamicArrayGetCount(Get_Dope(psyment))) + { // 常量数组(一定位于全局) + if ( ! ( value = malloc ( sizeof ( *value ) ) ) ) + { + goto Cleanup; + } + memset (value, 0, sizeof (*value)); + value->ve_valuename.num = 0; + value->ve_valuename.var = psyment; + if ( ! CAVLTreeAddNode(&names, value, NULL) ) + { + free(value); + goto Cleanup; + } + value->ve_type = 0; + if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) ) + { + goto Cleanup; + } + continue; + } + + defs = SymGetDefInfo(psyment); + nChildren = DynamicArrayGetCount(defs); + for (i = 0; i < nChildren; i++) + { + def = DynamicArrayRetrieve(defs, i); + if ( ! ( value = malloc ( sizeof ( *value ) ) ) ) + { + goto Cleanup; + } + memset (value, 0, sizeof (*value)); + value->ve_valuename.num = def->count; + value->ve_valuename.var = psyment; + if ( ! CAVLTreeAddNode(&names, value, NULL) ) + { + free(value); + goto Cleanup; + } + + if (IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL)) + { // 全局变量,且不是常量 + value->ve_type = -1; + if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) ) + { + goto Cleanup; + } + continue; + } + + iop = ir_getOp(def->insn); + + if (iop == IRINST_OP_PHI) + { + value->ve_type = 1; + } + else if (iop == IRINST_OP_ENTRY) + { // 参数 + value->ve_type = -1; + } + else if (iop == IRINST_OP_MEMSET) + { + value->ve_type = 0; + } + else if (iop == IRINST_OP_ASSIGN) + { + ir_GetOperand(def->insn, 0, &type, &isImmediate, &value->ve_value); + if (!isImmediate) + { + value->ve_type = 1; + } + else + { + value->IsInteger = (type==Integer); + } + } + else if (iop == IRINST_OP_FUNC_CALL) + { + value->ve_type = -1; + } + else if (iop == IRINST_OP_PLUS && DynamicArrayGetCount(Get_Dope(psyment))) + { + value->ve_type = -1; + } + else + { + value->ve_type = 1; + } + + if (value->ve_type != 1) + { + if ( ! CAVLTreeFindNode(&worklist, value) && ! CAVLTreeAddNode(&worklist, value, NULL) ) + { + goto Cleanup; + } + } + } + } + } + } + + while ( CAVLTreeGetItemCount(&worklist) != 0 ) + { + value = CAVLTreeGetIndexData(&worklist, 0); + CAVLTreeDelNodebyidx(&worklist, 0); + uses = SymGetUseInfo(value->ve_valuename.var); + n = (int)DynamicArrayGetCount(uses); + for ( i = 0; i < n; i++ ) + { + use = DynamicArrayRetrieve(uses, i); + if (use->count != value->ve_valuename.num) + { + continue; + } + + for (j=0; j < 3 ;j++ ) + { + if (ir_isDef(use->insn, j)) + { + if ( j == 0 ) + { + psyment = ir_GetArgVoidPtr(use->insn, 1); + } + else if ( j == 1 ) + { + psyment = ir_GetArgVoidPtr(use->insn, 0); + } + else + { + psyment = ir_GetDstVoidPtr(use->insn); + }// + dummy.ve_valuename.num = ir_GetNumber(use->insn, j); + dummy.ve_valuename.var = psyment; + if ( ! ( value2 = CAVLTreeFindNode ( &names, &dummy ) ) ) + { + goto Cleanup; + } + if (value2->ve_type != -1) + { + saved = *value2; + if (!evaluate(&names, value2, use->insn)) + { + goto Cleanup; + } + if (memcmp (&saved, value2, sizeof(saved)) != 0 ) + { + if ( ! CAVLTreeFindNode(&worklist, value2) && ! CAVLTreeAddNode(&worklist, value2, NULL) ) + { + goto Cleanup; + } + } + } + } + } + } + } + + n = cfg_GetBlockNumber (graph); + for (i = 0; i < n; i++) + { + bb = DynamicArrayRetrieve(&graph->bbs, i); + List_TRAVERSE(bb_GetInsts(bb), insn, &iterator) + { + iop = ir_getOp(insn); + if (iop == IRINST_OP_ARRAYASSIGN) + { + if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1)) + { + psyment = ir_GetArgVoidPtr(insn, 1); + if (psyment != NULL && !DynamicArrayGetCount(Get_Dope(psyment))) + { + dummy.ve_valuename.num = ir_GetNumber(insn, 0); + dummy.ve_valuename.var = psyment; + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL && + value->ve_type == 0 && + !SymIsRetval(psyment) && + !(IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL))) + { + uses = SymGetUseInfo(psyment); + nCount = (int)DynamicArrayGetCount(uses); + for ( k=0; k<nCount; k++ ) + { + use = DynamicArrayRetrieve(uses, k); + if (use->count == dummy.ve_valuename.num && + use->insn == insn) + { + DynArrayRemove2(uses, k); + break; + } + } + // PrintInstruction(stdout, insn, 0, 1); + // printf(" -> "); + SetImmediateValue(insn, value->IsInteger, 1, &value->ve_value); + // PrintInstruction(stdout, insn, 0, 1); + // printf("\n"); + } + } + } + } + else if (iop == IRINST_OP_ASSIGNARRAY) + { + if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0) && !SymIsConst(ir_GetArgVoidPtr(insn, 0), NULL, NULL)) + { + dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 0); + dummy.ve_valuename.num = ir_GetNumber(insn, 1); + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL && + value->ve_type == 0 && + !SymIsRetval(dummy.ve_valuename.var) && + !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL))) + { + uses = SymGetUseInfo(dummy.ve_valuename.var); + nCount = (int)DynamicArrayGetCount(uses); + for ( k=0; k<nCount; k++ ) + { + use = DynamicArrayRetrieve(uses, k); + if (use->count == dummy.ve_valuename.num && + use->insn == insn) + { + DynArrayRemove2(uses, k); + break; + } + } + // PrintInstruction(stdout, insn, 0, 1); + // printf(" -> "); + dummy.IsInteger = value->IsInteger; + memcpy ( &dummy.ve_value, &value->ve_value, sizeof(dummy.ve_value) ) ; + SetImmediateValue(insn,dummy.IsInteger, 0, &dummy.ve_value); + // PrintInstruction(stdout, insn, 0, 1); + // printf("\n"); + } + if (value != NULL) + { + dummy.ve_type = value->ve_type; + dummy.IsInteger = value->IsInteger; + memcpy ( &dummy.ve_value, &value->ve_value, sizeof(dummy.ve_value) ) ; + } + } + + dummy.ve_valuename.num = ir_GetNumber(insn, 0); + dummy.ve_valuename.var = ir_GetArgVoidPtr(insn, 1); + if (ir_IsArgInteger(insn, 0)) + { + dummy.IsInteger = 1; + dummy.ve_type = 0; + dummy.ve_value.integer_val = ir_GetArgInteger(insn, 0); + } + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL && + value->ve_type == 0 && dummy.ve_type == 0 && + !SymIsRetval(dummy.ve_valuename.var) && + !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL))) + { // 变量数组 + // PrintInstruction(stdout, insn, 0, 1); + // printf(" -> "); + SymIsConst(dummy.ve_valuename.var, &type, NULL); + if (!SymGetInitValueArray(dummy.ve_valuename.var, dummy.ve_value.integer_val / (type==Integer?SIZE_INTEGER : SIZE_FLOAT), &dummy.ve_value)) + { + goto Cleanup; + } + ir_SetOp(insn, IRINST_OP_ASSIGN); + SetImmediateValue(insn,type==Integer, 1, &dummy.ve_value); + // PrintInstruction(stdout, insn, 0, 1); + // printf("\n"); + } + } + else if (iop == IRINST_OP_MEMSET) + { + // do nothing + } + else if (iop == IRINST_OP_PHI) + { + bSkip = 0; + dummy.ve_valuename.num = ir_GetNumber(insn, 2); + dummy.ve_valuename.var = ir_GetDstVoidPtr(insn); + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL && + value->ve_type == 0 && + !SymIsRetval(dummy.ve_valuename.var) && + !(IsInFilescope(SymGetScope(dummy.ve_valuename.var)) && !SymIsConst(dummy.ve_valuename.var, NULL, NULL))) + { + for ( j=0; j<phi_num_args(ir_GetArgVoidPtr(insn, 1)); j++ ) + { + lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), j); + dummy.ve_valuename.num = lpArg->iNumber; + dummy.ve_valuename.var = lpArg->psyment; + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) == NULL || + value->ve_type == 1) + { + bSkip = 1; + } + } + if (DynamicArrayGetCount(Get_Dope(dummy.ve_valuename.var))) + { + bSkip = 1; + } + + if ( bSkip ) + continue; + + for ( j=0; j<phi_num_args(ir_GetArgVoidPtr(insn, 1)); j++ ) + { + lpArg = phi_arg(ir_GetArgVoidPtr(insn, 1), j); + uses = SymGetUseInfo(lpArg->psyment); + nCount = (int)DynamicArrayGetCount(uses); + for ( k=0; k<nCount; k++ ) + { + use = DynamicArrayRetrieve(uses, k); + if (use->count == lpArg->iNumber && + use->insn == insn) + { + DynArrayRemove2(uses, k); + break; + } + } + } + // PrintInstruction(stdout, insn, 0, 1); + // printf(" -> "); + free (ir_GetArgVoidPtr(insn, 1)); + ir_SetOp(insn, IRINST_OP_ASSIGN); + SetImmediateValue(insn, value->IsInteger, 1, &value->ve_value); + // PrintInstruction(stdout, insn, 0, 1); + // printf("\n"); + } + } + else + { + for (j=0; j < 4 ;j++ ) + { + psyment = NULL; + if (j == 0) + { + if (!ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && (!SymIsConst(ir_GetArgVoidPtr(insn, 1), NULL, NULL) || DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1))))) + { + psyment = ir_GetArgVoidPtr(insn, 1); + } + } + else if (j == 1) + { + if (!ir_IsArgFloat(insn, 0) && !ir_IsArgInteger(insn, 0) && !SymIsConst(ir_GetArgVoidPtr(insn, 0), NULL, NULL)) + { + psyment = ir_GetArgVoidPtr(insn, 0); + } + } + else if (j == 2) + { + psyment = NULL; + } + else if (ir_getOp(insn)==IRINST_OP_ARRAYASSIGN) + { + psyment = ir_GetDstVoidPtr(insn); + } + else if (ir_getOp(insn)==IRINST_OP_PLUS && !ir_IsArgFloat(insn, 1) && !ir_IsArgInteger(insn, 1) && DynamicArrayGetCount(Get_Dope(ir_GetArgVoidPtr(insn, 1)))) + { + psyment = ir_GetArgVoidPtr(insn, 1); + } + + if (psyment != NULL && !DynamicArrayGetCount(Get_Dope(psyment))) + { + dummy.ve_valuename.num = ir_GetNumber(insn, j); + dummy.ve_valuename.var = psyment; + if ( ( value = CAVLTreeFindNode ( &names, &dummy ) ) != NULL && + value->ve_type == 0 && + !SymIsRetval(psyment) && + !(IsInFilescope(SymGetScope(psyment)) && !SymIsConst(psyment, NULL, NULL))) + { + // 暂时不对全局变量进行常量传播,因为: + // 1) 函数调用可能会更改全局变量。 + // 2) 一个函数可能直接使用全局变量,而找不到的定值。 + // + // 删除此变量在此处的使用信息 + uses = SymGetUseInfo(psyment); + nCount = (int)DynamicArrayGetCount(uses); + for ( k=0; k<nCount; k++ ) + { + use = DynamicArrayRetrieve(uses, k); + if (use->count == dummy.ve_valuename.num && + use->insn == insn) + { + DynArrayRemove2(uses, k); + break; + } + } + // PrintInstruction(stdout, insn, 0, 1); + // printf(" -> "); + SetImmediateValue(insn, value->IsInteger, j==0, &value->ve_value); + // PrintInstruction(stdout, insn, 0, 1); + // printf("\n"); + } + } + } + } + } + } + + bSuccess = 1; +Cleanup: + FinalizeAVLTree(&worklist, NULL); + FinalizeAVLTree(&names, NULL); + DynamicArrayDestroy(&tmpqueue); + DynamicArrayDestroy(&MyQueue); + return bSuccess; +}