Chromium Code Reviews| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (ssize_t MemUsed = llvm::TimeRecord::getCurrentTime(false).getMemUsed()) | 215 if (ssize_t MemUsed = llvm::TimeRecord::getCurrentTime(false).getMemUsed()) |
| 216 Str << MemUsed; | 216 Str << MemUsed; |
| 217 else | 217 else |
| 218 Str << "(requires '-track-memory')"; | 218 Str << "(requires '-track-memory')"; |
| 219 Str << "\n"; | 219 Str << "\n"; |
| 220 } | 220 } |
| 221 | 221 |
| 222 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 222 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| 223 ELFStreamer *ELFStr, const ClFlags &Flags) | 223 ELFStreamer *ELFStr, const ClFlags &Flags) |
| 224 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 224 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
| 225 StrEmit(OsEmit), StrError(OsError), Flags(Flags), | 225 StrEmit(OsEmit), StrError(OsError), Flags(Flags), ObjectWriter(), |
| 226 RNG(Flags.getRandomSeed()), ObjectWriter(), | |
|
Jim Stichnoth
2015/08/20 04:04:41
A few points regarding ClFlags::RandomSeed. (Thes
jvoung (off chromium)
2015/08/20 12:41:04
I need to look at the rest of the CL, but BrowserC
qining
2015/08/20 16:19:33
I guess this would be a separate CL?
| |
| 227 OptQ(/*Sequential=*/Flags.isSequential(), | 226 OptQ(/*Sequential=*/Flags.isSequential(), |
| 228 /*MaxSize=*/Flags.getNumTranslationThreads()), | 227 /*MaxSize=*/Flags.getNumTranslationThreads()), |
| 229 // EmitQ is allowed unlimited size. | 228 // EmitQ is allowed unlimited size. |
| 230 EmitQ(/*Sequential=*/Flags.isSequential()), | 229 EmitQ(/*Sequential=*/Flags.isSequential()), |
| 231 DataLowering(TargetDataLowering::createLowering(this)) { | 230 DataLowering(TargetDataLowering::createLowering(this)) { |
| 232 assert(OsDump && "OsDump is not defined for GlobalContext"); | 231 assert(OsDump && "OsDump is not defined for GlobalContext"); |
| 233 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 232 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
| 234 assert(OsError && "OsError is not defined for GlobalContext"); | 233 assert(OsError && "OsError is not defined for GlobalContext"); |
| 235 // Make sure thread_local fields are properly initialized before any | 234 // Make sure thread_local fields are properly initialized before any |
| 236 // accesses are made. Do this here instead of at the start of | 235 // accesses are made. Do this here instead of at the start of |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 266 // ensure that at least this' member variables are initialized. | 265 // ensure that at least this' member variables are initialized. |
| 267 ProfileBlockInfoVarDecl = VariableDeclaration::create(this); | 266 ProfileBlockInfoVarDecl = VariableDeclaration::create(this); |
| 268 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); | 267 ProfileBlockInfoVarDecl->setAlignment(typeWidthInBytes(IceType_i64)); |
| 269 ProfileBlockInfoVarDecl->setIsConstant(true); | 268 ProfileBlockInfoVarDecl->setIsConstant(true); |
| 270 | 269 |
| 271 // Note: if you change this symbol, make sure to update | 270 // Note: if you change this symbol, make sure to update |
| 272 // runtime/szrt_profiler.c as well. | 271 // runtime/szrt_profiler.c as well. |
| 273 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); | 272 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); |
| 274 ProfileBlockInfoVarDecl->setSuppressMangling(); | 273 ProfileBlockInfoVarDecl->setSuppressMangling(); |
| 275 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 274 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 276 | |
| 277 // Initialize the randomization cookie for constant blinding only if constant | |
| 278 // blinding or pooling is turned on. | |
| 279 // TODO(stichnot): Using RNG for constant blinding will affect the random | |
| 280 // number to be used in nop-insertion and randomize-regalloc. | |
| 281 if (Flags.getRandomizeAndPoolImmediatesOption() != RPI_None) | |
| 282 RandomizationCookie = | |
| 283 (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max + 1); | |
| 284 } | 275 } |
| 285 | 276 |
| 286 void GlobalContext::translateFunctions() { | 277 void GlobalContext::translateFunctions() { |
| 287 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 278 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { |
| 288 // Install Func in TLS for Cfg-specific container allocators. | 279 // Install Func in TLS for Cfg-specific container allocators. |
| 289 Cfg::setCurrentCfg(Func.get()); | 280 Cfg::setCurrentCfg(Func.get()); |
| 290 // Reset per-function stats being accumulated in TLS. | 281 // Reset per-function stats being accumulated in TLS. |
| 291 resetStats(); | 282 resetStats(); |
| 292 // Set verbose level to none if the current function does NOT | 283 // Set verbose level to none if the current function does NOT |
| 293 // match the -verbose-focus command-line option. | 284 // match the -verbose-focus command-line option. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 for (const Ice::VariableDeclaration *Global : Globals) { | 387 for (const Ice::VariableDeclaration *Global : Globals) { |
| 397 Global->dump(this, Stream); | 388 Global->dump(this, Stream); |
| 398 } | 389 } |
| 399 } | 390 } |
| 400 if (Flags.getDisableTranslation()) | 391 if (Flags.getDisableTranslation()) |
| 401 return; | 392 return; |
| 402 | 393 |
| 403 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); | 394 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); |
| 404 // If we need to shuffle the layout of global variables, shuffle them now. | 395 // If we need to shuffle the layout of global variables, shuffle them now. |
| 405 if (getFlags().shouldReorderGlobalVariables()) { | 396 if (getFlags().shouldReorderGlobalVariables()) { |
| 406 auto *RNGPtr = &RNG; | 397 // Create a random number generator for global variable reordering. |
| 398 RandomNumberGenerator RNG(getFlags().getRandomSeed(), | |
| 399 RPE_GlobalVariableReordering); | |
| 407 RandomShuffle(Globals.begin(), Globals.end(), | 400 RandomShuffle(Globals.begin(), Globals.end(), |
| 408 [RNGPtr](int N) { return (uint32_t)RNGPtr->next(N); }); | 401 [&RNG](int N) { return (uint32_t)RNG.next(N); }); |
| 409 } | 402 } |
| 410 DataLowering->lowerGlobals(Globals, SectionSuffix); | 403 DataLowering->lowerGlobals(Globals, SectionSuffix); |
| 411 for (VariableDeclaration *Var : Globals) { | 404 for (VariableDeclaration *Var : Globals) { |
| 412 Var->discardInitializers(); | 405 Var->discardInitializers(); |
| 413 } | 406 } |
| 414 Globals.clear(); | 407 Globals.clear(); |
| 415 } | 408 } |
| 416 | 409 |
| 417 void GlobalContext::lowerProfileData() { | 410 void GlobalContext::lowerProfileData() { |
| 418 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only | 411 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 439 // insert it into Pending and repeat. The work item is deleted | 432 // insert it into Pending and repeat. The work item is deleted |
| 440 // after it is processed. | 433 // after it is processed. |
| 441 std::vector<EmitterWorkItem *> Pending; | 434 std::vector<EmitterWorkItem *> Pending; |
| 442 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); | 435 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); |
| 443 uint32_t ShuffleStartIndex = DesiredSequenceNumber; | 436 uint32_t ShuffleStartIndex = DesiredSequenceNumber; |
| 444 uint32_t ShuffleEndIndex = DesiredSequenceNumber; | 437 uint32_t ShuffleEndIndex = DesiredSequenceNumber; |
| 445 bool EmitQueueEmpty = false; | 438 bool EmitQueueEmpty = false; |
| 446 const uint32_t ShuffleWindowSize = | 439 const uint32_t ShuffleWindowSize = |
| 447 std::max(1u, getFlags().getReorderFunctionsWindowSize()); | 440 std::max(1u, getFlags().getReorderFunctionsWindowSize()); |
| 448 bool Shuffle = Threaded && getFlags().shouldReorderFunctions(); | 441 bool Shuffle = Threaded && getFlags().shouldReorderFunctions(); |
| 442 // Create a random number generator for function reordering. | |
| 443 RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_FunctionReordering); | |
| 444 | |
| 449 while (!EmitQueueEmpty) { | 445 while (!EmitQueueEmpty) { |
| 450 resizePending(Pending, DesiredSequenceNumber); | 446 resizePending(Pending, DesiredSequenceNumber); |
| 451 // See if Pending contains DesiredSequenceNumber. | 447 // See if Pending contains DesiredSequenceNumber. |
| 452 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; | 448 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; |
| 453 if (RawItem == nullptr) { | 449 if (RawItem == nullptr) { |
| 454 // We need to fetch an EmitterWorkItem from the queue. | 450 // We need to fetch an EmitterWorkItem from the queue. |
| 455 RawItem = emitQueueBlockingPop(); | 451 RawItem = emitQueueBlockingPop(); |
| 456 if (RawItem == nullptr) { | 452 if (RawItem == nullptr) { |
| 457 // This is the notifier for an empty queue. | 453 // This is the notifier for an empty queue. |
| 458 EmitQueueEmpty = true; | 454 EmitQueueEmpty = true; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize && | 486 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize && |
| 491 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits) | 487 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits) |
| 492 continue; | 488 continue; |
| 493 | 489 |
| 494 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to | 490 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to |
| 495 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the | 491 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the |
| 496 // pending items from Pending[ShuffleStartIndex] to | 492 // pending items from Pending[ShuffleStartIndex] to |
| 497 // Pending[ShuffleEndIndex]. | 493 // Pending[ShuffleEndIndex]. |
| 498 RandomShuffle(Pending.begin() + ShuffleStartIndex, | 494 RandomShuffle(Pending.begin() + ShuffleStartIndex, |
| 499 Pending.begin() + ShuffleEndIndex, | 495 Pending.begin() + ShuffleEndIndex, |
| 500 [this](uint64_t N) { return (uint32_t)RNG.next(N); }); | 496 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); |
| 501 } | 497 } |
| 502 | 498 |
| 503 // Emit the item from ShuffleStartIndex to ShuffleEndIndex. | 499 // Emit the item from ShuffleStartIndex to ShuffleEndIndex. |
| 504 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) { | 500 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) { |
| 505 std::unique_ptr<EmitterWorkItem> Item(Pending[I]); | 501 std::unique_ptr<EmitterWorkItem> Item(Pending[I]); |
| 506 | 502 |
| 507 switch (Item->getKind()) { | 503 switch (Item->getKind()) { |
| 508 case EmitterWorkItem::WI_Nop: | 504 case EmitterWorkItem::WI_Nop: |
| 509 break; | 505 break; |
| 510 case EmitterWorkItem::WI_GlobalInits: { | 506 case EmitterWorkItem::WI_GlobalInits: { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 } | 868 } |
| 873 llvm_unreachable("Unknown type"); | 869 llvm_unreachable("Unknown type"); |
| 874 } | 870 } |
| 875 | 871 |
| 876 ConstantList GlobalContext::getConstantExternSyms() { | 872 ConstantList GlobalContext::getConstantExternSyms() { |
| 877 return getConstPool()->ExternRelocatables.getConstantPool(); | 873 return getConstPool()->ExternRelocatables.getConstantPool(); |
| 878 } | 874 } |
| 879 | 875 |
| 880 JumpTableDataList GlobalContext::getJumpTables() { | 876 JumpTableDataList GlobalContext::getJumpTables() { |
| 881 JumpTableDataList JumpTables(*getJumpTableList()); | 877 JumpTableDataList JumpTables(*getJumpTableList()); |
| 878 // Make order deterministic by sorting into functions and then ID of the | |
| 879 // jump table within that function. | |
| 880 std::sort(JumpTables.begin(), JumpTables.end(), | |
| 881 [](const JumpTableData &A, const JumpTableData &B) { | |
| 882 if (A.getFunctionName() != B.getFunctionName()) | |
| 883 return A.getFunctionName() < B.getFunctionName(); | |
| 884 return A.getId() < B.getId(); | |
| 885 }); | |
| 886 | |
| 882 if (getFlags().shouldReorderPooledConstants()) { | 887 if (getFlags().shouldReorderPooledConstants()) { |
| 883 // If reorder-pooled-constants option is set to true, we need to shuffle the | 888 // If reorder-pooled-constants option is set to true, we also shuffle the |
| 884 // constant pool before emitting it. | 889 // jump tables before emitting them. |
| 890 | |
| 891 // Create a random number generator for jump tables reordering, considering | |
| 892 // jump tables as pooled constants. | |
| 893 RandomNumberGenerator RNG(getFlags().getRandomSeed(), | |
| 894 RPE_PooledConstantReordering); | |
| 885 RandomShuffle(JumpTables.begin(), JumpTables.end(), | 895 RandomShuffle(JumpTables.begin(), JumpTables.end(), |
| 886 [this](uint64_t N) { return (uint32_t)getRNG().next(N); }); | 896 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); }); |
| 887 } else { | |
| 888 // Make order deterministic by sorting into functions and then ID of the | |
| 889 // jump table within that function. | |
| 890 std::sort(JumpTables.begin(), JumpTables.end(), | |
| 891 [](const JumpTableData &A, const JumpTableData &B) { | |
| 892 if (A.getFunctionName() != B.getFunctionName()) | |
| 893 return A.getFunctionName() < B.getFunctionName(); | |
| 894 return A.getId() < B.getId(); | |
| 895 }); | |
| 896 } | 897 } |
| 897 return JumpTables; | 898 return JumpTables; |
| 898 } | 899 } |
| 899 | 900 |
| 900 JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id, | 901 JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id, |
| 901 SizeT NumTargets) { | 902 SizeT NumTargets) { |
| 902 auto JumpTableList = getJumpTableList(); | 903 auto JumpTableList = getJumpTableList(); |
| 903 JumpTableList->emplace_back(FuncName, Id, NumTargets); | 904 JumpTableList->emplace_back(FuncName, Id, NumTargets); |
| 904 return JumpTableList->back(); | 905 return JumpTableList->back(); |
| 905 } | 906 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1011 Ctx = Func->getContext(); | 1012 Ctx = Func->getContext(); |
| 1012 Active = | 1013 Active = |
| 1013 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 1014 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 1014 if (Active) | 1015 if (Active) |
| 1015 Ctx->pushTimer(ID, StackID); | 1016 Ctx->pushTimer(ID, StackID); |
| 1016 } | 1017 } |
| 1017 | 1018 |
| 1018 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 1019 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 1019 | 1020 |
| 1020 } // end of namespace Ice | 1021 } // end of namespace Ice |
| OLD | NEW |