Prechádzať zdrojové kódy

partially revived optimization for small vector and matrices: currently only static arrays are handled;

a working example:

VAR
x, y, z: ARRAY [4,4] OF REAL;

BEGIN
...
z := x * y;
...
END

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6458 8c9fc860-2736-0410-a75d-ab315db34111
eth.morozova 9 rokov pred
rodič
commit
fa4a0e213f
2 zmenil súbory, kde vykonal 94 pridanie a 11 odobranie
  1. 9 9
      source/FoxArrayBase.Mod
  2. 85 2
      source/FoxIntermediateBackend.Mod

+ 9 - 9
source/FoxArrayBase.Mod

@@ -76,7 +76,7 @@ CONST
 	MatVec7x7 = SYSTEM.VAL(LONGINT,{SmallMatrixFlag,SmallVectorFlag,Size7Flag});
 	MatVec8x8 = SYSTEM.VAL(LONGINT,{SmallMatrixFlag,SmallVectorFlag,Size8Flag});
 
-
+	SmallArrayMask = {SmallMatrixFlag,SmallVectorFlag,Size2Flag,Size3Flag,Size4Flag,Size5Flag,Size6Flag,Size7Flag,Size8Flag};
 
 TYPE
 	FastMatMul* = PROCEDURE ( matrixA, matrixB, matrixC, IncA, StrideA, IncB, StrideB, IncC, StrideC, RowsA, ColsA, RowsB, ColsB: LONGINT ): BOOLEAN;
@@ -7860,12 +7860,12 @@ Sufficient (but not necessary) conditions:
 		(* account possible inplace left := left*right, right := left*right, left := left*left, right := right*right *)
 		IF (ladr # dadr) & (radr # dadr) THEN
 
-			flags := SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(left)+MathFlagsOffset)) * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(right)+MathFlagsOffset));
+			flags := SmallArrayMask * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(left)+MathFlagsOffset)) * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(right)+MathFlagsOffset));
 
 			CASE SYSTEM.VAL(LONGINT,flags) OF
 
 				Mat2x2:
-					IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Mat2x2 THEN
+					IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Mat2x2 THEN
 						IF dadr = 0 THEN NEW(RESULT,2,2);
 						ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 						END;
@@ -7880,7 +7880,7 @@ Sufficient (but not necessary) conditions:
 					END;
 
 				|Mat3x3:
-					IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Mat3x3 THEN
+					IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Mat3x3 THEN
 						IF dadr = 0 THEN NEW(RESULT,3,3);
 						ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 						END;
@@ -7903,7 +7903,7 @@ Sufficient (but not necessary) conditions:
 
 
 				|Mat4x4:
-					IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Mat4x4 THEN
+					IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Mat4x4 THEN
 						IF dadr = 0 THEN NEW(RESULT,4,4);
 						ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 						END;
@@ -7957,12 +7957,12 @@ Sufficient (but not necessary) conditions:
 		ladr := GetAdr(ADDRESSOF(left));
 		radr := GetAdr(ADDRESSOF(right));
 
-		flags := SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(left)+MathFlagsOffset)) * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(right)+MathFlagsOffset));
+		flags := SmallArrayMask * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(left)+MathFlagsOffset)) * SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(right)+MathFlagsOffset));
 
 		CASE SYSTEM.VAL(LONGINT,flags) OF
 
 			MatVec2x2:
-				IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Vec2 THEN
+				IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Vec2 THEN
 					IF dadr = 0 THEN NEW(RESULT,2);
 					ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 					END;
@@ -7977,7 +7977,7 @@ Sufficient (but not necessary) conditions:
 				END;
 
 			|MatVec3x3:
-				IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Vec3 THEN
+				IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Vec3 THEN
 					IF dadr = 0 THEN NEW(RESULT,3);
 					ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 					END;
@@ -7993,7 +7993,7 @@ Sufficient (but not necessary) conditions:
 				END;
 
 			|MatVec4x4:
-				IF SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset) # Vec4 THEN
+				IF SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(ADDRESSOF(RESULT)+MathFlagsOffset)) * SmallArrayMask) # Vec4 THEN
 					IF dadr = 0 THEN NEW(RESULT,4);
 					ELSE Halt(GeometryMismatch,ADDRESSOF(left),ADDRESSOF(right),0);
 					END;

+ 85 - 2
source/FoxIntermediateBackend.Mod

@@ -90,6 +90,19 @@ CONST
 			ProcessorOffset = BaseObjectTypeSize + 1;
 			StackLimitOffset* = BaseObjectTypeSize + 3;
 			QuantumOffset = BaseObjectTypeSize + 4;
+			
+			
+			
+		(* flags for optimizations with small matricies and vectors (Alexey Morozov) *)
+		SmallMatrixFlag = 3; (* flag for identification of a small matrix *)
+		SmallVectorFlag = 3; (* flag for identification of a small vector *)
+		Size2Flag = 4; (* size = 2 *)
+		Size3Flag = 5; (* size = 3 *)
+		Size4Flag = 6; (* size = 4 *)
+		Size5Flag = 7; (* size = 5 *)
+		Size6Flag = 8; (* size = 6 *)
+		Size7Flag = 9; (* size = 7 *)
+		Size8Flag = 10; (* size = 8 *)
 		
 TYPE
 	SupportedInstructionProcedure* = PROCEDURE {DELEGATE} (CONST instr: IntermediateCode.Instruction; VAR moduleName,procedureName: ARRAY OF CHAR): BOOLEAN;
@@ -4325,6 +4338,9 @@ TYPE
 			oldArrayDestinationDimension: LONGINT;
 			position: LONGINT;
 			saved: RegisterEntry;
