Allow certain instructions to not be inlined

This commit is contained in:
HoLLy 2019-11-23 21:49:29 +01:00
Родитель 53750f7332
Коммит 44a25ea642
8 изменённых файлов: 11 добавлений и 5 удалений

Просмотреть файл

@ -112,9 +112,9 @@ namespace WasmLib.Decompilation
for (int i = 0; i < parameterEdges.Length; i++) { for (int i = 0; i < parameterEdges.Length; i++) {
var edge = parameterEdges[i]; var edge = parameterEdges[i];
var variableNode = edge.Source; var variableNode = edge.Source;
var isPure = !graph.Nodes.OfType<InstructionNode>().Any(x => !x.IsPure & x.Index > variableNode.Index && x.Index < currentNode.Index); var doesNotSkipImpure = !graph.Nodes.OfType<InstructionNode>().Any(x => !x.IsPure & x.Index > variableNode.Index && x.Index < currentNode.Index);
if (isPure) { // TODO: and instruction can be inlined if (doesNotSkipImpure && variableNode.Instruction.CanBeInlined) {
parameters[i] = statements[variableNode.Index]; parameters[i] = statements[variableNode.Index];
statements.Remove(variableNode.Index); statements.Remove(variableNode.Index);
} }

Просмотреть файл

@ -13,6 +13,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public bool IsIndirect { get; } public bool IsIndirect { get; }
public FunctionSignature Signature { get; } public FunctionSignature Signature { get; }
public override bool IsPure => false; // TODO: could be optimized by checking if referenced function is pure public override bool IsPure => false; // TODO: could be optimized by checking if referenced function is pure
public override bool CanBeInlined => false; // only for readability
public override ValueKind[] PopTypes => (IsIndirect ? new[] {ValueKind.I32} : new ValueKind[0]).Concat(Signature.Parameters.Reverse()).ToArray(); public override ValueKind[] PopTypes => (IsIndirect ? new[] {ValueKind.I32} : new ValueKind[0]).Concat(Signature.Parameters.Reverse()).ToArray();
public override ValueKind[] PushTypes => Signature.ReturnParameter.Reverse().ToArray(); public override ValueKind[] PushTypes => Signature.ReturnParameter.Reverse().ToArray();

Просмотреть файл

@ -11,6 +11,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public ControlBlockKind Kind { get; } public ControlBlockKind Kind { get; }
public ValueKind ValueKind { get; } public ValueKind ValueKind { get; }
public override bool IsPure => false; // TODO: could be optimized by checking if control blocks are pure public override bool IsPure => false; // TODO: could be optimized by checking if control blocks are pure
public override bool CanBeInlined => false;
public ControlBlockInstruction(in Instruction instruction, IReadOnlyList<IntermediateInstruction> block1, IReadOnlyList<IntermediateInstruction>? block2) public ControlBlockInstruction(in Instruction instruction, IReadOnlyList<IntermediateInstruction> block1, IReadOnlyList<IntermediateInstruction>? block2)
{ {

Просмотреть файл

@ -8,5 +8,6 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public override ValueKind[] PushTypes => new ValueKind[0]; public override ValueKind[] PushTypes => new ValueKind[0];
public override string OperationStringFormat => "// drop {0}"; public override string OperationStringFormat => "// drop {0}";
public override bool IsPure => true; public override bool IsPure => true;
public override bool CanBeInlined => false; // inlined behavior would be part of the comment
} }
} }

Просмотреть файл

@ -13,9 +13,8 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public uint Offset { get; } public uint Offset { get; }
public uint Alignment { get; } public uint Alignment { get; }
// inlining loads would be ugly public override bool IsPure => false;
// public override bool IsPure => Action == ActionKind.Load;
public MemoryInstruction(in Instruction instruction) public MemoryInstruction(in Instruction instruction)
{ {

Просмотреть файл

@ -9,5 +9,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public override string OperationStringFormat => "// UNREACHABLE"; public override string OperationStringFormat => "// UNREACHABLE";
public override bool RestOfBlockUnreachable => true; public override bool RestOfBlockUnreachable => true;
public override bool IsPure => false;
public override bool CanBeInlined => false;
} }
} }

Просмотреть файл

@ -15,6 +15,7 @@ namespace WasmLib.Decompilation.Intermediate.Instructions
public uint Index { get; } public uint Index { get; }
public ValueKind Type => Target == TargetKind.Local ? GetLocal(Index) : GetGlobal(Index); public ValueKind Type => Target == TargetKind.Local ? GetLocal(Index) : GetGlobal(Index);
public override bool IsPure => Action == ActionKind.Get; public override bool IsPure => Action == ActionKind.Get;
public override bool CanBeInlined => Action != ActionKind.Tee;
private readonly WasmModule module; private readonly WasmModule module;
private readonly FunctionBody body; private readonly FunctionBody body;

Просмотреть файл

@ -9,6 +9,7 @@ namespace WasmLib.Decompilation.Intermediate
public abstract ValueKind[] PushTypes { get; } public abstract ValueKind[] PushTypes { get; }
public virtual bool RestOfBlockUnreachable => false; public virtual bool RestOfBlockUnreachable => false;
public virtual bool IsPure => false; public virtual bool IsPure => false;
public virtual bool CanBeInlined => true; // only matters if PushTypes has items
public virtual bool IsImplicit => false; public virtual bool IsImplicit => false;
public bool HasBlock => Block1 != null; public bool HasBlock => Block1 != null;