diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp index 70f5e50b714883d420083ebb69f8d2fe714cdaa0..7c0d8e1f95a9bca2c4c519e4be9ae62ae680efee 100644 --- a/SMPBasicBlock.cpp +++ b/SMPBasicBlock.cpp @@ -935,7 +935,7 @@ bool SMPBasicBlock::PropagateGlobalDefType(op_t DefOp, SMPOperandType DefType, i // on pointer types, e.g. def a pointer, use it as pointer, then // perform hash function computations on it. Those computations // (shift, xor, etc.) should truly remain NUMERIC. - if (((DefType >= STACKPTR) && (DefType <= HEAPPTR)) && (POINTER == UseType)) { + if (IsRefinedDataPtr(DefType) && (IsEqType(POINTER, UseType))) { msg("Refining POINTER to %d at %x %s for USE:", DefType, (*InstIter)->GetAddr(), (*InstIter)->GetDisasm()); CurrUse->Dump(); @@ -1043,7 +1043,7 @@ bool SMPBasicBlock::InferLocalDefType(op_t DefOp, unsigned int LocIndex, ea_t De return false; } else { - if (CurrUse->GetType() != UseType) + if (IsNotEqType(CurrUse->GetType(), UseType)) return false; // no consistent type } } @@ -1097,7 +1097,7 @@ set<SMPPhiFunction, LessPhi>::iterator SMPBasicBlock::InferPhiDefType(set<SMPPhi return DefPhi; // not all USEs have type yet } else { - if (UseType != DefPhi->GetUseType(index)) + if (IsNotEqType(UseType, DefPhi->GetUseType(index))) return DefPhi; // inconsistent types } } diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index 6936181e806666ba5f00c87b137f419e88a834a6..f481d92c8ed733384be290aaa8acbb72c74261d1 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -548,7 +548,7 @@ bool DefOrUseSet::TypesAgreeNoFlags(void) { UseType = CurrUse->GetType(); } else { - if (CurrUse->GetType() != UseType) { + if (IsNotEqType(CurrUse->GetType(), UseType)) { return false; // inconsistent types } } diff --git a/SMPDataFlowAnalysis.h b/SMPDataFlowAnalysis.h index 092e6c461aee2b9b464b42d43518f03eb35a8135..c78b8583aae62b423646d50128c89ddf38de84c7 100644 --- a/SMPDataFlowAnalysis.h +++ b/SMPDataFlowAnalysis.h @@ -126,18 +126,48 @@ enum SMPitype { // type of numeric, then the annotation could tell mmStrata to do nothing // at all, which is even better. In order to emit these annotations, we // will track all operands in a function as to their basic SMP types. +#define PROF_BASE 256 enum SMPOperandType { // What type is a given register or memory operand? - UNINIT, // Operand type not yet analyzed; type lattice top - NUMERIC, // Definitely holds non-pointer value (char, int, etc.) - CODEPTR, // Definitely holds a code address - POINTER, // Definitely holds a data address - STACKPTR, // Definitely holds a stack data address (refinement of POINTER) - GLOBALPTR, // Definitely holds a global static data address (refinement of POINTER) - HEAPPTR, // Definitely holds a heap data address (refinement of POINTER) - PTROFFSET, // Offset from a pointer, e.g. a difference between two pointers - UNKNOWN // Might hold an address, might not (Bad!); type lattice bottom + UNINIT = 0, // Operand type not yet analyzed; type lattice top + NUMERIC = 1, // Definitely holds non-pointer value (char, int, etc.) + CODEPTR = 2, // Definitely holds a code address; mmStrata considers this NUMERIC + POINTER = 4, // Definitely holds a data address + STACKPTR = 8, // Definitely holds a stack data address (refinement of POINTER) + GLOBALPTR = 16, // Definitely holds a global static data address (refinement of POINTER) + HEAPPTR = 32, // Definitely holds a heap data address (refinement of POINTER) + PTROFFSET = 64, // Offset from a pointer, e.g. a difference between two pointers + UNKNOWN = 128, // Might hold an address, might not (Bad!); type lattice bottom + PROF_NUMERIC = NUMERIC + PROF_BASE, // NUMERIC, determined using profiler input + PROF_CODEPTR = CODEPTR + PROF_BASE, // CODEPTR, determined using profiler input + PROF_POINTER = POINTER + PROF_BASE, // POINTER, determined using profiler input + PROF_STACKPTR = STACKPTR + PROF_BASE, // STACKPTR, determined using profiler input + PROF_GLOBALPTR = GLOBALPTR + PROF_BASE, // GLOBALPTR, determined using profiler input + PROF_HEAPPTR = HEAPPTR + PROF_BASE, // HEAPPTR, determined using profiler input + PROF_PTROFFSET = PTROFFSET + PROF_BASE, // PTROFFSET, determined using profiler input + PROF_UNKNOWN = UNKNOWN + PROF_BASE // UNKNOWN, determined using profiler input }; +// Macros to query and compare SMPOperandType values. + +// Is OpType any kind of pointer to data, whether profile derived or not? +#define IsDataPtr(OpType) (((OpType & (~PROF_BASE)) >= POINTER) && ((OpType & (~PROF_BASE)) <= HEAPPTR)) + +// Is OpType one of the refined data pointer types (stack, global, heap)? +#define IsRefinedDataPtr(OpType) (((OpType & (~PROF_BASE)) >= STACKPTR) && ((OpType & (~PROF_BASE)) <= HEAPPTR)) + +// Is OpType the lattice bottom (overdefined) type UNKNOWN, profile derived or not? +#define IsUnknown(OpType) ((OpType & (~PROF_BASE)) == UNKNOWN) + +// Is OpType1 the same type as OpType2, ignoring profile derivation? +#define IsEqType(OpType1, OpType2) ((OpType1 & (~PROF_BASE)) == (OpType2 & (~PROF_BASE))) +#define IsNotEqType(OpType1, OpType2) ((OpType1 & (~PROF_BASE)) != (OpType2 & (~PROF_BASE))) + +// Is OpType a profile derived type? +#define IsProfDerived(OpType) (0 != (OpType & PROF_BASE)) + +// Make OpType into its equivalent profile derived type. +#define MakeProfDerived(OpType) (OpType | PROF_BASE) + class DefOrUse { public: // Constructors diff --git a/SMPFunction.cpp b/SMPFunction.cpp index f0a0d373d3775a71c2db79a9673e8358bd0b0f18..a463325c23010c730e26a944b5f61f52529af174 100644 --- a/SMPFunction.cpp +++ b/SMPFunction.cpp @@ -2473,7 +2473,7 @@ bool SMPFunction::InferGlobalDefType(op_t DefOp, int SSANum) { return false; } else { - if (CurrUse->GetType() != UseType) + if (IsNotEqType(CurrUse->GetType(), UseType)) return false; // no consistent type } } diff --git a/SMPInstr.cpp b/SMPInstr.cpp index 8e30f04595cba7a0ab7efd6b8863335405bf5166..0f5334e0a1b9d9470c76cbddcbc96b5336c3c4cc 100644 --- a/SMPInstr.cpp +++ b/SMPInstr.cpp @@ -1260,8 +1260,9 @@ bool SMPInstr::InferTypes(void) { } ++CurrDef; } - CategoryInference = true; + this->CategoryInference = true; changed = true; + this->TypeInferenceComplete = true; } break; @@ -1532,10 +1533,10 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { // then the ADD operator and the result will inherit this second type, // while AND and OR operators will remain UNINIT (we don't know what // type "ptr AND 0xfffffff8" has until we see how it is used). - LeftNumeric = (NUMERIC == LeftType); - RightNumeric = (NUMERIC == RightType); - LeftPointer = ((LeftType >= POINTER) && (LeftType <= HEAPPTR)); - RightPointer = ((RightType >= POINTER) && (RightType <= HEAPPTR)); + LeftNumeric = IsEqType(NUMERIC, LeftType); + RightNumeric = IsEqType(NUMERIC, RightType); + LeftPointer = IsDataPtr(LeftType); + RightPointer = IsDataPtr(RightType); if (UNINIT == CurrRT->GetOperatorType()) { // Infer operator type from left and right operands. if (LeftNumeric && RightNumeric) { @@ -1570,8 +1571,8 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } break; } - else if ((LeftPointer && (RightType == PTROFFSET)) - || (RightPointer && (LeftType == PTROFFSET))) { + else if ((LeftPointer && IsEqType(RightType, PTROFFSET)) + || (RightPointer && IsEqType(LeftType, PTROFFSET))) { // Arithmetic on PTR and PTROFFSET if (SMP_ADD == CurrOp) { // We assume (A-B) is being added to B or vice versa **!!** @@ -1646,10 +1647,10 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } } // If left operand is NUMERIC, operator is NUMERIC. - LeftNumeric = (NUMERIC == LeftType); - RightNumeric = (NUMERIC == RightType); - LeftPointer = ((LeftType >= POINTER) && (LeftType <= HEAPPTR)); - RightPointer = ((RightType >= POINTER) && (RightType <= HEAPPTR)); + LeftNumeric = IsEqType(NUMERIC, LeftType); + RightNumeric = IsEqType(NUMERIC, RightType); + LeftPointer = IsDataPtr(LeftType); + RightPointer = IsDataPtr(RightType); if (LeftNumeric) { // Subtracting anything from a NUMERIC leaves it NUMERIC. if (UNINIT == OperType) { @@ -1691,7 +1692,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { } } else { // we have an operator type for the SMP_SUBTRACT - bool OperatorPointer = ((OperType >= POINTER) && (OperType <= HEAPPTR)); + bool OperatorPointer = IsDataPtr(OperType); if (CurrRT->HasRightSubTree()) { // Must need to iterate through the right tree again, as the operator // has been typed. @@ -1702,7 +1703,7 @@ bool SMPInstr::InferOperatorType(SMPRegTransfer *CurrRT) { updated = true; } else if (OperType == PTROFFSET) { - // PTROFFSET := PTR - ?? ==? ?? is PTR + // PTROFFSET := PTR - ?? ==> ?? is PTR CurrRT->GetRightTree()->SetOperatorType(LeftType); updated = true; }