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 |
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 #include <unordered_map> | |
17 | 18 |
18 #include "IceCfg.h" | 19 #include "IceCfg.h" |
19 #include "IceClFlags.h" | 20 #include "IceClFlags.h" |
20 #include "IceDefs.h" | 21 #include "IceDefs.h" |
21 #include "IceGlobalContext.h" | 22 #include "IceGlobalContext.h" |
22 #include "IceGlobalInits.h" | 23 #include "IceGlobalInits.h" |
23 #include "IceOperand.h" | 24 #include "IceOperand.h" |
24 #include "IceTargetLowering.h" | 25 #include "IceTargetLowering.h" |
25 #include "IceTimerTree.h" | 26 #include "IceTimerTree.h" |
26 #include "IceTypes.h" | 27 #include "IceTypes.h" |
27 | 28 |
29 template <> struct std::hash<Ice::RelocatableTuple> { | |
30 std::size_t operator()(const Ice::RelocatableTuple &Key) const { | |
31 return std::hash<Ice::IceString>()(Key.Name) + | |
Jim Stichnoth
2014/11/19 18:18:39
Not sure this is the ideal hash function. However
| |
32 std::hash<Ice::RelocOffsetT>()(Key.Offset); | |
33 } | |
34 }; | |
35 | |
28 namespace Ice { | 36 namespace Ice { |
29 | 37 |
30 // TypePool maps constants of type KeyType (e.g. float) to pointers to | 38 // TypePool maps constants of type KeyType (e.g. float) to pointers to |
31 // type ValueType (e.g. ConstantFloat). KeyType values are compared | 39 // type ValueType (e.g. ConstantFloat). |
32 // using memcmp() because of potential NaN values in KeyType values. | 40 template <Type Ty, typename KeyType, typename ValueType> class TypePool { |
33 // KeyTypeHasFP indicates whether KeyType is a floating-point type | |
34 // whose values need to be compared using memcmp() for NaN | |
35 // correctness. TODO: use std::is_floating_point<KeyType> instead of | |
36 // KeyTypeHasFP with C++11. | |
37 template <typename KeyType, typename ValueType, bool KeyTypeHasFP = false> | |
38 class TypePool { | |
39 TypePool(const TypePool &) = delete; | 41 TypePool(const TypePool &) = delete; |
40 TypePool &operator=(const TypePool &) = delete; | 42 TypePool &operator=(const TypePool &) = delete; |
41 | 43 |
42 public: | 44 public: |
43 TypePool() : NextPoolID(0) {} | 45 TypePool() : NextPoolID(0) {} |
44 ValueType *getOrAdd(GlobalContext *Ctx, Type Ty, KeyType Key) { | 46 ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) { |
45 TupleType TupleKey = std::make_pair(Ty, Key); | 47 auto Iter = Pool.find(Key); |
46 auto Iter = Pool.find(TupleKey); | |
47 if (Iter != Pool.end()) | 48 if (Iter != Pool.end()) |
48 return Iter->second; | 49 return Iter->second; |
49 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); | 50 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); |
50 Pool[TupleKey] = Result; | 51 Pool[Key] = Result; |
51 return Result; | 52 return Result; |
52 } | 53 } |
53 ConstantList getConstantPool() const { | 54 ConstantList getConstantPool() const { |
54 ConstantList Constants; | 55 ConstantList Constants; |
55 Constants.reserve(Pool.size()); | 56 Constants.reserve(Pool.size()); |
56 for (auto &I : Pool) | 57 for (auto &I : Pool) |
57 Constants.push_back(I.second); | 58 Constants.push_back(I.second); |
58 return Constants; | 59 return Constants; |
59 } | 60 } |
60 | 61 |
61 private: | 62 private: |
62 typedef std::pair<Type, KeyType> TupleType; | 63 typedef std::unordered_map<KeyType, ValueType *> ContainerType; |
63 struct TupleCompare { | |
64 bool operator()(const TupleType &A, const TupleType &B) const { | |
65 if (A.first != B.first) | |
66 return A.first < B.first; | |
67 if (KeyTypeHasFP) | |
68 return memcmp(&A.second, &B.second, sizeof(KeyType)) < 0; | |
69 return A.second < B.second; | |
70 } | |
71 }; | |
72 typedef std::map<const TupleType, ValueType *, TupleCompare> ContainerType; | |
73 ContainerType Pool; | 64 ContainerType Pool; |
74 uint32_t NextPoolID; | 65 uint32_t NextPoolID; |
75 }; | 66 }; |
76 | 67 |
77 // UndefPool maps ICE types to the corresponding ConstantUndef values. | 68 // UndefPool maps ICE types to the corresponding ConstantUndef values. |
78 class UndefPool { | 69 class UndefPool { |
79 UndefPool(const UndefPool &) = delete; | 70 UndefPool(const UndefPool &) = delete; |
80 UndefPool &operator=(const UndefPool &) = delete; | 71 UndefPool &operator=(const UndefPool &) = delete; |
81 | 72 |
82 public: | 73 public: |
83 UndefPool() : NextPoolID(0) {} | 74 UndefPool() : NextPoolID(0), Pool(IceType_NUM) {} |
84 | 75 |
85 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { | 76 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { |
86 auto I = Pool.find(Ty); | 77 if (Pool[Ty] == NULL) |
87 if (I != Pool.end()) | 78 Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++); |
88 return I->second; | 79 return Pool[Ty]; |
89 ConstantUndef *Undef = ConstantUndef::create(Ctx, Ty, NextPoolID++); | |
90 Pool[Ty] = Undef; | |
91 return Undef; | |
92 } | 80 } |
93 | 81 |
94 private: | 82 private: |
95 uint32_t NextPoolID; | 83 uint32_t NextPoolID; |
96 typedef std::map<Type, ConstantUndef *> ContainerType; | 84 std::vector<ConstantUndef *> Pool; |
97 ContainerType Pool; | |
98 }; | 85 }; |
99 | 86 |
100 // The global constant pool bundles individual pools of each type of | 87 // The global constant pool bundles individual pools of each type of |
101 // interest. | 88 // interest. |
102 class ConstantPool { | 89 class ConstantPool { |
103 ConstantPool(const ConstantPool &) = delete; | 90 ConstantPool(const ConstantPool &) = delete; |
104 ConstantPool &operator=(const ConstantPool &) = delete; | 91 ConstantPool &operator=(const ConstantPool &) = delete; |
105 | 92 |
106 public: | 93 public: |
107 ConstantPool() {} | 94 ConstantPool() {} |
108 TypePool<float, ConstantFloat, true> Floats; | 95 TypePool<IceType_f32, float, ConstantFloat> Floats; |
109 TypePool<double, ConstantDouble, true> Doubles; | 96 TypePool<IceType_f64, double, ConstantDouble> Doubles; |
110 TypePool<uint32_t, ConstantInteger32> Integers32; | 97 TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1; |
111 TypePool<uint64_t, ConstantInteger64> Integers64; | 98 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; |
112 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; | 99 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; |
100 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; | |
101 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; | |
102 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; | |
113 UndefPool Undefs; | 103 UndefPool Undefs; |
114 }; | 104 }; |
115 | 105 |
116 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, | 106 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, |
117 llvm::raw_ostream *OsEmit, VerboseMask Mask, | 107 llvm::raw_ostream *OsEmit, VerboseMask Mask, |
118 TargetArch Arch, OptLevel Opt, | 108 TargetArch Arch, OptLevel Opt, |
119 IceString TestPrefix, const ClFlags &Flags) | 109 IceString TestPrefix, const ClFlags &Flags) |
120 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), | 110 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), |
121 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), | 111 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), |
122 TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false), | 112 TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false), |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
287 | 277 |
288 // Transform bar ==> Prefixbar | 278 // Transform bar ==> Prefixbar |
289 // ^^^^^^ | 279 // ^^^^^^ |
290 return getTestPrefix() + Name; | 280 return getTestPrefix() + Name; |
291 } | 281 } |
292 | 282 |
293 GlobalContext::~GlobalContext() { | 283 GlobalContext::~GlobalContext() { |
294 llvm::DeleteContainerPointers(GlobalDeclarations); | 284 llvm::DeleteContainerPointers(GlobalDeclarations); |
295 } | 285 } |
296 | 286 |
297 Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) { | 287 Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) { |
298 assert(Ty == IceType_i64); | 288 ConstantInt1 &= INT8_C(1); |
299 return ConstPool->Integers64.getOrAdd(this, Ty, ConstantInt64); | 289 return ConstPool->Integers1.getOrAdd(this, ConstantInt1); |
300 } | 290 } |
301 | 291 |
302 Constant *GlobalContext::getConstantInt32(Type Ty, uint32_t ConstantInt32) { | 292 Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) { |
303 if (Ty == IceType_i1) | 293 return ConstPool->Integers8.getOrAdd(this, ConstantInt8); |
304 ConstantInt32 &= UINT32_C(1); | 294 } |
305 return ConstPool->Integers32.getOrAdd(this, Ty, ConstantInt32); | 295 |
296 Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) { | |
297 return ConstPool->Integers16.getOrAdd(this, ConstantInt16); | |
298 } | |
299 | |
300 Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) { | |
301 return ConstPool->Integers32.getOrAdd(this, ConstantInt32); | |
302 } | |
303 | |
304 Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) { | |
305 return ConstPool->Integers64.getOrAdd(this, ConstantInt64); | |
306 } | 306 } |
307 | 307 |
308 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { | 308 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { |
309 return ConstPool->Floats.getOrAdd(this, IceType_f32, ConstantFloat); | 309 return ConstPool->Floats.getOrAdd(this, ConstantFloat); |
310 } | 310 } |
311 | 311 |
312 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { | 312 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { |
313 return ConstPool->Doubles.getOrAdd(this, IceType_f64, ConstantDouble); | 313 return ConstPool->Doubles.getOrAdd(this, ConstantDouble); |
314 } | 314 } |
315 | 315 |
316 Constant *GlobalContext::getConstantSym(Type Ty, RelocOffsetT Offset, | 316 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, |
317 const IceString &Name, | 317 const IceString &Name, |
318 bool SuppressMangling) { | 318 bool SuppressMangling) { |
319 return ConstPool->Relocatables.getOrAdd( | 319 return ConstPool->Relocatables.getOrAdd( |
320 this, Ty, RelocatableTuple(Offset, Name, SuppressMangling)); | 320 this, RelocatableTuple(Offset, Name, SuppressMangling)); |
321 } | 321 } |
322 | 322 |
323 Constant *GlobalContext::getConstantUndef(Type Ty) { | 323 Constant *GlobalContext::getConstantUndef(Type Ty) { |
324 return ConstPool->Undefs.getOrAdd(this, Ty); | 324 return ConstPool->Undefs.getOrAdd(this, Ty); |
325 } | 325 } |
326 | 326 |
327 Constant *GlobalContext::getConstantZero(Type Ty) { | 327 Constant *GlobalContext::getConstantZero(Type Ty) { |
328 switch (Ty) { | 328 switch (Ty) { |
329 case IceType_i1: | 329 case IceType_i1: |
330 return getConstantInt1(0); | |
330 case IceType_i8: | 331 case IceType_i8: |
332 return getConstantInt8(0); | |
331 case IceType_i16: | 333 case IceType_i16: |
334 return getConstantInt16(0); | |
332 case IceType_i32: | 335 case IceType_i32: |
333 return getConstantInt32(Ty, 0); | 336 return getConstantInt32(0); |
334 case IceType_i64: | 337 case IceType_i64: |
335 return getConstantInt64(Ty, 0); | 338 return getConstantInt64(0); |
336 case IceType_f32: | 339 case IceType_f32: |
337 return getConstantFloat(0); | 340 return getConstantFloat(0); |
338 case IceType_f64: | 341 case IceType_f64: |
339 return getConstantDouble(0); | 342 return getConstantDouble(0); |
340 case IceType_v4i1: | 343 case IceType_v4i1: |
341 case IceType_v8i1: | 344 case IceType_v8i1: |
342 case IceType_v16i1: | 345 case IceType_v16i1: |
343 case IceType_v16i8: | 346 case IceType_v16i8: |
344 case IceType_v8i16: | 347 case IceType_v8i16: |
345 case IceType_v4i32: | 348 case IceType_v4i32: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 } | 462 } |
460 | 463 |
461 TimerMarker::TimerMarker(TimerIdT ID, const Cfg *Func) | 464 TimerMarker::TimerMarker(TimerIdT ID, const Cfg *Func) |
462 : ID(ID), Ctx(Func->getContext()), | 465 : ID(ID), Ctx(Func->getContext()), |
463 Active(Func->getFocusedTiming() || Ctx->getFlags().SubzeroTimingEnabled) { | 466 Active(Func->getFocusedTiming() || Ctx->getFlags().SubzeroTimingEnabled) { |
464 if (Active) | 467 if (Active) |
465 Ctx->pushTimer(ID); | 468 Ctx->pushTimer(ID); |
466 } | 469 } |
467 | 470 |
468 } // end of namespace Ice | 471 } // end of namespace Ice |
OLD | NEW |