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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; | 211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; |
| 212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; | 212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; |
| 213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; | 213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; |
| 214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; | 214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; |
| 215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; | 215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; |
| 216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> | 216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> |
| 217 ExternRelocatables; | 217 ExternRelocatables; |
| 218 UndefPool Undefs; | 218 UndefPool Undefs; |
| 219 }; | 219 }; |
| 220 | 220 |
| 221 void GlobalContext::waitForWorkerThreads() { | |
| 222 { // Make sure we wait at most once. | |
| 223 std::unique_lock<GlobalLockType> L(WaitForWorkersLock); | |
|
Jim Stichnoth
2016/03/25 04:31:04
Our new super-awesome coding style would name this
Karl
2016/03/29 17:35:02
Removed, went with atomic_bool.
| |
| 224 if (WaitForWorkerThreadsCalled) | |
|
Jim Stichnoth
2016/03/25 04:31:04
It seems that WaitForWorkerThreadsCalled could act
Karl
2016/03/29 17:35:02
Changed to atomic_bool.
| |
| 225 return; | |
| 226 WaitForWorkerThreadsCalled = true; | |
| 227 } | |
| 228 optQueueNotifyEnd(); | |
| 229 for (std::thread &Worker : TranslationThreads) { | |
| 230 Worker.join(); | |
| 231 } | |
| 232 TranslationThreads.clear(); | |
| 233 | |
| 234 // Only notify the emit queue to end after all the translation threads have | |
| 235 // ended. | |
| 236 emitQueueNotifyEnd(); | |
| 237 for (std::thread &Worker : EmitterThreads) { | |
| 238 Worker.join(); | |
| 239 } | |
| 240 EmitterThreads.clear(); | |
| 241 | |
| 242 if (BuildDefs::timers()) { | |
| 243 auto Timers = getTimers(); | |
| 244 for (ThreadContext *TLS : AllThreadContexts) | |
| 245 Timers->mergeFrom(TLS->Timers); | |
| 246 } | |
| 247 if (BuildDefs::dump()) { | |
| 248 // Do a separate loop over AllThreadContexts to avoid holding two locks | |
| 249 // at once. | |
| 250 auto Stats = getStatsCumulative(); | |
| 251 for (ThreadContext *TLS : AllThreadContexts) | |
| 252 Stats->add(TLS->StatsCumulative); | |
| 253 } | |
| 254 } | |
| 255 | |
| 221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { | 256 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
| 222 if (!BuildDefs::dump()) | 257 if (!BuildDefs::dump()) |
| 223 return; | 258 return; |
| 224 OstreamLocker _(Ctx); | 259 OstreamLocker _(Ctx); |
| 225 Ostream &Str = Ctx->getStrDump(); | 260 Ostream &Str = Ctx->getStrDump(); |
| 226 #define X(str, tag) \ | 261 #define X(str, tag) \ |
| 227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; | 262 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; |
| 228 CODESTATS_TABLE | 263 CODESTATS_TABLE |
| 229 #undef X | 264 #undef X |
| 230 Str << "|" << Name << "|Spills+Fills|" | 265 Str << "|" << Name << "|Spills+Fills|" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); | 284 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); |
| 250 } | 285 } |
| 251 Str << "\n"; | 286 Str << "\n"; |
| 252 } | 287 } |
| 253 | 288 |
| 254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 289 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| 255 ELFStreamer *ELFStr) | 290 ELFStreamer *ELFStr) |
| 256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 291 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
| 257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), | 292 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), |
| 258 OptQ(/*Sequential=*/Flags.isSequential(), | 293 OptQ(/*Sequential=*/Flags.isSequential(), |
| 259 /*MaxSize=*/Flags.getNumTranslationThreads()), | 294 /*MaxSize=*/ |
| 295 (Flags.getParseParallel() && Flags.getBuildOnRead()) | |
| 296 ? MaxOptQSize | |
| 297 : Flags.getNumTranslationThreads()), | |
| 260 // EmitQ is allowed unlimited size. | 298 // EmitQ is allowed unlimited size. |
| 261 EmitQ(/*Sequential=*/Flags.isSequential()), | 299 EmitQ(/*Sequential=*/Flags.isSequential()), |
| 262 DataLowering(TargetDataLowering::createLowering(this)) { | 300 DataLowering(TargetDataLowering::createLowering(this)) { |
| 263 assert(OsDump && "OsDump is not defined for GlobalContext"); | 301 assert(OsDump && "OsDump is not defined for GlobalContext"); |
| 264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 302 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
| 265 assert(OsError && "OsError is not defined for GlobalContext"); | 303 assert(OsError && "OsError is not defined for GlobalContext"); |
| 266 // Make sure thread_local fields are properly initialized before any | 304 // Make sure thread_local fields are properly initialized before any |
| 267 // accesses are made. Do this here instead of at the start of | 305 // 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 | 306 // main() so that all clients (e.g. unit tests) can benefit for |
| 269 // free. | 307 // free. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ | 340 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ |
| 303 getConstantExternSym(Name); | 341 getConstantExternSym(Name); |
| 304 RUNTIME_HELPER_FUNCTIONS_TABLE | 342 RUNTIME_HELPER_FUNCTIONS_TABLE |
| 305 #undef X | 343 #undef X |
| 306 | 344 |
| 307 TargetLowering::staticInit(this); | 345 TargetLowering::staticInit(this); |
| 308 } | 346 } |
| 309 | 347 |
| 310 void GlobalContext::translateFunctions() { | 348 void GlobalContext::translateFunctions() { |
| 311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); | 349 TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
| 312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 350 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
| 351 std::unique_ptr<Cfg> Func = OptItem->getParsedCfg(); | |
| 313 // Install Func in TLS for Cfg-specific container allocators. | 352 // Install Func in TLS for Cfg-specific container allocators. |
| 314 CfgLocalAllocatorScope _(Func.get()); | 353 CfgLocalAllocatorScope _(Func.get()); |
| 315 // Reset per-function stats being accumulated in TLS. | 354 // Reset per-function stats being accumulated in TLS. |
| 316 resetStats(); | 355 resetStats(); |
| 317 // Set verbose level to none if the current function does NOT | 356 // Set verbose level to none if the current function does NOT |
| 318 // match the -verbose-focus command-line option. | 357 // match the -verbose-focus command-line option. |
| 319 if (!matchSymbolName(Func->getFunctionName(), | 358 if (!matchSymbolName(Func->getFunctionName(), |
| 320 getFlags().getVerboseFocusOn())) | 359 getFlags().getVerboseFocusOn())) |
| 321 Func->setVerbose(IceV_None); | 360 Func->setVerbose(IceV_None); |
| 322 // Disable translation if -notranslate is specified, or if the | 361 // Disable translation if -notranslate is specified, or if the |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 860 const IceString &NewName) { | 899 const IceString &NewName) { |
| 861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 900 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
| 862 assert(StackID < Timers->size()); | 901 assert(StackID < Timers->size()); |
| 863 Timers->at(StackID).setName(NewName); | 902 Timers->at(StackID).setName(NewName); |
| 864 } | 903 } |
| 865 | 904 |
| 866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the | 905 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the |
| 867 // interface to take and transfer ownership, but they internally store the raw | 906 // 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 | 907 // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
| 869 // such as the use of atomics to modify queue elements. | 908 // such as the use of atomics to modify queue elements. |
| 870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { | 909 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
| 871 assert(Func); | 910 assert(Item); |
| 872 { | 911 { |
| 873 TimerMarker _(TimerStack::TT_qTransPush, this); | 912 TimerMarker _(TimerStack::TT_qTransPush, this); |
| 874 OptQ.blockingPush(std::move(Func)); | 913 OptQ.blockingPush(std::move(Item)); |
| 875 } | 914 } |
| 876 if (getFlags().isSequential()) | 915 if (getFlags().isSequential()) |
| 877 translateFunctions(); | 916 translateFunctions(); |
| 878 } | 917 } |
| 879 | 918 |
| 880 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { | 919 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
| 881 TimerMarker _(TimerStack::TT_qTransPop, this); | 920 TimerMarker _(TimerStack::TT_qTransPop, this); |
| 882 return std::unique_ptr<Cfg>(OptQ.blockingPop()); | 921 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
| 883 } | 922 } |
| 884 | 923 |
| 885 void GlobalContext::emitQueueBlockingPush( | 924 void GlobalContext::emitQueueBlockingPush( |
| 886 std::unique_ptr<EmitterWorkItem> Item) { | 925 std::unique_ptr<EmitterWorkItem> Item) { |
| 887 assert(Item); | 926 assert(Item); |
| 888 { | 927 { |
| 889 TimerMarker _(TimerStack::TT_qEmitPush, this); | 928 TimerMarker _(TimerStack::TT_qEmitPush, this); |
| 890 EmitQ.blockingPush(std::move(Item)); | 929 EmitQ.blockingPush(std::move(Item)); |
| 891 } | 930 } |
| 892 if (getFlags().isSequential()) | 931 if (getFlags().isSequential()) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 Ctx = Func->getContext(); | 986 Ctx = Func->getContext(); |
| 948 Active = | 987 Active = |
| 949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 988 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 950 if (Active) | 989 if (Active) |
| 951 Ctx->pushTimer(ID, StackID); | 990 Ctx->pushTimer(ID, StackID); |
| 952 } | 991 } |
| 953 | 992 |
| 954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 993 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 955 | 994 |
| 956 } // end of namespace Ice | 995 } // end of namespace Ice |
| OLD | NEW |