コード例 #1
0
		private static void ProcessLocation(IRLinearizedLocation s, AssignedLocal[] locals)
		{
			switch (s.Type)
			{
				case IRLinearizedLocationType.Null: break;
				case IRLinearizedLocationType.ConstantI4: break;
				case IRLinearizedLocationType.ConstantI8: break;
				case IRLinearizedLocationType.ConstantR4: break;
				case IRLinearizedLocationType.ConstantR8: break;
				case IRLinearizedLocationType.SizeOf: break;
				case IRLinearizedLocationType.String: break;
				case IRLinearizedLocationType.Parameter: break;
				case IRLinearizedLocationType.ParameterAddress: break;
				case IRLinearizedLocationType.StaticField: break;
				case IRLinearizedLocationType.StaticFieldAddress: break;
				case IRLinearizedLocationType.RuntimeHandle: break;
				case IRLinearizedLocationType.Local:
					locals[s.Local.LocalIndex].UseCount++;
					break;
				case IRLinearizedLocationType.LocalAddress:
					locals[s.LocalAddress.LocalIndex].UseCount++;
					locals[s.LocalAddress.LocalIndex].AddressLoaded = true;
					break;
				case IRLinearizedLocationType.Field:
					ProcessLocation(s.Field.FieldLocation, locals);
					break;
				case IRLinearizedLocationType.FieldAddress:
					ProcessLocation(s.FieldAddress.FieldLocation, locals);
					break;
				case IRLinearizedLocationType.Indirect:
					ProcessLocation(s.Indirect.AddressLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayElement:
					ProcessLocation(s.ArrayElement.ArrayLocation, locals);
					ProcessLocation(s.ArrayElement.IndexLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayElementAddress:
					ProcessLocation(s.ArrayElementAddress.ArrayLocation, locals);
					ProcessLocation(s.ArrayElementAddress.IndexLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayLength:
					ProcessLocation(s.ArrayLength.ArrayLocation, locals);
					break;
				case IRLinearizedLocationType.FunctionAddress:
					if (s.FunctionAddress.Virtual)
						ProcessLocation(s.FunctionAddress.InstanceLocation, locals);
					break;
				case IRLinearizedLocationType.Phi:
					s.Phi.SourceLocations.ForEach(source => ProcessLocation(source, locals));
					break;
				default:
					throw new Exception("Unknown IRLinearizedLocation type!");
			}
		}
コード例 #2
0
		private static void RetargetLocation(IRMethod pMethod, ref IRLinearizedLocation location, AssignedLocal[] locals)
		{
			switch (location.Type)
			{
				case IRLinearizedLocationType.Null: break;
				case IRLinearizedLocationType.ConstantI4: break;
				case IRLinearizedLocationType.ConstantI8: break;
				case IRLinearizedLocationType.ConstantR4: break;
				case IRLinearizedLocationType.ConstantR8: break;
				case IRLinearizedLocationType.SizeOf: break;
				case IRLinearizedLocationType.String: break;
				case IRLinearizedLocationType.Parameter: break;
				case IRLinearizedLocationType.ParameterAddress: break;
				case IRLinearizedLocationType.StaticField: break;
				case IRLinearizedLocationType.StaticFieldAddress: break;
				case IRLinearizedLocationType.RuntimeHandle: break;
				case IRLinearizedLocationType.LocalAddress: break;

				case IRLinearizedLocationType.Local:
					var l = locals[location.Local.LocalIndex];
					if (l.UseCount == 1 && l.AssignedAt != -1 && !l.AddressLoaded && !pMethod.Locals[location.Local.LocalIndex].SSAData.Phi)
					{
						location = pMethod.Instructions[l.AssignedAt].Sources[0].Clone(location.ParentInstruction);
						l.Killed = true;
					}
					break;
				case IRLinearizedLocationType.Field:
					RetargetLocation(pMethod, ref location.Field.FieldLocation, locals);
					break;
				case IRLinearizedLocationType.FieldAddress:
					RetargetLocation(pMethod, ref location.FieldAddress.FieldLocation, locals);
					break;
				case IRLinearizedLocationType.Indirect:
					RetargetLocation(pMethod, ref location.Indirect.AddressLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayElement:
					RetargetLocation(pMethod, ref location.ArrayElement.ArrayLocation, locals);
					RetargetLocation(pMethod, ref location.ArrayElement.IndexLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayElementAddress:
					RetargetLocation(pMethod, ref location.ArrayElementAddress.ArrayLocation, locals);
					RetargetLocation(pMethod, ref location.ArrayElementAddress.IndexLocation, locals);
					break;
				case IRLinearizedLocationType.ArrayLength:
					RetargetLocation(pMethod, ref location.ArrayLength.ArrayLocation, locals);
					break;
				case IRLinearizedLocationType.FunctionAddress:
					if (location.FunctionAddress.Virtual)
						RetargetLocation(pMethod, ref location.FunctionAddress.InstanceLocation, locals);
					break;
				case IRLinearizedLocationType.Phi:
					for (int i = 0; i < location.Phi.SourceLocations.Count; i++)
					{
						var s = location.Phi.SourceLocations[i];
						RetargetLocation(pMethod, ref s, locals);
						location.Phi.SourceLocations[i] = s;
					}
					break;
				default:
					throw new Exception("Unknown IRLinearizedLocation type!");
			}
		}
コード例 #3
0
		public override void Run(IRMethod pMethod)
		{
			pMethod.Instructions.ImmediateRetargetModifiedInstructions = false;

			var localUseMap = new AssignedLocal[pMethod.Locals.Count];
			for (int i = 0; i < localUseMap.Length; i++) localUseMap[i] = new AssignedLocal();

			for (int i = 0; i < pMethod.Instructions.Count; i++)
			{
				var curInstr = pMethod.Instructions[i];
				curInstr.Sources.ForEach(s => ProcessLocation(s, localUseMap));
				if (curInstr.Destination != null)
				{
					ProcessLocation(curInstr.Destination, localUseMap);
					if (curInstr.Opcode == IROpcode.Move)
					{
						if (curInstr.Destination.Type == IRLinearizedLocationType.Local)
						{
							if (localUseMap[curInstr.Destination.Local.LocalIndex].AssignedAt >= 0)
								throw new Exception("Somehow it was already assigned!");
							localUseMap[curInstr.Destination.Local.LocalIndex].UseCount--;
							localUseMap[curInstr.Destination.Local.LocalIndex].AssignedAt = i;
						}
						
						if (curInstr.Sources[0].Type == IRLinearizedLocationType.Phi)
						{
							foreach (var v in curInstr.Sources[0].Phi.SourceLocations)
							{
								localUseMap[v.Local.LocalIndex].AddressLoaded = true;
							}
						}
					}
				}
			}

			for (int i = 0; i < pMethod.Instructions.Count; i++)
			{
				var curInstr = pMethod.Instructions[i];
				for (int i2 = 0; i2 < curInstr.Sources.Count; i2++)
				{
					var s = curInstr.Sources[i2];
					RetargetLocation(pMethod, ref s, localUseMap);
					curInstr.Sources[i2] = s;
				}
				if (curInstr.Destination != null)
					RetargetLocation(pMethod, ref curInstr.Destination, localUseMap);
			}

			for (int i = 0; i < localUseMap.Length; i++)
			{
				var l = localUseMap[i];
				if (l.Killed)
					pMethod.Instructions[l.AssignedAt] = new IRNopInstruction();
			}

			pMethod.Instructions.FixModifiedTargetInstructions();
			pMethod.Instructions.ImmediateRetargetModifiedInstructions = true;
		}