blob: d802603098da1c9310bf551ef180e38e16b04b9e [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of ssa;
/**
* This class implements an [IrNodesVisitor] that inlines a function represented
* as IR into an [SsaBuilder].
*/
class SsaFromIrInliner
extends IrNodesVisitor with SsaGraphBuilderMixin<IrNode>, SsaFromIrMixin {
final SsaBuilder builder;
SsaFromIrInliner(this.builder);
Compiler get compiler => builder.compiler;
JavaScriptBackend get backend => builder.backend;
Element get sourceElement => builder.sourceElementStack.last;
HGraph get graph => builder.graph;
HBasicBlock get current => builder.current;
void set current(HBasicBlock block) {
builder.current = block;
}
HBasicBlock get lastOpenedBlock => builder.lastOpenedBlock;
void set lastOpenedBlock(HBasicBlock block) {
builder.lastOpenedBlock = block;
}
bool get isReachable => builder.isReachable;
void set isReachable(bool value) {
builder.isReachable = value;
}
bool get inThrowExpression => builder.inThrowExpression;
int get loopNesting => builder.loopNesting;
List<InliningState> get inliningStack => builder.inliningStack;
List<Element> get sourceElementStack => builder.sourceElementStack;
void setupInliningState(FunctionElement function,
List<HInstruction> compiledArguments) {
builder.setupInliningState(function, compiledArguments);
}
void leaveInlinedMethod() {
builder.leaveInlinedMethod();
}
void doInline(Element element) {
builder.doInline(element);
}
void emitReturn(HInstruction value, IrReturn node) {
builder.localsHandler.updateLocal(builder.returnElement, value);
}
}
class IrInlineWeeder extends IrNodesVisitor {
static bool canBeInlined(IrFunction irFunction,
int maxInliningNodes,
bool useMaxInliningNodes) {
IrInlineWeeder weeder =
new IrInlineWeeder(maxInliningNodes, useMaxInliningNodes);
weeder.visitAll(irFunction.statements);
return !weeder.tooDifficult;
}
final int maxInliningNodes;
final bool useMaxInliningNodes;
IrInlineWeeder(this.maxInliningNodes, this.useMaxInliningNodes);
bool seenReturn = false;
bool tooDifficult = false;
int nodeCount = 0;
bool registerNode() {
if (!useMaxInliningNodes) return true;
if (nodeCount++ > maxInliningNodes) {
tooDifficult = true;
return false;
} else {
return true;
}
}
void visitIrNode(IrNode node) {
if (!registerNode()) return;
if (seenReturn) {
tooDifficult = true;
}
}
void visitIrReturn(IrReturn node) {
visitIrNode(node);
seenReturn = true;
}
void visitIrFunction(IrFunction node) {
tooDifficult = true;
}
}