Bug 768288: IonMonkey: Inline small functions with loops, r=djvj r=shu

This commit is contained in:
Hannes Verschore 2013-05-10 14:49:58 +02:00
parent 1f43f02b3e
commit 138801e0d0
3 changed files with 32 additions and 10 deletions

View File

@ -237,7 +237,8 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
RootedScript inlineScript(cx, target->nonLazyScript());
ExecutionMode executionMode = info().executionMode();
if (!CanIonCompile(inlineScript, executionMode)) {
IonSpew(IonSpew_Inlining, "Cannot inline due to disable Ion compilation");
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to disable Ion compilation",
inlineScript->filename(), inlineScript->lineno);
return false;
}
@ -246,7 +247,8 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
ion::IsBaselineEnabled(cx) &&
!inlineScript->hasBaselineScript())
{
IonSpew(IonSpew_Inlining, "Cannot inline target with no baseline jitcode");
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline target with no baseline jitcode",
inlineScript->filename(), inlineScript->lineno);
return false;
}
@ -254,18 +256,20 @@ IonBuilder::canInlineTarget(JSFunction *target, CallInfo &callInfo)
IonBuilder *builder = callerBuilder_;
while (builder) {
if (builder->script() == inlineScript) {
IonSpew(IonSpew_Inlining, "Not inlining recursive call");
IonSpew(IonSpew_Inlining, "%s:%d Not inlining recursive call",
inlineScript->filename(), inlineScript->lineno);
return false;
}
builder = builder->callerBuilder_;
}
if (!canEnterInlinedFunction(target)) {
IonSpew(IonSpew_Inlining, "Cannot inline due to analysis data %d", script()->lineno);
IonSpew(IonSpew_Inlining, "%s:%d Cannot inline due to oracle veto %d",
inlineScript->filename(), inlineScript->lineno,
script()->lineno);
return false;
}
IonSpew(IonSpew_Inlining, "Inlining good to go!");
return true;
}
@ -3429,6 +3433,12 @@ IonBuilder::inlineScriptedCall(CallInfo &callInfo, JSFunction *target)
// Accumulate return values.
MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();
if (exits.length() == 0) {
// Inlining of functions that have no exit is not supported.
calleeScript->analysis()->setIonUninlineable();
abortReason_ = AbortReason_Inlining;
return false;
}
MDefinition *retvalDefn = patchInlinedReturns(callInfo, exits, returnBlock);
if (!retvalDefn)
return false;
@ -3537,11 +3547,13 @@ IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
targetScript->filename(), targetScript->lineno);
return false;
}
}
// Always inline the empty script up to the inlining depth.
if (targetScript->length == 1)
return true;
if (targetScript->analysis()->hasLoops()) {
IonSpew(IonSpew_Inlining, "%s:%d - Vetoed: big function that contains a loop",
targetScript->filename(), targetScript->lineno);
return false;
}
}
// Callee must not be excessively large.
// This heuristic also applies to the callsite as a whole.

View File

@ -76,6 +76,16 @@ MIRGraph::removeBlocksAfter(MBasicBlock *start)
if (block == osrBlock_)
osrBlock_ = NULL;
if (exitAccumulator_) {
size_t i = 0;
while (i < exitAccumulator_->length()) {
if ((*exitAccumulator_)[i] == block)
exitAccumulator_->erase(exitAccumulator_->begin() + i);
else
i++;
}
}
block->discardAllInstructions();
block->discardAllPhis();
block->discardAllResumePoints();

View File

@ -65,7 +65,7 @@ ScriptAnalysis::addJump(JSContext *cx, unsigned offset,
if (offset < *currentOffset) {
/* Scripts containing loops are never inlined. */
isJaegerInlineable = isIonInlineable = false;
isJaegerInlineable = false;
hasLoops_ = true;
if (code->analyzed) {