Merge pull request #199 from Sonicadvance1/ir_has_sideeffects

Implements HasSideEffects IR option
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis authored and GitHub committed 2020-05-26 09:36:02 +03:00
commit 7799cd43a4
4 files changed
+55 -28

No files matched your search

+21
View File
@@ -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
View File
@@ -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
View File
@@ -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) {