| OLD | NEW |
| 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// | 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines aspects of the compilation that persist across | 10 // This file defines aspects of the compilation that persist across |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 template <> struct hash<Ice::RelocatableTuple> { | 33 template <> struct hash<Ice::RelocatableTuple> { |
| 34 size_t operator()(const Ice::RelocatableTuple &Key) const { | 34 size_t operator()(const Ice::RelocatableTuple &Key) const { |
| 35 return hash<Ice::IceString>()(Key.Name) + | 35 return hash<Ice::IceString>()(Key.Name) + |
| 36 hash<Ice::RelocOffsetT>()(Key.Offset); | 36 hash<Ice::RelocOffsetT>()(Key.Offset); |
| 37 } | 37 } |
| 38 }; | 38 }; |
| 39 } // end of namespace std | 39 } // end of namespace std |
| 40 | 40 |
| 41 namespace Ice { | 41 namespace Ice { |
| 42 | 42 |
| 43 namespace { |
| 44 |
| 45 // Define the key comparison function for the constant pool's |
| 46 // unordered_map, but only for key types of interest: integer types, |
| 47 // floating point types, and the special RelocatableTuple. |
| 48 template <typename KeyType, class Enable = void> struct KeyCompare {}; |
| 49 |
| 50 template <typename KeyType> |
| 51 struct KeyCompare<KeyType, |
| 52 typename std::enable_if< |
| 53 std::is_integral<KeyType>::value || |
| 54 std::is_same<KeyType, RelocatableTuple>::value>::type> { |
| 55 bool operator()(const KeyType &Value1, const KeyType &Value2) const { |
| 56 return Value1 == Value2; |
| 57 } |
| 58 }; |
| 59 template <typename KeyType> |
| 60 struct KeyCompare<KeyType, typename std::enable_if< |
| 61 std::is_floating_point<KeyType>::value>::type> { |
| 62 bool operator()(const KeyType &Value1, const KeyType &Value2) const { |
| 63 return !memcmp(&Value1, &Value2, sizeof(KeyType)); |
| 64 } |
| 65 }; |
| 66 |
| 43 // TypePool maps constants of type KeyType (e.g. float) to pointers to | 67 // TypePool maps constants of type KeyType (e.g. float) to pointers to |
| 44 // type ValueType (e.g. ConstantFloat). | 68 // type ValueType (e.g. ConstantFloat). |
| 45 template <Type Ty, typename KeyType, typename ValueType> class TypePool { | 69 template <Type Ty, typename KeyType, typename ValueType> class TypePool { |
| 46 TypePool(const TypePool &) = delete; | 70 TypePool(const TypePool &) = delete; |
| 47 TypePool &operator=(const TypePool &) = delete; | 71 TypePool &operator=(const TypePool &) = delete; |
| 48 | 72 |
| 49 public: | 73 public: |
| 50 TypePool() : NextPoolID(0) {} | 74 TypePool() : NextPoolID(0) {} |
| 51 ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) { | 75 ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) { |
| 52 auto Iter = Pool.find(Key); | 76 auto Iter = Pool.find(Key); |
| 53 if (Iter != Pool.end()) | 77 if (Iter != Pool.end()) |
| 54 return Iter->second; | 78 return Iter->second; |
| 55 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); | 79 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); |
| 56 Pool[Key] = Result; | 80 Pool[Key] = Result; |
| 57 return Result; | 81 return Result; |
| 58 } | 82 } |
| 59 ConstantList getConstantPool() const { | 83 ConstantList getConstantPool() const { |
| 60 ConstantList Constants; | 84 ConstantList Constants; |
| 61 Constants.reserve(Pool.size()); | 85 Constants.reserve(Pool.size()); |
| 62 for (auto &I : Pool) | 86 for (auto &I : Pool) |
| 63 Constants.push_back(I.second); | 87 Constants.push_back(I.second); |
| 64 return Constants; | 88 return Constants; |
| 65 } | 89 } |
| 66 | 90 |
| 67 private: | 91 private: |
| 68 typedef std::unordered_map<KeyType, ValueType *> ContainerType; | 92 // Use the default hash function, and a custom key comparison |
| 93 // function. The key comparison function for floating point |
| 94 // variables can't use the default == based implementation because |
| 95 // of special C++ semantics regarding +0.0, -0.0, and NaN |
| 96 // comparison. However, it's OK to use the default hash for |
| 97 // floating point values because KeyCompare is the final source of |
| 98 // truth - in the worst case a "false" collision must be resolved. |
| 99 typedef std::unordered_map<KeyType, ValueType *, std::hash<KeyType>, |
| 100 KeyCompare<KeyType>> ContainerType; |
| 69 ContainerType Pool; | 101 ContainerType Pool; |
| 70 uint32_t NextPoolID; | 102 uint32_t NextPoolID; |
| 71 }; | 103 }; |
| 72 | 104 |
| 73 // UndefPool maps ICE types to the corresponding ConstantUndef values. | 105 // UndefPool maps ICE types to the corresponding ConstantUndef values. |
| 74 class UndefPool { | 106 class UndefPool { |
| 75 UndefPool(const UndefPool &) = delete; | 107 UndefPool(const UndefPool &) = delete; |
| 76 UndefPool &operator=(const UndefPool &) = delete; | 108 UndefPool &operator=(const UndefPool &) = delete; |
| 77 | 109 |
| 78 public: | 110 public: |
| 79 UndefPool() : NextPoolID(0), Pool(IceType_NUM) {} | 111 UndefPool() : NextPoolID(0), Pool(IceType_NUM) {} |
| 80 | 112 |
| 81 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { | 113 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { |
| 82 if (Pool[Ty] == nullptr) | 114 if (Pool[Ty] == nullptr) |
| 83 Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++); | 115 Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++); |
| 84 return Pool[Ty]; | 116 return Pool[Ty]; |
| 85 } | 117 } |
| 86 | 118 |
| 87 private: | 119 private: |
| 88 uint32_t NextPoolID; | 120 uint32_t NextPoolID; |
| 89 std::vector<ConstantUndef *> Pool; | 121 std::vector<ConstantUndef *> Pool; |
| 90 }; | 122 }; |
| 91 | 123 |
| 124 } // end of anonymous namespace |
| 125 |
| 92 // The global constant pool bundles individual pools of each type of | 126 // The global constant pool bundles individual pools of each type of |
| 93 // interest. | 127 // interest. |
| 94 class ConstantPool { | 128 class ConstantPool { |
| 95 ConstantPool(const ConstantPool &) = delete; | 129 ConstantPool(const ConstantPool &) = delete; |
| 96 ConstantPool &operator=(const ConstantPool &) = delete; | 130 ConstantPool &operator=(const ConstantPool &) = delete; |
| 97 | 131 |
| 98 public: | 132 public: |
| 99 ConstantPool() {} | 133 ConstantPool() {} |
| 100 TypePool<IceType_f32, float, ConstantFloat> Floats; | 134 TypePool<IceType_f32, float, ConstantFloat> Floats; |
| 101 TypePool<IceType_f64, double, ConstantDouble> Doubles; | 135 TypePool<IceType_f64, double, ConstantDouble> Doubles; |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 Ctx = Func->getContext(); | 775 Ctx = Func->getContext(); |
| 742 Active = | 776 Active = |
| 743 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 777 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 744 if (Active) | 778 if (Active) |
| 745 Ctx->pushTimer(ID, StackID); | 779 Ctx->pushTimer(ID, StackID); |
| 746 } | 780 } |
| 747 | 781 |
| 748 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 782 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 749 | 783 |
| 750 } // end of namespace Ice | 784 } // end of namespace Ice |
| OLD | NEW |