From fc9fe57c3b0139539fd939b9cb61f566a1d89c31 Mon Sep 17 00:00:00 2001
From: clc5q <clc5q@git.zephyr-software.com>
Date: Fri, 2 May 2008 16:20:54 +0000
Subject: [PATCH] Macros and other preparation for integrating profiler
 annotations into the type inference system.

---
 SMPBasicBlock.cpp       |  6 +++---
 SMPDataFlowAnalysis.cpp |  2 +-
 SMPDataFlowAnalysis.h   | 48 +++++++++++++++++++++++++++++++++--------
 SMPFunction.cpp         |  2 +-
 SMPInstr.cpp            | 27 ++++++++++++-----------
 5 files changed, 58 insertions(+), 27 deletions(-)

diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp
index 70f5e50b..7c0d8e1f 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 6936181e..f481d92c 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 092e6c46..c78b8583 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 f0a0d373..a463325c 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 8e30f045..0f5334e0 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;
 							}
-- 
GitLab