Skip to content

Commit

Permalink
Merge pull request #3449 from Sonicadvance1/syscalls_passthrough_not_…
Browse files Browse the repository at this point in the history
…json

Linux: Converts passthrough syscalls to direct passthrough handlers
  • Loading branch information
Sonicadvance1 authored and pmatos committed Feb 27, 2024
2 parents 49e798a + 151e227 commit 5f27180
Show file tree
Hide file tree
Showing 53 changed files with 1,239 additions and 2,545 deletions.
4 changes: 2 additions & 2 deletions FEXCore/Source/Interface/IR/PassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ void PassManager::AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool Inli

InsertPass(CreateDeadStoreElimination(ctx->HostFeatures.SupportsAVX));
InsertPass(CreatePassDeadCodeElimination());
InsertPass(CreateConstProp(InlineConstants, ctx->HostFeatures.SupportsTSOImm9));
InsertPass(CreateConstProp(
InlineConstants, ctx->HostFeatures.SupportsTSOImm9, Is64BitMode()));

InsertPass(CreateDeadFlagCalculationEliminination());

Expand Down Expand Up @@ -121,5 +122,4 @@ bool PassManager::Run(IREmitter *IREmit) {

return Changed;
}

}
8 changes: 5 additions & 3 deletions FEXCore/Source/Interface/IR/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@ class Pass;
class RegisterAllocationPass;
class RegisterAllocationData;

fextl::unique_ptr<FEXCore::IR::Pass> CreateConstProp(bool InlineConstants, bool SupportsTSOImm9);
fextl::unique_ptr<FEXCore::IR::Pass>
CreateConstProp(bool InlineConstants, bool SupportsTSOImm9, bool Is64BitMode);
fextl::unique_ptr<FEXCore::IR::Pass> CreateContextLoadStoreElimination(bool SupportsAVX);
fextl::unique_ptr<FEXCore::IR::Pass> CreateInlineCallOptimization(const FEXCore::CPUIDEmu* CPUID);
fextl::unique_ptr<FEXCore::IR::Pass> CreateDeadFlagCalculationEliminination();
fextl::unique_ptr<FEXCore::IR::Pass> CreateDeadStoreElimination(bool SupportsAVX);
fextl::unique_ptr<FEXCore::IR::Pass> CreatePassDeadCodeElimination();
fextl::unique_ptr<FEXCore::IR::Pass> CreateIRCompaction(FEXCore::Utils::IntrusivePooledAllocator &Allocator);
fextl::unique_ptr<FEXCore::IR::RegisterAllocationPass> CreateRegisterAllocationPass(FEXCore::IR::Pass* CompactionPass,
bool SupportsAVX);
fextl::unique_ptr<FEXCore::IR::RegisterAllocationPass>
CreateRegisterAllocationPass(FEXCore::IR::Pass *CompactionPass,
bool SupportsAVX);
fextl::unique_ptr<FEXCore::IR::Pass> CreateLongDivideEliminationPass();

