Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===// | 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===// |
| 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 |
| 11 // multiple functions. | 11 // multiple functions. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #include <ctype.h> // isdigit(), isupper() | 15 #include <ctype.h> // isdigit(), isupper() |
| 16 #include <locale> // locale | 16 #include <locale> // locale |
| 17 | 17 |
| 18 #include "IceDefs.h" | 18 #include "IceDefs.h" |
| 19 #include "IceTypes.h" | 19 #include "IceTypes.h" |
| 20 #include "IceCfg.h" | 20 #include "IceCfg.h" |
| 21 #include "IceClFlags.h" | 21 #include "IceClFlags.h" |
| 22 #include "IceGlobalContext.h" | 22 #include "IceGlobalContext.h" |
| 23 #include "IceOperand.h" | 23 #include "IceOperand.h" |
| 24 #include "IceTargetLowering.h" | 24 #include "IceTargetLowering.h" |
| 25 | 25 |
| 26 namespace Ice { | 26 namespace Ice { |
| 27 | 27 |
| 28 namespace { | |
| 29 | |
| 30 template <class MapTy, class ListTy> | |
| 31 ListTy makeListOfValues(const MapTy &Pool) { | |
| 32 ListTy Values; | |
| 33 Values.reserve(Pool.size()); | |
| 34 // TODO: replace the loop with std::transform + lambdas. | |
| 35 for (typename MapTy::const_iterator I = Pool.begin(), E = Pool.end(); | |
| 36 I != E; ++I) { | |
| 37 Values.push_back(I->second); | |
| 38 } | |
| 39 return Values; | |
| 40 } | |
| 41 | |
| 42 } // end anonymous namespace | |
|
Jim Stichnoth
2014/08/13 23:30:25
"end of anonymous namespace" has more votes. :)
wala
2014/08/16 00:07:12
Done.
| |
| 43 | |
| 28 // TypePool maps constants of type KeyType (e.g. float) to pointers to | 44 // TypePool maps constants of type KeyType (e.g. float) to pointers to |
| 29 // type ValueType (e.g. ConstantFloat). KeyType values are compared | 45 // type ValueType (e.g. ConstantFloat). KeyType values are compared |
| 30 // using memcmp() because of potential NaN values in KeyType values. | 46 // using memcmp() because of potential NaN values in KeyType values. |
| 31 // KeyTypeHasFP indicates whether KeyType is a floating-point type | 47 // KeyTypeHasFP indicates whether KeyType is a floating-point type |
| 32 // whose values need to be compared using memcmp() for NaN | 48 // whose values need to be compared using memcmp() for NaN |
| 33 // correctness. TODO: use std::is_floating_point<KeyType> instead of | 49 // correctness. TODO: use std::is_floating_point<KeyType> instead of |
| 34 // KeyTypeHasFP with C++11. | 50 // KeyTypeHasFP with C++11. |
| 35 template <typename KeyType, typename ValueType, bool KeyTypeHasFP = false> | 51 template <typename KeyType, typename ValueType, bool KeyTypeHasFP = false> |
| 36 class TypePool { | 52 class TypePool { |
| 37 TypePool(const TypePool &) LLVM_DELETED_FUNCTION; | 53 TypePool(const TypePool &) LLVM_DELETED_FUNCTION; |
| 38 TypePool &operator=(const TypePool &) LLVM_DELETED_FUNCTION; | 54 TypePool &operator=(const TypePool &) LLVM_DELETED_FUNCTION; |
| 39 | 55 |
| 40 public: | 56 public: |
| 41 TypePool() : NextPoolID(0) {} | 57 TypePool() : NextPoolID(0) {} |
| 42 ValueType *getOrAdd(GlobalContext *Ctx, Type Ty, KeyType Key) { | 58 ValueType *getOrAdd(GlobalContext *Ctx, Type Ty, KeyType Key) { |
| 43 TupleType TupleKey = std::make_pair(Ty, Key); | 59 TupleType TupleKey = std::make_pair(Ty, Key); |
| 44 typename ContainerType::const_iterator Iter = Pool.find(TupleKey); | 60 typename ContainerType::const_iterator Iter = Pool.find(TupleKey); |
| 45 if (Iter != Pool.end()) | 61 if (Iter != Pool.end()) |
| 46 return Iter->second; | 62 return Iter->second; |
| 47 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); | 63 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); |
| 48 Pool[TupleKey] = Result; | 64 Pool[TupleKey] = Result; |
| 49 return Result; | 65 return Result; |
| 50 } | 66 } |
| 51 ConstantList getConstantPool() const { | 67 ConstantList getConstantPool() const { |
| 52 ConstantList Constants; | 68 return makeListOfValues<ContainerType, ConstantList>(Pool); |
| 53 Constants.reserve(Pool.size()); | |
| 54 // TODO: replace the loop with std::transform + lambdas. | |
| 55 for (typename ContainerType::const_iterator I = Pool.begin(), | |
| 56 E = Pool.end(); | |
| 57 I != E; ++I) { | |
| 58 Constants.push_back(I->second); | |
| 59 } | |
| 60 return Constants; | |
| 61 } | 69 } |
| 62 | 70 |
| 63 private: | 71 private: |
| 64 typedef std::pair<Type, KeyType> TupleType; | 72 typedef std::pair<Type, KeyType> TupleType; |
| 65 struct TupleCompare { | 73 struct TupleCompare { |
| 66 bool operator()(const TupleType &A, const TupleType &B) const { | 74 bool operator()(const TupleType &A, const TupleType &B) const { |
| 67 if (A.first != B.first) | 75 if (A.first != B.first) |
| 68 return A.first < B.first; | 76 return A.first < B.first; |
| 69 if (KeyTypeHasFP) | 77 if (KeyTypeHasFP) |
| 70 return memcmp(&A.second, &B.second, sizeof(KeyType)) < 0; | 78 return memcmp(&A.second, &B.second, sizeof(KeyType)) < 0; |
| 71 return A.second < B.second; | 79 return A.second < B.second; |
| 72 } | 80 } |
| 73 }; | 81 }; |
| 74 typedef std::map<const TupleType, ValueType *, TupleCompare> ContainerType; | 82 typedef std::map<const TupleType, ValueType *, TupleCompare> ContainerType; |
| 75 ContainerType Pool; | 83 ContainerType Pool; |
| 76 uint32_t NextPoolID; | 84 uint32_t NextPoolID; |
| 77 }; | 85 }; |
| 78 | 86 |
| 87 // ImmediatePool maps strings to immediates, which can be constants of | |
| 88 // any type. | |
|
Jim Stichnoth
2014/08/13 23:30:25
Can you clarify in the comment that the string is
wala
2014/08/16 00:07:12
I don't know exactly what you mean, but I've clari
| |
| 89 class ImmediatePool { | |
| 90 ImmediatePool(const ImmediatePool &) LLVM_DELETED_FUNCTION; | |
| 91 ImmediatePool &operator=(const ImmediatePool &) LLVM_DELETED_FUNCTION; | |
| 92 public: | |
| 93 ImmediatePool() {} | |
| 94 | |
| 95 void add(IceString Name, Constant *Value) { | |
| 96 Pool[Name] = Value; | |
| 97 } | |
| 98 ConstantList getConstantPool() const { | |
| 99 return makeListOfValues<ContainerType, ConstantList>(Pool); | |
| 100 } | |
| 101 | |
| 102 private: | |
| 103 typedef std::map<IceString, Constant *> ContainerType; | |
| 104 ContainerType Pool; | |
| 105 }; | |
| 106 | |
| 79 // UndefPool maps ICE types to the corresponding ConstantUndef values. | 107 // UndefPool maps ICE types to the corresponding ConstantUndef values. |
| 80 class UndefPool { | 108 class UndefPool { |
| 81 UndefPool(const UndefPool &) LLVM_DELETED_FUNCTION; | 109 UndefPool(const UndefPool &) LLVM_DELETED_FUNCTION; |
| 82 UndefPool &operator=(const UndefPool &) LLVM_DELETED_FUNCTION; | 110 UndefPool &operator=(const UndefPool &) LLVM_DELETED_FUNCTION; |
| 83 | 111 |
| 84 public: | 112 public: |
| 85 UndefPool() : NextPoolID(0) {} | 113 UndefPool() : NextPoolID(0) {} |
| 86 | 114 |
| 87 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { | 115 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { |
| 88 ContainerType::iterator I = Pool.find(Ty); | 116 ContainerType::iterator I = Pool.find(Ty); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 104 class ConstantPool { | 132 class ConstantPool { |
| 105 ConstantPool(const ConstantPool &) LLVM_DELETED_FUNCTION; | 133 ConstantPool(const ConstantPool &) LLVM_DELETED_FUNCTION; |
| 106 ConstantPool &operator=(const ConstantPool &) LLVM_DELETED_FUNCTION; | 134 ConstantPool &operator=(const ConstantPool &) LLVM_DELETED_FUNCTION; |
| 107 | 135 |
| 108 public: | 136 public: |
| 109 ConstantPool() {} | 137 ConstantPool() {} |
| 110 TypePool<float, ConstantFloat, true> Floats; | 138 TypePool<float, ConstantFloat, true> Floats; |
| 111 TypePool<double, ConstantDouble, true> Doubles; | 139 TypePool<double, ConstantDouble, true> Doubles; |
| 112 TypePool<uint64_t, ConstantInteger> Integers; | 140 TypePool<uint64_t, ConstantInteger> Integers; |
| 113 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; | 141 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; |
| 142 ImmediatePool Immediates; | |
| 114 UndefPool Undefs; | 143 UndefPool Undefs; |
| 115 }; | 144 }; |
| 116 | 145 |
| 117 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, | 146 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, |
| 118 llvm::raw_ostream *OsEmit, VerboseMask Mask, | 147 llvm::raw_ostream *OsEmit, VerboseMask Mask, |
| 119 TargetArch Arch, OptLevel Opt, | 148 TargetArch Arch, OptLevel Opt, |
| 120 IceString TestPrefix, const ClFlags &Flags) | 149 IceString TestPrefix, const ClFlags &Flags) |
| 121 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), | 150 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), |
| 122 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), | 151 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), |
| 123 TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false), | 152 TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false), |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 BaseOS << "Unsupported constant type: " << Ty; | 365 BaseOS << "Unsupported constant type: " << Ty; |
| 337 llvm_unreachable(BaseOS.str().c_str()); | 366 llvm_unreachable(BaseOS.str().c_str()); |
| 338 } break; | 367 } break; |
| 339 case IceType_void: | 368 case IceType_void: |
| 340 case IceType_NUM: | 369 case IceType_NUM: |
| 341 break; | 370 break; |
| 342 } | 371 } |
| 343 llvm_unreachable("Unknown type"); | 372 llvm_unreachable("Unknown type"); |
| 344 } | 373 } |
| 345 | 374 |
| 375 void GlobalContext::addConstantPooledImmediate(IceString Name, | |
| 376 Constant *Immediate) { | |
| 377 ConstPool->Immediates.add(Name, Immediate); | |
| 378 } | |
| 379 | |
| 346 ConstantList GlobalContext::getConstantPool(Type Ty) const { | 380 ConstantList GlobalContext::getConstantPool(Type Ty) const { |
| 347 switch (Ty) { | 381 switch (Ty) { |
| 348 case IceType_i1: | 382 case IceType_i1: |
| 349 case IceType_i8: | 383 case IceType_i8: |
| 350 case IceType_i16: | 384 case IceType_i16: |
| 351 case IceType_i32: | 385 case IceType_i32: |
| 352 case IceType_i64: | 386 case IceType_i64: |
| 353 return ConstPool->Integers.getConstantPool(); | 387 return ConstPool->Integers.getConstantPool(); |
| 354 case IceType_f32: | 388 case IceType_f32: |
| 355 return ConstPool->Floats.getConstantPool(); | 389 return ConstPool->Floats.getConstantPool(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 367 BaseOS << "Unsupported constant type: " << Ty; | 401 BaseOS << "Unsupported constant type: " << Ty; |
| 368 llvm_unreachable(BaseOS.str().c_str()); | 402 llvm_unreachable(BaseOS.str().c_str()); |
| 369 } break; | 403 } break; |
| 370 case IceType_void: | 404 case IceType_void: |
| 371 case IceType_NUM: | 405 case IceType_NUM: |
| 372 break; | 406 break; |
| 373 } | 407 } |
| 374 llvm_unreachable("Unknown type"); | 408 llvm_unreachable("Unknown type"); |
| 375 } | 409 } |
| 376 | 410 |
| 411 ConstantList GlobalContext::getImmediatePool() const { | |
| 412 return ConstPool->Immediates.getConstantPool(); | |
| 413 } | |
| 414 | |
| 377 void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const { | 415 void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const { |
| 378 if (Ctx->isVerbose(IceV_Timing)) { | 416 if (Ctx->isVerbose(IceV_Timing)) { |
| 379 // Prefixing with '#' allows timing strings to be included | 417 // Prefixing with '#' allows timing strings to be included |
| 380 // without error in textual assembly output. | 418 // without error in textual assembly output. |
| 381 Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n"; | 419 Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n"; |
| 382 } | 420 } |
| 383 } | 421 } |
| 384 | 422 |
| 385 } // end of namespace Ice | 423 } // end of namespace Ice |
| OLD | NEW |