diff --git a/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs b/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs index 65901e80cc..417f3bae68 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs @@ -2,6 +2,9 @@ using ARMeilleure.IntermediateRepresentation; using System; using System.Collections.Generic; +using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; + namespace ARMeilleure.CodeGen.RegisterAllocators { class CopyResolver @@ -133,14 +136,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators private static void EmitCopy(List sequence, Operand x, Operand y) { - sequence.Add(new Operation(Instruction.Copy, x, y)); + sequence.Add(Operation(Instruction.Copy, x, y)); } private static void EmitXorSwap(List sequence, Operand x, Operand y) { - sequence.Add(new Operation(Instruction.BitwiseExclusiveOr, x, x, y)); - sequence.Add(new Operation(Instruction.BitwiseExclusiveOr, y, y, x)); - sequence.Add(new Operation(Instruction.BitwiseExclusiveOr, x, x, y)); + sequence.Add(Operation(Instruction.BitwiseExclusiveOr, x, x, y)); + sequence.Add(Operation(Instruction.BitwiseExclusiveOr, y, y, x)); + sequence.Add(Operation(Instruction.BitwiseExclusiveOr, x, x, y)); } } @@ -194,20 +197,20 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { Operand register = GetRegister(right.Register, type); - Operand offset = new Operand(left.SpillOffset); + Operand offset = Const(left.SpillOffset); - _fillQueue.Enqueue(new Operation(Instruction.Fill, register, offset)); + _fillQueue.Enqueue(Operation(Instruction.Fill, register, offset)); HasCopy = true; } private void AddSplitSpill(LiveInterval left, LiveInterval right, OperandType type) { - Operand offset = new Operand(right.SpillOffset); + Operand offset = Const(right.SpillOffset); Operand register = GetRegister(left.Register, type); - _spillQueue.Enqueue(new Operation(Instruction.Spill, null, offset, register)); + _spillQueue.Enqueue(Operation(Instruction.Spill, null, offset, register)); HasCopy = true; } @@ -240,7 +243,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators private static Operand GetRegister(Register reg, OperandType type) { - return new Operand(reg.Index, reg.Type, type); + return Register(reg.Index, reg.Type, type); } } } \ No newline at end of file diff --git a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs index ce7936f916..ca494cd67d 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; namespace ARMeilleure.CodeGen.RegisterAllocators { @@ -265,7 +266,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators node.SetSource(srcIndex, temp); } - Operation fillOp = new Operation(Instruction.Fill, temp, Const(info.SpillOffset)); + Operation fillOp = Operation(Instruction.Fill, temp, Const(info.SpillOffset)); block.Operations.AddBefore(node, fillOp); } @@ -363,7 +364,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators node.SetDestination(dstIndex, temp); - Operation spillOp = new Operation(Instruction.Spill, null, Const(info.SpillOffset), temp); + Operation spillOp = Operation(Instruction.Spill, null, Const(info.SpillOffset), temp); block.Operations.AddAfter(node, spillOp); diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs index 1dc6ad7372..86efd375e6 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs @@ -743,7 +743,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators { Debug.Assert(!interval.IsSpilled, "Spilled intervals are not allowed."); - return new Operand( + return OperandHelper.Register( interval.Register.Index, interval.Register.Type, interval.Local.Type); diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 32ca6a7812..7028bdb706 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -10,6 +10,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using static ARMeilleure.IntermediateRepresentation.OperandHelper; + namespace ARMeilleure.CodeGen.X86 { static class CodeGenerator @@ -547,7 +549,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand source = operation.GetSource(0); - MemoryOperand memOp = new MemoryOperand(OperandType.I64, source); + MemoryOperand memOp = MemoryOp(OperandType.I64, source); context.Assembler.Cmpxchg16b(memOp); } @@ -736,7 +738,7 @@ namespace ARMeilleure.CodeGen.X86 // operand size constant to the destination register. context.JumpToNear(X86Condition.NotEqual); - context.Assembler.Mov(dest, new Operand(operandSize | operandMask), OperandType.I32); + context.Assembler.Mov(dest, Const(operandSize | operandMask), OperandType.I32); context.JumpHere(); @@ -744,7 +746,7 @@ namespace ARMeilleure.CodeGen.X86 // starting from the least significant bit. However we are supposed to // return the number of 0 bits on the high end. So, we invert the result // of the BSR using XOR to get the correct value. - context.Assembler.Xor(dest, new Operand(operandMask), OperandType.I32); + context.Assembler.Xor(dest, Const(operandMask), OperandType.I32); } private static void GenerateCpuId(CodeGenContext context, Operation operation) @@ -813,7 +815,7 @@ namespace ARMeilleure.CodeGen.X86 Operand rsp = Register(X86Register.Rsp); - MemoryOperand memOp = new MemoryOperand(dest.Type, rsp, null, Multiplier.x1, offs); + MemoryOperand memOp = MemoryOp(dest.Type, rsp, null, Multiplier.x1, offs); GenerateLoad(context, memOp, dest); } @@ -1012,7 +1014,7 @@ namespace ARMeilleure.CodeGen.X86 Operand rsp = Register(X86Register.Rsp); - MemoryOperand memOp = new MemoryOperand(source.Type, rsp, null, Multiplier.x1, offs); + MemoryOperand memOp = MemoryOp(source.Type, rsp, null, Multiplier.x1, offs); GenerateStore(context, memOp, source); } @@ -1028,7 +1030,7 @@ namespace ARMeilleure.CodeGen.X86 Operand rsp = Register(X86Register.Rsp); - MemoryOperand memOp = new MemoryOperand(OperandType.I64, rsp, null, Multiplier.x1, offs); + MemoryOperand memOp = MemoryOp(OperandType.I64, rsp, null, Multiplier.x1, offs); context.Assembler.Lea(dest, memOp, OperandType.I64); } @@ -1225,7 +1227,7 @@ namespace ARMeilleure.CodeGen.X86 if ((index & 1) != 0) { - context.Assembler.Shr(dest, new Operand(8), OperandType.I32); + context.Assembler.Shr(dest, Const(8), OperandType.I32); } else { @@ -1264,7 +1266,7 @@ namespace ARMeilleure.CodeGen.X86 context.Assembler.Pinsrw(dest, dest, src2, (byte)(index * words + word)); // Move next word down. - context.Assembler.Ror(src2, new Operand(16), src2.Type); + context.Assembler.Ror(src2, Const(16), src2.Type); } } @@ -1592,7 +1594,7 @@ namespace ARMeilleure.CodeGen.X86 if (reservedStackSize != 0) { - context.Assembler.Sub(rsp, new Operand(reservedStackSize), OperandType.I64); + context.Assembler.Sub(rsp, Const(reservedStackSize), OperandType.I64); } int offset = reservedStackSize; @@ -1605,7 +1607,7 @@ namespace ARMeilleure.CodeGen.X86 offset -= 16; - MemoryOperand memOp = new MemoryOperand(OperandType.V128, rsp, null, Multiplier.x1, offset); + MemoryOperand memOp = MemoryOp(OperandType.V128, rsp, null, Multiplier.x1, offset); context.Assembler.Movdqu(memOp, Xmm((X86Register)bit)); @@ -1635,7 +1637,7 @@ namespace ARMeilleure.CodeGen.X86 offset -= 16; - MemoryOperand memOp = new MemoryOperand(OperandType.V128, rsp, null, Multiplier.x1, offset); + MemoryOperand memOp = MemoryOp(OperandType.V128, rsp, null, Multiplier.x1, offset); context.Assembler.Movdqu(Xmm((X86Register)bit), memOp); @@ -1644,7 +1646,7 @@ namespace ARMeilleure.CodeGen.X86 if (reservedStackSize != 0) { - context.Assembler.Add(rsp, new Operand(reservedStackSize), OperandType.I64); + context.Assembler.Add(rsp, Const(reservedStackSize), OperandType.I64); } mask = CallingConvention.GetIntCalleeSavedRegisters() & context.AllocResult.IntUsedRegisters; @@ -1676,7 +1678,7 @@ namespace ARMeilleure.CodeGen.X86 for (int offset = PageSize; offset < size; offset += PageSize) { - Operand memOp = new MemoryOperand(OperandType.I32, rsp, null, Multiplier.x1, -offset); + Operand memOp = MemoryOp(OperandType.I32, rsp, null, Multiplier.x1, -offset); context.Assembler.Mov(temp, memOp, OperandType.I32); } @@ -1689,17 +1691,17 @@ namespace ARMeilleure.CodeGen.X86 return operand as MemoryOperand; } - return new MemoryOperand(type, operand); + return MemoryOp(type, operand); } private static Operand Register(X86Register register, OperandType type = OperandType.I64) { - return new Operand((int)register, RegisterType.Integer, type); + return OperandHelper.Register((int)register, RegisterType.Integer, type); } private static Operand Xmm(X86Register register) { - return new Operand((int)register, RegisterType.Vector, OperandType.V128); + return OperandHelper.Register((int)register, RegisterType.Vector, OperandType.V128); } } } \ No newline at end of file diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index 75844b099b..25ffa7f4df 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -1,10 +1,12 @@ using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; +using System; using System.Collections.Generic; using System.Diagnostics; using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; namespace ARMeilleure.CodeGen.X86 { @@ -207,8 +209,8 @@ namespace ARMeilleure.CodeGen.X86 // - The value at the memory location is loaded to RDX:RAX. void SplitOperand(Operand source, Operand lr, Operand hr) { - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, lr, source, Const(0))); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, hr, source, Const(1))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, lr, source, Const(0))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, hr, source, Const(1))); } Operand rax = Gpr(X86Register.Rax, OperandType.I64); @@ -219,8 +221,8 @@ namespace ARMeilleure.CodeGen.X86 SplitOperand(operation.GetSource(1), rax, rdx); SplitOperand(operation.GetSource(2), rbx, rcx); - node = nodes.AddAfter(node, new Operation(Instruction.VectorCreateScalar, dest, rax)); - node = nodes.AddAfter(node, new Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); + node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); + node = nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1))); operation.SetDestinations(new Operand[] { rdx, rax }); @@ -243,16 +245,16 @@ namespace ARMeilleure.CodeGen.X86 Operand edx = Gpr(X86Register.Rdx, OperandType.I32); // Value 0x01 = Version, family and feature information. - nodes.AddBefore(node, new Operation(Instruction.Copy, eax, Const(1))); + nodes.AddBefore(node, Operation(Instruction.Copy, eax, Const(1))); // Copy results to the destination register. // The values are split into 2 32-bits registers, we merge them // into a single 64-bits register. Operand rcx = Gpr(X86Register.Rcx, OperandType.I64); - node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend32, dest, edx)); - node = nodes.AddAfter(node, new Operation(Instruction.ShiftLeft, dest, dest, Const(32))); - node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, dest, dest, rcx)); + node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, dest, edx)); + node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, dest, dest, Const(32))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, dest, dest, rcx)); operation.SetDestinations(new Operand[] { eax, ebx, ecx, edx }); @@ -275,10 +277,10 @@ namespace ARMeilleure.CodeGen.X86 Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type); - nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1)); - nodes.AddBefore(node, new Operation(Instruction.Clobber, rdx)); + nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); + nodes.AddBefore(node, Operation(Instruction.Clobber, rdx)); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rax)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); operation.SetDestinations(new Operand[] { rdx, rax }); @@ -302,7 +304,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand xmm0 = Xmm(X86Register.Xmm0, OperandType.V128); - nodes.AddBefore(node, new Operation(Instruction.Copy, xmm0, operation.GetSource(2))); + nodes.AddBefore(node, Operation(Instruction.Copy, xmm0, operation.GetSource(2))); operation.SetSource(2, xmm0); } @@ -322,11 +324,11 @@ namespace ARMeilleure.CodeGen.X86 Operand rax = Gpr(X86Register.Rax, src1.Type); Operand rdx = Gpr(X86Register.Rdx, src1.Type); - nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1)); + nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); operation.SetSource(0, rax); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rdx)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx)); operation.SetDestinations(new Operand[] { rdx, rax }); @@ -343,7 +345,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand rcx = Gpr(X86Register.Rcx, OperandType.I32); - nodes.AddBefore(node, new Operation(Instruction.Copy, rcx, operation.GetSource(1))); + nodes.AddBefore(node, Operation(Instruction.Copy, rcx, operation.GetSource(1))); operation.SetSource(1, rcx); } @@ -392,17 +394,17 @@ namespace ARMeilleure.CodeGen.X86 // local would be overwritten. Operand temp = Local(dest.Type); - nodes.AddBefore(node, new Operation(Instruction.Copy, temp, src1)); + nodes.AddBefore(node, Operation(Instruction.Copy, temp, src1)); operation.SetSource(0, temp); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, temp)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); operation.Destination = temp; } else { - nodes.AddBefore(node, new Operation(Instruction.Copy, dest, src1)); + nodes.AddBefore(node, Operation(Instruction.Copy, dest, src1)); operation.SetSource(0, dest); } @@ -416,17 +418,17 @@ namespace ARMeilleure.CodeGen.X86 { Operand temp = Local(dest.Type); - nodes.AddBefore(node, new Operation(Instruction.Copy, temp, src3)); + nodes.AddBefore(node, Operation(Instruction.Copy, temp, src3)); operation.SetSource(2, temp); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, temp)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); operation.Destination = temp; } else { - nodes.AddBefore(node, new Operation(Instruction.Copy, dest, src3)); + nodes.AddBefore(node, Operation(Instruction.Copy, dest, src3)); operation.SetSource(2, dest); } @@ -453,8 +455,8 @@ namespace ARMeilleure.CodeGen.X86 // and then use the 64-bits signed conversion instructions. Operand zex = Local(OperandType.I64); - node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend32, zex, source)); - node = nodes.AddAfter(node, new Operation(Instruction.ConvertToFP, dest, zex)); + node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend32, zex, source)); + node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, zex)); } else /* if (source.Type == OperandType.I64) */ { @@ -473,17 +475,17 @@ namespace ARMeilleure.CodeGen.X86 Operand lsbF = Local(dest.Type); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, lsb, source)); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, half, source)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, lsb, source)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, half, source)); - node = nodes.AddAfter(node, new Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L))); - node = nodes.AddAfter(node, new Operation(Instruction.ShiftRightUI, half, half, Const(1))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, lsb, lsb, Const(1L))); + node = nodes.AddAfter(node, Operation(Instruction.ShiftRightUI, half, half, Const(1))); - node = nodes.AddAfter(node, new Operation(Instruction.ConvertToFP, lsbF, lsb)); - node = nodes.AddAfter(node, new Operation(Instruction.ConvertToFP, dest, half)); + node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, lsbF, lsb)); + node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, half)); - node = nodes.AddAfter(node, new Operation(Instruction.Add, dest, dest, dest)); - node = nodes.AddAfter(node, new Operation(Instruction.Add, dest, dest, lsbF)); + node = nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, dest)); + node = nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, lsbF)); } Delete(nodes, currentNode, operation); @@ -506,7 +508,7 @@ namespace ARMeilleure.CodeGen.X86 Operand res = Local(dest.Type); - node = nodes.AddAfter(node, new Operation(Instruction.VectorOne, res)); + node = nodes.AddAfter(node, Operation(Instruction.VectorOne, res)); if (dest.Type == OperandType.FP32) { @@ -519,7 +521,7 @@ namespace ARMeilleure.CodeGen.X86 node = nodes.AddAfter(node, new IntrinsicOperation(Intrinsic.X86Xorps, res, res, source)); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, res)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, res)); Delete(nodes, currentNode, operation); @@ -545,26 +547,26 @@ namespace ARMeilleure.CodeGen.X86 Operand temp1 = Local(OperandType.I32); Operand temp2 = Local(OperandType.I32); - node = nodes.AddAfter(node, new Operation(Instruction.Copy, temp2, src2)); + node = nodes.AddAfter(node, Operation(Instruction.Copy, temp2, src2)); - Operation vextOp = new Operation(Instruction.VectorExtract16, temp1, src1, Const(index >> 1)); + Operation vextOp = Operation(Instruction.VectorExtract16, temp1, src1, Const(index >> 1)); node = nodes.AddAfter(node, vextOp); if ((index & 1) != 0) { - node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp1, temp1)); - node = nodes.AddAfter(node, new Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); - node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); + node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp1, temp1)); + node = nodes.AddAfter(node, Operation(Instruction.ShiftLeft, temp2, temp2, Const(8))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } else { - node = nodes.AddAfter(node, new Operation(Instruction.ZeroExtend8, temp2, temp2)); - node = nodes.AddAfter(node, new Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); - node = nodes.AddAfter(node, new Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); + node = nodes.AddAfter(node, Operation(Instruction.ZeroExtend8, temp2, temp2)); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseAnd, temp1, temp1, Const(0xff00))); + node = nodes.AddAfter(node, Operation(Instruction.BitwiseOr, temp1, temp1, temp2)); } - Operation vinsOp = new Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); + Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); node = nodes.AddAfter(node, vinsOp); @@ -608,7 +610,7 @@ namespace ARMeilleure.CodeGen.X86 arg0Reg = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); - Operation allocOp = new Operation(Instruction.StackAlloc, arg0Reg, Const(stackOffset)); + Operation allocOp = Operation(Instruction.StackAlloc, arg0Reg, Const(stackOffset)); nodes.AddBefore(node, allocOp); @@ -643,9 +645,9 @@ namespace ARMeilleure.CodeGen.X86 int stackOffset = AllocateOnStack(source.Type.GetSizeInBytes()); - nodes.AddBefore(node, new Operation(Instruction.StackAlloc, stackAddr, Const(stackOffset))); + nodes.AddBefore(node, Operation(Instruction.StackAlloc, stackAddr, Const(stackOffset))); - Operation storeOp = new Operation(Instruction.Store, null, stackAddr, source); + Operation storeOp = Operation(Instruction.Store, null, stackAddr, source); HandleConstantCopy(nodes, nodes.AddBefore(node, storeOp), storeOp); @@ -671,7 +673,7 @@ namespace ARMeilleure.CodeGen.X86 argReg = Xmm(CallingConvention.GetVecArgumentRegister(argIndex), source.Type); } - Operation copyOp = new Operation(Instruction.Copy, argReg, source); + Operation copyOp = Operation(Instruction.Copy, argReg, source); HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); @@ -684,9 +686,9 @@ namespace ARMeilleure.CodeGen.X86 { Operand source = operation.GetSource(index + 1); - Operand offset = new Operand((index + retArgs) * 8); + Operand offset = Const((index + retArgs) * 8); - Operation spillOp = new Operation(Instruction.SpillArg, null, offset, source); + Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); } @@ -697,9 +699,9 @@ namespace ARMeilleure.CodeGen.X86 { Operand retValueAddr = Local(OperandType.I64); - nodes.AddBefore(node, new Operation(Instruction.Copy, retValueAddr, arg0Reg)); + nodes.AddBefore(node, Operation(Instruction.Copy, retValueAddr, arg0Reg)); - Operation loadOp = new Operation(Instruction.Load, dest, retValueAddr); + Operation loadOp = Operation(Instruction.Load, dest, retValueAddr); node = nodes.AddAfter(node, loadOp); @@ -711,7 +713,7 @@ namespace ARMeilleure.CodeGen.X86 ? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type) : Xmm(CallingConvention.GetVecReturnRegister(), dest.Type); - Operation copyOp = new Operation(Instruction.Copy, dest, retReg); + Operation copyOp = Operation(Instruction.Copy, dest, retReg); node = nodes.AddAfter(node, copyOp); @@ -768,8 +770,8 @@ namespace ARMeilleure.CodeGen.X86 Operand argReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); Operand argReg2 = Gpr(CallingConvention.GetIntArgumentRegister(intCount++), OperandType.I64); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, argReg, source, Const(0))); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, argReg2, source, Const(1))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg, source, Const(0))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, argReg2, source, Const(1))); continue; } @@ -780,7 +782,7 @@ namespace ARMeilleure.CodeGen.X86 ? Gpr(CallingConvention.GetIntArgumentRegister(intCount++), source.Type) : Xmm(CallingConvention.GetVecArgumentRegister(vecCount++), source.Type); - Operation copyOp = new Operation(Instruction.Copy, argReg, source); + Operation copyOp = Operation(Instruction.Copy, argReg, source); HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); @@ -788,9 +790,9 @@ namespace ARMeilleure.CodeGen.X86 } else { - Operand offset = new Operand(stackOffset); + Operand offset = Const(stackOffset); - Operation spillOp = new Operation(Instruction.SpillArg, null, offset, source); + Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); @@ -805,8 +807,8 @@ namespace ARMeilleure.CodeGen.X86 Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); - node = nodes.AddAfter(node, new Operation(Instruction.VectorCreateScalar, dest, retLReg)); - node = nodes.AddAfter(node, new Operation(Instruction.VectorInsert, dest, dest, retHReg, Const(1))); + node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg)); + node = nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, retHReg, Const(1))); operation.Destination = null; } @@ -816,7 +818,7 @@ namespace ARMeilleure.CodeGen.X86 ? Gpr(CallingConvention.GetIntReturnRegister(), dest.Type) : Xmm(CallingConvention.GetVecReturnRegister(), dest.Type); - Operation copyOp = new Operation(Instruction.Copy, dest, retReg); + Operation copyOp = Operation(Instruction.Copy, dest, retReg); node = nodes.AddAfter(node, copyOp); @@ -871,14 +873,14 @@ namespace ARMeilleure.CodeGen.X86 pArg = Local(dest.Type); } - Operation copyOp = new Operation(Instruction.Copy, pArg, argReg); + Operation copyOp = Operation(Instruction.Copy, pArg, argReg); cctx.Cfg.Entry.Operations.AddFirst(copyOp); preservedArgs[index] = pArg; } - Operation argCopyOp = new Operation(dest.Type == OperandType.V128 + Operation argCopyOp = Operation(dest.Type == OperandType.V128 ? Instruction.Load : Instruction.Copy, dest, preservedArgs[index]); @@ -955,8 +957,8 @@ namespace ARMeilleure.CodeGen.X86 Operand argLReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount), OperandType.I64); Operand argHReg = Gpr(CallingConvention.GetIntArgumentRegister(intCount + 1), OperandType.I64); - Operation copyL = new Operation(Instruction.VectorCreateScalar, pArg, argLReg); - Operation copyH = new Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1)); + Operation copyL = Operation(Instruction.VectorCreateScalar, pArg, argLReg); + Operation copyH = Operation(Instruction.VectorInsert, pArg, pArg, argHReg, Const(1)); cctx.Cfg.Entry.Operations.AddFirst(copyH); cctx.Cfg.Entry.Operations.AddFirst(copyL); @@ -971,7 +973,7 @@ namespace ARMeilleure.CodeGen.X86 ? Gpr(CallingConvention.GetIntArgumentRegister(intCount), dest.Type) : Xmm(CallingConvention.GetVecArgumentRegister(vecCount), dest.Type); - Operation copyOp = new Operation(Instruction.Copy, pArg, argReg); + Operation copyOp = Operation(Instruction.Copy, pArg, argReg); cctx.Cfg.Entry.Operations.AddFirst(copyOp); @@ -979,7 +981,7 @@ namespace ARMeilleure.CodeGen.X86 } } - Operation argCopyOp = new Operation(Instruction.Copy, dest, preservedArgs[index]); + Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]); nodes.AddBefore(node, argCopyOp); @@ -1019,7 +1021,7 @@ namespace ARMeilleure.CodeGen.X86 Operand arg0 = Gpr(CallingConvention.GetIntArgumentRegister(0), OperandType.I64); - Operation copyOp = new Operation(Instruction.Copy, preservedArg, arg0); + Operation copyOp = Operation(Instruction.Copy, preservedArg, arg0); cctx.Cfg.Entry.Operations.AddFirst(copyOp); @@ -1035,18 +1037,18 @@ namespace ARMeilleure.CodeGen.X86 if (source.Type == OperandType.V128) { - Operation retStoreOp = new Operation(Instruction.Store, null, retReg, source); + Operation retStoreOp = Operation(Instruction.Store, null, retReg, source); nodes.AddBefore(node, retStoreOp); } else { - Operation retCopyOp = new Operation(Instruction.Copy, retReg, source); + Operation retCopyOp = Operation(Instruction.Copy, retReg, source); nodes.AddBefore(node, retCopyOp); } - operation.SetSources(System.Array.Empty()); + operation.SetSources(Array.Empty()); } private static void HandleReturnSystemVAbi(IntrusiveList nodes, Node node, Operation operation) @@ -1063,8 +1065,8 @@ namespace ARMeilleure.CodeGen.X86 Operand retLReg = Gpr(CallingConvention.GetIntReturnRegister(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, retLReg, source, Const(0))); - nodes.AddBefore(node, new Operation(Instruction.VectorExtract, retHReg, source, Const(1))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, retLReg, source, Const(0))); + nodes.AddBefore(node, Operation(Instruction.VectorExtract, retHReg, source, Const(1))); } else { @@ -1072,7 +1074,7 @@ namespace ARMeilleure.CodeGen.X86 ? Gpr(CallingConvention.GetIntReturnRegister(), source.Type) : Xmm(CallingConvention.GetVecReturnRegister(), source.Type); - Operation retCopyOp = new Operation(Instruction.Copy, retReg, source); + Operation retCopyOp = Operation(Instruction.Copy, retReg, source); nodes.AddBefore(node, retCopyOp); } @@ -1084,7 +1086,7 @@ namespace ARMeilleure.CodeGen.X86 Operand intConst = AddCopy(nodes, node, GetIntConst(source)); - Operation copyOp = new Operation(Instruction.VectorCreateScalar, temp, intConst); + Operation copyOp = Operation(Instruction.VectorCreateScalar, temp, intConst); nodes.AddBefore(node, copyOp); @@ -1095,7 +1097,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand temp = Local(source.Type); - Operation copyOp = new Operation(Instruction.Copy, temp, source); + Operation copyOp = Operation(Instruction.Copy, temp, source); nodes.AddBefore(node, copyOp); diff --git a/ARMeilleure/CodeGen/X86/X86Optimizer.cs b/ARMeilleure/CodeGen/X86/X86Optimizer.cs index c52541ca99..30fd6c714f 100644 --- a/ARMeilleure/CodeGen/X86/X86Optimizer.cs +++ b/ARMeilleure/CodeGen/X86/X86Optimizer.cs @@ -3,6 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; namespace ARMeilleure.CodeGen.X86 { @@ -34,7 +35,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand temp = Local(src1.Type); - Operation copyOp = new Operation(Instruction.Copy, temp, src1); + Operation copyOp = Operation(Instruction.Copy, temp, src1); block.Operations.AddBefore(operation, copyOp); @@ -45,7 +46,7 @@ namespace ARMeilleure.CodeGen.X86 { Operand temp = Local(src2.Type); - Operation copyOp = new Operation(Instruction.Copy, temp, src2); + Operation copyOp = Operation(Instruction.Copy, temp, src2); block.Operations.AddBefore(operation, copyOp); @@ -110,7 +111,7 @@ namespace ARMeilleure.CodeGen.X86 return null; } - return new MemoryOperand(type, baseOp, indexOp, scale, imm); + return MemoryOp(type, baseOp, indexOp, scale, imm); } private static int GetConstOp(ref Operand baseOp) diff --git a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs index 742842fa72..56d07288a0 100644 --- a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs +++ b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs @@ -5,21 +5,25 @@ namespace ARMeilleure.IntermediateRepresentation public Operand BaseAddress { get; set; } public Operand Index { get; set; } - public Multiplier Scale { get; } + public Multiplier Scale { get; private set; } - public int Displacement { get; } + public int Displacement { get; private set; } - public MemoryOperand( + public MemoryOperand() { } + + public MemoryOperand With( OperandType type, Operand baseAddress, Operand index = null, Multiplier scale = Multiplier.x1, - int displacement = 0) : base(OperandKind.Memory, type) + int displacement = 0) { + With(OperandKind.Memory, type); BaseAddress = baseAddress; Index = index; Scale = scale; Displacement = displacement; + return this; } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs index 37647c5600..d80964d47f 100644 --- a/ARMeilleure/IntermediateRepresentation/Node.cs +++ b/ARMeilleure/IntermediateRepresentation/Node.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace ARMeilleure.IntermediateRepresentation { @@ -11,39 +12,78 @@ namespace ARMeilleure.IntermediateRepresentation { get { - return _destinations.Length != 0 ? GetDestination(0) : null; + return _destinations.Count != 0 ? GetDestination(0) : null; } set { if (value != null) { - SetDestinations(new Operand[] { value }); + SetDestination(value); } else { - SetDestinations(new Operand[0]); + _destinations.Clear(); } } } - private Operand[] _destinations; - private Operand[] _sources; + private List _destinations; + private List _sources; + private bool _clearedDest; - public int DestinationsCount => _destinations.Length; - public int SourcesCount => _sources.Length; + public int DestinationsCount => _destinations.Count; + public int SourcesCount => _sources.Count; - public Node(Operand destination, int sourcesCount) + private void Resize(List list, int size) + { + while (list.Count > size) + { + list.RemoveAt(list.Count - 1); + } + + while (list.Count < size) + { + list.Add(null); + } + } + + public Node() + { + _destinations = new List(); + _sources = new List(); + } + + public Node(Operand destination, int sourcesCount) : this() { Destination = destination; - _sources = new Operand[sourcesCount]; + Resize(_sources, sourcesCount); } - public Node(Operand[] destinations, int sourcesCount) + private void Reset(int sourcesCount) { + _clearedDest = true; + _sources.Clear(); + ListPrevious = null; + ListNext = null; + + Resize(_sources, sourcesCount); + } + + public Node With(Operand destination, int sourcesCount) + { + Reset(sourcesCount); + Destination = destination; + + return this; + } + + public Node With(Operand[] destinations, int sourcesCount) + { + Reset(sourcesCount); SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations))); - _sources = new Operand[sourcesCount]; + return this; } public Operand GetDestination(int index) @@ -58,10 +98,15 @@ namespace ARMeilleure.IntermediateRepresentation public void SetDestination(int index, Operand destination) { - RemoveAssignment(_destinations[index]); + if (!_clearedDest) + { + RemoveAssignment(_destinations[index]); + } AddAssignment(destination); + _clearedDest = false; + _destinations[index] = destination; } @@ -74,21 +119,37 @@ namespace ARMeilleure.IntermediateRepresentation _sources[index] = source; } - public void SetDestinations(Operand[] destinations) + private void RemoveOldDestinations() { - if (_destinations != null) + if (_destinations != null && !_clearedDest) { - for (int index = 0; index < _destinations.Length; index++) + for (int index = 0; index < _destinations.Count; index++) { RemoveAssignment(_destinations[index]); } + } + _clearedDest = false; + } - _destinations = destinations; - } - else + public void SetDestination(Operand destination) + { + RemoveOldDestinations(); + + Resize(_destinations, 1); + + _destinations[0] = destination; + + if (destination.Kind == OperandKind.LocalVariable) { - _destinations = new Operand[destinations.Length]; + destination.Assignments.Add(this); } + } + + public void SetDestinations(Operand[] destinations) + { + RemoveOldDestinations(); + + Resize(_destinations, destinations.Length); for (int index = 0; index < destinations.Length; index++) { @@ -100,14 +161,33 @@ namespace ARMeilleure.IntermediateRepresentation } } - public void SetSources(Operand[] sources) + private void RemoveOldSources() { - for (int index = 0; index < _sources.Length; index++) + for (int index = 0; index < _sources.Count; index++) { RemoveUse(_sources[index]); } + } - _sources = new Operand[sources.Length]; + public void SetSource(Operand source) + { + RemoveOldSources(); + + Resize(_sources, 1); + + _sources[0] = source; + + if (source.Kind == OperandKind.LocalVariable) + { + source.Uses.Add(this); + } + } + + public void SetSources(Operand[] sources) + { + RemoveOldSources(); + + Resize(_sources, sources.Length); for (int index = 0; index < sources.Length; index++) { diff --git a/ARMeilleure/IntermediateRepresentation/Operand.cs b/ARMeilleure/IntermediateRepresentation/Operand.cs index fe5bf0732c..13bb9ba536 100644 --- a/ARMeilleure/IntermediateRepresentation/Operand.cs +++ b/ARMeilleure/IntermediateRepresentation/Operand.cs @@ -5,16 +5,16 @@ namespace ARMeilleure.IntermediateRepresentation { class Operand { - public OperandKind Kind { get; } + public OperandKind Kind { get; private set; } - public OperandType Type { get; } + public OperandType Type { get; private set; } public ulong Value { get; private set; } public List Assignments { get; } public List Uses { get; } - private Operand() + public Operand() { Assignments = new List(); Uses = new List(); @@ -26,42 +26,64 @@ namespace ARMeilleure.IntermediateRepresentation Type = type; } - public Operand(int value) : this(OperandKind.Constant, OperandType.I32) + public Operand With(OperandKind kind, OperandType type = OperandType.None) { - Value = (uint)value; - } - - public Operand(uint value) : this(OperandKind.Constant, OperandType.I32) - { - Value = (uint)value; - } - - public Operand(long value) : this(OperandKind.Constant, OperandType.I64) - { - Value = (ulong)value; - } - - public Operand(ulong value) : this(OperandKind.Constant, OperandType.I64) - { - Value = value; - } - - public Operand(float value) : this(OperandKind.Constant, OperandType.FP32) - { - Value = (ulong)BitConverter.SingleToInt32Bits(value); - } - - public Operand(double value) : this(OperandKind.Constant, OperandType.FP64) - { - Value = (ulong)BitConverter.DoubleToInt64Bits(value); - } - - public Operand(int index, RegisterType regType, OperandType type) : this() - { - Kind = OperandKind.Register; + Kind = kind; Type = type; + Value = 0; + Assignments.Clear(); + Uses.Clear(); + return this; + } + + public Operand With(int value) + { + With(OperandKind.Constant, OperandType.I32); + Value = (uint)value; + return this; + } + + public Operand With(uint value) + { + With(OperandKind.Constant, OperandType.I32); + Value = (uint)value; + return this; + } + + public Operand With(long value) + { + With(OperandKind.Constant, OperandType.I64); + Value = (ulong)value; + return this; + } + + public Operand With(ulong value) + { + With(OperandKind.Constant, OperandType.I64); + Value = value; + return this; + } + + public Operand With(float value) + { + With(OperandKind.Constant, OperandType.FP32); + Value = (ulong)BitConverter.SingleToInt32Bits(value); + return this; + } + + public Operand With(double value) + { + With(OperandKind.Constant, OperandType.FP64); + Value = (ulong)BitConverter.DoubleToInt64Bits(value); + return this; + } + + public Operand With(int index, RegisterType regType, OperandType type) + { + With(OperandKind.Register, type); Value = (ulong)((int)regType << 24 | index); + return this; } public Register GetRegister() diff --git a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs index 4a930e03f4..350826d667 100644 --- a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs +++ b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs @@ -5,64 +5,90 @@ namespace ARMeilleure.IntermediateRepresentation { static class OperandHelper { + private static MemoryOperand MemoryOperand() + { + return ThreadStaticPool.Instance.Allocate(); + } + + private static Operand Operand() + { + return ThreadStaticPool.Instance.Allocate(); + } + public static Operand Const(OperandType type, long value) { - return type == OperandType.I32 ? new Operand((int)value) : new Operand(value); + return type == OperandType.I32 ? Operand().With((int)value) : Operand().With(value); } public static Operand Const(bool value) { - return new Operand(value ? 1 : 0); + return Operand().With(value ? 1 : 0); } public static Operand Const(int value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(uint value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(long value) { - return new Operand(value); + return Operand().With(value); } public static Operand Const(ulong value) { - return new Operand(value); + return Operand().With(value); } public static Operand ConstF(float value) { - return new Operand(value); + return Operand().With(value); } public static Operand ConstF(double value) { - return new Operand(value); + return Operand().With(value); } public static Operand Label() { - return new Operand(OperandKind.Label); + return Operand().With(OperandKind.Label); } public static Operand Local(OperandType type) { - return new Operand(OperandKind.LocalVariable, type); + return Operand().With(OperandKind.LocalVariable, type); } public static Operand Register(int index, RegisterType regType, OperandType type) { - return new Operand(index, regType, type); + return Operand().With(index, regType, type); } public static Operand Undef() { - return new Operand(OperandKind.Undefined); + return Operand().With(OperandKind.Undefined); + } + + public static MemoryOperand MemoryOp( + OperandType type, + Operand baseAddress, + Operand index = null, + Multiplier scale = Multiplier.x1, + int displacement = 0) + { + return MemoryOperand().With(type, baseAddress, index, scale, displacement); + } + + public static void ResetOperandPool() + { + ThreadStaticPool.Instance.Clear(); + ThreadStaticPool.Instance.Clear(); } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/Operation.cs b/ARMeilleure/IntermediateRepresentation/Operation.cs index 620bf3f6e2..4cdbe3261a 100644 --- a/ARMeilleure/IntermediateRepresentation/Operation.cs +++ b/ARMeilleure/IntermediateRepresentation/Operation.cs @@ -4,10 +4,12 @@ namespace ARMeilleure.IntermediateRepresentation { public Instruction Instruction { get; private set; } + public Operation() : base() { } + public Operation( Instruction instruction, Operand destination, - params Operand[] sources) : base(destination, sources.Length) + Operand[] sources) : base(destination, sources.Length) { Instruction = instruction; @@ -17,24 +19,78 @@ namespace ARMeilleure.IntermediateRepresentation } } - public Operation( - Instruction instruction, - Operand[] destinations, - Operand[] sources) : base(destinations, sources.Length) + public Operation With(Instruction instruction, Operand destination) { + With(destination, 0); + Instruction = instruction; + return this; + } + + public Operation With(Instruction instruction, Operand destination, Operand[] sources) + { + With(destination, sources.Length); Instruction = instruction; for (int index = 0; index < sources.Length; index++) { SetSource(index, sources[index]); } + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0) + { + With(destination, 1); + Instruction = instruction; + + SetSource(0, source0); + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0, Operand source1) + { + With(destination, 2); + Instruction = instruction; + + SetSource(0, source0); + SetSource(1, source1); + return this; + } + + public Operation With(Instruction instruction, Operand destination, + Operand source0, Operand source1, Operand source2) + { + With(destination, 3); + Instruction = instruction; + + SetSource(0, source0); + SetSource(1, source1); + SetSource(2, source2); + return this; + } + + public Operation With( + Instruction instruction, + Operand[] destinations, + Operand[] sources) + { + With(destinations, sources.Length); + Instruction = instruction; + + for (int index = 0; index < sources.Length; index++) + { + SetSource(index, sources[index]); + } + return this; } public void TurnIntoCopy(Operand source) { Instruction = Instruction.Copy; - SetSources(new Operand[] { source }); + SetSource(source); } } } \ No newline at end of file diff --git a/ARMeilleure/IntermediateRepresentation/OperationHelper.cs b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs new file mode 100644 index 0000000000..16567a3cec --- /dev/null +++ b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs @@ -0,0 +1,52 @@ +namespace ARMeilleure.IntermediateRepresentation +{ + static class OperationHelper + { + public static Operation Operation() + { + return ThreadStaticPool.Instance.Allocate(); + } + + public static Operation Operation(Instruction instruction, Operand destination) + { + return Operation().With(instruction, destination); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand[] sources) + { + return Operation().With(instruction, destination, sources); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0) + { + return Operation().With(instruction, destination, source0); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0, Operand source1) + { + return Operation().With(instruction, destination, source0, source1); + } + + public static Operation Operation(Instruction instruction, Operand destination, + Operand source0, Operand source1, Operand source2) + { + return Operation().With(instruction, destination, source0, source1, source2); + } + + public static Operation Operation( + Instruction instruction, + Operand[] destinations, + Operand[] sources) + { + return Operation().With(instruction, destinations, sources); + } + + public static void ResetOperationPool() + { + ThreadStaticPool.Instance.Clear(); + } + } +} diff --git a/ARMeilleure/ThreadStaticPool.cs b/ARMeilleure/ThreadStaticPool.cs new file mode 100644 index 0000000000..542ba29fbc --- /dev/null +++ b/ARMeilleure/ThreadStaticPool.cs @@ -0,0 +1,69 @@ +using System; +using System.Threading; + +namespace ARMeilleure +{ + public class ThreadStaticPool where T : class, new() + { + [ThreadStatic] + private static ThreadStaticPool _instance; + public static ThreadStaticPool Instance + { + get + { + if (_instance == null) + { + _instance = new ThreadStaticPool(_poolSizeIncrement * 2); + } + return _instance; + } + } + + private T[] _pool; + private int _poolUsed = -1; + private int _poolSize; + private static readonly int _poolSizeIncrement = 200; + + public ThreadStaticPool(int initialSize) + { + _pool = new T[initialSize]; + + for (int i = 0; i < initialSize; i++) + { + _pool[i] = new T(); + } + + _poolSize = initialSize; + } + + public T Allocate() + { + int index = Interlocked.Increment(ref _poolUsed); + if (index >= _poolSize) + { + IncreaseSize(); + } + return _pool[index]; + } + + private void IncreaseSize() + { + _poolSize += _poolSizeIncrement; + + T[] newArray = new T[_poolSize]; + Array.Copy(_pool, 0, newArray, 0, _pool.Length); + + for (int i = _pool.Length; i < _poolSize; i++) + { + newArray[i] = new T(); + } + + Interlocked.Exchange(ref _pool, newArray); + } + + public void Clear() + { + _poolUsed = -1; + } + } +} diff --git a/ARMeilleure/Translation/ControlFlowGraph.cs b/ARMeilleure/Translation/ControlFlowGraph.cs index 37613eb495..16b406ab0d 100644 --- a/ARMeilleure/Translation/ControlFlowGraph.cs +++ b/ARMeilleure/Translation/ControlFlowGraph.cs @@ -141,7 +141,7 @@ namespace ARMeilleure.Translation splitBlock2.Branch = successor; - splitBlock2.Operations.AddLast(new Operation(Instruction.Branch, null)); + splitBlock2.Operations.AddLast(OperationHelper.Operation(Instruction.Branch, null)); Blocks.AddBefore(successor, splitBlock2); } diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs index a125a715da..3118628ff6 100644 --- a/ARMeilleure/Translation/EmitterContext.cs +++ b/ARMeilleure/Translation/EmitterContext.cs @@ -446,14 +446,63 @@ namespace ARMeilleure.Translation return Add(Instruction.ZeroExtend8, Local(type), op1); } - private Operand Add(Instruction inst, Operand dest = null, params Operand[] sources) + private void NewNextBlockIfNeeded() { if (_needsNewBlock) { NewNextBlock(); } + } - Operation operation = new Operation(inst, dest, sources); + private Operand Add(Instruction inst, Operand dest = null) + { + NewNextBlockIfNeeded(); + + Operation operation = OperationHelper.Operation(inst, dest); + + _irBlock.Operations.AddLast(operation); + + return dest; + } + + private Operand Add(Instruction inst, Operand dest, Operand[] sources) + { + NewNextBlockIfNeeded(); + + Operation operation = OperationHelper.Operation(inst, dest, sources); + + _irBlock.Operations.AddLast(operation); + + return dest; + } + + private Operand Add(Instruction inst, Operand dest, Operand source0) + { + NewNextBlockIfNeeded(); + + Operation operation = OperationHelper.Operation(inst, dest, source0); + + _irBlock.Operations.AddLast(operation); + + return dest; + } + + private Operand Add(Instruction inst, Operand dest, Operand source0, Operand source1) + { + NewNextBlockIfNeeded(); + + Operation operation = OperationHelper.Operation(inst, dest, source0, source1); + + _irBlock.Operations.AddLast(operation); + + return dest; + } + + private Operand Add(Instruction inst, Operand dest, Operand source0, Operand source1, Operand source2) + { + NewNextBlockIfNeeded(); + + Operation operation = OperationHelper.Operation(inst, dest, source0, source1, source2); _irBlock.Operations.AddLast(operation); diff --git a/ARMeilleure/Translation/RegisterUsage.cs b/ARMeilleure/Translation/RegisterUsage.cs index 84dfce7b57..d512428564 100644 --- a/ARMeilleure/Translation/RegisterUsage.cs +++ b/ARMeilleure/Translation/RegisterUsage.cs @@ -3,6 +3,7 @@ using ARMeilleure.State; using System; using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; namespace ARMeilleure.Translation { @@ -299,16 +300,16 @@ namespace ARMeilleure.Translation Operand addr = Local(OperandType.I64); - Operation loadOp = new Operation(Instruction.Load, dest, addr); + Operation loadOp = Operation(Instruction.Load, dest, addr); block.Operations.AddFirst(loadOp); - Operation calcOffsOp = new Operation(Instruction.Add, addr, arg0, Const(offset)); + Operation calcOffsOp = Operation(Instruction.Add, addr, arg0, Const(offset)); block.Operations.AddFirst(calcOffsOp); } - Operation loadArg0 = new Operation(Instruction.LoadArgument, arg0, Const(0)); + Operation loadArg0 = Operation(Instruction.LoadArgument, arg0, Const(0)); block.Operations.AddFirst(loadArg0); } @@ -329,7 +330,7 @@ namespace ARMeilleure.Translation Operand arg0 = Local(OperandType.I64); - Operation loadArg0 = new Operation(Instruction.LoadArgument, arg0, Const(0)); + Operation loadArg0 = Operation(Instruction.LoadArgument, arg0, Const(0)); block.Append(loadArg0); @@ -348,11 +349,11 @@ namespace ARMeilleure.Translation Operand addr = Local(OperandType.I64); - Operation calcOffsOp = new Operation(Instruction.Add, addr, arg0, Const(offset)); + Operation calcOffsOp = Operation(Instruction.Add, addr, arg0, Const(offset)); block.Append(calcOffsOp); - Operation storeOp = new Operation(Instruction.Store, null, addr, source); + Operation storeOp = Operation(Instruction.Store, null, addr, source); block.Append(storeOp); } @@ -362,15 +363,15 @@ namespace ARMeilleure.Translation { if (bit < RegsCount) { - return new Operand(bit, baseType, GetOperandType(baseType, mode)); + return OperandHelper.Register(bit, baseType, GetOperandType(baseType, mode)); } else if (baseType == RegisterType.Integer) { - return new Operand(bit & RegsMask, RegisterType.Flag, OperandType.I32); + return OperandHelper.Register(bit & RegsMask, RegisterType.Flag, OperandType.I32); } else if (baseType == RegisterType.Vector) { - return new Operand(bit & RegsMask, RegisterType.FpFlag, OperandType.I32); + return OperandHelper.Register(bit & RegsMask, RegisterType.FpFlag, OperandType.I32); } else { diff --git a/ARMeilleure/Translation/SsaDeconstruction.cs b/ARMeilleure/Translation/SsaDeconstruction.cs index 37d616252d..c3bcaf8c1c 100644 --- a/ARMeilleure/Translation/SsaDeconstruction.cs +++ b/ARMeilleure/Translation/SsaDeconstruction.cs @@ -2,6 +2,7 @@ using ARMeilleure.IntermediateRepresentation; using System.Collections.Generic; using static ARMeilleure.IntermediateRepresentation.OperandHelper; +using static ARMeilleure.IntermediateRepresentation.OperationHelper; namespace ARMeilleure.Translation { @@ -25,12 +26,12 @@ namespace ARMeilleure.Translation Operand source = phi.GetSource(index); - predecessor.Append(new Operation(Instruction.Copy, local, source)); + predecessor.Append(Operation(Instruction.Copy, local, source)); phi.SetSource(index, null); } - Operation copyOp = new Operation(Instruction.Copy, phi.Destination, local); + Operation copyOp = Operation(Instruction.Copy, phi.Destination, local); block.Operations.AddBefore(node, copyOp); diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 3008303e76..9202042f3e 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -161,6 +161,9 @@ namespace ARMeilleure.Translation GuestFunction func = Compiler.Compile(cfg, argTypes, OperandType.I64, options); + OperandHelper.ResetOperandPool(); + OperationHelper.ResetOperationPool(); + return new TranslatedFunction(func, rejit: !highCq); }