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