| 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 /// \file | 10 /// \file |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 // Define a key comparison function for sorting the constant pool's | 73 // Define a key comparison function for sorting the constant pool's |
| 74 // values after they are dumped to a vector. This covers integer | 74 // values after they are dumped to a vector. This covers integer |
| 75 // types, floating point types, and ConstantRelocatable values. | 75 // types, floating point types, and ConstantRelocatable values. |
| 76 template <typename ValueType, class Enable = void> struct KeyCompareLess {}; | 76 template <typename ValueType, class Enable = void> struct KeyCompareLess {}; |
| 77 | 77 |
| 78 template <typename ValueType> | 78 template <typename ValueType> |
| 79 struct KeyCompareLess<ValueType, | 79 struct KeyCompareLess<ValueType, |
| 80 typename std::enable_if<std::is_floating_point< | 80 typename std::enable_if<std::is_floating_point< |
| 81 typename ValueType::PrimType>::value>::type> { | 81 typename ValueType::PrimType>::value>::type> { |
| 82 bool operator()(const Constant *Const1, const Constant *Const2) const { | 82 bool operator()(const Constant *Const1, const Constant *Const2) const { |
| 83 typedef uint64_t CompareType; | 83 using CompareType = uint64_t; |
| 84 static_assert(sizeof(typename ValueType::PrimType) <= sizeof(CompareType), | 84 static_assert(sizeof(typename ValueType::PrimType) <= sizeof(CompareType), |
| 85 "Expected floating-point type of width 64-bit or less"); | 85 "Expected floating-point type of width 64-bit or less"); |
| 86 typename ValueType::PrimType V1 = llvm::cast<ValueType>(Const1)->getValue(); | 86 typename ValueType::PrimType V1 = llvm::cast<ValueType>(Const1)->getValue(); |
| 87 typename ValueType::PrimType V2 = llvm::cast<ValueType>(Const2)->getValue(); | 87 typename ValueType::PrimType V2 = llvm::cast<ValueType>(Const2)->getValue(); |
| 88 // We avoid "V1<V2" because of NaN. | 88 // We avoid "V1<V2" because of NaN. |
| 89 // We avoid "memcmp(&V1,&V2,sizeof(V1))<0" which depends on the | 89 // We avoid "memcmp(&V1,&V2,sizeof(V1))<0" which depends on the |
| 90 // endian-ness of the host system running Subzero. | 90 // endian-ness of the host system running Subzero. |
| 91 // Instead, compare the result of bit_cast to uint64_t. | 91 // Instead, compare the result of bit_cast to uint64_t. |
| 92 uint64_t I1 = 0, I2 = 0; | 92 uint64_t I1 = 0, I2 = 0; |
| 93 memcpy(&I1, &V1, sizeof(V1)); | 93 memcpy(&I1, &V1, sizeof(V1)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 return Iter->second; | 132 return Iter->second; |
| 133 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); | 133 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); |
| 134 Pool[Key] = Result; | 134 Pool[Key] = Result; |
| 135 return Result; | 135 return Result; |
| 136 } | 136 } |
| 137 ConstantList getConstantPool() const { | 137 ConstantList getConstantPool() const { |
| 138 ConstantList Constants; | 138 ConstantList Constants; |
| 139 Constants.reserve(Pool.size()); | 139 Constants.reserve(Pool.size()); |
| 140 for (auto &I : Pool) | 140 for (auto &I : Pool) |
| 141 Constants.push_back(I.second); | 141 Constants.push_back(I.second); |
| 142 // The sort (and its KeyCompareLess machinery) is not strictly | 142 // The sort (and its KeyCompareLess machinery) is not strictly necessary, |
| 143 // necessary, but is desirable for producing output that is | 143 // but is desirable for producing output that is deterministic across |
| 144 // deterministic across unordered_map::iterator implementations. | 144 // unordered_map::iterator implementations. |
| 145 std::sort(Constants.begin(), Constants.end(), KeyCompareLess<ValueType>()); | 145 std::sort(Constants.begin(), Constants.end(), KeyCompareLess<ValueType>()); |
| 146 return Constants; | 146 return Constants; |
| 147 } | 147 } |
| 148 | 148 |
| 149 private: | 149 private: |
| 150 // Use the default hash function, and a custom key comparison | 150 // Use the default hash function, and a custom key comparison function. The |
| 151 // function. The key comparison function for floating point | 151 // key comparison function for floating point variables can't use the default |
| 152 // variables can't use the default == based implementation because | 152 // == based implementation because of special C++ semantics regarding +0.0, |
| 153 // of special C++ semantics regarding +0.0, -0.0, and NaN | 153 // -0.0, and NaN comparison. However, it's OK to use the default hash for |
| 154 // comparison. However, it's OK to use the default hash for | 154 // floating point values because KeyCompare is the final source of truth - in |
| 155 // floating point values because KeyCompare is the final source of | 155 // the worst case a "false" collision must be resolved. |
| 156 // truth - in the worst case a "false" collision must be resolved. | 156 using ContainerType = |
| 157 typedef std::unordered_map<KeyType, ValueType *, std::hash<KeyType>, | 157 std::unordered_map<KeyType, ValueType *, std::hash<KeyType>, |
| 158 KeyCompare<KeyType>> ContainerType; | 158 KeyCompare<KeyType>>; |
| 159 ContainerType Pool; | 159 ContainerType Pool; |
| 160 uint32_t NextPoolID = 0; | 160 uint32_t NextPoolID = 0; |
| 161 }; | 161 }; |
| 162 | 162 |
| 163 // UndefPool maps ICE types to the corresponding ConstantUndef values. | 163 // UndefPool maps ICE types to the corresponding ConstantUndef values. |
| 164 class UndefPool { | 164 class UndefPool { |
| 165 UndefPool(const UndefPool &) = delete; | 165 UndefPool(const UndefPool &) = delete; |
| 166 UndefPool &operator=(const UndefPool &) = delete; | 166 UndefPool &operator=(const UndefPool &) = delete; |
| 167 | 167 |
| 168 public: | 168 public: |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 Ctx = Func->getContext(); | 1012 Ctx = Func->getContext(); |
| 1013 Active = | 1013 Active = |
| 1014 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 1014 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 1015 if (Active) | 1015 if (Active) |
| 1016 Ctx->pushTimer(ID, StackID); | 1016 Ctx->pushTimer(ID, StackID); |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 1019 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 1020 | 1020 |
| 1021 } // end of namespace Ice | 1021 } // end of namespace Ice |
| OLD | NEW |