namespace Validation {
Expand Down
52 changes: 41 additions & 11 deletions FEXCore/Source/Interface/IR/Passes/ConstProp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ static bool IsTSOImm9(uint64_t imm) {
}

static std::tuple<MemOffsetType, uint8_t, OrderedNode*, OrderedNode*> MemExtendedAddressing(IREmitter *IREmit, uint8_t AccessSize, IROp_Header* AddressHeader) {
LOGMAN_THROW_A_FMT(AddressHeader->Op == OP_ADD, "Invalid address Op");
auto Src0Header = IREmit->GetOpHeader(AddressHeader->Args[0]);
if (Src0Header->Size == 8) {
//Try to optimize: Base + MUL(Offset, Scale)
Expand Down Expand Up @@ -141,7 +142,28 @@ static std::tuple<MemOffsetType, uint8_t, OrderedNode*, OrderedNode*> MemExtende
}

// no match anywhere, just add
return { MEM_OFFSET_SXTX, 1, IREmit->UnwrapNode(AddressHeader->Args[0]), IREmit->UnwrapNode(AddressHeader->Args[1]) };
// However, if we have one 32bit negative constant, we need to sign extend it
auto Arg0_ = AddressHeader->Args[0];
auto Arg1_ = AddressHeader->Args[1];
auto Arg1H = IREmit->GetOpHeader(Arg1_);
auto Arg0 = IREmit->UnwrapNode(Arg0_);
auto Arg1 = IREmit->UnwrapNode(Arg1_);

uint64_t ConstVal = 0;
if (IREmit->IsValueConstant(Arg1_, &ConstVal) && Arg1H->Size == 4) {
// Base is Arg0, Constant (Displacement in Arg1)
OrderedNode *Base = Arg0;
OrderedNode *Cnt = Arg1;
int32_t Val32 = (int32_t)ConstVal;

if (Val32 < 0) {
return {MEM_OFFSET_SXTW, 1, Base, Cnt};
} else {
return {MEM_OFFSET_SXTX, 1, Base, Cnt};
}
} else {
return {MEM_OFFSET_SXTX, 1, Arg0, Arg1};
}
}

static OrderedNodeWrapper RemoveUselessMasking(IREmitter *IREmit, OrderedNodeWrapper src, uint64_t mask) {
Expand Down Expand Up @@ -184,9 +206,10 @@ static bool IsBfeAlreadyDone(IREmitter *IREmit, OrderedNodeWrapper src, uint64_t

class ConstProp final : public FEXCore::IR::Pass {
public:
explicit ConstProp(bool DoInlineConstants, bool SupportsTSOImm9)
: InlineConstants(DoInlineConstants)
, SupportsTSOImm9 {SupportsTSOImm9} { }
explicit ConstProp(bool DoInlineConstants, bool SupportsTSOImm9,
bool Is64BitMode)
: InlineConstants(DoInlineConstants), SupportsTSOImm9{SupportsTSOImm9},
Is64BitMode(Is64BitMode) {}

bool Run(IREmitter *IREmit) override;

Expand Down Expand Up @@ -219,6 +242,7 @@ class ConstProp final : public FEXCore::IR::Pass {
return Result.first->second;
}
bool SupportsTSOImm9{};
bool Is64BitMode;
// This is a heuristic to limit constant pool live ranges to reduce RA interference pressure.
// If the range is unbounded then RA interference pressure seems to increase to the point
// that long blocks of constant usage can slow to a crawl.
Expand Down Expand Up @@ -525,12 +549,15 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current
auto Op = IROp->CW<IR::IROp_LoadMem>();
auto AddressHeader = IREmit->GetOpHeader(Op->Addr);

if (AddressHeader->Op == OP_ADD && AddressHeader->Size == 8) {
auto [OffsetType, OffsetScale, Arg0, Arg1] = MemExtendedAddressing(IREmit, IROp->Size, AddressHeader);
if (AddressHeader->Op == OP_ADD &&
((Is64BitMode && AddressHeader->Size == 8) ||
(!Is64BitMode && AddressHeader->Size == 4))) {
auto [OffsetType, OffsetScale, Arg0, Arg1] =
MemExtendedAddressing(IREmit, IROp->Size, AddressHeader);

Op->OffsetType = OffsetType;
Op->OffsetScale = OffsetScale;
IREmit->ReplaceNodeArgument(CodeNode, Op->Addr_Index, Arg0); // Addr
IREmit->ReplaceNodeArgument(CodeNode, Op->Addr_Index, Arg0); // Addr
IREmit->ReplaceNodeArgument(CodeNode, Op->Offset_Index, Arg1); // Offset

Changed = true;
Expand All @@ -542,7 +569,9 @@ bool ConstProp::ConstantPropagation(IREmitter *IREmit, const IRListView& Current
auto Op = IROp->CW<IR::IROp_StoreMem>();
auto AddressHeader = IREmit->GetOpHeader(Op->Addr);

if (AddressHeader->Op == OP_ADD && AddressHeader->Size == 8) {
if (AddressHeader->Op == OP_ADD &&
((Is64BitMode && AddressHeader->Size == 8) ||
(!Is64BitMode && AddressHeader->Size == 4))) {
auto [OffsetType, OffsetScale, Arg0, Arg1] = MemExtendedAddressing(IREmit, IROp->Size, AddressHeader);

Op->OffsetType = OffsetType;
Expand Down Expand Up @@ -1311,8 +1340,9 @@ bool ConstProp::Run(IREmitter *IREmit) {
return Changed;
}

fextl::unique_ptr<FEXCore::IR::Pass> CreateConstProp(bool InlineConstants, bool SupportsTSOImm9) {
return fextl::make_unique<ConstProp>(InlineConstants, SupportsTSOImm9);
fextl::unique_ptr<FEXCore::IR::Pass>
CreateConstProp(bool InlineConstants, bool SupportsTSOImm9, bool Is64BitMode) {
return fextl::make_unique<ConstProp>(InlineConstants, SupportsTSOImm9,
Is64BitMode);
}

}
15 changes: 1 addition & 14 deletions Source/Tools/LinuxEmulation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,23 @@ set (SRCS
LinuxSyscalls/x32/IoctlEmulation.cpp
LinuxSyscalls/x64/EPoll.cpp
LinuxSyscalls/x64/FD.cpp
LinuxSyscalls/x64/IO.cpp
LinuxSyscalls/x64/Ioctl.cpp
LinuxSyscalls/x64/Info.cpp
LinuxSyscalls/x64/Memory.cpp
LinuxSyscalls/x64/Msg.cpp
LinuxSyscalls/x64/NotImplemented.cpp
LinuxSyscalls/x64/Semaphore.cpp
LinuxSyscalls/x64/Sched.cpp
LinuxSyscalls/x64/Signals.cpp
LinuxSyscalls/x64/Socket.cpp
LinuxSyscalls/x64/Thread.cpp
LinuxSyscalls/x64/Syscalls.cpp
LinuxSyscalls/x64/Time.cpp
LinuxSyscalls/Syscalls/EPoll.cpp
LinuxSyscalls/Syscalls/FD.cpp
LinuxSyscalls/Syscalls/FS.cpp
LinuxSyscalls/Syscalls/Passthrough.cpp
LinuxSyscalls/Syscalls/Info.cpp
LinuxSyscalls/Syscalls/IO.cpp
LinuxSyscalls/Syscalls/IOUring.cpp
LinuxSyscalls/Syscalls/Key.cpp
LinuxSyscalls/Syscalls/Memory.cpp
LinuxSyscalls/Syscalls/Msg.cpp
LinuxSyscalls/Syscalls/Namespace.cpp
LinuxSyscalls/Syscalls/Sched.cpp
LinuxSyscalls/Syscalls/Semaphore.cpp
LinuxSyscalls/Syscalls/SHM.cpp
LinuxSyscalls/Syscalls/Signals.cpp
LinuxSyscalls/Syscalls/Socket.cpp
LinuxSyscalls/Syscalls/Thread.cpp
LinuxSyscalls/Syscalls/Time.cpp
LinuxSyscalls/Syscalls/Timer.cpp
LinuxSyscalls/Syscalls/NotImplemented.cpp
LinuxSyscalls/Syscalls/Stubs.cpp)
Expand Down
12 changes: 0 additions & 12 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,10 @@ class SignalDelegator;
void RegisterFS(FEX::HLE::SyscallHandler *Handler);
void RegisterInfo(FEX::HLE::SyscallHandler *Handler);
void RegisterIO(FEX::HLE::SyscallHandler *Handler);
void RegisterIOUring(FEX::HLE::SyscallHandler *Handler);
void RegisterKey(FEX::HLE::SyscallHandler *Handler);
void RegisterMemory(FEX::HLE::SyscallHandler *Handler);
void RegisterMsg(FEX::HLE::SyscallHandler *Handler);
void RegisterNamespace(FEX::HLE::SyscallHandler *Handler);
void RegisterNuma(FEX::HLE::SyscallHandler *Handler);
void RegisterSched(FEX::HLE::SyscallHandler *Handler);
void RegisterSemaphore(FEX::HLE::SyscallHandler *Handler);
void RegisterSHM(FEX::HLE::SyscallHandler *Handler);
void RegisterSignals(FEX::HLE::SyscallHandler *Handler);
void RegisterSocket(FEX::HLE::SyscallHandler *Handler);
void RegisterThread(FEX::HLE::SyscallHandler *Handler);
void RegisterTime(FEX::HLE::SyscallHandler *Handler);
void RegisterTimer(FEX::HLE::SyscallHandler *Handler);
void RegisterNotImplemented(FEX::HLE::SyscallHandler *Handler);
void RegisterStubs(FEX::HLE::SyscallHandler *Handler);
Expand Down Expand Up @@ -636,9 +627,6 @@ bool IsFaultLocation(uint64_t PC);
#define REGISTER_SYSCALL_IMPL(name, lambda) \
REGISTER_SYSCALL_IMPL_INTERNAL(name, ~0, FEXCore::IR::SyscallFlags::DEFAULT, lambda)

#define REGISTER_SYSCALL_IMPL_PASS(name, lambda) \
REGISTER_SYSCALL_IMPL_INTERNAL(name, SYSCALL_DEF(name), FEXCore::IR::SyscallFlags::DEFAULT, lambda)

#define REGISTER_SYSCALL_IMPL_FLAGS(name, flags, lambda) \
REGISTER_SYSCALL_IMPL_INTERNAL(name, ~0, flags, lambda)

Expand Down
8 changes: 1 addition & 7 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/EPoll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,10 @@ namespace FEX::HLE {
void RegisterEpoll(FEX::HLE::SyscallHandler *Handler) {
using namespace FEXCore::IR;

REGISTER_SYSCALL_IMPL_PASS_FLAGS(epoll_create, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
REGISTER_SYSCALL_IMPL_FLAGS(epoll_create, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int size) -> uint64_t {
uint64_t Result = epoll_create(size);
SYSCALL_ERRNO();
});

REGISTER_SYSCALL_IMPL_PASS_FLAGS(epoll_create1, SyscallFlags::OPTIMIZETHROUGH | SyscallFlags::NOSYNCSTATEONENTRY,
[](FEXCore::Core::CpuStateFrame *Frame, int flags) -> uint64_t {
uint64_t Result = epoll_create1(flags);
SYSCALL_ERRNO();
});
}
}
Loading

0 comments on commit 5f27180

Please sign in to comment.