10511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// Copyright 2011 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
40511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
50511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#ifndef V8_IA32_LITHIUM_GAP_RESOLVER_IA32_H_
60511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#define V8_IA32_LITHIUM_GAP_RESOLVER_IA32_H_
70511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
90511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium.h"
110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comnamespace v8 {
130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comnamespace internal {
140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass LCodeGen;
160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass LGapResolver;
170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
18ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass LGapResolver FINAL BASE_EMBEDDED {
190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public:
200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  explicit LGapResolver(LCodeGen* owner);
210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Resolve a set of parallel moves, emitting assembler instructions.
230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void Resolve(LParallelMove* parallel_move);
240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private:
260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Build the initial list of moves.
270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void BuildInitialMoveList(LParallelMove* parallel_move);
280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Perform the move at the moves_ index in question (possibly requiring
300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // other moves to satisfy dependencies).
310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void PerformMove(int index);
320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Emit any code necessary at the end of a gap move.
340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void Finish();
350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Add or delete a move from the move graph without emitting any code.
370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Used to build up the graph and remove trivial moves.
380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void AddMove(LMoveOperands move);
390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void RemoveMove(int index);
400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Report the count of uses of operand as a source in a not-yet-performed
420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // move.  Used to rebuild use counts.
430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int CountSourceUses(LOperand* operand);
440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Emit a move and remove it from the move graph.
460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void EmitMove(int index);
470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Execute a move by emitting a swap of two operands.  The move from
490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // source to destination is removed from the move graph.
500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void EmitSwap(int index);
510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Ensure that the given operand is not spilled.
530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void EnsureRestored(LOperand* operand);
540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Return a register that can be used as a temp register, spilling
560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // something if necessary.
570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Register EnsureTempRegister();
580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Return a known free register different from the given one (which could
600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // be no_reg---returning any free register), or no_reg if there is no such
610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // register.
620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  Register GetFreeRegisterNot(Register reg);
630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Verify that the state is the initial one, ready to resolve a single
650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // parallel move.
660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  bool HasBeenReset();
670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Verify the move list before performing moves.
690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  void Verify();
700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  LCodeGen* cgen_;
720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // List of moves not yet resolved.
740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  ZoneList<LMoveOperands> moves_;
750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // Source and destination use counts for the general purpose registers.
77a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int source_uses_[Register::kMaxNumAllocatableRegisters];
78a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  int destination_uses_[Register::kMaxNumAllocatableRegisters];
790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // If we had to spill on demand, the currently spilled register's
810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  // allocation index.
820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com  int spilled_register_;
830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com};
840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} }  // namespace v8::internal
860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif  // V8_IA32_LITHIUM_GAP_RESOLVER_IA32_H_
88