| OLD | NEW |
| 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// | 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines aspects of the compilation that persist across | 10 // This file defines aspects of the compilation that persist across |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 217 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| 218 ELFStreamer *ELFStr, const ClFlags &Flags) | 218 ELFStreamer *ELFStr, const ClFlags &Flags) |
| 219 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 219 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
| 220 StrEmit(OsEmit), StrError(OsError), Flags(Flags), | 220 StrEmit(OsEmit), StrError(OsError), Flags(Flags), |
| 221 RNG(Flags.getRandomSeed()), ObjectWriter(), | 221 RNG(Flags.getRandomSeed()), ObjectWriter(), |
| 222 OptQ(/*Sequential=*/Flags.isSequential(), | 222 OptQ(/*Sequential=*/Flags.isSequential(), |
| 223 /*MaxSize=*/Flags.getNumTranslationThreads()), | 223 /*MaxSize=*/Flags.getNumTranslationThreads()), |
| 224 // EmitQ is allowed unlimited size. | 224 // EmitQ is allowed unlimited size. |
| 225 EmitQ(/*Sequential=*/Flags.isSequential()), | 225 EmitQ(/*Sequential=*/Flags.isSequential()), |
| 226 DataLowering(TargetDataLowering::createLowering(this)), | 226 DataLowering(TargetDataLowering::createLowering(this)), |
| 227 HasSeenCode(false), | 227 HasSeenCode(false) { |
| 228 ProfileBlockInfoVarDecl(VariableDeclaration::create()) { | |
| 229 assert(OsDump && "OsDump is not defined for GlobalContext"); | 228 assert(OsDump && "OsDump is not defined for GlobalContext"); |
| 230 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 229 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
| 231 assert(OsError && "OsError is not defined for GlobalContext"); | 230 assert(OsError && "OsError is not defined for GlobalContext"); |
| 232 // Make sure thread_local fields are properly initialized before any | 231 // Make sure thread_local fields are properly initialized before any |
| 233 // accesses are made. Do this here instead of at the start of | 232 // accesses are made. Do this here instead of at the start of |
| 234 // main() so that all clients (e.g. unit tests) can benefit for | 233 // main() so that all clients (e.g. unit tests) can benefit for |
| 235 // free. | 234 // free. |
| 236 GlobalContext::TlsInit(); | 235 GlobalContext::TlsInit(); |
| 237 Cfg::TlsInit(); | 236 Cfg::TlsInit(); |
| 238 // Create a new ThreadContext for the current thread. No need to | 237 // Create a new ThreadContext for the current thread. No need to |
| (...skipping 11 matching lines...) Expand all Loading... |
| 250 } | 249 } |
| 251 Timers.initInto(MyTLS->Timers); | 250 Timers.initInto(MyTLS->Timers); |
| 252 switch (Flags.getOutFileType()) { | 251 switch (Flags.getOutFileType()) { |
| 253 case FT_Elf: | 252 case FT_Elf: |
| 254 ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr)); | 253 ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr)); |
| 255 break; | 254 break; |
| 256 case FT_Asm: | 255 case FT_Asm: |
| 257 case FT_Iasm: | 256 case FT_Iasm: |
| 258 break; | 257 break; |
| 259 } | 258 } |
| 259 |
| 260 // ProfileBlockInfoVarDecl is initialized here because it takes this as a |
| 261 // parameter -- we want to |
| 262 // ensure that at least this' member variables are initialized. |
| 263 ProfileBlockInfoVarDecl = VariableDeclaration::create(this); |
| 260 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); | 264 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); |
| 261 ProfileBlockInfoVarDecl->setIsConstant(true); | 265 ProfileBlockInfoVarDecl->setIsConstant(true); |
| 262 | 266 |
| 263 // Note: if you change this symbol, make sure to update | 267 // Note: if you change this symbol, make sure to update |
| 264 // runtime/szrt_profiler.c as well. | 268 // runtime/szrt_profiler.c as well. |
| 265 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); | 269 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); |
| 266 ProfileBlockInfoVarDecl->setSuppressMangling(); | 270 ProfileBlockInfoVarDecl->setSuppressMangling(); |
| 267 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 271 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 268 } | 272 } |
| 269 | 273 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 } | 336 } |
| 333 | 337 |
| 334 namespace { | 338 namespace { |
| 335 | 339 |
| 336 void addBlockInfoPtrs(const VariableDeclarationList &Globals, | 340 void addBlockInfoPtrs(const VariableDeclarationList &Globals, |
| 337 VariableDeclaration *ProfileBlockInfo) { | 341 VariableDeclaration *ProfileBlockInfo) { |
| 338 for (const VariableDeclaration *Global : Globals) { | 342 for (const VariableDeclaration *Global : Globals) { |
| 339 if (Cfg::isProfileGlobal(*Global)) { | 343 if (Cfg::isProfileGlobal(*Global)) { |
| 340 constexpr RelocOffsetT BlockExecutionCounterOffset = 0; | 344 constexpr RelocOffsetT BlockExecutionCounterOffset = 0; |
| 341 ProfileBlockInfo->addInitializer( | 345 ProfileBlockInfo->addInitializer( |
| 342 new VariableDeclaration::RelocInitializer( | 346 VariableDeclaration::RelocInitializer::create( |
| 343 Global, BlockExecutionCounterOffset)); | 347 Global, BlockExecutionCounterOffset)); |
| 344 } | 348 } |
| 345 } | 349 } |
| 346 } | 350 } |
| 347 | 351 |
| 348 // Ensure Pending is large enough that Pending[Index] is valid. | 352 // Ensure Pending is large enough that Pending[Index] is valid. |
| 349 void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) { | 353 void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) { |
| 350 if (Index >= Pending.size()) | 354 if (Index >= Pending.size()) |
| 351 Pending.resize(Index + 1); | 355 Pending.resize(Index + 1); |
| 352 } | 356 } |
| 353 | 357 |
| 354 } // end of anonymous namespace | 358 } // end of anonymous namespace |
| 355 | 359 |
| 356 void GlobalContext::emitFileHeader() { | 360 void GlobalContext::emitFileHeader() { |
| 357 TimerMarker T1(Ice::TimerStack::TT_emit, this); | 361 TimerMarker T1(Ice::TimerStack::TT_emit, this); |
| 358 if (getFlags().getOutFileType() == FT_Elf) { | 362 if (getFlags().getOutFileType() == FT_Elf) { |
| 359 getObjectWriter()->writeInitialELFHeader(); | 363 getObjectWriter()->writeInitialELFHeader(); |
| 360 } else { | 364 } else { |
| 361 if (!ALLOW_DUMP) | 365 if (!ALLOW_DUMP) |
| 362 llvm::report_fatal_error("emitFileHeader for non-ELF"); | 366 llvm::report_fatal_error("emitFileHeader for non-ELF"); |
| 363 TargetHeaderLowering::createLowering(this)->lower(); | 367 TargetHeaderLowering::createLowering(this)->lower(); |
| 364 } | 368 } |
| 365 } | 369 } |
| 366 | 370 |
| 367 void GlobalContext::lowerConstants() { | 371 void GlobalContext::lowerConstants() { DataLowering->lowerConstants(); } |
| 368 DataLowering->lowerConstants(); | |
| 369 } | |
| 370 | 372 |
| 371 void GlobalContext::lowerGlobals(const IceString &SectionSuffix) { | 373 void GlobalContext::lowerGlobals(const IceString &SectionSuffix) { |
| 372 TimerMarker T(TimerStack::TT_emitGlobalInitializers, this); | 374 TimerMarker T(TimerStack::TT_emitGlobalInitializers, this); |
| 373 const bool DumpGlobalVariables = | 375 const bool DumpGlobalVariables = |
| 374 ALLOW_DUMP && Flags.getVerbose() && Flags.getVerboseFocusOn().empty(); | 376 ALLOW_DUMP && Flags.getVerbose() && Flags.getVerboseFocusOn().empty(); |
| 375 if (DumpGlobalVariables) { | 377 if (DumpGlobalVariables) { |
| 376 OstreamLocker L(this); | 378 OstreamLocker L(this); |
| 377 Ostream &Stream = getStrDump(); | 379 Ostream &Stream = getStrDump(); |
| 378 for (const Ice::VariableDeclaration *Global : Globals) { | 380 for (const Ice::VariableDeclaration *Global : Globals) { |
| 379 Global->dump(this, Stream); | 381 Global->dump(this, Stream); |
| 380 } | 382 } |
| 381 } | 383 } |
| 382 if (Flags.getDisableTranslation()) | 384 if (Flags.getDisableTranslation()) |
| 383 return; | 385 return; |
| 384 | 386 |
| 385 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl.get()); | 387 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); |
| 386 DataLowering->lowerGlobals(Globals, SectionSuffix); | 388 DataLowering->lowerGlobals(Globals, SectionSuffix); |
| 389 for (VariableDeclaration *Var : Globals) { |
| 390 Var->discardInitializers(); |
| 391 } |
| 387 Globals.clear(); | 392 Globals.clear(); |
| 388 } | 393 } |
| 389 | 394 |
| 390 void GlobalContext::lowerProfileData() { | 395 void GlobalContext::lowerProfileData() { |
| 396 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only |
| 397 // ever be nullptr after this method completes. This assertion is a convoluted |
| 398 // way of ensuring lowerProfileData is invoked a single time. |
| 399 assert(ProfileBlockInfoVarDecl != nullptr); |
| 391 // This adds a 64-bit sentinel entry to the end of our array. For 32-bit | 400 // This adds a 64-bit sentinel entry to the end of our array. For 32-bit |
| 392 // architectures this will waste 4 bytes. | 401 // architectures this will waste 4 bytes. |
| 393 const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64); | 402 const SizeT Sizeof64BitNullPtr = typeWidthInBytes(IceType_i64); |
| 394 ProfileBlockInfoVarDecl->addInitializer( | 403 ProfileBlockInfoVarDecl->addInitializer( |
| 395 new VariableDeclaration::ZeroInitializer(Sizeof64BitNullPtr)); | 404 VariableDeclaration::ZeroInitializer::create(Sizeof64BitNullPtr)); |
| 396 Globals.push_back(ProfileBlockInfoVarDecl.get()); | 405 Globals.push_back(ProfileBlockInfoVarDecl); |
| 397 constexpr char ProfileDataSection[] = "$sz_profiler$"; | 406 constexpr char ProfileDataSection[] = "$sz_profiler$"; |
| 398 lowerGlobals(ProfileDataSection); | 407 lowerGlobals(ProfileDataSection); |
| 408 ProfileBlockInfoVarDecl = nullptr; |
| 399 } | 409 } |
| 400 | 410 |
| 401 void GlobalContext::emitItems() { | 411 void GlobalContext::emitItems() { |
| 402 const bool Threaded = !getFlags().isSequential(); | 412 const bool Threaded = !getFlags().isSequential(); |
| 403 // Pending is a vector containing the reassembled, ordered list of | 413 // Pending is a vector containing the reassembled, ordered list of |
| 404 // work items. When we're ready for the next item, we first check | 414 // work items. When we're ready for the next item, we first check |
| 405 // whether it's in the Pending list. If not, we take an item from | 415 // whether it's in the Pending list. If not, we take an item from |
| 406 // the work queue, and if it's not the item we're waiting for, we | 416 // the work queue, and if it's not the item we're waiting for, we |
| 407 // insert it into Pending and repeat. The work item is deleted | 417 // insert it into Pending and repeat. The work item is deleted |
| 408 // after it is processed. | 418 // after it is processed. |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 return NewName.data(); | 647 return NewName.data(); |
| 638 } | 648 } |
| 639 | 649 |
| 640 // Transform bar ==> Prefixbar | 650 // Transform bar ==> Prefixbar |
| 641 // ^^^^^^ | 651 // ^^^^^^ |
| 642 return TestPrefix + Name; | 652 return TestPrefix + Name; |
| 643 } | 653 } |
| 644 | 654 |
| 645 GlobalContext::~GlobalContext() { | 655 GlobalContext::~GlobalContext() { |
| 646 llvm::DeleteContainerPointers(AllThreadContexts); | 656 llvm::DeleteContainerPointers(AllThreadContexts); |
| 657 LockedPtr<DestructorArray> Dtors = getDestructors(); |
| 658 // Destructors are invoked in the opposite object construction order. |
| 659 for (auto DtorIter = Dtors->crbegin(); DtorIter != Dtors->crend(); |
| 660 ++DtorIter) { |
| 661 (*DtorIter)(); |
| 662 } |
| 647 } | 663 } |
| 648 | 664 |
| 649 // TODO(stichnot): Consider adding thread-local caches of constant | 665 // TODO(stichnot): Consider adding thread-local caches of constant |
| 650 // pool entries to reduce contention. | 666 // pool entries to reduce contention. |
| 651 | 667 |
| 652 // All locking is done by the getConstantInt[0-9]+() target function. | 668 // All locking is done by the getConstantInt[0-9]+() target function. |
| 653 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) { | 669 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) { |
| 654 switch (Ty) { | 670 switch (Ty) { |
| 655 case IceType_i1: | 671 case IceType_i1: |
| 656 return getConstantInt1(Value); | 672 return getConstantInt1(Value); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 Ctx = Func->getContext(); | 910 Ctx = Func->getContext(); |
| 895 Active = | 911 Active = |
| 896 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 912 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 897 if (Active) | 913 if (Active) |
| 898 Ctx->pushTimer(ID, StackID); | 914 Ctx->pushTimer(ID, StackID); |
| 899 } | 915 } |
| 900 | 916 |
| 901 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 917 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 902 | 918 |
| 903 } // end of namespace Ice | 919 } // end of namespace Ice |
| OLD | NEW |