From ebe6871e0f2e8e078f054f8c1c2ac990087a871d Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Fri, 25 Apr 2008 13:56:53 +0000 Subject: [PATCH] Separate SMP_SUBTRACT type inference from ADD, AND, and OR. --- SMPInstr.cpp | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 5 deletions(-) diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 18411c25..419540c0 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -1324,8 +1324,11 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { bool LeftPointer, RightPointer; set<DefOrUse, LessDefUse>::iterator CurrDef; set<DefOrUse, LessDefUse>::iterator CurrUse; + set<DefOrUse, LessDefUse>::iterator LeftUse; + set<DefOrUse, LessDefUse>::iterator RightUse; SMPOperandType LeftType = UNINIT; SMPOperandType RightType = UNINIT; + SMPOperandType OperType = UNINIT; op_t UseOp, DefOp, LeftOp, RightOp; SMPoperator CurrOp = CurrRT->GetOperator(); bool DebugFlag = false; @@ -1490,7 +1493,6 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { break; case SMP_ADD: - case SMP_SUBTRACT: case SMP_BITWISE_AND: case SMP_BITWISE_OR: // Extract the current types of right and left operands and the operator. @@ -1578,10 +1580,6 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { // We assume (A-B) is being added to B or vice versa **!!** CurrRT->SetOperatorType(POINTER); } - else if (SMP_SUBTRACT == CurrOp) { - // We assume B - (B - A) == A **!!** - CurrRT->SetOperatorType(POINTER); - } else { // bitwise AND or OR of pointer and pointer difference msg("WARNING: hash of PTROFFSET and POINTER at %x in %s\n", this->GetAddr(), this->GetDisasm()); @@ -1619,6 +1617,130 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } break; + case SMP_SUBTRACT: + // Extract the current types of right and left operands and the operator. + OperType = CurrRT->GetOperatorType(); + LeftOp = CurrRT->GetLeftOperand(); + LeftUse = this->Uses.FindRef(LeftOp); + assert(LeftUse != this->GetLastUse()); // found it + LeftType = LeftUse->GetType(); + if (CurrRT->HasRightSubTree()) { + RightType = CurrRT->GetRightTree()->GetOperatorType(); + } + else { + RightOp = CurrRT->GetRightOperand(); + if (o_void == RightOp.type) { + msg("ERROR: void operand in %s\n", this->GetDisasm()); + return false; + } + else { + RightUse = this->Uses.FindRef(RightOp); + if (RightUse == this->GetLastUse()) { + msg("WARNING: Adding missing USE of "); + PrintOperand(RightOp); + msg(" in %s\n", this->GetDisasm()); + this->Uses.SetRef(RightOp); + updated = true; + break; + } + else { + RightType = RightUse->GetType(); + } + } + } + // If left operand is NUMERIC, operator is NUMERIC. + LeftNumeric = (NUMERIC == LeftType); + RightNumeric = (NUMERIC == RightType); + LeftPointer = ((LeftType >= POINTER) && (LeftType <= HEAPPTR)); + RightPointer = ((RightType >= POINTER) && (RightType <= HEAPPTR)); + if (LeftNumeric) { + // Subtracting anything from a NUMERIC leaves it NUMERIC. + if (UNINIT == OperType) { + CurrRT->SetOperatorType(NUMERIC); + updated = true; + } + else if (NUMERIC != OperType) { + msg("ERROR: SMP_SUBTRACT from NUMERIC should be NUMERIC operator."); + msg(" Operator type is %d in: %s\n", OperType, this->GetDisasm()); + } + if (!RightNumeric) { + // Right operand is being used as a NUMERIC, so propagate NUMERIC to it. + if (CurrRT->HasRightSubTree()) { + CurrRT->GetRightTree()->SetOperatorType(NUMERIC); + } + else { + RightUse = this->SetUseType(RightOp, NUMERIC); + } + updated = true; + } + } // end if LeftNumeric + else if (LeftPointer) { + if (UNINIT == OperType) { + // If we subtract another pointer type, we produce PTROFFSET. + if (RightPointer) { + CurrRT->SetOperatorType(PTROFFSET); + updated = true; + } + else if (RightType == PTROFFSET) { + // We assume B - (B - A) == A **!!** + CurrRT->SetOperatorType(POINTER); + msg("WARNING: PTR - PTROFFSET produces PTR in %s\n", this->GetDisasm()); + updated = true; + } + else if (RightNumeric) { + // pointer minus NUMERIC keeps same pointer type + CurrRT->SetOperatorType(LeftType); + updated = true; + } + } + else { // we have an operator type for the SMP_SUBTRACT + bool OperatorPointer = ((OperType >= POINTER) && (OperType <= HEAPPTR)); + if (CurrRT->HasRightSubTree()) { + // Must need to iterate through the right tree again, as the operator + // has been typed. + if (UNINIT == RightType) { + if (OperatorPointer) { + // PTR := PTR - ?? ==> ?? is NUMERIC + CurrRT->GetRightTree()->SetOperatorType(NUMERIC); + updated = true; + } + else if (OperType == PTROFFSET) { + // PTROFFSET := PTR - ?? ==? ?? is PTR + CurrRT->GetRightTree()->SetOperatorType(LeftType); + updated = true; + } + } + updated |= this->InferOperatorType(CurrRT->GetRightTree()); + break; + } + else { // right operand; propagate operator type if needed + if (UNINIT == RightType) { + if (OperatorPointer) { + // PTR := PTR - ?? ==> ?? is NUMERIC + RightUse = this->SetUseType(RightOp, NUMERIC); + updated = true; + assert(RightUse != this->GetLastUse()); + } + else if (OperType == PTROFFSET) { + // PTROFFSET := PTR - ?? ==? ?? is PTR + RightUse = this->SetUseType(RightOp, LeftType); + updated = true; + } + break; + } + } + } // end if OperType is UNINIT ... else ... + } // end if LeftNumeric ... else if LeftPointer ... + else if (UNINIT == LeftType) { + if (UNINIT != OperType) { + LeftUse = this->SetUseType(LeftOp, OperType); + assert(LeftUse != this->GetLastUse()); + updated = true; + } + } + break; + + case SMP_ASSIGN: // Extract the current types of right and left operands and SMP_ASSIGN operator. DefOp = CurrRT->GetLeftOperand(); -- GitLab