LLVM API Documentation

AllocationOrder.h
Go to the documentation of this file.
00001 //===-- llvm/CodeGen/AllocationOrder.h - Allocation Order -*- C++ -*-------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements an allocation order for virtual registers.
00011 //
00012 // The preferred allocation order for a virtual register depends on allocation
00013 // hints and target hooks. The AllocationOrder class encapsulates all of that.
00014 //
00015 //===----------------------------------------------------------------------===//
00016 
00017 #ifndef LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
00018 #define LLVM_LIB_CODEGEN_ALLOCATIONORDER_H
00019 
00020 #include "llvm/ADT/ArrayRef.h"
00021 #include "llvm/MC/MCRegisterInfo.h"
00022 
00023 namespace llvm {
00024 
00025 class RegisterClassInfo;
00026 class VirtRegMap;
00027 
00028 class AllocationOrder {
00029   SmallVector<MCPhysReg, 16> Hints;
00030   ArrayRef<MCPhysReg> Order;
00031   int Pos;
00032 
00033 public:
00034   /// Create a new AllocationOrder for VirtReg.
00035   /// @param VirtReg      Virtual register to allocate for.
00036   /// @param VRM          Virtual register map for function.
00037   /// @param RegClassInfo Information about reserved and allocatable registers.
00038   AllocationOrder(unsigned VirtReg,
00039                   const VirtRegMap &VRM,
00040                   const RegisterClassInfo &RegClassInfo);
00041 
00042   /// Get the allocation order without reordered hints.
00043   ArrayRef<MCPhysReg> getOrder() const { return Order; }
00044 
00045   /// Return the next physical register in the allocation order, or 0.
00046   /// It is safe to call next() again after it returned 0, it will keep
00047   /// returning 0 until rewind() is called.
00048   unsigned next(unsigned Limit = 0) {
00049     if (Pos < 0)
00050       return Hints.end()[Pos++];
00051     if (!Limit)
00052       Limit = Order.size();
00053     while (Pos < int(Limit)) {
00054       unsigned Reg = Order[Pos++];
00055       if (!isHint(Reg))
00056         return Reg;
00057     }
00058     return 0;
00059   }
00060 
00061   /// As next(), but allow duplicates to be returned, and stop before the
00062   /// Limit'th register in the RegisterClassInfo allocation order.
00063   ///
00064   /// This can produce more than Limit registers if there are hints.
00065   unsigned nextWithDups(unsigned Limit) {
00066     if (Pos < 0)
00067       return Hints.end()[Pos++];
00068     if (Pos < int(Limit))
00069       return Order[Pos++];
00070     return 0;
00071   }
00072 
00073   /// Start over from the beginning.
00074   void rewind() { Pos = -int(Hints.size()); }
00075 
00076   /// Return true if the last register returned from next() was a preferred register.
00077   bool isHint() const { return Pos <= 0; }
00078 
00079   /// Return true if PhysReg is a preferred register.
00080   bool isHint(unsigned PhysReg) const {
00081     return std::find(Hints.begin(), Hints.end(), PhysReg) != Hints.end();
00082   }
00083 };
00084 
00085 } // end namespace llvm
00086 
00087 #endif