Commit 1164f06e authored by baptiste.afsa's avatar baptiste.afsa Committed by Commit bot

[turbofan] Relax dependencies due to deopt during instruction scheduling.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2376963002
Cr-Commit-Position: refs/heads/master@{#39819}
parent ab486146
......@@ -28,8 +28,6 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kIA32Imul:
case kIA32ImulHigh:
case kIA32UmulHigh:
case kIA32Idiv:
case kIA32Udiv:
case kIA32Not:
case kIA32Neg:
case kIA32Shl:
......@@ -103,6 +101,12 @@ int InstructionScheduler::GetTargetInstructionFlags(
? kNoOpcodeFlags
: kIsLoadOperation | kHasSideEffect;
case kIA32Idiv:
case kIA32Udiv:
return (instr->addressing_mode() == kMode_None)
? kMayNeedDeoptCheck
: kMayNeedDeoptCheck | kIsLoadOperation | kHasSideEffect;
case kIA32Movsxbl:
case kIA32Movzxbl:
case kIA32Movb:
......
......@@ -136,9 +136,9 @@ void InstructionScheduler::AddInstruction(Instruction* instr) {
last_live_in_reg_marker_->AddSuccessor(new_node);
}
// Make sure that new instructions are not scheduled before the last
// deoptimization point.
if (last_deopt_ != nullptr) {
// Make sure that instructions are not scheduled before the last
// deoptimization point when they depend on it.
if ((last_deopt_ != nullptr) && DependsOnDeoptimization(instr)) {
last_deopt_->AddSuccessor(new_node);
}
......
......@@ -21,9 +21,12 @@ enum ArchOpcodeFlags {
kHasSideEffect = 2, // The instruction has some side effects (memory
// store, function call...)
kIsLoadOperation = 4, // The instruction is a memory load.
kMayNeedDeoptCheck = 8, // The instruction might be associated with a deopt
// check. This is the case of instruction which can
// blow up with particular inputs (e.g.: division by
// zero on Intel platforms).
};
class InstructionScheduler final : public ZoneObject {
public:
InstructionScheduler(Zone* zone, InstructionSequence* sequence);
......@@ -155,12 +158,25 @@ class InstructionScheduler final : public ZoneObject {
// Check whether the given instruction has side effects (e.g. function call,
// memory store).
bool HasSideEffect(const Instruction* instr) const {
return GetInstructionFlags(instr) & kHasSideEffect;
return (GetInstructionFlags(instr) & kHasSideEffect) != 0;
}
// Return true if the instruction is a memory load.
bool IsLoadOperation(const Instruction* instr) const {
return GetInstructionFlags(instr) & kIsLoadOperation;
return (GetInstructionFlags(instr) & kIsLoadOperation) != 0;
}
// Return true if this instruction is usually associated with a deopt check
// to validate its input.
bool MayNeedDeoptCheck(const Instruction* instr) const {
return (GetInstructionFlags(instr) & kMayNeedDeoptCheck) != 0;
}
// Return true if the instruction cannot be moved before the last deopt
// point we encountered.
bool DependsOnDeoptimization(const Instruction* instr) const {
return MayNeedDeoptCheck(instr) || instr->IsDeoptimizeCall() ||
HasSideEffect(instr) || IsLoadOperation(instr);
}
// Identify nops used as a definition point for live-in registers at
......
......@@ -36,10 +36,6 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64Imul32:
case kX64ImulHigh32:
case kX64UmulHigh32:
case kX64Idiv:
case kX64Idiv32:
case kX64Udiv:
case kX64Udiv32:
case kX64Not:
case kX64Not32:
case kX64Neg:
......@@ -133,6 +129,14 @@ int InstructionScheduler::GetTargetInstructionFlags(
? kNoOpcodeFlags
: kIsLoadOperation | kHasSideEffect;
case kX64Idiv:
case kX64Idiv32:
case kX64Udiv:
case kX64Udiv32:
return (instr->addressing_mode() == kMode_None)
? kMayNeedDeoptCheck
: kMayNeedDeoptCheck | kIsLoadOperation | kHasSideEffect;
case kX64Movsxbl:
case kX64Movzxbl:
case kX64Movsxbq:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment