Do temp constant copy for CompareAndSwap, other improvements to PreAllocator (#1126)

* Do temp constant copy for CompareAndSwap, other improvements to PreAllocator

* Nit
This commit is contained in:
gdkchan 2020-04-25 10:00:54 -03:00 committed by GitHub
parent a728610b40
commit fe5bb439f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -22,22 +22,16 @@ namespace ARMeilleure.CodeGen.X86
for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext) for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext)
{ {
Node nextNode; for (Node node = block.Operations.First; node != null; node = node.ListNext)
for (Node node = block.Operations.First; node != null; node = nextNode)
{ {
nextNode = node.ListNext;
if (!(node is Operation operation)) if (!(node is Operation operation))
{ {
continue; continue;
} }
HandleConstantCopy(block.Operations, node, operation); HandleConstantRegCopy(block.Operations, node, operation);
node = HandleDestructiveRegCopy(block.Operations, node, operation);
HandleSameDestSrc1Copy(block.Operations, node, operation); node = HandleConstrainedRegCopy(block.Operations, node, operation);
HandleFixedRegisterCopy(block.Operations, node, operation);
switch (operation.Instruction) switch (operation.Instruction)
{ {
@ -71,17 +65,17 @@ namespace ARMeilleure.CodeGen.X86
break; break;
case Instruction.ConvertToFPUI: case Instruction.ConvertToFPUI:
HandleConvertToFPUI(block.Operations, node, operation); node = HandleConvertToFPUI(block.Operations, node, operation);
break; break;
case Instruction.LoadArgument: case Instruction.LoadArgument:
if (callConv == CallConvName.Windows) if (callConv == CallConvName.Windows)
{ {
HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation); node = HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation);
} }
else /* if (callConv == CallConvName.SystemV) */ else /* if (callConv == CallConvName.SystemV) */
{ {
HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation); node = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
} }
break; break;
@ -125,7 +119,7 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
private static void HandleConstantCopy(IntrusiveList<Node> nodes, Node node, Operation operation) private static void HandleConstantRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
{ {
if (operation.SourcesCount == 0 || IsIntrinsic(operation.Instruction)) if (operation.SourcesCount == 0 || IsIntrinsic(operation.Instruction))
{ {
@ -206,7 +200,7 @@ namespace ARMeilleure.CodeGen.X86
} }
} }
private static Node HandleFixedRegisterCopy(IntrusiveList<Node> nodes, Node node, Operation operation) private static Node HandleConstrainedRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
{ {
Operand dest = operation.Destination; Operand dest = operation.Destination;
@ -248,14 +242,20 @@ namespace ARMeilleure.CodeGen.X86
// Handle the many restrictions of the compare and exchange (32/64) instruction: // Handle the many restrictions of the compare and exchange (32/64) instruction:
// - The expected value should be in (E/R)AX. // - The expected value should be in (E/R)AX.
// - The value at the memory location is loaded to (E/R)AX. // - The value at the memory location is loaded to (E/R)AX.
Operand expected = operation.GetSource(1); Operand expected = operation.GetSource(1);
Operand newValue = operation.GetSource(2);
Operand rax = Gpr(X86Register.Rax, expected.Type); Operand rax = Gpr(X86Register.Rax, expected.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected)); nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected));
operation.SetSources(new Operand[] { operation.GetSource(0), rax, operation.GetSource(2) }); // We need to store the new value into a temp, since it may
// be a constant, and this instruction does not support immediate operands.
Operand temp = Local(newValue.Type);
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
operation.SetSources(new Operand[] { operation.GetSource(0), rax, temp });
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax)); node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
@ -391,7 +391,7 @@ namespace ARMeilleure.CodeGen.X86
return node; return node;
} }
private static Node HandleSameDestSrc1Copy(IntrusiveList<Node> nodes, Node node, Operation operation) private static Node HandleDestructiveRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
{ {
if (operation.Destination == null || operation.SourcesCount == 0) if (operation.Destination == null || operation.SourcesCount == 0)
{ {
@ -683,7 +683,7 @@ namespace ARMeilleure.CodeGen.X86
Operation storeOp = Operation(Instruction.Store, null, stackAddr, source); Operation storeOp = Operation(Instruction.Store, null, stackAddr, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, storeOp), storeOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, storeOp), storeOp);
operation.SetSource(index, stackAddr); operation.SetSource(index, stackAddr);
} }
@ -709,7 +709,7 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, argReg, source); Operation copyOp = Operation(Instruction.Copy, argReg, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
sources[1 + retArgs + index] = argReg; sources[1 + retArgs + index] = argReg;
} }
@ -724,7 +724,7 @@ namespace ARMeilleure.CodeGen.X86
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
} }
if (dest != null) if (dest != null)
@ -818,7 +818,7 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, argReg, source); Operation copyOp = Operation(Instruction.Copy, argReg, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
sources.Add(argReg); sources.Add(argReg);
} }
@ -828,7 +828,7 @@ namespace ARMeilleure.CodeGen.X86
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source); Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
stackOffset += source.Type.GetSizeInBytes(); stackOffset += source.Type.GetSizeInBytes();
} }
@ -867,9 +867,10 @@ namespace ARMeilleure.CodeGen.X86
private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation) private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation)
{ {
List<Operand> sources = new List<Operand>(); List<Operand> sources = new List<Operand>
{
sources.Add(operation.GetSource(0)); operation.GetSource(0)
};
int argsCount = operation.SourcesCount - 1; int argsCount = operation.SourcesCount - 1;
@ -915,7 +916,7 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, argReg, source); Operation copyOp = Operation(Instruction.Copy, argReg, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
sources.Add(argReg); sources.Add(argReg);
} }
@ -963,7 +964,7 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, argReg, source); Operation copyOp = Operation(Instruction.Copy, argReg, source);
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp); HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
sources[1 + index] = argReg; sources[1 + index] = argReg;
} }
@ -982,7 +983,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSources(sources); operation.SetSources(sources);
} }
private static void HandleLoadArgumentWindowsAbi( private static Node HandleLoadArgumentWindowsAbi(
CompilerContext cctx, CompilerContext cctx,
IntrusiveList<Node> nodes, IntrusiveList<Node> nodes,
Node node, Node node,
@ -1035,17 +1036,20 @@ namespace ARMeilleure.CodeGen.X86
? Instruction.Load ? Instruction.Load
: Instruction.Copy, dest, preservedArgs[index]); : Instruction.Copy, dest, preservedArgs[index]);
nodes.AddBefore(node, argCopyOp); Node newNode = nodes.AddBefore(node, argCopyOp);
Delete(nodes, node, operation); Delete(nodes, node, operation);
return newNode;
} }
else else
{ {
// TODO: Pass on stack. // TODO: Pass on stack.
return node;
} }
} }
private static void HandleLoadArgumentSystemVAbi( private static Node HandleLoadArgumentSystemVAbi(
CompilerContext cctx, CompilerContext cctx,
IntrusiveList<Node> nodes, IntrusiveList<Node> nodes,
Node node, Node node,
@ -1134,13 +1138,16 @@ namespace ARMeilleure.CodeGen.X86
Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]); Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]);
nodes.AddBefore(node, argCopyOp); Node newNode = nodes.AddBefore(node, argCopyOp);
Delete(nodes, node, operation); Delete(nodes, node, operation);
return newNode;
} }
else else
{ {
// TODO: Pass on stack. // TODO: Pass on stack.
return node;
} }
} }