mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-23 19:00:49 +02:00
Merge pull request #199 from Sonicadvance1/ir_has_sideeffects
Implements HasSideEffects IR option
This commit is contained in:
commit
7799cd43a4
4 files changed
+55
-28
No files matched your search
+21
@@ -115,6 +115,7 @@ def print_ir_sizes(ops, defines):
|
||||
output_file.write("std::string_view const& GetName(IROps Op);\n")
|
||||
output_file.write("uint8_t GetArgs(IROps Op);\n")
|
||||
output_file.write("FEXCore::IR::RegisterClassType GetRegClass(IROps Op);\n\n")
|
||||
output_file.write("bool HasSideEffects(IROps Op);\n")
|
||||
|
||||
output_file.write("#undef IROP_SIZES\n")
|
||||
output_file.write("#endif\n\n")
|
||||
@@ -187,6 +188,25 @@ def print_ir_getraargs(ops, defines):
|
||||
output_file.write("#undef IROP_GETRAARGS_IMPL\n")
|
||||
output_file.write("#endif\n\n")
|
||||
|
||||
def print_ir_hassideeffects(ops, defines):
|
||||
output_file.write("#ifdef IROP_HASSIDEEFFECTS_IMPL\n")
|
||||
|
||||
output_file.write("constexpr std::array<uint8_t, OP_LAST + 1> SideEffects = {\n")
|
||||
for op_key, op_vals in ops.items():
|
||||
HasSideEffects = False
|
||||
if ("HasSideEffects" in op_vals):
|
||||
SSAArgs = op_vals["HasSideEffects"]
|
||||
|
||||
output_file.write("\t%s,\n" % ("true" if SSAArgs else "false"))
|
||||
|
||||
output_file.write("};\n\n")
|
||||
|
||||
output_file.write("bool HasSideEffects(IROps Op) {\n")
|
||||
output_file.write(" return SideEffects[Op];\n")
|
||||
output_file.write("}\n")
|
||||
|
||||
output_file.write("#undef IROP_HASSIDEEFFECTS_IMPL\n")
|
||||
output_file.write("#endif\n\n")
|
||||
|
||||
# Print out IR argument printing
|
||||
def print_ir_arg_printer(ops, defines):
|
||||
@@ -619,6 +639,7 @@ print_ir_sizes(ops, defines)
|
||||
print_ir_reg_classes(ops, defines)
|
||||
print_ir_getname(ops, defines)
|
||||
print_ir_getraargs(ops, defines)
|
||||
print_ir_hassideeffects(ops, defines)
|
||||
print_ir_arg_printer(ops, defines)
|
||||
print_ir_allocator_helpers(ops, defines)
|
||||
print_ir_parser_allocator_helpers(ops, defines)
|
||||
|
||||
+1
@@ -7,6 +7,7 @@ namespace FEXCore::IR {
|
||||
#define IROP_GETNAME_IMPL
|
||||
#define IROP_GETRAARGS_IMPL
|
||||
#define IROP_REG_CLASSES_IMPL
|
||||
#define IROP_HASSIDEEFFECTS_IMPL
|
||||
|
||||
#include <FEXCore/IR/IRDefines.inc>
|
||||
|
||||
|
||||
+28
@@ -41,6 +41,7 @@
|
||||
|
||||
"Ops": {
|
||||
"Dummy": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Misc",
|
||||
"SwitchGen": false
|
||||
},
|
||||
@@ -72,6 +73,7 @@
|
||||
},
|
||||
|
||||
"EndBlock": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Misc",
|
||||
"SwitchGen": false,
|
||||
"Args": [
|
||||
@@ -103,6 +105,7 @@
|
||||
},
|
||||
|
||||
"CASPair": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Atomic",
|
||||
"Desc": ["Does a compare and exchange with two GPRPair values",
|
||||
"ssa0 is the comparison value",
|
||||
@@ -138,6 +141,7 @@
|
||||
},
|
||||
|
||||
"StoreContextPair": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Memory",
|
||||
"Desc": ["Stores a pair of values back in to the context"],
|
||||
"SSAArgs": "1",
|
||||
@@ -213,6 +217,7 @@
|
||||
},
|
||||
|
||||
"Break": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Misc",
|
||||
"Args": [
|
||||
"uint8_t", "Reason",
|
||||
@@ -221,10 +226,12 @@
|
||||
},
|
||||
|
||||
"ExitFunction": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Branch"
|
||||
},
|
||||
|
||||
"Jump": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Branch",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
@@ -234,6 +241,7 @@
|
||||
},
|
||||
|
||||
"CondJump": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Branch",
|
||||
"SSAArgs": "3",
|
||||
"RAOverride": "1",
|
||||
@@ -320,6 +328,7 @@
|
||||
},
|
||||
|
||||
"StoreContext": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Stores a value to the context with offset",
|
||||
"Ctx[Offset] = Value"
|
||||
],
|
||||
@@ -359,6 +368,7 @@
|
||||
},
|
||||
|
||||
"StoreContextIndexed": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Stores a value to the context with offset and indexed by SSA value",
|
||||
"Ctx[BaseOffset + Index * Stride] = Value"
|
||||
],
|
||||
@@ -377,6 +387,7 @@
|
||||
},
|
||||
|
||||
"SpillRegister": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Spills an SSA value to memory",
|
||||
"Spill slots are register allocated and has live ranges calculated to handle slot calculation",
|
||||
"```diff\n- !Don't use this op. It is for RA to handle spilling and filling!\n```"
|
||||
@@ -421,6 +432,7 @@
|
||||
},
|
||||
|
||||
"StoreFlag": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Stores 1-bit of the flag in to the specified x86-64 flag",
|
||||
"Specialized to allow flexible implementation of flag handling"
|
||||
],
|
||||
@@ -435,6 +447,7 @@
|
||||
},
|
||||
|
||||
"Syscall": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Branch",
|
||||
"HasDest": true,
|
||||
"DestClass": "GPR",
|
||||
@@ -468,6 +481,7 @@
|
||||
},
|
||||
|
||||
"StoreMem": {
|
||||
"HasSideEffects": true,
|
||||
"OpClass": "Memory",
|
||||
"SSAArgs": "2",
|
||||
"SSANames": [
|
||||
@@ -900,6 +914,7 @@
|
||||
},
|
||||
|
||||
"CAS": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Does a compare and swap of values to a memory location",
|
||||
"This mostly matches the C++ atomic_compare_exchange_strong function",
|
||||
"Dest = atomic_compare_exchange_strong(%Addr, %Expected, %Desired)",
|
||||
@@ -922,6 +937,7 @@
|
||||
},
|
||||
|
||||
"AtomicAdd": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer add"
|
||||
],
|
||||
"OpClass": "Atomic",
|
||||
@@ -936,6 +952,7 @@
|
||||
},
|
||||
|
||||
"AtomicSub": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer sub"
|
||||
],
|
||||
"OpClass": "Atomic",
|
||||
@@ -950,6 +967,7 @@
|
||||
},
|
||||
|
||||
"AtomicAnd": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic binary and"
|
||||
],
|
||||
"OpClass": "Atomic",
|
||||
@@ -964,6 +982,7 @@
|
||||
},
|
||||
|
||||
"AtomicOr": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic binary or"
|
||||
],
|
||||
"OpClass": "Atomic",
|
||||
@@ -978,6 +997,7 @@
|
||||
},
|
||||
|
||||
"AtomicXor": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic binary exclusive or"
|
||||
],
|
||||
"OpClass": "Atomic",
|
||||
@@ -992,6 +1012,7 @@
|
||||
},
|
||||
|
||||
"AtomicSwap": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic swap",
|
||||
"Atomically swaps contents of GPR and memory location"
|
||||
],
|
||||
@@ -1010,6 +1031,7 @@
|
||||
},
|
||||
|
||||
"AtomicFetchAdd": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer fetch and add",
|
||||
"Atomically fetches %Addr and adds %value to the memory location",
|
||||
"Dest is the value prior to operating on the value in memory"
|
||||
@@ -1029,6 +1051,7 @@
|
||||
},
|
||||
|
||||
"AtomicFetchSub": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer fetch and sub",
|
||||
"Atomically fetches %Addr and subtracts %value to the memory location",
|
||||
"Dest is the value prior to operating on the value in memory"
|
||||
@@ -1049,6 +1072,7 @@
|
||||
},
|
||||
|
||||
"AtomicFetchAnd": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer fetch and binary and",
|
||||
"Atomically fetches %Addr and binary ands %value to the memory location",
|
||||
"Dest is the value prior to operating on the value in memory"
|
||||
@@ -1068,6 +1092,7 @@
|
||||
},
|
||||
|
||||
"AtomicFetchOr": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer fetch and binary or",
|
||||
"Atomically fetches %Addr and binary ors %value to the memory location",
|
||||
"Dest is the value prior to operating on the value in memory"
|
||||
@@ -1087,6 +1112,7 @@
|
||||
},
|
||||
|
||||
"AtomicFetchXor": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Atomic integer fetch and binary exclusive or",
|
||||
"Atomically fetches %Addr and binary exclusive ors %value to the memory location",
|
||||
"Dest is the value prior to operating on the value in memory"
|
||||
@@ -1180,11 +1206,13 @@
|
||||
},
|
||||
|
||||
"Print": {
|
||||
"HasSideEffects": true,
|
||||
"Desc": ["Debug operation that prints an SSA value to the console",
|
||||
"May only print 64bits of the value",
|
||||
"Depending on backend, may only support GPR printing"
|
||||
],
|
||||
"OpClass": "Misc",
|
||||
"DestSize": "GetOpSize(ssa0)",
|
||||
"SSAArgs": "1",
|
||||
"SSANames": [
|
||||
"Value"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "Interface/IR/PassManager.h"
|
||||
#include "Interface/Core/OpcodeDispatcher.h"
|
||||
|
||||
#include <FEXCore/IR/IR.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace FEXCore::IR {
|
||||
@@ -42,38 +44,13 @@ bool DeadCodeElimination::Run(IREmitter *IREmit) {
|
||||
OrderedNode *CodeNode = CodeOp->GetNode(ListBegin);
|
||||
auto IROp = CodeNode->Op(DataBegin);
|
||||
|
||||
switch (IROp->Op) {
|
||||
// State/memory storage
|
||||
case OP_STORECONTEXTINDEXED:
|
||||
case OP_STORECONTEXT:
|
||||
case OP_STORECONTEXTPAIR:
|
||||
case OP_STOREFLAG:
|
||||
case OP_STOREMEM:
|
||||
case OP_CAS:
|
||||
case OP_PRINT:
|
||||
// Keep
|
||||
break;
|
||||
// IO
|
||||
case OP_SYSCALL:
|
||||
// Keep
|
||||
break;
|
||||
// Control flow
|
||||
case OP_BREAK:
|
||||
case OP_JUMP:
|
||||
case OP_EXITFUNCTION:
|
||||
case OP_CONDJUMP:
|
||||
// Keep
|
||||
break;
|
||||
case OP_DUMMY:
|
||||
case OP_ENDBLOCK:
|
||||
// Keep, so we don't have to update block first/last
|
||||
break;
|
||||
default:
|
||||
// Skip over anything that has side effects
|
||||
// Use count tracking can't safely remove anything with side effects
|
||||
if (!IR::HasSideEffects(IROp->Op)) {
|
||||
if (CodeNode->GetUses() == 0) {
|
||||
NumRemoved++;
|
||||
IREmit->Remove(CodeNode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (CodeLast == CodeBegin) {
|
||||
|
||||
Reference in new issue
Block a user