1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_ 18 #define ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_ 19 20 #include "utils/allocation.h" 21 #include "utils/growable_array.h" 22 23 namespace art { 24 25 class HParallelMove; 26 class Location; 27 class MoveOperands; 28 29 /** 30 * Helper class to resolve a set of parallel moves. Architecture dependent code 31 * generator must have their own subclass that implements the `EmitMove` and `EmitSwap` 32 * operations. 33 */ 34 class ParallelMoveResolver : public ValueObject { 35 public: ParallelMoveResolver(ArenaAllocator * allocator)36 explicit ParallelMoveResolver(ArenaAllocator* allocator) : moves_(allocator, 32) {} ~ParallelMoveResolver()37 virtual ~ParallelMoveResolver() {} 38 39 // Resolve a set of parallel moves, emitting assembler instructions. 40 void EmitNativeCode(HParallelMove* parallel_move); 41 42 protected: 43 class ScratchRegisterScope : public ValueObject { 44 public: 45 ScratchRegisterScope(ParallelMoveResolver* resolver, 46 int blocked, 47 int if_scratch, 48 int number_of_registers); 49 ~ScratchRegisterScope(); 50 GetRegister()51 int GetRegister() const { return reg_; } IsSpilled()52 bool IsSpilled() const { return spilled_; } 53 54 private: 55 ParallelMoveResolver* resolver_; 56 int reg_; 57 bool spilled_; 58 }; 59 60 bool IsScratchLocation(Location loc); 61 int AllocateScratchRegister(int blocked, int if_scratch, int register_count, bool* spilled); 62 63 // Emit a move. 64 virtual void EmitMove(size_t index) = 0; 65 66 // Execute a move by emitting a swap of two operands. 67 virtual void EmitSwap(size_t index) = 0; 68 69 virtual void SpillScratch(int reg) = 0; 70 virtual void RestoreScratch(int reg) = 0; 71 72 // List of moves not yet resolved. 73 GrowableArray<MoveOperands*> moves_; 74 75 static constexpr int kNoRegister = -1; 76 77 private: 78 // Build the initial list of moves. 79 void BuildInitialMoveList(HParallelMove* parallel_move); 80 81 // Perform the move at the moves_ index in question (possibly requiring 82 // other moves to satisfy dependencies). 83 void PerformMove(size_t index); 84 85 DISALLOW_COPY_AND_ASSIGN(ParallelMoveResolver); 86 }; 87 88 } // namespace art 89 90 #endif // ART_COMPILER_OPTIMIZING_PARALLEL_MOVE_RESOLVER_H_ 91