Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(993)

Unified Diff: frog/leg/ssa/bailout.dart

Issue 9873021: Move frog/leg to lib/compiler/implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « frog/leg/source_file.dart ('k') | frog/leg/ssa/builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/bailout.dart
===================================================================
--- frog/leg/ssa/bailout.dart (revision 5925)
+++ frog/leg/ssa/bailout.dart (working copy)
@@ -1,366 +0,0 @@
-// Copyright (c) 2012, 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.
-
-class BailoutInfo {
- int instructionId;
- int bailoutId;
- BailoutInfo(this.instructionId, this.bailoutId);
-}
-
-/**
- * Keeps track of the execution environment for instructions. An
- * execution environment contains the SSA instructions that are live.
- */
-class Environment {
- final Set<HInstruction> lives;
- final Set<HBasicBlock> loopMarkers;
- Environment() : lives = new Set<HInstruction>(),
- loopMarkers = new Set<HBasicBlock>();
- Environment.from(Environment other)
- : lives = new Set<HInstruction>.from(other.lives),
- loopMarkers = new Set<HBasicBlock>.from(other.loopMarkers);
-
- Environment.forLoopBody(Environment other)
- : lives = new Set<HInstruction>(),
- loopMarkers = new Set<HBasicBlock>.from(other.loopMarkers);
-
- void remove(HInstruction instruction) {
- lives.remove(instruction);
- }
-
- void add(HInstruction instruction) {
- if (!instruction.isCodeMotionInvariant()) {
- lives.add(instruction);
- } else {
- for (int i = 0, len = instruction.inputs.length; i < len; i++) {
- add(instruction.inputs[i]);
- }
- }
- }
-
- void addLoopMarker(HBasicBlock block) {
- loopMarkers.add(block);
- }
-
- void removeLoopMarker(HBasicBlock block) {
- loopMarkers.remove(block);
- }
-
- void addAll(Environment other) {
- lives.addAll(other.lives);
- loopMarkers.addAll(other.loopMarkers);
- }
-
- List<HInstruction> buildAndSetLast(HInstruction instruction) {
- remove(instruction);
- List<HInstruction> result = new List<HInstruction>.from(lives);
- result.addLast(instruction);
- add(instruction);
- return result;
- }
-
- bool isEmpty() => lives.isEmpty();
- bool contains(HInstruction instruction) => lives.contains(instruction);
- bool containsLoopMarker(HBasicBlock block) => loopMarkers.contains(block);
- void clear() => lives.clear();
-}
-
-/**
- * Computes the environment for each SSA instruction: visits the graph
- * in post-dominator order. Removes an instruction from the environment
- * and adds its inputs to the environment at the instruction's
- * definition.
- *
- * At the end of the computation, insert type guards in the graph.
- */
-class SsaTypeGuardBuilder extends HBaseVisitor implements OptimizationPhase {
- final Compiler compiler;
- final WorkItem work;
- final String name = 'SsaTypeGuardBuilder';
- Environment environment;
- SubGraph subGraph;
-
- final Map<HInstruction, Environment> capturedEnvironments;
-
- SsaTypeGuardBuilder(Compiler this.compiler, WorkItem this.work)
- : capturedEnvironments = new Map<HInstruction, Environment>();
-
-
- void visitGraph(HGraph graph) {
- subGraph = new SubGraph(graph.entry, graph.exit);
- environment = new Environment();
- visitBasicBlock(graph.entry);
- if (!environment.isEmpty()) {
- compiler.internalError('Bailout environment computation',
- node: compiler.currentElement.parseNode(compiler));
- }
- insertCapturedEnvironments();
- }
-
- void maybeCaptureEnvironment(HInstruction instruction) {
- if (shouldCaptureEnvironment(instruction)) {
- capturedEnvironments[instruction] = new Environment.from(environment);
- }
- }
-
- void visitSubGraph(SubGraph newSubGraph) {
- SubGraph oldSubGraph = subGraph;
- subGraph = newSubGraph;
- visitBasicBlock(subGraph.start);
- subGraph = oldSubGraph;
- }
-
- void visitBasicBlock(HBasicBlock block) {
- if (!subGraph.contains(block)) return;
- block.last.accept(this);
-
- HInstruction instruction = block.last.previous;
- while (instruction != null) {
- HInstruction previous = instruction.previous;
- instruction.accept(this);
- instruction = previous;
- }
-
- for (HPhi phi = block.phis.first; phi != null; phi = phi.next) {
- phi.accept(this);
- }
-
- if (block.isLoopHeader()) {
- // If the block is a loop header, we need to change every uses
- // of its loop marker to the current set of live instructions.
- // For example with the following loop (read the example in
- // reverse):
- //
- // while (true) { <-- (4) update the marker with the environment
- // use(x); <-- (3) environment = {x}
- // bailout; <-- (2) has the marker when computed
- // } <-- (1) create a loop marker
- //
- // The bailout instruction first captures the marker, but it
- // will be replaced by the live environment at the loop entry,
- // in this case {x}.
- environment.removeLoopMarker(block);
- capturedEnvironments.forEach((instruction, env) {
- if (env.containsLoopMarker(block)) {
- env.removeLoopMarker(block);
- env.addAll(environment);
- }
- });
- }
- }
-
- void visitPhi(HPhi phi) {
- maybeCaptureEnvironment(phi);
- environment.remove(phi);
- // If the block is a loop header, we insert the incoming values of
- // the phis, and remove the loop values.
- // If the block is not a loop header, the phi will be handled by
- // the control flow instruction.
- if (phi.block.isLoopHeader()) {
- environment.add(phi.inputs[0]);
- for (int i = 1, len = phi.inputs.length; i < len; i++) {
- environment.remove(phi.inputs[i]);
- }
- }
- }
-
- void visitInstruction(HInstruction instruction) {
- maybeCaptureEnvironment(instruction);
- environment.remove(instruction);
- for (int i = 0, len = instruction.inputs.length; i < len; i++) {
- environment.add(instruction.inputs[i]);
- }
- }
-
- void visitIf(HIf instruction) {
- HIfBlockInformation info = instruction.blockInformation;
- HBasicBlock joinBlock = info.joinBlock;
-
- if (joinBlock != null) {
- visitBasicBlock(joinBlock);
- }
- Environment thenEnvironment = new Environment.from(environment);
- Environment elseEnvironment = environment;
-
- if (joinBlock != null) {
- for (HPhi phi = joinBlock.phis.first; phi != null; phi = phi.next) {
- if (joinBlock.predecessors[0] == instruction.block) {
- // We're dealing with an 'if' without an else branch.
- thenEnvironment.add(phi.inputs[1]);
- elseEnvironment.add(phi.inputs[0]);
- } else {
- thenEnvironment.add(phi.inputs[0]);
- elseEnvironment.add(phi.inputs[1]);
- }
- }
- }
-
- if (instruction.hasElse) {
- environment = elseEnvironment;
- visitSubGraph(info.elseGraph);
- elseEnvironment = environment;
- }
-
- environment = thenEnvironment;
- visitSubGraph(info.thenGraph);
- environment.addAll(elseEnvironment);
- }
-
- void visitGoto(HGoto goto) {
- HBasicBlock block = goto.block;
- if (block.successors[0].dominator != block) return;
- visitBasicBlock(block.successors[0]);
- }
-
- void visitBreak(HBreak breakInstruction) {
- compiler.unimplemented("SsaEnvironmentBuilder.visitBreak");
- }
-
- void visitLoopBranch(HLoopBranch branch) {
- HBasicBlock block = branch.block;
-
- // Visit the code after the loop.
- visitBasicBlock(block.successors[1]);
-
- Environment joinEnvironment = environment;
-
- // When visiting the loop body, we don't require the live
- // instructions after the loop body to be in the environment. They
- // will be either recomputed in the loop header, or inserted
- // with the loop marker. We still need to transfer existing loop
- // markers from the current environment, because they must be live
- // for this loop body.
- environment = new Environment.forLoopBody(environment);
-
- // Put the loop phis in the environment.
- HBasicBlock header = block.isLoopHeader() ? block : block.parentLoopHeader;
- for (HPhi phi = header.phis.first; phi != null; phi = phi.next) {
- for (int i = 1, len = phi.inputs.length; i < len; i++) {
- environment.add(phi.inputs[i]);
- }
- }
-
- // Add the loop marker
- environment.addLoopMarker(header);
-
- if (!branch.isDoWhile()) {
- assert(block.successors[0] == block.dominatedBlocks[0]);
- visitBasicBlock(block.successors[0]);
- }
-
- // We merge the environment required by the code after the loop,
- // and the code inside the loop.
- environment.addAll(joinEnvironment);
- }
-
- // Deal with all kinds of control flow instructions. In case we add
- // a new one, we will hit an internal error.
- void visitExit(HExit exit) {}
-
- void visitReturn(HReturn instruction) {
- environment.clear();
- visitInstruction(instruction);
- }
-
- void visitThrow(HThrow instruction) {
- environment.clear();
- visitInstruction(instruction);
- }
-
- void visitControlFlow(HControlFlow instruction) {
- compiler.internalError('Control flow instructions already dealt with.',
- instruction: instruction);
- }
-
- bool shouldCaptureEnvironment(HInstruction instruction) {
- return instruction.type.isKnown() && !instruction.hasExpectedType();
- }
-
- void insertCapturedEnvironments() {
- work.guards = <HTypeGuard>[];
- int state = 1;
- capturedEnvironments.forEach((HInstruction instruction, Environment env) {
- List<HInstruction> inputs = env.buildAndSetLast(instruction);
- HTypeGuard guard = new HTypeGuard(state++, inputs);
- work.guards.add(guard);
- instruction.block.rewrite(instruction, guard);
- HInstruction insertionPoint = (instruction is HPhi)
- ? instruction.block.first
- : instruction.next;
- insertionPoint.block.addBefore(insertionPoint, guard);
- });
- }
-}
-
-/**
- * Propagates bailout information to blocks that need it. This visitor
- * is run before codegen, to know which blocks have to deal with
- * bailouts.
- */
-class SsaBailoutPropagator extends HBaseVisitor {
- final Compiler compiler;
- final List<HBasicBlock> blocks;
-
- SsaBailoutPropagator(Compiler this.compiler) : blocks = <HBasicBlock>[];
-
- void visitGraph(HGraph graph) {
- blocks.addLast(graph.entry);
- visitBasicBlock(graph.entry);
- }
-
- void visitBasicBlock(HBasicBlock block) {
- if (block.isLoopHeader()) blocks.addLast(block);
- HInstruction instruction = block.first;
- while (instruction != null) {
- instruction.accept(this);
- instruction = instruction.next;
- }
- }
-
- void enterBlock(HBasicBlock block) {
- if (block == null) return;
- blocks.addLast(block);
- visitBasicBlock(block);
- blocks.removeLast();
- }
-
- void visitIf(HIf instruction) {
- enterBlock(instruction.thenBlock);
- enterBlock(instruction.elseBlock);
- enterBlock(instruction.joinBlock);
- }
-
- void visitGoto(HGoto goto) {
- HBasicBlock block = goto.block;
- if (block.successors[0].dominator != block) return;
- visitBasicBlock(block.successors[0]);
- }
-
- void visitLoopBranch(HLoopBranch branch) {
- HBasicBlock branchBlock = branch.block;
- if (!branch.isDoWhile()) {
- // Not a do while loop. We visit the body of the loop.
- visitBasicBlock(branchBlock.dominatedBlocks[0]);
- }
- blocks.removeLast();
- visitBasicBlock(branchBlock.successors[1]);
- }
-
- // Deal with all kinds of control flow instructions. In case we add
- // a new one, we will hit an internal error.
- void visitExit(HExit exit) {}
- void visitReturn(HReturn instruction) {}
- void visitThrow(HThrow instruction) {}
-
- void visitControlFlow(HControlFlow instruction) {
- compiler.internalError('Control flow instructions already dealt with.',
- instruction: instruction);
- }
-
- visitTypeGuard(HTypeGuard guard) {
- blocks.forEach((HBasicBlock block) {
- block.guards.add(guard);
- });
- }
-}
« no previous file with comments | « frog/leg/source_file.dart ('k') | frog/leg/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698