From d3b22c2c9c0df0ce002e1ec7256739cf6078897b Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Mon, 5 May 2008 23:42:48 +0000 Subject: [PATCH] Emit optimizing annotations for ADD/SUB instructions with NUMERIC source operand. --- SMPInstr.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++------- SMPInstr.h | 2 ++ SMPProgram.cpp | 2 +- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 8abcc4a8..b6a770c9 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -202,6 +202,7 @@ SMPInstr::SMPInstr(ea_t addr) { this->UsesFlags = false; this->TypeInferenceComplete = false; this->CategoryInference = false; + this->AddSubSourceType = UNINIT; this->BasicBlock = NULL; return; } @@ -261,6 +262,35 @@ bool SMPInstr::IsSecondSrcOperandNumeric(flags_t F) const { return (SecondOpImm && IsImmedNumeric(TempImm)); } // end of SMPInstr::IsSecondSrcOperandNumeric() +// Determine the type of the USE-only operand for add and subtract +// instructions. If it is NUMERIC or PROF_NUMERIC, an optimizing +// annotation will result. +void SMPInstr::SetAddSubSourceType(void) { + set<DefOrUse, LessDefUse>::iterator UseIter, DefIter; + + // First, ensure that we are dealing with a register source. + if (this->HasSourceMemoryOperand()) { + this->AddSubSourceType = UNINIT; + return; + } + + // The USE and DEF lists will have the flags and the destination + // operand in common for adds and subtracts. The USE-only operand + // is the one we are concerned with. + for (UseIter = this->GetFirstUse(); UseIter != this->GetLastUse(); ++UseIter) { + if (this->GetLastDef() == this->FindDef(UseIter->GetOp())) { + // Found the USE that is not a DEF + this->AddSubSourceType = UseIter->GetType(); +#if SMP_VERBOSE_DEBUG_INFER_TYPES + msg("Set AddSubSourceType to %d at %x: %s\n", UseIter->GetType(), + this->address, this->GetDisasm()); +#endif + break; + } + } + return; +} // end of SMPInstr::SetAddSubSourceType() + // Are all DEFs in the DEF set NUMERIC type? bool SMPInstr::AllDefsNumeric(void) { bool AllNumeric = (this->Defs.GetSize() > 0); // false if no DEFs, true otherwise @@ -1391,8 +1421,6 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { case SMP_ROTATE_LEFT_CARRY: // rotate left through carry case SMP_ROTATE_RIGHT: case SMP_ROTATE_RIGHT_CARRY: // rotate right through carry - case SMP_ADD_CARRY: // add with carry - case SMP_SUBTRACT_BORROW: // subtract with borrow case SMP_U_MULTIPLY: case SMP_S_MULTIPLY: case SMP_U_DIVIDE: @@ -1491,6 +1519,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { break; case SMP_ADD: + case SMP_ADD_CARRY: // add with carry case SMP_BITWISE_AND: case SMP_BITWISE_OR: // Extract the current types of right and left operands and the operator. @@ -1548,12 +1577,14 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { else if (LeftNumeric || RightNumeric) { // ADD of NUMERIC to non-NUMERIC preserves non-NUMERIC type. // AND and OR operations should leave the operator UNINIT for now. - if (LeftNumeric && (UNINIT != RightType) && (SMP_ADD == CurrOp)) { + if (LeftNumeric && (UNINIT != RightType) + && ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp))) { CurrRT->SetOperatorType(RightType); updated = true; break; } - else if (RightNumeric && (UNINIT != LeftType) && (SMP_ADD == CurrOp)) { + else if (RightNumeric && (UNINIT != LeftType) + && ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp))) { CurrRT->SetOperatorType(LeftType); updated = true; break; @@ -1561,7 +1592,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } else if (LeftPointer && RightPointer) { // Arithmetic on two pointers - if (SMP_ADD == CurrOp) { + if ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp)) { CurrRT->SetOperatorType(UNKNOWN); updated = true; } @@ -1575,7 +1606,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { else if ((LeftPointer && IsEqType(RightType, PTROFFSET)) || (RightPointer && IsEqType(LeftType, PTROFFSET))) { // Arithmetic on PTR and PTROFFSET - if (SMP_ADD == CurrOp) { + if ((SMP_ADD == CurrOp) || (SMP_ADD_CARRY == CurrOp)) { // We assume (A-B) is being added to B or vice versa **!!** CurrRT->SetOperatorType(POINTER); updated = true; @@ -1617,6 +1648,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { break; case SMP_SUBTRACT: + case SMP_SUBTRACT_BORROW: // subtract with borrow // Extract the current types of right and left operands and the operator. OperType = CurrRT->GetOperatorType(); LeftOp = CurrRT->GetLeftOperand(); @@ -1662,6 +1694,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { msg("ERROR: SMP_SUBTRACT from NUMERIC should be NUMERIC operator."); msg(" Operator type is %d in: %s\n", OperType, this->GetDisasm()); } +#if 0 if (!RightNumeric) { // Right operand is being used as a NUMERIC, so propagate NUMERIC to it. if (CurrRT->HasRightSubTree()) { @@ -1672,6 +1705,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } updated = true; } +#endif } // end if LeftNumeric else if (LeftPointer) { if (UNINIT == OperType) { @@ -2187,18 +2221,25 @@ void SMPInstr::EmitTypeAnnotations(bool UseFP, bool AllocSeen, FILE *AnnotFile) ++AnnotationCount[OptType]; break; - case 5: // ADD, etc.: If numeric 2nd src operand, no SDT work. + case 5: // ADD, etc.: If numeric 2nd src operand, no SDT work. #if 1 - if (MemDest || MemSrc) { + if (MemDest) { SDTInstrumentation = true; break; // treat as category 0 } #endif + this->SetAddSubSourceType(); if (SecondSrcOperandNum && !this->MDIsFrameAllocInstr()) { // treat as category 1 qfprintf(AnnotFile, "%10x %6d INSTR LOCAL %s %s \n", addr, -1, OptExplanation[OptType], disasm); ++AnnotationCount[OptType]; } + else if (IsEqType(NUMERIC, this->AddSubSourceType) + && !this->MDIsFrameAllocInstr()) { + qfprintf(AnnotFile, "%10x %6d INSTR LOCAL 2ndSrcNumeric %s \n", + addr, -1, disasm); + ++AnnotationCount[OptType]; + } else if (NumericDEFs) { qfprintf(AnnotFile, "%10x %6d INSTR LOCAL n %s NumericDEFs %s \n", addr, -2, this->DestString(OptType), disasm); diff --git a/SMPInstr.h b/SMPInstr.h index fdb913ac..3b920f42 100644 --- a/SMPInstr.h +++ b/SMPInstr.h @@ -242,6 +242,7 @@ private: char DeadRegsString[MAXSTR]; // Registers that are dead at this instruction bool DefsFlags; // Instr DEFs the flags bool UsesFlags; // Instr USEs the flags + SMPOperandType AddSubSourceType; // Source op (USE only) type for add/sub bool TypeInferenceComplete; // All types have been resolved // For some type categories, inference just based on the category is done one time // only, so this is a variable that is set to true after the first inference @@ -280,6 +281,7 @@ private: bool BuildMultiplyDivideRTL(SMPoperator BinaryOp); // helper for BuildRTL() void SyncRTLDefUse(SMPRegTransfer *CurrRT); // Ensure that all RTL operands are in the DEF/USE lists bool InferOperatorType(SMPRegTransfer *CurrRT); // return true if type updated + void SetAddSubSourceType(void); }; // end class SMPInstr #endif diff --git a/SMPProgram.cpp b/SMPProgram.cpp index 32793dbc..f4317017 100644 --- a/SMPProgram.cpp +++ b/SMPProgram.cpp @@ -301,7 +301,7 @@ void SMPProgram::Analyze(void) { pair<ea_t, SMPFunction *> TempFunc(FuncInfo->startEA, CurrFunc); this->FuncMap.insert(TempFunc); CurrFunc->Analyze(); - if (0 == strcmp("EvVar", CurrFunc->GetFuncName())) { + if (0 == strcmp("load_subblock_array", CurrFunc->GetFuncName())) { DebugFlag = true; } #if SMP_INFER_TYPES -- GitLab