| 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 |