diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 | 
| commit | 6b943ff3a3f8617113ecbf611cf0f8957e4e19d2 (patch) | |
| tree | fc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /lib/CodeGen/InterferenceCache.h | |
| parent | d0e4e96dc17a6c1c6de3340842c80f0e187ba349 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/InterferenceCache.h')
| -rw-r--r-- | lib/CodeGen/InterferenceCache.h | 163 | 
1 files changed, 163 insertions, 0 deletions
diff --git a/lib/CodeGen/InterferenceCache.h b/lib/CodeGen/InterferenceCache.h new file mode 100644 index 000000000000..6c36fa4021fb --- /dev/null +++ b/lib/CodeGen/InterferenceCache.h @@ -0,0 +1,163 @@ +//===-- InterferenceCache.h - Caching per-block interference ---*- C++ -*--===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// InterferenceCache remembers per-block interference in LiveIntervalUnions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_INTERFERENCECACHE +#define LLVM_CODEGEN_INTERFERENCECACHE + +#include "LiveIntervalUnion.h" + +namespace llvm { + +class InterferenceCache { +  const TargetRegisterInfo *TRI; +  LiveIntervalUnion *LIUArray; +  SlotIndexes *Indexes; +  MachineFunction *MF; + +  /// BlockInterference - information about the interference in a single basic +  /// block. +  struct BlockInterference { +    BlockInterference() : Tag(0) {} +    unsigned Tag; +    SlotIndex First; +    SlotIndex Last; +  }; + +  /// Entry - A cache entry containing interference information for all aliases +  /// of PhysReg in all basic blocks. +  class Entry { +    /// PhysReg - The register currently represented. +    unsigned PhysReg; + +    /// Tag - Cache tag is changed when any of the underlying LiveIntervalUnions +    /// change. +    unsigned Tag; + +    /// MF - The current function. +    MachineFunction *MF; + +    /// Indexes - Mapping block numbers to SlotIndex ranges. +    SlotIndexes *Indexes; + +    /// PrevPos - The previous position the iterators were moved to. +    SlotIndex PrevPos; + +    /// AliasTags - A LiveIntervalUnion pointer and tag for each alias of +    /// PhysReg. +    SmallVector<std::pair<LiveIntervalUnion*, unsigned>, 8> Aliases; + +    typedef LiveIntervalUnion::SegmentIter Iter; + +    /// Iters - an iterator for each alias +    SmallVector<Iter, 8> Iters; + +    /// Blocks - Interference for each block in the function. +    SmallVector<BlockInterference, 8> Blocks; + +    /// update - Recompute Blocks[MBBNum] +    void update(unsigned MBBNum); + +  public: +    Entry() : PhysReg(0), Tag(0), Indexes(0) {} + +    void clear(MachineFunction *mf, SlotIndexes *indexes) { +      PhysReg = 0; +      MF = mf; +      Indexes = indexes; +    } + +    unsigned getPhysReg() const { return PhysReg; } + +    void revalidate(); + +    /// valid - Return true if this is a valid entry for physReg. +    bool valid(LiveIntervalUnion *LIUArray, const TargetRegisterInfo *TRI); + +    /// reset - Initialize entry to represent physReg's aliases. +    void reset(unsigned physReg, +               LiveIntervalUnion *LIUArray, +               const TargetRegisterInfo *TRI, +               const MachineFunction *MF); + +    /// get - Return an up to date BlockInterference. +    BlockInterference *get(unsigned MBBNum) { +      if (Blocks[MBBNum].Tag != Tag) +        update(MBBNum); +      return &Blocks[MBBNum]; +    } +  }; + +  // We don't keep a cache entry for every physical register, that would use too +  // much memory. Instead, a fixed number of cache entries are used in a round- +  // robin manner. +  enum { CacheEntries = 32 }; + +  // Point to an entry for each physreg. The entry pointed to may not be up to +  // date, and it may have been reused for a different physreg. +  SmallVector<unsigned char, 2> PhysRegEntries; + +  // Next round-robin entry to be picked. +  unsigned RoundRobin; + +  // The actual cache entries. +  Entry Entries[CacheEntries]; + +  // get - Get a valid entry for PhysReg. +  Entry *get(unsigned PhysReg); + +public: +  InterferenceCache() : TRI(0), LIUArray(0), Indexes(0), MF(0), RoundRobin(0) {} + +  /// init - Prepare cache for a new function. +  void init(MachineFunction*, LiveIntervalUnion*, SlotIndexes*, +            const TargetRegisterInfo *); + +  /// Cursor - The primary query interface for the block interference cache. +  class Cursor { +    Entry *CacheEntry; +    BlockInterference *Current; +  public: +    /// Cursor - Create a cursor for the interference allocated to PhysReg and +    /// all its aliases. +    Cursor(InterferenceCache &Cache, unsigned PhysReg) +      : CacheEntry(Cache.get(PhysReg)), Current(0) {} + +    /// moveTo - Move cursor to basic block MBBNum. +    void moveToBlock(unsigned MBBNum) { +      Current = CacheEntry->get(MBBNum); +    } + +    /// hasInterference - Return true if the current block has any interference. +    bool hasInterference() { +      return Current->First.isValid(); +    } + +    /// first - Return the starting index of the first interfering range in the +    /// current block. +    SlotIndex first() { +      return Current->First; +    } + +    /// last - Return the ending index of the last interfering range in the +    /// current block. +    SlotIndex last() { +      return Current->Last; +    } +  }; + +  friend class Cursor; +}; + +} // namespace llvm + +#endif  | 