+			
+			arrayFlags: SET;
+			m, n: LONGINT;
 
 			PROCEDURE Pass(op: IntermediateCode.Operand);
 			VAR registerClass: IntermediateCode.RegisterClass; parameterRegister: IntermediateCode.Operand;
@@ -4363,6 +4379,19 @@ TYPE
 					PushArrayLens(formalType(SyntaxTree.ArrayType).arrayBase.resolved, actualArrayBase,dim-1);
 				END;
 			END PushArrayLens;
+			
+			PROCEDURE SetSmallArraySizeFlag(VAR flags: SET; size: LONGINT);
+			BEGIN
+				CASE size OF
+					|2: INCL(flags,Size2Flag);
+					|3: INCL(flags,Size3Flag);
+					|4: INCL(flags,Size4Flag);
+					|5: INCL(flags,Size5Flag);
+					|6: INCL(flags,Size6Flag);
+					|7: INCL(flags,Size7Flag);
+					|8: INCL(flags,Size8Flag);
+				END;
+			END SetSmallArraySizeFlag;
 
 		BEGIN
 			IF Trace THEN TraceEnter("PushParameter") END;
@@ -4459,11 +4488,38 @@ TYPE
 							PutMathArrayIncrement(arrayDestinationTag,tmpOperand.op,i);
 							ReleaseOperand(tmpOperand);
 						END;
+						
+						(*******
+							identify the cases of small vector and matrices, used for optimizations in FoxArrayBase module (Alexey Morozov)
+						*)
+						arrayFlags := {StaticFlag};
+						IF dim = 1 THEN
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,0,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							m := LONGINT(tmpOperand.op.intValue);
+							IF (m >= 2) & (m <= 8) THEN INCL(arrayFlags,SmallVectorFlag); SetSmallArraySizeFlag(arrayFlags,m); END;
+						ELSIF dim = 2 THEN
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,0,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							m := LONGINT(tmpOperand.op.intValue);
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,1,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							n := LONGINT(tmpOperand.op.intValue);
+							IF (m >= 2) & (m <= 8) & (n >= 2) & (n <= 8) THEN
+								INCL(arrayFlags,SmallMatrixFlag); 
+								IF m = n THEN SetSmallArraySizeFlag(arrayFlags,m); END;
+							END;
+						END;
+						(*******)
+						
 						dimOp := IntermediateCode.Immediate(addressType,dim);
 						PutMathArrayField(arrayDestinationTag,dimOp,MathDimOffset);
 						PutMathArrayField(arrayDestinationTag,operand.op,MathAdrOffset);
 						PutMathArrayField(arrayDestinationTag,nil,MathPtrOffset);
-						PutMathArrayField(arrayDestinationTag,IntermediateCode.Immediate(addressType,SYSTEM.VAL(LONGINT,{StaticFlag})),MathFlagsOffset);
+						PutMathArrayField(arrayDestinationTag,IntermediateCode.Immediate(addressType,SYSTEM.VAL(LONGINT,arrayFlags)),MathFlagsOffset);
 						baseType := SemanticChecker.ArrayBase(type,dim);
 						tmp := IntermediateCode.Immediate(addressType,ToMemoryUnits(system,system.AlignedSizeOf(baseType)));
 						PutMathArrayField(arrayDestinationTag,tmp,MathElementSizeOffset);
@@ -4538,11 +4594,38 @@ TYPE
 							PutMathArrayIncrement(arrayDestinationTag,tmpOperand.op,i);
 							ReleaseOperand(tmpOperand);
 						END;
+						
+						(*
+							identify the cases of small vector and matrices, used for optimizations in FoxArrayBase module (Alexey Morozov)
+						*)
+						arrayFlags := {StaticFlag};
+						IF dim = 1 THEN
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,0,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							m := LONGINT(tmpOperand.op.intValue);
+							IF (m >= 2) & (m <= 8) THEN INCL(arrayFlags,SmallVectorFlag); SetSmallArraySizeFlag(arrayFlags,m); END;
+						ELSIF dim = 2 THEN
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,0,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							m := LONGINT(tmpOperand.op.intValue);
+							GetMathArrayLengthAt(type.resolved(SyntaxTree.MathArrayType),operand,1,FALSE,tmpOperand);
+							ReleaseOperand(tmpOperand);
+							ASSERT(tmpOperand.op.mode = IntermediateCode.ModeImmediate);
+							n := LONGINT(tmpOperand.op.intValue);
+							IF (m >= 2) & (m <= 8) & (n >= 2) & (n <= 8) THEN
+								INCL(arrayFlags,SmallMatrixFlag); 
+								IF m = n THEN SetSmallArraySizeFlag(arrayFlags,m); END;
+							END;
+						END;
+						(*******)
+						
 						dimOp := IntermediateCode.Immediate(addressType,dim);
 						PutMathArrayField(arrayDestinationTag,dimOp,MathDimOffset);
 						PutMathArrayField(arrayDestinationTag,operand.op,MathAdrOffset);
 						PutMathArrayField(arrayDestinationTag,nil,MathPtrOffset);
-						PutMathArrayField(arrayDestinationTag,IntermediateCode.Immediate(addressType,SYSTEM.VAL(LONGINT,{StaticFlag})),MathFlagsOffset);
+						PutMathArrayField(arrayDestinationTag,IntermediateCode.Immediate(addressType,SYSTEM.VAL(LONGINT,arrayFlags)),MathFlagsOffset);
 						baseType := SemanticChecker.ArrayBase(type,dim);
 						tmp := IntermediateCode.Immediate(addressType,ToMemoryUnits(system,system.AlignedSizeOf(baseType)));
 						PutMathArrayField(arrayDestinationTag,tmp,MathElementSizeOffset);