Fix optimization for collapse operators.
This commit is contained in:
@@ -17,7 +17,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
readonly StackFrame[] _stack = new StackFrame[256];
|
readonly StackFrame[] _stack = new StackFrame[256];
|
||||||
readonly byte[] _mem = new byte[0x100000];
|
readonly byte[] _mem = new byte[0x100000];
|
||||||
bool _revokepttconst;
|
bool _revokepttconst;
|
||||||
LinkedListNode<PdtInstruction> _rip;
|
LinkedListNode<PdtInstruction> _ip;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Evaluates an expression and passes the result to a target operator.
|
/// Evaluates an expression and passes the result to a target operator.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -28,8 +28,8 @@ namespace Cryville.Common.Pdt {
|
|||||||
_framecount = 0;
|
_framecount = 0;
|
||||||
_goffset = 0;
|
_goffset = 0;
|
||||||
_revokepttconst = false;
|
_revokepttconst = false;
|
||||||
for (_rip = exp.Instructions.First; _rip != null; _rip = _rip.Next)
|
for (_ip = exp.Instructions.First; _ip != null; _ip = _ip.Next)
|
||||||
_rip.Value.Execute(this);
|
_ip.Value.Execute(this);
|
||||||
if (exp.IsPotentialConstant) {
|
if (exp.IsPotentialConstant) {
|
||||||
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,10 @@ namespace Cryville.Common.Pdt {
|
|||||||
List<PdtInstruction.Collapse> ct;
|
List<PdtInstruction.Collapse> ct;
|
||||||
var cols = new Dictionary<LinkedListNode<PdtInstruction>, List<PdtInstruction.Collapse>>();
|
var cols = new Dictionary<LinkedListNode<PdtInstruction>, List<PdtInstruction.Collapse>>();
|
||||||
var il = exp.Instructions;
|
var il = exp.Instructions;
|
||||||
for (_rip = il.First; _rip != null; _rip = _rip == null ? il.First : _rip.Next) {
|
_ip = il.First;
|
||||||
var i = _rip.Value;
|
while (_ip != null) {
|
||||||
|
bool nextFlag = false;
|
||||||
|
var i = _ip.Value;
|
||||||
if (i is PdtInstruction.Operate) {
|
if (i is PdtInstruction.Operate) {
|
||||||
int fc0 = _framecount;
|
int fc0 = _framecount;
|
||||||
int fc1 = ((PdtInstruction.Operate)i).Signature.ParamCount;
|
int fc1 = ((PdtInstruction.Operate)i).Signature.ParamCount;
|
||||||
@@ -72,29 +74,36 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var frame = _stack[_framecount - 1];
|
var frame = _stack[_framecount - 1];
|
||||||
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
ReplaceIP(il, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols);
|
||||||
for (var j = 0; j <= fc1; j++) il.Remove(_rip.Previous);
|
for (var j = 0; j < fc1; j++) il.Remove(_ip.Previous);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (i is PdtInstruction.Collapse) {
|
else if (i is PdtInstruction.Collapse) {
|
||||||
var t = (PdtInstruction.Collapse)i;
|
var t = (PdtInstruction.Collapse)i;
|
||||||
try {
|
try {
|
||||||
var pins = _rip;
|
var pins = _ip;
|
||||||
i.Execute(this);
|
i.Execute(this);
|
||||||
if (_rip == pins) {
|
if (_stack[_framecount - 1].Type == PdtInternalType.Error) {
|
||||||
_rip = _rip.Next;
|
throw new EvaluationFailureException();
|
||||||
il.Remove(_rip.Previous);
|
}
|
||||||
il.Remove(_rip.Previous);
|
if (_ip == pins) {
|
||||||
_rip = _rip.Previous;
|
_ip = _ip.Next;
|
||||||
|
il.Remove(_ip.Previous);
|
||||||
|
il.Remove(_ip.Previous);
|
||||||
|
_ip = _ip.Previous;
|
||||||
|
if (_ip == null) {
|
||||||
|
_ip = il.First;
|
||||||
|
nextFlag = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_rip = pins.Previous;
|
_ip = pins.Previous;
|
||||||
while (_rip.Next != t.Target) il.Remove(_rip.Next);
|
while (_ip.Next != t.Target) il.Remove(_ip.Next);
|
||||||
il.Remove(_rip.Next);
|
il.Remove(_ip.Next);
|
||||||
if (cols.TryGetValue(t.Target, out ct)) {
|
if (cols.TryGetValue(t.Target, out ct)) {
|
||||||
foreach (var u in ct) u.Target = _rip;
|
foreach (var u in ct) u.Target = _ip;
|
||||||
cols.Remove(t.Target);
|
cols.Remove(t.Target);
|
||||||
cols.Add(_rip, ct);
|
cols.Add(_ip, ct);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,12 +116,11 @@ namespace Cryville.Common.Pdt {
|
|||||||
i.Execute(this);
|
i.Execute(this);
|
||||||
var frame = _stack[_framecount - 1];
|
var frame = _stack[_framecount - 1];
|
||||||
if (frame.Type != PdtInternalType.Undefined && frame.Type != PdtInternalType.Error) {
|
if (frame.Type != PdtInternalType.Undefined && frame.Type != PdtInternalType.Error) {
|
||||||
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
ReplaceIP(il, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols);
|
||||||
il.Remove(_rip.Previous);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else i.Execute(this);
|
else i.Execute(this);
|
||||||
if (_rip != null && cols.TryGetValue(_rip, out ct)) {
|
if (_ip != null && cols.TryGetValue(_ip, out ct)) {
|
||||||
unsafe {
|
unsafe {
|
||||||
fixed (StackFrame* frame = &_stack[_framecount - 1]) {
|
fixed (StackFrame* frame = &_stack[_framecount - 1]) {
|
||||||
frame->Type = PdtInternalType.Error;
|
frame->Type = PdtInternalType.Error;
|
||||||
@@ -121,6 +129,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!nextFlag) _ip = _ip.Next;
|
||||||
}
|
}
|
||||||
exp.IsConstant = true;
|
exp.IsConstant = true;
|
||||||
exp.IsPotentialConstant = true;
|
exp.IsPotentialConstant = true;
|
||||||
@@ -134,6 +143,13 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void ReplaceIP(LinkedList<PdtInstruction> il, PdtInstruction ins, Dictionary<LinkedListNode<PdtInstruction>, List<PdtInstruction.Collapse>> cols) {
|
||||||
|
List<PdtInstruction.Collapse> cins;
|
||||||
|
if (cols.TryGetValue(_ip, out cins)) cols.Remove(_ip);
|
||||||
|
_ip = il.AddAfter(_ip, ins);
|
||||||
|
il.Remove(_ip.Previous);
|
||||||
|
if (cins != null) cols.Add(_ip, cins);
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Revokes the potential constant mark of the current expression.
|
/// Revokes the potential constant mark of the current expression.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -207,12 +223,12 @@ namespace Cryville.Common.Pdt {
|
|||||||
var frame = _stack[--_framecount];
|
var frame = _stack[--_framecount];
|
||||||
if (frame.Type == PdtInternalType.Error) {
|
if (frame.Type == PdtInternalType.Error) {
|
||||||
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 };
|
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 };
|
||||||
_rip = target;
|
_ip = target;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
||||||
_framecount++;
|
_framecount++;
|
||||||
_rip = target;
|
_ip = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user