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 25 matching lines...) Expand all Loading... |
36 | 36 |
37 #ifdef __clang__ | 37 #ifdef __clang__ |
38 #pragma clang diagnostic pop | 38 #pragma clang diagnostic pop |
39 #endif // __clang__ | 39 #endif // __clang__ |
40 | 40 |
41 #include <algorithm> // max() | 41 #include <algorithm> // max() |
42 | 42 |
43 namespace std { | 43 namespace std { |
44 template <> struct hash<Ice::RelocatableTuple> { | 44 template <> struct hash<Ice::RelocatableTuple> { |
45 size_t operator()(const Ice::RelocatableTuple &Key) const { | 45 size_t operator()(const Ice::RelocatableTuple &Key) const { |
46 if (!Key.EmitString.empty()) { | 46 // Use the relocatable's name, plus the hash of a combination of the number |
47 return hash<Ice::IceString>()(Key.EmitString); | 47 // of OffsetExprs and the known, fixed offset for the reloc. We left shift |
48 } | 48 // the known relocatable by 5 trying to minimize the interaction between the |
49 | 49 // bits in OffsetExpr.size() and Key.Offset. |
50 // If there's no emit string, then we use the relocatable's name, plus the | 50 return hash<Ice::SizeT>()(Key.Name.getID()) + |
51 // hash of a combination of the number of OffsetExprs and the known, fixed | |
52 // offset for the reloc. We left shift the known relocatable by 5 trying to | |
53 // minimize the interaction between the bits in OffsetExpr.size() and | |
54 // Key.Offset. | |
55 return hash<Ice::IceString>()(Key.Name) + | |
56 hash<std::size_t>()(Key.OffsetExpr.size() + (Key.Offset << 5)); | 51 hash<std::size_t>()(Key.OffsetExpr.size() + (Key.Offset << 5)); |
57 } | 52 } |
58 }; | 53 }; |
59 } // end of namespace std | 54 } // end of namespace std |
60 | 55 |
61 namespace Ice { | 56 namespace Ice { |
62 | 57 |
63 namespace { | 58 namespace { |
64 | 59 |
65 // Define the key comparison function for the constant pool's unordered_map, | 60 // Define the key comparison function for the constant pool's unordered_map, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; | 206 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; |
212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; | 207 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; |
213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; | 208 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; |
214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; | 209 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; |
215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; | 210 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; |
216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> | 211 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> |
217 ExternRelocatables; | 212 ExternRelocatables; |
218 UndefPool Undefs; | 213 UndefPool Undefs; |
219 }; | 214 }; |
220 | 215 |
221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { | 216 void GlobalContext::CodeStats::dump(const std::string &Name, |
| 217 GlobalContext *Ctx) { |
222 if (!BuildDefs::dump()) | 218 if (!BuildDefs::dump()) |
223 return; | 219 return; |
224 OstreamLocker _(Ctx); | 220 OstreamLocker _(Ctx); |
225 Ostream &Str = Ctx->getStrDump(); | 221 Ostream &Str = Ctx->getStrDump(); |
226 #define X(str, tag) \ | 222 #define X(str, tag) \ |
227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; | 223 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; |
228 CODESTATS_TABLE | 224 CODESTATS_TABLE |
229 #undef X | 225 #undef X |
230 Str << "|" << Name << "|Spills+Fills|" | 226 Str << "|" << Name << "|Spills+Fills|" |
231 << Stats[CS_NumSpills] + Stats[CS_NumFills] << "\n"; | 227 << Stats[CS_NumSpills] + Stats[CS_NumFills] << "\n"; |
(...skipping 14 matching lines...) Expand all Loading... |
246 Str << "|i32=" << Pool->Integers32.size(); | 242 Str << "|i32=" << Pool->Integers32.size(); |
247 Str << "|i64=" << Pool->Integers64.size(); | 243 Str << "|i64=" << Pool->Integers64.size(); |
248 Str << "|Rel=" << Pool->Relocatables.size(); | 244 Str << "|Rel=" << Pool->Relocatables.size(); |
249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); | 245 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); |
250 } | 246 } |
251 Str << "\n"; | 247 Str << "\n"; |
252 } | 248 } |
253 | 249 |
254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 250 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
255 ELFStreamer *ELFStr) | 251 ELFStreamer *ELFStr) |
256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 252 : Strings(new StringPool()), ConstPool(new ConstantPool()), ErrorStatus(), |
257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), | 253 StrDump(OsDump), StrEmit(OsEmit), StrError(OsError), IntrinsicsInfo(this), |
258 OptQ(/*Sequential=*/Flags.isSequential(), | 254 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), |
259 /*MaxSize=*/Flags.getNumTranslationThreads()), | 255 /*MaxSize=*/Flags.getNumTranslationThreads()), |
260 // EmitQ is allowed unlimited size. | 256 // EmitQ is allowed unlimited size. |
261 EmitQ(/*Sequential=*/Flags.isSequential()), | 257 EmitQ(/*Sequential=*/Flags.isSequential()), |
262 DataLowering(TargetDataLowering::createLowering(this)) { | 258 DataLowering(TargetDataLowering::createLowering(this)) { |
263 assert(OsDump && "OsDump is not defined for GlobalContext"); | 259 assert(OsDump && "OsDump is not defined for GlobalContext"); |
264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 260 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
265 assert(OsError && "OsError is not defined for GlobalContext"); | 261 assert(OsError && "OsError is not defined for GlobalContext"); |
266 // Make sure thread_local fields are properly initialized before any | 262 // Make sure thread_local fields are properly initialized before any |
267 // accesses are made. Do this here instead of at the start of | 263 // accesses are made. Do this here instead of at the start of |
268 // main() so that all clients (e.g. unit tests) can benefit for | 264 // main() so that all clients (e.g. unit tests) can benefit for |
269 // free. | 265 // free. |
(...skipping 23 matching lines...) Expand all Loading... |
293 } | 289 } |
294 // Cache up front common constants. | 290 // Cache up front common constants. |
295 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ | 291 #define X(tag, sizeLog2, align, elts, elty, str, rcstr) \ |
296 ConstZeroForType[IceType_##tag] = getConstantZeroInternal(IceType_##tag); | 292 ConstZeroForType[IceType_##tag] = getConstantZeroInternal(IceType_##tag); |
297 ICETYPE_TABLE; | 293 ICETYPE_TABLE; |
298 #undef X | 294 #undef X |
299 ConstantTrue = getConstantInt1Internal(1); | 295 ConstantTrue = getConstantInt1Internal(1); |
300 // Define runtime helper functions. | 296 // Define runtime helper functions. |
301 #define X(Tag, Name) \ | 297 #define X(Tag, Name) \ |
302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ | 298 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ |
303 getConstantExternSym(Name); | 299 getConstantExternSym(getGlobalString(Name)); |
304 RUNTIME_HELPER_FUNCTIONS_TABLE | 300 RUNTIME_HELPER_FUNCTIONS_TABLE |
305 #undef X | 301 #undef X |
306 | 302 |
307 TargetLowering::staticInit(this); | 303 TargetLowering::staticInit(this); |
308 } | 304 } |
309 | 305 |
310 void GlobalContext::translateFunctions() { | 306 void GlobalContext::translateFunctions() { |
311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); | 307 TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 308 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { |
313 // Install Func in TLS for Cfg-specific container allocators. | 309 // Install Func in TLS for Cfg-specific container allocators. |
(...skipping 27 matching lines...) Expand all Loading... |
341 Item = makeUnique<EmitterWorkItem>(Func->getSequenceNumber()); | 337 Item = makeUnique<EmitterWorkItem>(Func->getSequenceNumber()); |
342 } else { | 338 } else { |
343 Func->getAssembler<>()->setInternal(Func->getInternal()); | 339 Func->getAssembler<>()->setInternal(Func->getInternal()); |
344 switch (getFlags().getOutFileType()) { | 340 switch (getFlags().getOutFileType()) { |
345 case FT_Elf: | 341 case FT_Elf: |
346 case FT_Iasm: { | 342 case FT_Iasm: { |
347 Func->emitIAS(); | 343 Func->emitIAS(); |
348 // The Cfg has already emitted into the assembly buffer, so | 344 // The Cfg has already emitted into the assembly buffer, so |
349 // stats have been fully collected into this thread's TLS. | 345 // stats have been fully collected into this thread's TLS. |
350 // Dump them before TLS is reset for the next Cfg. | 346 // Dump them before TLS is reset for the next Cfg. |
351 dumpStats(Func->getFunctionNameAndSize()); | 347 if (BuildDefs::dump()) |
| 348 dumpStats(Func->getFunctionNameAndSize()); |
352 auto Asm = Func->releaseAssembler(); | 349 auto Asm = Func->releaseAssembler(); |
353 // Copy relevant fields into Asm before Func is deleted. | 350 // Copy relevant fields into Asm before Func is deleted. |
354 Asm->setFunctionName(Func->getFunctionName()); | 351 Asm->setFunctionName(Func->getFunctionName()); |
355 Item = makeUnique<EmitterWorkItem>(Func->getSequenceNumber(), | 352 Item = makeUnique<EmitterWorkItem>(Func->getSequenceNumber(), |
356 std::move(Asm)); | 353 std::move(Asm)); |
357 Item->setGlobalInits(Func->getGlobalInits()); | 354 Item->setGlobalInits(Func->getGlobalInits()); |
358 } break; | 355 } break; |
359 case FT_Asm: | 356 case FT_Asm: |
360 // The Cfg has not been emitted yet, so stats are not ready | 357 // The Cfg has not been emitted yet, so stats are not ready |
361 // to be dumped. | 358 // to be dumped. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 void GlobalContext::lowerJumpTables() { DataLowering->lowerJumpTables(); } | 399 void GlobalContext::lowerJumpTables() { DataLowering->lowerJumpTables(); } |
403 | 400 |
404 void GlobalContext::saveBlockInfoPtrs() { | 401 void GlobalContext::saveBlockInfoPtrs() { |
405 for (VariableDeclaration *Global : Globals) { | 402 for (VariableDeclaration *Global : Globals) { |
406 if (Cfg::isProfileGlobal(*Global)) { | 403 if (Cfg::isProfileGlobal(*Global)) { |
407 ProfileBlockInfos.push_back(Global); | 404 ProfileBlockInfos.push_back(Global); |
408 } | 405 } |
409 } | 406 } |
410 } | 407 } |
411 | 408 |
412 void GlobalContext::lowerGlobals(const IceString &SectionSuffix) { | 409 void GlobalContext::lowerGlobals(const std::string &SectionSuffix) { |
413 TimerMarker T(TimerStack::TT_emitGlobalInitializers, this); | 410 TimerMarker T(TimerStack::TT_emitGlobalInitializers, this); |
414 const bool DumpGlobalVariables = BuildDefs::dump() && | 411 const bool DumpGlobalVariables = BuildDefs::dump() && |
415 (Flags.getVerbose() & IceV_GlobalInit) && | 412 (Flags.getVerbose() & IceV_GlobalInit) && |
416 Flags.getVerboseFocusOn().empty(); | 413 Flags.getVerboseFocusOn().empty(); |
417 if (DumpGlobalVariables) { | 414 if (DumpGlobalVariables) { |
418 OstreamLocker L(this); | 415 OstreamLocker L(this); |
419 Ostream &Stream = getStrDump(); | 416 Ostream &Stream = getStrDump(); |
420 for (const Ice::VariableDeclaration *Global : Globals) { | 417 for (const Ice::VariableDeclaration *Global : Globals) { |
421 Global->dump(Stream); | 418 Global->dump(Stream); |
422 } | 419 } |
(...skipping 25 matching lines...) Expand all Loading... |
448 assert(ProfileBlockInfoVarDecl == nullptr); | 445 assert(ProfileBlockInfoVarDecl == nullptr); |
449 | 446 |
450 auto GlobalVariablePool = getInitializerAllocator(); | 447 auto GlobalVariablePool = getInitializerAllocator(); |
451 ProfileBlockInfoVarDecl = | 448 ProfileBlockInfoVarDecl = |
452 VariableDeclaration::createExternal(GlobalVariablePool.get()); | 449 VariableDeclaration::createExternal(GlobalVariablePool.get()); |
453 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); | 450 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); |
454 ProfileBlockInfoVarDecl->setIsConstant(true); | 451 ProfileBlockInfoVarDecl->setIsConstant(true); |
455 | 452 |
456 // Note: if you change this symbol, make sure to update | 453 // Note: if you change this symbol, make sure to update |
457 // runtime/szrt_profiler.c as well. | 454 // runtime/szrt_profiler.c as well. |
458 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); | 455 ProfileBlockInfoVarDecl->setName(this, "__Sz_block_profile_info"); |
459 | 456 |
460 for (const VariableDeclaration *PBI : ProfileBlockInfos) { | 457 for (const VariableDeclaration *PBI : ProfileBlockInfos) { |
461 if (Cfg::isProfileGlobal(*PBI)) { | 458 if (Cfg::isProfileGlobal(*PBI)) { |
462 constexpr RelocOffsetT BlockExecutionCounterOffset = 0; | 459 constexpr RelocOffsetT BlockExecutionCounterOffset = 0; |
463 ProfileBlockInfoVarDecl->addInitializer( | 460 ProfileBlockInfoVarDecl->addInitializer( |
464 VariableDeclaration::RelocInitializer::create( | 461 VariableDeclaration::RelocInitializer::create( |
465 GlobalVariablePool.get(), PBI, | 462 GlobalVariablePool.get(), PBI, |
466 {RelocOffset::create(this, BlockExecutionCounterOffset)})); | 463 {RelocOffset::create(this, BlockExecutionCounterOffset)})); |
467 } | 464 } |
468 } | 465 } |
469 | 466 |
470 // This adds a 64-bit sentinel entry to the end of our array. For 32-bit | 467 // This adds a 64-bit sentinel entry to the end of our array. For 32-bit |
471 // architectures this will waste 4 bytes. | 468 // architectures this will waste 4 bytes. |
472 const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64); | 469 const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64); |
473 ProfileBlockInfoVarDecl->addInitializer( | 470 ProfileBlockInfoVarDecl->addInitializer( |
474 VariableDeclaration::ZeroInitializer::create(GlobalVariablePool.get(), | 471 VariableDeclaration::ZeroInitializer::create(GlobalVariablePool.get(), |
475 Sizeof64BitNullPtr)); | 472 Sizeof64BitNullPtr)); |
476 Globals.push_back(ProfileBlockInfoVarDecl); | 473 Globals.push_back(ProfileBlockInfoVarDecl); |
477 constexpr char ProfileDataSection[] = "$sz_profiler$"; | 474 constexpr char ProfileDataSection[] = "$sz_profiler$"; |
478 lowerGlobals(ProfileDataSection); | 475 lowerGlobals(ProfileDataSection); |
479 } | 476 } |
480 | 477 |
| 478 bool GlobalContext::matchSymbolName(const GlobalString &SymbolName, |
| 479 const std::string &Match) { |
| 480 return Match.empty() || Match == SymbolName.toString(); |
| 481 } |
| 482 |
481 void GlobalContext::emitItems() { | 483 void GlobalContext::emitItems() { |
482 const bool Threaded = !getFlags().isSequential(); | 484 const bool Threaded = !getFlags().isSequential(); |
483 // Pending is a vector containing the reassembled, ordered list of | 485 // Pending is a vector containing the reassembled, ordered list of |
484 // work items. When we're ready for the next item, we first check | 486 // work items. When we're ready for the next item, we first check |
485 // whether it's in the Pending list. If not, we take an item from | 487 // whether it's in the Pending list. If not, we take an item from |
486 // the work queue, and if it's not the item we're waiting for, we | 488 // the work queue, and if it's not the item we're waiting for, we |
487 // insert it into Pending and repeat. The work item is deleted | 489 // insert it into Pending and repeat. The work item is deleted |
488 // after it is processed. | 490 // after it is processed. |
489 std::vector<std::unique_ptr<EmitterWorkItem>> Pending; | 491 std::vector<std::unique_ptr<EmitterWorkItem>> Pending; |
490 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); | 492 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 break; | 563 break; |
562 case EmitterWorkItem::WI_GlobalInits: { | 564 case EmitterWorkItem::WI_GlobalInits: { |
563 accumulateGlobals(Item->getGlobalInits()); | 565 accumulateGlobals(Item->getGlobalInits()); |
564 } break; | 566 } break; |
565 case EmitterWorkItem::WI_Asm: { | 567 case EmitterWorkItem::WI_Asm: { |
566 lowerGlobalsIfNoCodeHasBeenSeen(); | 568 lowerGlobalsIfNoCodeHasBeenSeen(); |
567 accumulateGlobals(Item->getGlobalInits()); | 569 accumulateGlobals(Item->getGlobalInits()); |
568 | 570 |
569 std::unique_ptr<Assembler> Asm = Item->getAsm(); | 571 std::unique_ptr<Assembler> Asm = Item->getAsm(); |
570 Asm->alignFunction(); | 572 Asm->alignFunction(); |
571 const IceString &Name = Asm->getFunctionName(); | 573 GlobalString Name = Asm->getFunctionName(); |
572 switch (getFlags().getOutFileType()) { | 574 switch (getFlags().getOutFileType()) { |
573 case FT_Elf: | 575 case FT_Elf: |
574 getObjectWriter()->writeFunctionCode(Name, Asm->getInternal(), | 576 getObjectWriter()->writeFunctionCode(Name, Asm->getInternal(), |
575 Asm.get()); | 577 Asm.get()); |
576 break; | 578 break; |
577 case FT_Iasm: { | 579 case FT_Iasm: { |
578 OstreamLocker L(this); | 580 OstreamLocker L(this); |
579 Cfg::emitTextHeader(Name, this, Asm.get()); | 581 Cfg::emitTextHeader(Name, this, Asm.get()); |
580 Asm->emitIASBytes(this); | 582 Asm->emitIASBytes(this); |
581 } break; | 583 } break; |
(...skipping 29 matching lines...) Expand all Loading... |
611 } | 613 } |
612 | 614 |
613 GlobalContext::~GlobalContext() { | 615 GlobalContext::~GlobalContext() { |
614 llvm::DeleteContainerPointers(AllThreadContexts); | 616 llvm::DeleteContainerPointers(AllThreadContexts); |
615 LockedPtr<DestructorArray> Dtors = getDestructors(); | 617 LockedPtr<DestructorArray> Dtors = getDestructors(); |
616 // Destructors are invoked in the opposite object construction order. | 618 // Destructors are invoked in the opposite object construction order. |
617 for (const auto &Dtor : reverse_range(*Dtors)) | 619 for (const auto &Dtor : reverse_range(*Dtors)) |
618 Dtor(); | 620 Dtor(); |
619 } | 621 } |
620 | 622 |
| 623 void GlobalContext::dumpStrings() { |
| 624 if (!getFlags().getDumpStrings()) |
| 625 return; |
| 626 OstreamLocker _(this); |
| 627 Ostream &Str = getStrDump(); |
| 628 Str << "GlobalContext strings:\n"; |
| 629 getStrings()->dump(Str); |
| 630 } |
| 631 |
621 void GlobalContext::dumpConstantLookupCounts() { | 632 void GlobalContext::dumpConstantLookupCounts() { |
622 if (!BuildDefs::dump()) | 633 if (!BuildDefs::dump()) |
623 return; | 634 return; |
624 const bool DumpCounts = (Flags.getVerbose() & IceV_ConstPoolStats) && | 635 const bool DumpCounts = (Flags.getVerbose() & IceV_ConstPoolStats) && |
625 Flags.getVerboseFocusOn().empty(); | 636 Flags.getVerboseFocusOn().empty(); |
626 if (!DumpCounts) | 637 if (!DumpCounts) |
627 return; | 638 return; |
628 | 639 |
629 OstreamLocker _(this); | 640 OstreamLocker _(this); |
630 Ostream &Str = getStrDump(); | 641 Ostream &Str = getStrDump(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 } | 702 } |
692 | 703 |
693 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { | 704 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { |
694 return getConstPool()->Floats.getOrAdd(this, ConstantFloat); | 705 return getConstPool()->Floats.getOrAdd(this, ConstantFloat); |
695 } | 706 } |
696 | 707 |
697 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { | 708 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { |
698 return getConstPool()->Doubles.getOrAdd(this, ConstantDouble); | 709 return getConstPool()->Doubles.getOrAdd(this, ConstantDouble); |
699 } | 710 } |
700 | 711 |
701 Constant *GlobalContext::getConstantSym(const RelocOffsetT Offset, | 712 Constant *GlobalContext::getConstantSymWithEmitString( |
702 const RelocOffsetArray &OffsetExpr, | 713 const RelocOffsetT Offset, const RelocOffsetArray &OffsetExpr, |
703 const IceString &Name, | 714 GlobalString Name, const std::string &EmitString) { |
704 const IceString &EmitString) { | |
705 return getConstPool()->Relocatables.getOrAdd( | 715 return getConstPool()->Relocatables.getOrAdd( |
706 this, RelocatableTuple(Offset, OffsetExpr, Name, EmitString)); | 716 this, RelocatableTuple(Offset, OffsetExpr, Name, EmitString)); |
707 } | 717 } |
708 | 718 |
709 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, | 719 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, |
710 const IceString &Name) { | 720 GlobalString Name) { |
711 constexpr char EmptyEmitString[] = ""; | 721 constexpr char EmptyEmitString[] = ""; |
712 return getConstantSym(Offset, {}, Name, EmptyEmitString); | 722 return getConstantSymWithEmitString(Offset, {}, Name, EmptyEmitString); |
713 } | 723 } |
714 | 724 |
715 Constant *GlobalContext::getConstantExternSym(const IceString &Name) { | 725 Constant *GlobalContext::getConstantExternSym(GlobalString Name) { |
716 constexpr RelocOffsetT Offset = 0; | 726 constexpr RelocOffsetT Offset = 0; |
717 return getConstPool()->ExternRelocatables.getOrAdd( | 727 return getConstPool()->ExternRelocatables.getOrAdd( |
718 this, RelocatableTuple(Offset, {}, Name)); | 728 this, RelocatableTuple(Offset, {}, Name)); |
719 } | 729 } |
720 | 730 |
721 Constant *GlobalContext::getConstantUndef(Type Ty) { | 731 Constant *GlobalContext::getConstantUndef(Type Ty) { |
722 return getConstPool()->Undefs.getOrAdd(this, Ty); | 732 return getConstPool()->Undefs.getOrAdd(this, Ty); |
723 } | 733 } |
724 | 734 |
725 Constant *GlobalContext::getConstantZero(Type Ty) { | 735 Constant *GlobalContext::getConstantZero(Type Ty) { |
726 Constant *Zero = ConstZeroForType[Ty]; | 736 Constant *Zero = ConstZeroForType[Ty]; |
727 if (Zero == nullptr) | 737 if (Zero == nullptr) |
728 llvm::report_fatal_error("Unsupported constant type: " + typeIceString(Ty)); | 738 llvm::report_fatal_error("Unsupported constant type: " + typeStdString(Ty)); |
729 return Zero; | 739 return Zero; |
730 } | 740 } |
731 | 741 |
732 // All locking is done by the getConstant*() target function. | 742 // All locking is done by the getConstant*() target function. |
733 Constant *GlobalContext::getConstantZeroInternal(Type Ty) { | 743 Constant *GlobalContext::getConstantZeroInternal(Type Ty) { |
734 switch (Ty) { | 744 switch (Ty) { |
735 case IceType_i1: | 745 case IceType_i1: |
736 return getConstantInt1Internal(0); | 746 return getConstantInt1Internal(0); |
737 case IceType_i8: | 747 case IceType_i8: |
738 return getConstantInt8Internal(0); | 748 return getConstantInt8Internal(0); |
(...skipping 26 matching lines...) Expand all Loading... |
765 case IceType_f32: | 775 case IceType_f32: |
766 return getConstPool()->Floats.getConstantPool(); | 776 return getConstPool()->Floats.getConstantPool(); |
767 case IceType_f64: | 777 case IceType_f64: |
768 return getConstPool()->Doubles.getConstantPool(); | 778 return getConstPool()->Doubles.getConstantPool(); |
769 case IceType_v4i1: | 779 case IceType_v4i1: |
770 case IceType_v8i1: | 780 case IceType_v8i1: |
771 case IceType_v16i1: | 781 case IceType_v16i1: |
772 case IceType_v16i8: | 782 case IceType_v16i8: |
773 case IceType_v8i16: | 783 case IceType_v8i16: |
774 case IceType_v4i32: | 784 case IceType_v4i32: |
775 case IceType_v4f32: { | 785 case IceType_v4f32: |
776 IceString Str; | 786 llvm::report_fatal_error("Unsupported constant type: " + typeStdString(Ty)); |
777 llvm::raw_string_ostream BaseOS(Str); | 787 break; |
778 BaseOS << "Unsupported constant type: " << Ty; | |
779 llvm_unreachable(BaseOS.str().c_str()); | |
780 } break; | |
781 case IceType_void: | 788 case IceType_void: |
782 case IceType_NUM: | 789 case IceType_NUM: |
783 break; | 790 break; |
784 } | 791 } |
785 llvm_unreachable("Unknown type"); | 792 llvm_unreachable("Unknown type"); |
786 } | 793 } |
787 | 794 |
788 ConstantList GlobalContext::getConstantExternSyms() { | 795 ConstantList GlobalContext::getConstantExternSyms() { |
789 return getConstPool()->ExternRelocatables.getConstantPool(); | 796 return getConstPool()->ExternRelocatables.getConstantPool(); |
790 } | 797 } |
791 | 798 |
| 799 GlobalString GlobalContext::getGlobalString(const std::string &Name) { |
| 800 return GlobalString::createWithString(this, Name); |
| 801 } |
| 802 |
792 JumpTableDataList GlobalContext::getJumpTables() { | 803 JumpTableDataList GlobalContext::getJumpTables() { |
793 JumpTableDataList JumpTables(*getJumpTableList()); | 804 JumpTableDataList JumpTables(*getJumpTableList()); |
794 // Make order deterministic by sorting into functions and then ID of the jump | 805 // Make order deterministic by sorting into functions and then ID of the jump |
795 // table within that function. | 806 // table within that function. |
796 std::sort(JumpTables.begin(), JumpTables.end(), | 807 std::sort(JumpTables.begin(), JumpTables.end(), |
797 [](const JumpTableData &A, const JumpTableData &B) { | 808 [](const JumpTableData &A, const JumpTableData &B) { |
798 if (A.getFunctionName() != B.getFunctionName()) | 809 if (A.getFunctionName() != B.getFunctionName()) |
799 return A.getFunctionName() < B.getFunctionName(); | 810 return A.getFunctionName() < B.getFunctionName(); |
800 return A.getId() < B.getId(); | 811 return A.getId() < B.getId(); |
801 }); | 812 }); |
802 | 813 |
803 if (getFlags().getReorderPooledConstants()) { | 814 if (getFlags().getReorderPooledConstants()) { |
804 // If reorder-pooled-constants option is set to true, we also shuffle the | 815 // If reorder-pooled-constants option is set to true, we also shuffle the |
805 // jump tables before emitting them. | 816 // jump tables before emitting them. |
806 | 817 |
807 // Create a random number generator for jump tables reordering, considering | 818 // Create a random number generator for jump tables reordering, considering |
808 // jump tables as pooled constants. | 819 // jump tables as pooled constants. |
809 RandomNumberGenerator RNG(getFlags().getRandomSeed(), | 820 RandomNumberGenerator RNG(getFlags().getRandomSeed(), |
810 RPE_PooledConstantReordering); | 821 RPE_PooledConstantReordering); |
811 RandomShuffle(JumpTables.begin(), JumpTables.end(), | 822 RandomShuffle(JumpTables.begin(), JumpTables.end(), |
812 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); | 823 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); |
813 } | 824 } |
814 return JumpTables; | 825 return JumpTables; |
815 } | 826 } |
816 | 827 |
817 JumpTableData & | 828 JumpTableData & |
818 GlobalContext::addJumpTable(const IceString &FuncName, SizeT Id, | 829 GlobalContext::addJumpTable(GlobalString FuncName, SizeT Id, |
819 const JumpTableData::TargetList &TargetList) { | 830 const JumpTableData::TargetList &TargetList) { |
820 auto JumpTableList = getJumpTableList(); | 831 auto JumpTableList = getJumpTableList(); |
821 JumpTableList->emplace_back(FuncName, Id, TargetList); | 832 JumpTableList->emplace_back(FuncName, Id, TargetList); |
822 return JumpTableList->back(); | 833 return JumpTableList->back(); |
823 } | 834 } |
824 | 835 |
825 TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) { | 836 TimerStackIdT GlobalContext::newTimerStackID(const std::string &Name) { |
826 if (!BuildDefs::timers()) | 837 if (!BuildDefs::timers()) |
827 return 0; | 838 return 0; |
828 auto Timers = getTimers(); | 839 auto Timers = getTimers(); |
829 TimerStackIdT NewID = Timers->size(); | 840 TimerStackIdT NewID = Timers->size(); |
830 Timers->push_back(TimerStack(Name)); | 841 Timers->push_back(TimerStack(Name)); |
831 return NewID; | 842 return NewID; |
832 } | 843 } |
833 | 844 |
834 TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID, | 845 TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID, |
835 const IceString &Name) { | 846 const std::string &Name) { |
836 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 847 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
837 assert(StackID < Timers->size()); | 848 assert(StackID < Timers->size()); |
838 return Timers->at(StackID).getTimerID(Name); | 849 return Timers->at(StackID).getTimerID(Name); |
839 } | 850 } |
840 | 851 |
841 void GlobalContext::pushTimer(TimerIdT ID, TimerStackIdT StackID) { | 852 void GlobalContext::pushTimer(TimerIdT ID, TimerStackIdT StackID) { |
842 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 853 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
843 assert(StackID < Timers->size()); | 854 assert(StackID < Timers->size()); |
844 Timers->at(StackID).push(ID); | 855 Timers->at(StackID).push(ID); |
845 } | 856 } |
846 | 857 |
847 void GlobalContext::popTimer(TimerIdT ID, TimerStackIdT StackID) { | 858 void GlobalContext::popTimer(TimerIdT ID, TimerStackIdT StackID) { |
848 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 859 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
849 assert(StackID < Timers->size()); | 860 assert(StackID < Timers->size()); |
850 Timers->at(StackID).pop(ID); | 861 Timers->at(StackID).pop(ID); |
851 } | 862 } |
852 | 863 |
853 void GlobalContext::resetTimer(TimerStackIdT StackID) { | 864 void GlobalContext::resetTimer(TimerStackIdT StackID) { |
854 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 865 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
855 assert(StackID < Timers->size()); | 866 assert(StackID < Timers->size()); |
856 Timers->at(StackID).reset(); | 867 Timers->at(StackID).reset(); |
857 } | 868 } |
858 | 869 |
859 void GlobalContext::setTimerName(TimerStackIdT StackID, | 870 void GlobalContext::setTimerName(TimerStackIdT StackID, |
860 const IceString &NewName) { | 871 const std::string &NewName) { |
861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 872 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
862 assert(StackID < Timers->size()); | 873 assert(StackID < Timers->size()); |
863 Timers->at(StackID).setName(NewName); | 874 Timers->at(StackID).setName(NewName); |
864 } | 875 } |
865 | 876 |
866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the | 877 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the |
867 // interface to take and transfer ownership, but they internally store the raw | 878 // interface to take and transfer ownership, but they internally store the raw |
868 // Cfg pointer in the work queue. This allows e.g. future queue optimizations | 879 // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
869 // such as the use of atomics to modify queue elements. | 880 // such as the use of atomics to modify queue elements. |
870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { | 881 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { |
(...skipping 20 matching lines...) Expand all Loading... |
891 } | 902 } |
892 if (getFlags().isSequential()) | 903 if (getFlags().isSequential()) |
893 emitItems(); | 904 emitItems(); |
894 } | 905 } |
895 | 906 |
896 std::unique_ptr<EmitterWorkItem> GlobalContext::emitQueueBlockingPop() { | 907 std::unique_ptr<EmitterWorkItem> GlobalContext::emitQueueBlockingPop() { |
897 TimerMarker _(TimerStack::TT_qEmitPop, this); | 908 TimerMarker _(TimerStack::TT_qEmitPop, this); |
898 return EmitQ.blockingPop(); | 909 return EmitQ.blockingPop(); |
899 } | 910 } |
900 | 911 |
901 void GlobalContext::dumpStats(const IceString &Name, bool Final) { | 912 void GlobalContext::dumpStats(const std::string &Name, bool Final) { |
902 if (!getFlags().getDumpStats()) | 913 if (!getFlags().getDumpStats()) |
903 return; | 914 return; |
904 if (Final) { | 915 if (Final) { |
905 getStatsCumulative()->dump(Name, this); | 916 getStatsCumulative()->dump(Name, this); |
906 } else { | 917 } else { |
907 ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Name, this); | 918 ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Name, this); |
908 } | 919 } |
909 } | 920 } |
910 | 921 |
911 void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) { | 922 void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) { |
912 if (!BuildDefs::timers()) | 923 if (!BuildDefs::timers()) |
913 return; | 924 return; |
914 auto Timers = getTimers(); | 925 auto Timers = getTimers(); |
915 assert(Timers->size() > StackID); | 926 assert(Timers->size() > StackID); |
916 OstreamLocker L(this); | 927 OstreamLocker L(this); |
917 Timers->at(StackID).dump(getStrDump(), DumpCumulative); | 928 Timers->at(StackID).dump(getStrDump(), DumpCumulative); |
918 } | 929 } |
919 | 930 |
| 931 LockedPtr<StringPool> |
| 932 GlobalStringPoolTraits::getStrings(const GlobalContext *PoolOwner) { |
| 933 return PoolOwner->getStrings(); |
| 934 } |
| 935 |
920 ClFlags GlobalContext::Flags; | 936 ClFlags GlobalContext::Flags; |
921 | 937 |
922 TimerIdT TimerMarker::getTimerIdFromFuncName(GlobalContext *Ctx, | 938 TimerIdT TimerMarker::getTimerIdFromFuncName(GlobalContext *Ctx, |
923 const IceString &FuncName) { | 939 const std::string &FuncName) { |
924 if (!BuildDefs::timers()) | 940 if (!BuildDefs::timers()) |
925 return 0; | 941 return 0; |
926 if (!Ctx->getFlags().getTimeEachFunction()) | 942 if (!Ctx->getFlags().getTimeEachFunction()) |
927 return 0; | 943 return 0; |
928 return Ctx->getTimerID(GlobalContext::TSK_Funcs, FuncName); | 944 return Ctx->getTimerID(GlobalContext::TSK_Funcs, FuncName); |
929 } | 945 } |
930 | 946 |
931 void TimerMarker::push() { | 947 void TimerMarker::push() { |
932 switch (StackID) { | 948 switch (StackID) { |
933 case GlobalContext::TSK_Default: | 949 case GlobalContext::TSK_Default: |
(...skipping 13 matching lines...) Expand all Loading... |
947 Ctx = Func->getContext(); | 963 Ctx = Func->getContext(); |
948 Active = | 964 Active = |
949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 965 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
950 if (Active) | 966 if (Active) |
951 Ctx->pushTimer(ID, StackID); | 967 Ctx->pushTimer(ID, StackID); |
952 } | 968 } |
953 | 969 |
954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 970 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
955 | 971 |
956 } // end of namespace Ice | 972 } // end of namespace Ice |
OLD | NEW |