1*9880d681SAndroid Build Coastguard Worker //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file implements an allocation order for virtual registers. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker // The preferred allocation order for a virtual register depends on allocation 13*9880d681SAndroid Build Coastguard Worker // hints and target hooks. The AllocationOrder class encapsulates all of that. 14*9880d681SAndroid Build Coastguard Worker // 15*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H 18*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/ArrayRef.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h" 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker namespace llvm { 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker class RegisterClassInfo; 26*9880d681SAndroid Build Coastguard Worker class VirtRegMap; 27*9880d681SAndroid Build Coastguard Worker class LiveRegMatrix; 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker class LLVM_LIBRARY_VISIBILITY AllocationOrder { 30*9880d681SAndroid Build Coastguard Worker SmallVector<MCPhysReg, 16> Hints; 31*9880d681SAndroid Build Coastguard Worker ArrayRef<MCPhysReg> Order; 32*9880d681SAndroid Build Coastguard Worker int Pos; 33*9880d681SAndroid Build Coastguard Worker 34*9880d681SAndroid Build Coastguard Worker public: 35*9880d681SAndroid Build Coastguard Worker /// Create a new AllocationOrder for VirtReg. 36*9880d681SAndroid Build Coastguard Worker /// @param VirtReg Virtual register to allocate for. 37*9880d681SAndroid Build Coastguard Worker /// @param VRM Virtual register map for function. 38*9880d681SAndroid Build Coastguard Worker /// @param RegClassInfo Information about reserved and allocatable registers. 39*9880d681SAndroid Build Coastguard Worker AllocationOrder(unsigned VirtReg, 40*9880d681SAndroid Build Coastguard Worker const VirtRegMap &VRM, 41*9880d681SAndroid Build Coastguard Worker const RegisterClassInfo &RegClassInfo, 42*9880d681SAndroid Build Coastguard Worker const LiveRegMatrix *Matrix); 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker /// Get the allocation order without reordered hints. getOrder()45*9880d681SAndroid Build Coastguard Worker ArrayRef<MCPhysReg> getOrder() const { return Order; } 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker /// Return the next physical register in the allocation order, or 0. 48*9880d681SAndroid Build Coastguard Worker /// It is safe to call next() again after it returned 0, it will keep 49*9880d681SAndroid Build Coastguard Worker /// returning 0 until rewind() is called. 50*9880d681SAndroid Build Coastguard Worker unsigned next(unsigned Limit = 0) { 51*9880d681SAndroid Build Coastguard Worker if (Pos < 0) 52*9880d681SAndroid Build Coastguard Worker return Hints.end()[Pos++]; 53*9880d681SAndroid Build Coastguard Worker if (!Limit) 54*9880d681SAndroid Build Coastguard Worker Limit = Order.size(); 55*9880d681SAndroid Build Coastguard Worker while (Pos < int(Limit)) { 56*9880d681SAndroid Build Coastguard Worker unsigned Reg = Order[Pos++]; 57*9880d681SAndroid Build Coastguard Worker if (!isHint(Reg)) 58*9880d681SAndroid Build Coastguard Worker return Reg; 59*9880d681SAndroid Build Coastguard Worker } 60*9880d681SAndroid Build Coastguard Worker return 0; 61*9880d681SAndroid Build Coastguard Worker } 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker /// As next(), but allow duplicates to be returned, and stop before the 64*9880d681SAndroid Build Coastguard Worker /// Limit'th register in the RegisterClassInfo allocation order. 65*9880d681SAndroid Build Coastguard Worker /// 66*9880d681SAndroid Build Coastguard Worker /// This can produce more than Limit registers if there are hints. nextWithDups(unsigned Limit)67*9880d681SAndroid Build Coastguard Worker unsigned nextWithDups(unsigned Limit) { 68*9880d681SAndroid Build Coastguard Worker if (Pos < 0) 69*9880d681SAndroid Build Coastguard Worker return Hints.end()[Pos++]; 70*9880d681SAndroid Build Coastguard Worker if (Pos < int(Limit)) 71*9880d681SAndroid Build Coastguard Worker return Order[Pos++]; 72*9880d681SAndroid Build Coastguard Worker return 0; 73*9880d681SAndroid Build Coastguard Worker } 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker /// Start over from the beginning. rewind()76*9880d681SAndroid Build Coastguard Worker void rewind() { Pos = -int(Hints.size()); } 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker /// Return true if the last register returned from next() was a preferred register. isHint()79*9880d681SAndroid Build Coastguard Worker bool isHint() const { return Pos <= 0; } 80*9880d681SAndroid Build Coastguard Worker 81*9880d681SAndroid Build Coastguard Worker /// Return true if PhysReg is a preferred register. isHint(unsigned PhysReg)82*9880d681SAndroid Build Coastguard Worker bool isHint(unsigned PhysReg) const { 83*9880d681SAndroid Build Coastguard Worker return std::find(Hints.begin(), Hints.end(), PhysReg) != Hints.end(); 84*9880d681SAndroid Build Coastguard Worker } 85*9880d681SAndroid Build Coastguard Worker }; 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker #endif 90