OLD | NEW |
(Empty) | |
| 1 //===- subzero/src/IceDefs.h - Common Subzero declaraions -------*- C++ -*-===// |
| 2 // |
| 3 // The Subzero Code Generator |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // This file declares various useful types and classes that have |
| 11 // widespread use across Subzero. Every Subzero source file is |
| 12 // expected to include IceDefs.h. |
| 13 // |
| 14 //===----------------------------------------------------------------------===// |
| 15 |
| 16 #ifndef SUBZERO_SRC_ICEDEFS_H |
| 17 #define SUBZERO_SRC_ICEDEFS_H |
| 18 |
| 19 #include <assert.h> |
| 20 #include <stdint.h> |
| 21 #include <stdio.h> // sprintf |
| 22 |
| 23 #include <list> |
| 24 #include <map> |
| 25 #include <set> |
| 26 #include <string> |
| 27 #include <vector> |
| 28 |
| 29 #include "llvm/ADT/BitVector.h" |
| 30 #include "llvm/ADT/SmallBitVector.h" |
| 31 #include "llvm/Support/Casting.h" |
| 32 #include "llvm/Support/raw_ostream.h" |
| 33 #include "llvm/Support/Timer.h" |
| 34 |
| 35 class IceCfg; |
| 36 class IceCfgNode; |
| 37 class IceConstant; |
| 38 class IceInst; |
| 39 class IceInstPhi; |
| 40 class IceInstTarget; |
| 41 class IceOperand; |
| 42 class IceVariable; |
| 43 |
| 44 // TODO: Switch over to LLVM's ADT container classes. |
| 45 // http://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-
for-a-task |
| 46 typedef std::string IceString; |
| 47 typedef std::list<IceInst *> IceInstList; |
| 48 typedef std::list<IceInstPhi *> IcePhiList; |
| 49 typedef std::vector<IceOperand *> IceOpList; |
| 50 typedef std::vector<IceVariable *> IceVarList; |
| 51 typedef std::vector<IceCfgNode *> IceNodeList; |
| 52 |
| 53 // This is a convenience templated class that provides a mapping |
| 54 // between a parameterized type and small unsigned integers. |
| 55 template <typename T> class IceValueTranslation { |
| 56 public: |
| 57 typedef typename std::map<const T, uint32_t> ContainerType; |
| 58 IceValueTranslation() {} |
| 59 void clear() { Entries.clear(); } |
| 60 uint32_t translate(const T &Value) { |
| 61 typename ContainerType::const_iterator Iter = Entries.find(Value); |
| 62 if (Iter != Entries.end()) |
| 63 return Iter->second; |
| 64 uint32_t Index = Entries.size(); |
| 65 Entries[Value] = Index; |
| 66 return Index; |
| 67 } |
| 68 |
| 69 private: |
| 70 ContainerType Entries; |
| 71 }; |
| 72 |
| 73 enum IceVerbose { |
| 74 IceV_None = 0, |
| 75 IceV_Instructions = 1 << 0, |
| 76 IceV_Deleted = 1 << 1, |
| 77 IceV_InstNumbers = 1 << 2, |
| 78 IceV_Preds = 1 << 3, |
| 79 IceV_Succs = 1 << 4, |
| 80 IceV_Liveness = 1 << 5, |
| 81 IceV_RegManager = 1 << 6, |
| 82 IceV_RegOrigins = 1 << 7, |
| 83 IceV_LinearScan = 1 << 8, |
| 84 IceV_Frame = 1 << 9, |
| 85 IceV_Timing = 1 << 10, |
| 86 IceV_All = ~IceV_None |
| 87 }; |
| 88 typedef uint32_t IceVerboseMask; |
| 89 |
| 90 // The IceOstream class wraps an output stream and an IceCfg pointer, |
| 91 // so that dump routines have access to the IceCfg object and can |
| 92 // print labels and variable names. |
| 93 |
| 94 class IceOstream { |
| 95 public: |
| 96 IceOstream(IceCfg *Cfg) |
| 97 : Stream(NULL), Cfg(Cfg), Verbose(IceV_Instructions | IceV_Preds), |
| 98 CurrentNode(NULL) {} |
| 99 |
| 100 // Returns true if any of the specified options in the verbose mask |
| 101 // are set. If the argument is omitted, it checks if any verbose |
| 102 // options at all are set. IceV_Timing is treated specially, so |
| 103 // that running with just IceV_Timing verbosity doesn't trigger an |
| 104 // avalanche of extra output. |
| 105 bool isVerbose(IceVerboseMask Mask = (IceV_All & ~IceV_Timing)) { |
| 106 return Verbose & Mask; |
| 107 } |
| 108 void setVerbose(IceVerboseMask Mask) { Verbose = Mask; } |
| 109 void addVerbose(IceVerboseMask Mask) { Verbose |= Mask; } |
| 110 void subVerbose(IceVerboseMask Mask) { Verbose &= ~Mask; } |
| 111 |
| 112 void setCurrentNode(const IceCfgNode *Node) { CurrentNode = Node; } |
| 113 const IceCfgNode *getCurrentNode() const { return CurrentNode; } |
| 114 |
| 115 llvm::raw_ostream *Stream; |
| 116 IceCfg *const Cfg; |
| 117 |
| 118 private: |
| 119 IceVerboseMask Verbose; |
| 120 // CurrentNode is maintained during dumping/emitting just for |
| 121 // validating IceVariable::DefNode. Normally, a traversal over |
| 122 // IceCfgNodes maintains this, but before global operations like |
| 123 // register allocation, setCurrentNode(NULL) should be called to |
| 124 // avoid spurious validation failures. |
| 125 const IceCfgNode *CurrentNode; |
| 126 }; |
| 127 |
| 128 inline IceOstream &operator<<(IceOstream &Str, const char *S) { |
| 129 if (Str.Stream) |
| 130 *(Str.Stream) << S; |
| 131 return Str; |
| 132 } |
| 133 |
| 134 inline IceOstream &operator<<(IceOstream &Str, const IceString &S) { |
| 135 if (Str.Stream) |
| 136 *(Str.Stream) << S; |
| 137 return Str; |
| 138 } |
| 139 |
| 140 inline IceOstream &operator<<(IceOstream &Str, uint32_t U) { |
| 141 if (Str.Stream) |
| 142 *(Str.Stream) << U; |
| 143 return Str; |
| 144 } |
| 145 |
| 146 inline IceOstream &operator<<(IceOstream &Str, int32_t I) { |
| 147 if (Str.Stream) |
| 148 *(Str.Stream) << I; |
| 149 return Str; |
| 150 } |
| 151 |
| 152 inline IceOstream &operator<<(IceOstream &Str, uint64_t U) { |
| 153 if (Str.Stream) |
| 154 *(Str.Stream) << U; |
| 155 return Str; |
| 156 } |
| 157 |
| 158 inline IceOstream &operator<<(IceOstream &Str, int64_t I) { |
| 159 if (Str.Stream) |
| 160 *(Str.Stream) << I; |
| 161 return Str; |
| 162 } |
| 163 |
| 164 inline IceOstream &operator<<(IceOstream &Str, double D) { |
| 165 if (Str.Stream) |
| 166 *(Str.Stream) << D; |
| 167 return Str; |
| 168 } |
| 169 |
| 170 class IceTimer { |
| 171 public: |
| 172 IceTimer() : Start(llvm::TimeRecord::getCurrentTime(false)) {} |
| 173 uint64_t getElapsedNs() const { return getElapsedSec() * 1000 * 1000 * 1000; } |
| 174 uint64_t getElapsedUs() const { return getElapsedSec() * 1000 * 1000; } |
| 175 uint64_t getElapsedMs() const { return getElapsedSec() * 1000; } |
| 176 double getElapsedSec() const { |
| 177 llvm::TimeRecord End = llvm::TimeRecord::getCurrentTime(false); |
| 178 return End.getWallTime() - Start.getWallTime(); |
| 179 } |
| 180 void printElapsedUs(IceOstream &Str, const IceString &Tag) const { |
| 181 if (Str.isVerbose(IceV_Timing)) { |
| 182 // Prefixing with '#' allows timing strings to be included |
| 183 // without error in textual assembly output. |
| 184 Str << "# " << getElapsedUs() << " usec " << Tag << "\n"; |
| 185 } |
| 186 } |
| 187 |
| 188 private: |
| 189 const llvm::TimeRecord Start; |
| 190 }; |
| 191 |
| 192 #endif // SUBZERO_SRC_ICEDEFS_H |
OLD | NEW |