From 81214ca556a8751297966a7b3b244fed00788b3d Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 4 Sep 2020 12:30:59 +0300 Subject: [PATCH 1/3] RCLSE: Also optimize when Access is ACCESS_PARTIAL_READ --- .../Source/Interface/IR/Passes/DeadContextStoreElimination.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp index d043019a4..81d2c86d4 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp @@ -484,7 +484,7 @@ bool RCLSE::RedundantStoreLoadElimination(FEXCore::IR::IREmitter *IREmit) { LastClass == Op->Class && LastOffset == Op->Offset && LastSize == IROp->Size && - Info->Accessed == ACCESS_READ) { + (Info->Accessed == ACCESS_READ || Info->Accessed == ACCESS_PARTIAL_READ)) { // Did we read and then read again? IREmit->ReplaceAllUsesWith(CodeNode, LastNode); RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); From de5ae1fe1368a2cc661fa670b0d6d9215274caf8 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Sat, 24 Oct 2020 14:19:01 +0300 Subject: [PATCH 2/3] RCLSE: Handle more cases --- .../IR/Passes/DeadContextStoreElimination.cpp | 85 +++++++++++++------ 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp index 81d2c86d4..bb55737d9 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp @@ -424,10 +424,14 @@ bool RCLSE::RedundantStoreLoadElimination(FEXCore::IR::IREmitter *IREmit) { if (LastAccess == ACCESS_WRITE && LastClass == Op->Class && LastOffset == Op->Offset && - LastSize == IROp->Size) { + LastSize <= IROp->Size) { // Remove the last store because this one overwrites it entirely // Happens when we store in to a location then store again IREmit->Remove(LastStoreNode); + + if (LastSize < IROp->Size) { + //printf("RCLSE: Eliminated partial write\n"); + } Changed = true; } } @@ -445,40 +449,73 @@ bool RCLSE::RedundantStoreLoadElimination(FEXCore::IR::IREmitter *IREmit) { if ((LastAccess == ACCESS_WRITE || LastAccess == ACCESS_PARTIAL_WRITE) && LastClass == Op->Class && LastOffset == Op->Offset && - LastClass == GPRClass && IROp->Size <= LastSize) { // If the last store matches this load value then we can replace the loaded value with the previous valid one - IREmit->SetWriteCursor(CodeNode); + if (LastClass == GPRClass) { + IREmit->SetWriteCursor(CodeNode); - uint8_t TruncateSize = IREmit->GetOpSize(LastNode); + uint8_t TruncateSize = IREmit->GetOpSize(LastNode); - // Did store context do an implicit truncation? - if (IREmit->GetOpSize(LastStoreNode) < TruncateSize) - TruncateSize = IREmit->GetOpSize(LastStoreNode); + // Did store context do an implicit truncation? + if (IREmit->GetOpSize(LastStoreNode) < TruncateSize) + TruncateSize = IREmit->GetOpSize(LastStoreNode); - // Or are we doing a partial read - if (IROp->Size < TruncateSize) - TruncateSize = IROp->Size; + // Or are we doing a partial read + if (IROp->Size < TruncateSize) + TruncateSize = IROp->Size; - if (TruncateSize != IREmit->GetOpSize(LastNode)) { - // We need to insert an explict truncation - if (LastClass == FPRClass) { - LastNode = IREmit->_VMov(LastNode, TruncateSize); // Vmov truncates and zexts when register width is smaller than source + if (TruncateSize != IREmit->GetOpSize(LastNode)) { + // We need to insert an explict truncation + if (LastClass == FPRClass) { + LastNode = IREmit->_VMov(LastNode, TruncateSize); // Vmov truncates and zexts when register width is smaller than source + } + else if (LastClass == GPRPairClass) { + LastNode = IREmit->_TruncElementPair(LastNode, TruncateSize); + } + else if (LastClass == GPRClass) { + LastNode = IREmit->_Bfe(Info->AccessSize, TruncateSize * 8, 0, LastNode); + } else { + LogMan::Msg::A("Unhandled Register class"); + } } - else if (LastClass == GPRPairClass) { - LastNode = IREmit->_TruncElementPair(LastNode, TruncateSize); - } - else if (LastClass == GPRClass) { - LastNode = IREmit->_Bfe(Info->AccessSize, TruncateSize * 8, 0, LastNode); + + IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + Changed = true; + } else { + if (LastClass == FPRClass && LastSize == IROp->Size && LastSize == IREmit->GetOpSize(LastNode)) { + // LoadCtx matches StoreCtx and Node Size + IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + Changed = true; + } else if (LastClass == FPRClass && LastSize >= IROp->Size && IROp->Size == IREmit->GetOpSize(LastNode)) { + // LoadCtx is <= StoreCtx and Node is LoadCtx + IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + Changed = true; + } else if (LastClass == FPRClass && LastSize >= IROp->Size && IROp->Size < IREmit->GetOpSize(LastNode)) { + + // trucate to size + // For some reason this doesn't work + //LastNode = IREmit->_VMov(LastNode, IROp->Size); + + //IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + //RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + //Changed = true; + } else if (LastClass == FPRClass && LastSize >= IROp->Size && IROp->Size > IREmit->GetOpSize(LastNode)) { + + // zext to size + // for some reason this doesn't work + //LastNode = IREmit->_VMov(LastNode, IROp->Size); + + //IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + //RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + //Changed = true; } else { - LogMan::Msg::A("Unhandled Register class"); + //printf("RCLSE: Not GPR class, missed, %d, lastS: %d, S: %d, Node S: %d\n", LastClass, LastSize, IROp->Size, IREmit->GetOpSize(LastNode)); } } - - IREmit->ReplaceAllUsesWith(CodeNode, LastNode); - RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); - Changed = true; } else if ((LastAccess == ACCESS_READ || LastAccess == ACCESS_PARTIAL_READ) && LastClass == Op->Class && From 790618cea996ef8aecb70895c881b2a5b5db46b0 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Fri, 6 Nov 2020 02:47:04 +0200 Subject: [PATCH 3/3] RCLSE: Enable VMOV cases --- .../IR/Passes/DeadContextStoreElimination.cpp | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp index bb55737d9..4d7ee36eb 100644 --- a/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp +++ b/External/FEXCore/Source/Interface/IR/Passes/DeadContextStoreElimination.cpp @@ -495,23 +495,20 @@ bool RCLSE::RedundantStoreLoadElimination(FEXCore::IR::IREmitter *IREmit) { RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); Changed = true; } else if (LastClass == FPRClass && LastSize >= IROp->Size && IROp->Size < IREmit->GetOpSize(LastNode)) { - + IREmit->SetWriteCursor(CodeNode); // trucate to size - // For some reason this doesn't work - //LastNode = IREmit->_VMov(LastNode, IROp->Size); - - //IREmit->ReplaceAllUsesWith(CodeNode, LastNode); - //RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); - //Changed = true; + LastNode = IREmit->_VMov(LastNode, IROp->Size); + IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + Changed = true; } else if (LastClass == FPRClass && LastSize >= IROp->Size && IROp->Size > IREmit->GetOpSize(LastNode)) { - + IREmit->SetWriteCursor(CodeNode); // zext to size - // for some reason this doesn't work - //LastNode = IREmit->_VMov(LastNode, IROp->Size); + LastNode = IREmit->_VMov(LastNode, IROp->Size); - //IREmit->ReplaceAllUsesWith(CodeNode, LastNode); - //RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); - //Changed = true; + IREmit->ReplaceAllUsesWith(CodeNode, LastNode); + RecordAccess(Info, Op->Class, Op->Offset, IROp->Size, ACCESS_READ, LastNode); + Changed = true; } else { //printf("RCLSE: Not GPR class, missed, %d, lastS: %d, S: %d, Node S: %d\n", LastClass, LastSize, IROp->Size, IREmit->GetOpSize(LastNode)); }