summaryrefslogtreecommitdiff
path: root/compiler/optimizing/parallel_move_resolver.cc
diff options
context:
space:
mode:
author Mark Mendell <mark.p.mendell@intel.com> 2015-07-28 17:26:55 -0400
committer Mark Mendell <mark.p.mendell@intel.com> 2015-07-28 17:26:55 -0400
commit6e18dcb5d2c35c646f2c95cb776abb79799f52ae (patch)
tree7db4912d4d10f465a162dc93be717526dbb075c4 /compiler/optimizing/parallel_move_resolver.cc
parent595335100a947693b9af5fb6c0b5b3c1f0b91788 (diff)
Parallel Move Resolver: Perform Stack/Stack first
On machines like x86, by the time other parallel moves are done, there may be no free registers available to move/swap without having to save and restore a register. To avoid this, perform stack/stack first, while there is a good chance that there is a destination register that we can use. On the X86, this avoids a lot of push eax/pop eax code. Change-Id: I57076271b5672c931a93888ff23e30b2567f43b8 Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/optimizing/parallel_move_resolver.cc')
-rw-r--r--compiler/optimizing/parallel_move_resolver.cc14
1 files changed, 14 insertions, 0 deletions
diff --git a/compiler/optimizing/parallel_move_resolver.cc b/compiler/optimizing/parallel_move_resolver.cc
index 54ea6f19d4..f9d812f6a6 100644
--- a/compiler/optimizing/parallel_move_resolver.cc
+++ b/compiler/optimizing/parallel_move_resolver.cc
@@ -38,6 +38,20 @@ void ParallelMoveResolverWithSwap::EmitNativeCode(HParallelMove* parallel_move)
// Build up a worklist of moves.
BuildInitialMoveList(parallel_move);
+ // Move stack/stack slot to take advantage of a free register on constrained machines.
+ for (size_t i = 0; i < moves_.Size(); ++i) {
+ const MoveOperands& move = *moves_.Get(i);
+ // Ignore constants and moves already eliminated.
+ if (move.IsEliminated() || move.GetSource().IsConstant()) {
+ continue;
+ }
+
+ if ((move.GetSource().IsStackSlot() || move.GetSource().IsDoubleStackSlot()) &&
+ (move.GetDestination().IsStackSlot() || move.GetDestination().IsDoubleStackSlot())) {
+ PerformMove(i);
+ }
+ }
+
for (size_t i = 0; i < moves_.Size(); ++i) {
const MoveOperands& move = *moves_.Get(i);
// Skip constants to perform them last. They don't block other moves