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