blob: 84d7b685b75bc3b08833f7e12fa0420b36d5c928 [file] [log] [blame]
Jim Stichnothc4554d72014-09-30 16:49:38 -07001//===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===//
Jim Stichnothf7c9a142014-04-29 10:52:43 -07002//
3// The Subzero Code Generator
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines aspects of the compilation that persist across
11// multiple functions.
12//
13//===----------------------------------------------------------------------===//
14
Jim Stichnoth217dc082014-07-11 14:06:55 -070015#include <ctype.h> // isdigit(), isupper()
Jan Voung839c4ce2014-07-28 15:19:43 -070016#include <locale> // locale
Jim Stichnothd2cb4362014-11-20 11:24:42 -080017#include <unordered_map>
Jim Stichnothd97c7df2014-06-04 11:57:08 -070018
Jim Stichnothf7c9a142014-04-29 10:52:43 -070019#include "IceCfg.h"
Jim Stichnoth989a7032014-08-08 10:13:44 -070020#include "IceClFlags.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070021#include "IceDefs.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022#include "IceGlobalContext.h"
Karl Schimpf9d98d792014-10-13 15:01:08 -070023#include "IceGlobalInits.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070024#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070025#include "IceTargetLowering.h"
Jim Stichnothc4554d72014-09-30 16:49:38 -070026#include "IceTimerTree.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070027#include "IceTypes.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070028
Jim Stichnothdddaf9c2014-12-04 14:09:21 -080029namespace std {
30template <> struct hash<Ice::RelocatableTuple> {
31 size_t operator()(const Ice::RelocatableTuple &Key) const {
32 return hash<Ice::IceString>()(Key.Name) +
33 hash<Ice::RelocOffsetT>()(Key.Offset);
Jim Stichnothd2cb4362014-11-20 11:24:42 -080034 }
35};
Jim Stichnothdddaf9c2014-12-04 14:09:21 -080036} // end of namespace std
Jim Stichnothd2cb4362014-11-20 11:24:42 -080037
Jim Stichnothf7c9a142014-04-29 10:52:43 -070038namespace Ice {
39
40// TypePool maps constants of type KeyType (e.g. float) to pointers to
Jim Stichnothd2cb4362014-11-20 11:24:42 -080041// type ValueType (e.g. ConstantFloat).
42template <Type Ty, typename KeyType, typename ValueType> class TypePool {
Jim Stichnoth0795ba02014-10-01 14:23:01 -070043 TypePool(const TypePool &) = delete;
44 TypePool &operator=(const TypePool &) = delete;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070045
46public:
Jim Stichnothf61d5b22014-05-23 13:31:24 -070047 TypePool() : NextPoolID(0) {}
Jim Stichnothd2cb4362014-11-20 11:24:42 -080048 ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) {
49 auto Iter = Pool.find(Key);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070050 if (Iter != Pool.end())
51 return Iter->second;
Jim Stichnothf61d5b22014-05-23 13:31:24 -070052 ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++);
Jim Stichnothd2cb4362014-11-20 11:24:42 -080053 Pool[Key] = Result;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070054 return Result;
55 }
Jim Stichnothf61d5b22014-05-23 13:31:24 -070056 ConstantList getConstantPool() const {
57 ConstantList Constants;
58 Constants.reserve(Pool.size());
Jim Stichnothf44f3712014-10-01 14:05:51 -070059 for (auto &I : Pool)
60 Constants.push_back(I.second);
Jim Stichnothf61d5b22014-05-23 13:31:24 -070061 return Constants;
62 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070063
64private:
Jim Stichnothd2cb4362014-11-20 11:24:42 -080065 typedef std::unordered_map<KeyType, ValueType *> ContainerType;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070066 ContainerType Pool;
Jim Stichnothf61d5b22014-05-23 13:31:24 -070067 uint32_t NextPoolID;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070068};
69
Matt Walad8f4a7d2014-06-18 09:55:03 -070070// UndefPool maps ICE types to the corresponding ConstantUndef values.
71class UndefPool {
Jim Stichnoth0795ba02014-10-01 14:23:01 -070072 UndefPool(const UndefPool &) = delete;
73 UndefPool &operator=(const UndefPool &) = delete;
Matt Walad8f4a7d2014-06-18 09:55:03 -070074
75public:
Jim Stichnothd2cb4362014-11-20 11:24:42 -080076 UndefPool() : NextPoolID(0), Pool(IceType_NUM) {}
Matt Walad8f4a7d2014-06-18 09:55:03 -070077
78 ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) {
Jim Stichnothd2cb4362014-11-20 11:24:42 -080079 if (Pool[Ty] == NULL)
80 Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++);
81 return Pool[Ty];
Matt Walad8f4a7d2014-06-18 09:55:03 -070082 }
83
84private:
85 uint32_t NextPoolID;
Jim Stichnothd2cb4362014-11-20 11:24:42 -080086 std::vector<ConstantUndef *> Pool;
Matt Walad8f4a7d2014-06-18 09:55:03 -070087};
88
Jim Stichnothf7c9a142014-04-29 10:52:43 -070089// The global constant pool bundles individual pools of each type of
90// interest.
91class ConstantPool {
Jim Stichnoth0795ba02014-10-01 14:23:01 -070092 ConstantPool(const ConstantPool &) = delete;
93 ConstantPool &operator=(const ConstantPool &) = delete;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070094
95public:
96 ConstantPool() {}
Jim Stichnothd2cb4362014-11-20 11:24:42 -080097 TypePool<IceType_f32, float, ConstantFloat> Floats;
98 TypePool<IceType_f64, double, ConstantDouble> Doubles;
99 TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1;
100 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
101 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16;
102 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
103 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
104 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
Matt Walad8f4a7d2014-06-18 09:55:03 -0700105 UndefPool Undefs;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700106};
107
Jan Voung08c3bcd2014-12-01 17:55:16 -0800108GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit,
109 ELFStreamer *ELFStr, VerboseMask Mask,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700110 TargetArch Arch, OptLevel Opt,
Jim Stichnoth989a7032014-08-08 10:13:44 -0700111 IceString TestPrefix, const ClFlags &Flags)
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700112 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask),
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700113 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt),
Matt Wala1bd2fce2014-08-08 14:02:09 -0700114 TestPrefix(TestPrefix), Flags(Flags), HasEmittedFirstMethod(false),
Jan Voung08c3bcd2014-12-01 17:55:16 -0800115 RNG(""), ObjectWriter() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700116 // Pre-register built-in stack names.
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800117 if (ALLOW_DUMP) {
118 newTimerStackID("Total across all functions");
119 newTimerStackID("Per-function summary");
120 }
Jan Voung08c3bcd2014-12-01 17:55:16 -0800121 if (Flags.UseELFWriter) {
122 ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr));
123 }
Jim Stichnoth8363a062014-10-07 10:02:38 -0700124}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700125
Jim Stichnoth217dc082014-07-11 14:06:55 -0700126// Scan a string for S[0-9A-Z]*_ patterns and replace them with
127// S<num>_ where <num> is the next base-36 value. If a type name
128// legitimately contains that pattern, then the substitution will be
129// made in error and most likely the link will fail. In this case,
130// the test classes can be rewritten not to use that pattern, which is
131// much simpler and more reliable than implementing a full demangling
132// parser. Another substitution-in-error may occur if a type
133// identifier ends with the pattern S[0-9A-Z]*, because an immediately
134// following substitution string like "S1_" or "PS1_" may be combined
135// with the previous type.
136void GlobalContext::incrementSubstitutions(ManglerVector &OldName) const {
137 const std::locale CLocale("C");
138 // Provide extra space in case the length of <num> increases.
139 ManglerVector NewName(OldName.size() * 2);
140 size_t OldPos = 0;
141 size_t NewPos = 0;
142 size_t OldLen = OldName.size();
143 for (; OldPos < OldLen; ++OldPos, ++NewPos) {
144 if (OldName[OldPos] == '\0')
145 break;
146 if (OldName[OldPos] == 'S') {
147 // Search forward until we find _ or invalid character (including \0).
148 bool AllZs = true;
149 bool Found = false;
150 size_t Last;
151 for (Last = OldPos + 1; Last < OldLen; ++Last) {
152 char Ch = OldName[Last];
153 if (Ch == '_') {
154 Found = true;
155 break;
156 } else if (std::isdigit(Ch) || std::isupper(Ch, CLocale)) {
157 if (Ch != 'Z')
158 AllZs = false;
159 } else {
160 // Invalid character, stop searching.
161 break;
162 }
163 }
164 if (Found) {
165 NewName[NewPos++] = OldName[OldPos++]; // 'S'
166 size_t Length = Last - OldPos;
167 // NewPos and OldPos point just past the 'S'.
168 assert(NewName[NewPos - 1] == 'S');
169 assert(OldName[OldPos - 1] == 'S');
170 assert(OldName[OldPos + Length] == '_');
171 if (AllZs) {
Jim Stichnoth78b4c0b2014-07-11 15:29:23 -0700172 // Replace N 'Z' characters with a '0' (if N=0) or '1' (if
173 // N>0) followed by N '0' characters.
174 NewName[NewPos++] = (Length ? '1' : '0');
175 for (size_t i = 0; i < Length; ++i) {
Jim Stichnoth217dc082014-07-11 14:06:55 -0700176 NewName[NewPos++] = '0';
177 }
178 } else {
179 // Iterate right-to-left and increment the base-36 number.
180 bool Carry = true;
181 for (size_t i = 0; i < Length; ++i) {
182 size_t Offset = Length - 1 - i;
183 char Ch = OldName[OldPos + Offset];
184 if (Carry) {
185 Carry = false;
186 switch (Ch) {
187 case '9':
188 Ch = 'A';
189 break;
190 case 'Z':
191 Ch = '0';
192 Carry = true;
193 break;
194 default:
195 ++Ch;
196 break;
197 }
198 }
199 NewName[NewPos + Offset] = Ch;
200 }
201 NewPos += Length;
202 }
203 OldPos = Last;
204 // Fall through and let the '_' be copied across.
205 }
206 }
207 NewName[NewPos] = OldName[OldPos];
208 }
209 assert(NewName[NewPos] == '\0');
210 OldName = NewName;
211}
212
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700213// In this context, name mangling means to rewrite a symbol using a
214// given prefix. For a C++ symbol, nest the original symbol inside
215// the "prefix" namespace. For other symbols, just prepend the
216// prefix.
217IceString GlobalContext::mangleName(const IceString &Name) const {
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700218 // An already-nested name like foo::bar() gets pushed down one
219 // level, making it equivalent to Prefix::foo::bar().
220 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
221 // A non-nested but mangled name like bar() gets nested, making it
222 // equivalent to Prefix::bar().
223 // _Z3barxyz ==> ZN6Prefix3barExyz
224 // An unmangled, extern "C" style name, gets a simple prefix:
225 // bar ==> Prefixbar
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800226 if (!ALLOW_DUMP || getTestPrefix().empty())
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700227 return Name;
228
229 unsigned PrefixLength = getTestPrefix().length();
Jim Stichnoth217dc082014-07-11 14:06:55 -0700230 ManglerVector NameBase(1 + Name.length());
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700231 const size_t BufLen = 30 + Name.length() + PrefixLength;
Jim Stichnoth217dc082014-07-11 14:06:55 -0700232 ManglerVector NewName(BufLen);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700233 uint32_t BaseLength = 0; // using uint32_t due to sscanf format string
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700234
Derek Schuff44712d12014-06-17 14:34:34 -0700235 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase.data());
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700236 if (ItemsParsed == 1) {
237 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
238 // (splice in "6Prefix") ^^^^^^^
Derek Schuff44712d12014-06-17 14:34:34 -0700239 snprintf(NewName.data(), BufLen, "_ZN%u%s%s", PrefixLength,
240 getTestPrefix().c_str(), NameBase.data());
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700241 // We ignore the snprintf return value (here and below). If we
242 // somehow miscalculated the output buffer length, the output will
243 // be truncated, but it will be truncated consistently for all
244 // mangleName() calls on the same input string.
Jim Stichnoth217dc082014-07-11 14:06:55 -0700245 incrementSubstitutions(NewName);
Derek Schuff44712d12014-06-17 14:34:34 -0700246 return NewName.data();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700247 }
248
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700249 // Artificially limit BaseLength to 9 digits (less than 1 billion)
250 // because sscanf behavior is undefined on integer overflow. If
251 // there are more than 9 digits (which we test by looking at the
252 // beginning of NameBase), then we consider this a failure to parse
253 // a namespace mangling, and fall back to the simple prefixing.
Derek Schuff44712d12014-06-17 14:34:34 -0700254 ItemsParsed = sscanf(Name.c_str(), "_Z%9u%s", &BaseLength, NameBase.data());
255 if (ItemsParsed == 2 && BaseLength <= strlen(NameBase.data()) &&
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700256 !isdigit(NameBase[0])) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700257 // Transform _Z3barxyz ==> _ZN6Prefix3barExyz
258 // ^^^^^^^^ ^
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700259 // (splice in "N6Prefix", and insert "E" after "3bar")
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700260 // But an "I" after the identifier indicates a template argument
261 // list terminated with "E"; insert the new "E" before/after the
262 // old "E". E.g.:
263 // Transform _Z3barIabcExyz ==> _ZN6Prefix3barIabcEExyz
264 // ^^^^^^^^ ^
265 // (splice in "N6Prefix", and insert "E" after "3barIabcE")
Jim Stichnoth217dc082014-07-11 14:06:55 -0700266 ManglerVector OrigName(Name.length());
267 ManglerVector OrigSuffix(Name.length());
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700268 uint32_t ActualBaseLength = BaseLength;
269 if (NameBase[ActualBaseLength] == 'I') {
270 ++ActualBaseLength;
271 while (NameBase[ActualBaseLength] != 'E' &&
272 NameBase[ActualBaseLength] != '\0')
273 ++ActualBaseLength;
274 }
Derek Schuff44712d12014-06-17 14:34:34 -0700275 strncpy(OrigName.data(), NameBase.data(), ActualBaseLength);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700276 OrigName[ActualBaseLength] = '\0';
Derek Schuff44712d12014-06-17 14:34:34 -0700277 strcpy(OrigSuffix.data(), NameBase.data() + ActualBaseLength);
278 snprintf(NewName.data(), BufLen, "_ZN%u%s%u%sE%s", PrefixLength,
279 getTestPrefix().c_str(), BaseLength, OrigName.data(),
280 OrigSuffix.data());
Jim Stichnoth217dc082014-07-11 14:06:55 -0700281 incrementSubstitutions(NewName);
Derek Schuff44712d12014-06-17 14:34:34 -0700282 return NewName.data();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700283 }
284
285 // Transform bar ==> Prefixbar
286 // ^^^^^^
287 return getTestPrefix() + Name;
288}
289
Karl Schimpf9d98d792014-10-13 15:01:08 -0700290GlobalContext::~GlobalContext() {
291 llvm::DeleteContainerPointers(GlobalDeclarations);
292}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700293
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800294Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
295 switch (Ty) {
296 case IceType_i1:
297 return getConstantInt1(Value);
298 case IceType_i8:
299 return getConstantInt8(Value);
300 case IceType_i16:
301 return getConstantInt16(Value);
302 case IceType_i32:
303 return getConstantInt32(Value);
304 case IceType_i64:
305 return getConstantInt64(Value);
306 default:
307 llvm_unreachable("Bad integer type for getConstant");
308 }
309 return NULL;
Jan Voungbc004632014-09-16 15:09:10 -0700310}
311
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800312Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) {
313 ConstantInt1 &= INT8_C(1);
314 return ConstPool->Integers1.getOrAdd(this, ConstantInt1);
315}
316
317Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) {
318 return ConstPool->Integers8.getOrAdd(this, ConstantInt8);
319}
320
321Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) {
322 return ConstPool->Integers16.getOrAdd(this, ConstantInt16);
323}
324
325Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) {
326 return ConstPool->Integers32.getOrAdd(this, ConstantInt32);
327}
328
329Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) {
330 return ConstPool->Integers64.getOrAdd(this, ConstantInt64);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700331}
332
333Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800334 return ConstPool->Floats.getOrAdd(this, ConstantFloat);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700335}
336
337Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800338 return ConstPool->Doubles.getOrAdd(this, ConstantDouble);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700339}
340
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800341Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700342 const IceString &Name,
343 bool SuppressMangling) {
344 return ConstPool->Relocatables.getOrAdd(
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800345 this, RelocatableTuple(Offset, Name, SuppressMangling));
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700346}
347
Matt Walad8f4a7d2014-06-18 09:55:03 -0700348Constant *GlobalContext::getConstantUndef(Type Ty) {
349 return ConstPool->Undefs.getOrAdd(this, Ty);
350}
351
352Constant *GlobalContext::getConstantZero(Type Ty) {
353 switch (Ty) {
354 case IceType_i1:
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800355 return getConstantInt1(0);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700356 case IceType_i8:
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800357 return getConstantInt8(0);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700358 case IceType_i16:
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800359 return getConstantInt16(0);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700360 case IceType_i32:
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800361 return getConstantInt32(0);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700362 case IceType_i64:
Jim Stichnothd2cb4362014-11-20 11:24:42 -0800363 return getConstantInt64(0);
Matt Walad8f4a7d2014-06-18 09:55:03 -0700364 case IceType_f32:
365 return getConstantFloat(0);
366 case IceType_f64:
367 return getConstantDouble(0);
Matt Wala928f1292014-07-07 16:50:46 -0700368 case IceType_v4i1:
369 case IceType_v8i1:
370 case IceType_v16i1:
371 case IceType_v16i8:
372 case IceType_v8i16:
373 case IceType_v4i32:
374 case IceType_v4f32: {
375 IceString Str;
376 llvm::raw_string_ostream BaseOS(Str);
Jim Stichnoth78282f62014-07-27 23:14:00 -0700377 BaseOS << "Unsupported constant type: " << Ty;
Matt Wala928f1292014-07-07 16:50:46 -0700378 llvm_unreachable(BaseOS.str().c_str());
379 } break;
Matt Walad8f4a7d2014-06-18 09:55:03 -0700380 case IceType_void:
381 case IceType_NUM:
382 break;
383 }
384 llvm_unreachable("Unknown type");
385}
386
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700387ConstantList GlobalContext::getConstantPool(Type Ty) const {
388 switch (Ty) {
389 case IceType_i1:
390 case IceType_i8:
391 case IceType_i16:
392 case IceType_i32:
Jan Voungbc004632014-09-16 15:09:10 -0700393 return ConstPool->Integers32.getConstantPool();
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700394 case IceType_i64:
Jan Voungbc004632014-09-16 15:09:10 -0700395 return ConstPool->Integers64.getConstantPool();
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700396 case IceType_f32:
397 return ConstPool->Floats.getConstantPool();
398 case IceType_f64:
399 return ConstPool->Doubles.getConstantPool();
Matt Wala928f1292014-07-07 16:50:46 -0700400 case IceType_v4i1:
401 case IceType_v8i1:
402 case IceType_v16i1:
403 case IceType_v16i8:
404 case IceType_v8i16:
405 case IceType_v4i32:
406 case IceType_v4f32: {
407 IceString Str;
408 llvm::raw_string_ostream BaseOS(Str);
Jim Stichnoth78282f62014-07-27 23:14:00 -0700409 BaseOS << "Unsupported constant type: " << Ty;
Matt Wala928f1292014-07-07 16:50:46 -0700410 llvm_unreachable(BaseOS.str().c_str());
411 } break;
Jim Stichnothf61d5b22014-05-23 13:31:24 -0700412 case IceType_void:
413 case IceType_NUM:
414 break;
415 }
416 llvm_unreachable("Unknown type");
417}
418
Karl Schimpf9d98d792014-10-13 15:01:08 -0700419FunctionDeclaration *
420GlobalContext::newFunctionDeclaration(const FuncSigType *Signature,
421 unsigned CallingConv, unsigned Linkage,
422 bool IsProto) {
423 FunctionDeclaration *Func = new FunctionDeclaration(
424 *Signature, static_cast<llvm::CallingConv::ID>(CallingConv),
425 static_cast<llvm::GlobalValue::LinkageTypes>(Linkage), IsProto);
426 GlobalDeclarations.push_back(Func);
427 return Func;
428}
429
430VariableDeclaration *GlobalContext::newVariableDeclaration() {
431 VariableDeclaration *Var = new VariableDeclaration();
432 GlobalDeclarations.push_back(Var);
433 return Var;
434}
435
Jim Stichnoth8363a062014-10-07 10:02:38 -0700436TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID,
437 const IceString &Name) {
438 assert(StackID < Timers.size());
439 return Timers[StackID].getTimerID(Name);
Jim Stichnothc4554d72014-09-30 16:49:38 -0700440}
441
Jim Stichnoth8363a062014-10-07 10:02:38 -0700442TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800443 if (!ALLOW_DUMP)
444 return 0;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700445 TimerStackIdT NewID = Timers.size();
446 Timers.push_back(TimerStack(Name));
447 return NewID;
448}
Jim Stichnothc4554d72014-09-30 16:49:38 -0700449
Jim Stichnoth8363a062014-10-07 10:02:38 -0700450void GlobalContext::pushTimer(TimerIdT ID, TimerStackIdT StackID) {
451 assert(StackID < Timers.size());
452 Timers[StackID].push(ID);
453}
454
455void GlobalContext::popTimer(TimerIdT ID, TimerStackIdT StackID) {
456 assert(StackID < Timers.size());
457 Timers[StackID].pop(ID);
458}
Jim Stichnothc4554d72014-09-30 16:49:38 -0700459
Jim Stichnothd14b1a02014-10-08 08:28:36 -0700460void GlobalContext::resetTimer(TimerStackIdT StackID) {
461 assert(StackID < Timers.size());
462 Timers[StackID].reset();
463}
464
465void GlobalContext::setTimerName(TimerStackIdT StackID,
466 const IceString &NewName) {
467 assert(StackID < Timers.size());
468 Timers[StackID].setName(NewName);
469}
470
Jim Stichnothff9c7062014-09-18 04:50:49 -0700471void GlobalContext::dumpStats(const IceString &Name, bool Final) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800472 if (!ALLOW_DUMP)
473 return;
Jim Stichnoth18735602014-09-16 19:59:35 -0700474 if (Flags.DumpStats) {
Jim Stichnothff9c7062014-09-18 04:50:49 -0700475 if (Final) {
476 StatsCumulative.dump(Name, getStrDump());
477 } else {
478 StatsFunction.dump(Name, getStrDump());
479 StatsCumulative.dump("_TOTAL_", getStrDump());
480 }
Jim Stichnoth18735602014-09-16 19:59:35 -0700481 }
482}
483
Jim Stichnoth8363a062014-10-07 10:02:38 -0700484void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800485 if (!ALLOW_DUMP)
486 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700487 assert(Timers.size() > StackID);
488 Timers[StackID].dump(getStrDump(), DumpCumulative);
489}
490
491TimerMarker::TimerMarker(TimerIdT ID, const Cfg *Func)
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800492 : ID(ID), Ctx(Func->getContext()), Active(false) {
493 if (ALLOW_DUMP) {
494 Active = Func->getFocusedTiming() || Ctx->getFlags().SubzeroTimingEnabled;
495 if (Active)
496 Ctx->pushTimer(ID);
497 }
Jim Stichnoth8363a062014-10-07 10:02:38 -0700498}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700499
500} // end of namespace Ice