diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-05-22 14:45:59 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-06-17 14:44:23 +0200 |
commit | c6921eca61d1f393f6cd08484da29da7d67d9695 (patch) | |
tree | 82605ddef1a519c2772836eaf692eb66210b7035 | |
parent | 7acdace9be3a68954152455acd527fa052c47b09 (diff) |
V4 JIT: teach regalloc about callee-saved registers.
Callee-saved registers won't get clobbered by a call, so any value
stored in it will survive the call.
Change-Id: I2b61b84617b01bf7ce7e81cd0119a6da689ee9d5
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 20 | ||||
-rw-r--r-- | src/qml/jit/qv4targetplatform_p.h | 15 |
2 files changed, 26 insertions, 9 deletions
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index e21676e520..6a2f5ca640 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -1280,19 +1280,23 @@ void RegisterAllocator::prepareRanges() const int regCount = _normalRegisters.size(); _fixedRegisterRanges.reserve(regCount); for (int reg = 0; reg < regCount; ++reg) { - LifeTimeInterval *lti = cloneFixedInterval(reg, false, ltiWithCalls); - _fixedRegisterRanges.append(lti); - if (lti->isValid()) - _active.append(lti); + if (_normalRegisters.at(reg)->isCallerSaved()) { + LifeTimeInterval *lti = cloneFixedInterval(reg, false, ltiWithCalls); + _fixedRegisterRanges.append(lti); + if (lti->isValid()) + _active.append(lti); + } } const int fpRegCount = _fpRegisters.size(); _fixedFPRegisterRanges.reserve(fpRegCount); for (int fpReg = 0; fpReg < fpRegCount; ++fpReg) { - LifeTimeInterval *lti = cloneFixedInterval(fpReg, true, ltiWithCalls); - _fixedFPRegisterRanges.append(lti); - if (lti->isValid()) - _active.append(lti); + if (_fpRegisters.at(fpReg)->isCallerSaved()) { + LifeTimeInterval *lti = cloneFixedInterval(fpReg, true, ltiWithCalls); + _fixedFPRegisterRanges.append(lti); + if (lti->isValid()) + _active.append(lti); + } } } diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h index 1f08a0df2b..95db247d0f 100644 --- a/src/qml/jit/qv4targetplatform_p.h +++ b/src/qml/jit/qv4targetplatform_p.h @@ -61,6 +61,13 @@ namespace JIT { // restore ebx (which holds the GOT ptr) before a call // - All (supported) ARM platforms, where the only variety is the platform specific usage of r9, // and the frame-pointer in Thumb/Thumb2 v.s. ARM mode. +// +// Specific handling of ebx when it holds the GOT: +// In this case we can use it, but it needs to be restored when doing a call. So, the handling is as +// follows: it is marked as caller saved, meaning the value in it won't survive a call. When +// calculating the list of callee saved registers in getCalleeSavedRegisters (which is used to +// generate push/pop instructions in the prelude/postlude), we add ebx too. Then when synthesizing +// a call, we add a load it right before emitting the call instruction. class TargetPlatform { public: @@ -81,7 +88,7 @@ public: typedef RegisterInfo RI; return RegisterInformation() << RI(JSC::X86Registers::edx, QStringLiteral("edx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc) - << RI(JSC::X86Registers::ebx, QStringLiteral("ebx"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc) + << RI(JSC::X86Registers::ebx, QStringLiteral("ebx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc) << RI(JSC::X86Registers::edi, QStringLiteral("edi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined) << RI(JSC::X86Registers::esi, QStringLiteral("esi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined) << RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc) @@ -351,6 +358,12 @@ public: // utility functions static RegisterInformation regs; if (regs.isEmpty()) { foreach (const RegisterInfo &info, getRegisterInfo()) { +#if defined(RESTORE_EBX_ON_CALL) + if (info.reg<JSC::X86Registers::RegisterID>() == JSC::X86Registers::ebx) { + regs.append(info); + continue; + } +#endif // RESTORE_EBX_ON_CALL if (info.isCalleeSaved()) regs.append(info); } |