| 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 30 matching lines...) Expand all Loading... |
| 41 #include <cctype> // isdigit(), isupper() | 41 #include <cctype> // isdigit(), isupper() |
| 42 #include <locale> // locale | 42 #include <locale> // locale |
| 43 | 43 |
| 44 namespace std { | 44 namespace std { |
| 45 template <> struct hash<Ice::RelocatableTuple> { | 45 template <> struct hash<Ice::RelocatableTuple> { |
| 46 size_t operator()(const Ice::RelocatableTuple &Key) const { | 46 size_t operator()(const Ice::RelocatableTuple &Key) const { |
| 47 if (!Key.EmitString.empty()) { | 47 if (!Key.EmitString.empty()) { |
| 48 return hash<Ice::IceString>()(Key.EmitString); | 48 return hash<Ice::IceString>()(Key.EmitString); |
| 49 } | 49 } |
| 50 | 50 |
| 51 assert(!Key.OffsetExpr.empty()); | 51 // If there's no emit string, then we use the relocatable's name, plus the |
| 52 if (Key.OffsetExpr[0]->hasOffset()) { | 52 // hash of a combination of the number of OffsetExprs and the known, fixed |
| 53 return hash<Ice::IceString>()(Key.Name) + | 53 // offset for the reloc. We left shift the known relocatable by 5 trying to |
| 54 hash<Ice::RelocOffsetT>()(Key.OffsetExpr[0]->getOffset()); | 54 // minimize the interaction between the bits in OffsetExpr.size() and |
| 55 } | 55 // Key.Offset. |
| 56 | |
| 57 return hash<Ice::IceString>()(Key.Name) + | 56 return hash<Ice::IceString>()(Key.Name) + |
| 58 hash<std::size_t>()(Key.OffsetExpr.size()); | 57 hash<std::size_t>()(Key.OffsetExpr.size() + (Key.Offset << 5)); |
| 59 } | 58 } |
| 60 }; | 59 }; |
| 61 } // end of namespace std | 60 } // end of namespace std |
| 62 | 61 |
| 63 namespace Ice { | 62 namespace Ice { |
| 64 | 63 |
| 65 namespace { | 64 namespace { |
| 66 | 65 |
| 67 // Define the key comparison function for the constant pool's unordered_map, | 66 // Define the key comparison function for the constant pool's unordered_map, |
| 68 // but only for key types of interest: integer types, floating point types, and | 67 // but only for key types of interest: integer types, floating point types, and |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); | 285 ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); |
| 287 ProfileBlockInfoVarDecl->setSuppressMangling(); | 286 ProfileBlockInfoVarDecl->setSuppressMangling(); |
| 288 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); | 287 ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| 289 | 288 |
| 290 TargetLowering::staticInit(this); | 289 TargetLowering::staticInit(this); |
| 291 } | 290 } |
| 292 | 291 |
| 293 void GlobalContext::translateFunctions() { | 292 void GlobalContext::translateFunctions() { |
| 294 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 293 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { |
| 295 // Install Func in TLS for Cfg-specific container allocators. | 294 // Install Func in TLS for Cfg-specific container allocators. |
| 296 Cfg::setCurrentCfg(Func.get()); | 295 CfgLocalAllocatorScope _(Func.get()); |
| 297 // Reset per-function stats being accumulated in TLS. | 296 // Reset per-function stats being accumulated in TLS. |
| 298 resetStats(); | 297 resetStats(); |
| 299 // Set verbose level to none if the current function does NOT | 298 // Set verbose level to none if the current function does NOT |
| 300 // match the -verbose-focus command-line option. | 299 // match the -verbose-focus command-line option. |
| 301 if (!matchSymbolName(Func->getFunctionName(), | 300 if (!matchSymbolName(Func->getFunctionName(), |
| 302 getFlags().getVerboseFocusOn())) | 301 getFlags().getVerboseFocusOn())) |
| 303 Func->setVerbose(IceV_None); | 302 Func->setVerbose(IceV_None); |
| 304 // Disable translation if -notranslate is specified, or if the | 303 // Disable translation if -notranslate is specified, or if the |
| 305 // current function matches the -translate-only option. If | 304 // current function matches the -translate-only option. If |
| 306 // translation is disabled, just dump the high-level IR and | 305 // translation is disabled, just dump the high-level IR and |
| 307 // continue. | 306 // continue. |
| 308 if (getFlags().getDisableTranslation() || | 307 if (getFlags().getDisableTranslation() || |
| 309 !matchSymbolName(Func->getFunctionName(), | 308 !matchSymbolName(Func->getFunctionName(), |
| 310 getFlags().getTranslateOnly())) { | 309 getFlags().getTranslateOnly())) { |
| 311 Func->dump(); | 310 Func->dump(); |
| 312 Cfg::setCurrentCfg(nullptr); | |
| 313 continue; // Func goes out of scope and gets deleted | 311 continue; // Func goes out of scope and gets deleted |
| 314 } | 312 } |
| 315 | 313 |
| 316 Func->translate(); | 314 Func->translate(); |
| 317 EmitterWorkItem *Item = nullptr; | 315 EmitterWorkItem *Item = nullptr; |
| 318 if (Func->hasError()) { | 316 if (Func->hasError()) { |
| 319 getErrorStatus()->assign(EC_Translation); | 317 getErrorStatus()->assign(EC_Translation); |
| 320 OstreamLocker L(this); | 318 OstreamLocker L(this); |
| 321 getStrError() << "ICE translation error: " << Func->getFunctionName() | 319 getStrError() << "ICE translation error: " << Func->getFunctionName() |
| 322 << ": " << Func->getError() << ": " | 320 << ": " << Func->getError() << ": " |
| (...skipping 18 matching lines...) Expand all Loading... |
| 341 case FT_Asm: | 339 case FT_Asm: |
| 342 // The Cfg has not been emitted yet, so stats are not ready | 340 // The Cfg has not been emitted yet, so stats are not ready |
| 343 // to be dumped. | 341 // to be dumped. |
| 344 std::unique_ptr<VariableDeclarationList> GlobalInits = | 342 std::unique_ptr<VariableDeclarationList> GlobalInits = |
| 345 Func->getGlobalInits(); | 343 Func->getGlobalInits(); |
| 346 Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release()); | 344 Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release()); |
| 347 Item->setGlobalInits(std::move(GlobalInits)); | 345 Item->setGlobalInits(std::move(GlobalInits)); |
| 348 break; | 346 break; |
| 349 } | 347 } |
| 350 } | 348 } |
| 351 Cfg::setCurrentCfg(nullptr); | |
| 352 assert(Item); | 349 assert(Item); |
| 353 emitQueueBlockingPush(Item); | 350 emitQueueBlockingPush(Item); |
| 354 // The Cfg now gets deleted as Func goes out of scope. | 351 // The Cfg now gets deleted as Func goes out of scope. |
| 355 } | 352 } |
| 356 } | 353 } |
| 357 | 354 |
| 358 namespace { | 355 namespace { |
| 359 | 356 |
| 360 // Ensure Pending is large enough that Pending[Index] is valid. | 357 // Ensure Pending is large enough that Pending[Index] is valid. |
| 361 void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) { | 358 void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 if (!BuildDefs::dump()) | 547 if (!BuildDefs::dump()) |
| 551 llvm::report_fatal_error("WI_Cfg work item created inappropriately"); | 548 llvm::report_fatal_error("WI_Cfg work item created inappropriately"); |
| 552 lowerGlobalsIfNoCodeHasBeenSeen(); | 549 lowerGlobalsIfNoCodeHasBeenSeen(); |
| 553 accumulateGlobals(Item->getGlobalInits()); | 550 accumulateGlobals(Item->getGlobalInits()); |
| 554 | 551 |
| 555 assert(getFlags().getOutFileType() == FT_Asm); | 552 assert(getFlags().getOutFileType() == FT_Asm); |
| 556 std::unique_ptr<Cfg> Func = Item->getCfg(); | 553 std::unique_ptr<Cfg> Func = Item->getCfg(); |
| 557 // Unfortunately, we have to temporarily install the Cfg in TLS | 554 // Unfortunately, we have to temporarily install the Cfg in TLS |
| 558 // because Variable::asType() uses the allocator to create the | 555 // because Variable::asType() uses the allocator to create the |
| 559 // differently-typed copy. | 556 // differently-typed copy. |
| 560 Cfg::setCurrentCfg(Func.get()); | 557 CfgLocalAllocatorScope _(Func.get()); |
| 561 Func->emit(); | 558 Func->emit(); |
| 562 Cfg::setCurrentCfg(nullptr); | |
| 563 dumpStats(Func->getFunctionNameAndSize()); | 559 dumpStats(Func->getFunctionNameAndSize()); |
| 564 } break; | 560 } break; |
| 565 } | 561 } |
| 566 } | 562 } |
| 567 // Update the start index for next shuffling queue | 563 // Update the start index for next shuffling queue |
| 568 ShuffleStartIndex = ShuffleEndIndex; | 564 ShuffleStartIndex = ShuffleEndIndex; |
| 569 } | 565 } |
| 570 | 566 |
| 571 // In case there are no code to be generated, we invoke the conditional | 567 // In case there are no code to be generated, we invoke the conditional |
| 572 // lowerGlobals again -- this is a no-op if code has been emitted. | 568 // lowerGlobals again -- this is a no-op if code has been emitted. |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 } | 784 } |
| 789 | 785 |
| 790 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { | 786 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { |
| 791 return getConstPool()->Floats.getOrAdd(this, ConstantFloat); | 787 return getConstPool()->Floats.getOrAdd(this, ConstantFloat); |
| 792 } | 788 } |
| 793 | 789 |
| 794 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { | 790 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { |
| 795 return getConstPool()->Doubles.getOrAdd(this, ConstantDouble); | 791 return getConstPool()->Doubles.getOrAdd(this, ConstantDouble); |
| 796 } | 792 } |
| 797 | 793 |
| 798 Constant *GlobalContext::getConstantSym(const RelocOffsetArray &Offset, | 794 Constant *GlobalContext::getConstantSym(const RelocOffsetT Offset, |
| 795 const RelocOffsetArray &OffsetExpr, |
| 799 const IceString &Name, | 796 const IceString &Name, |
| 800 const IceString &EmitString, | 797 const IceString &EmitString, |
| 801 bool SuppressMangling) { | 798 bool SuppressMangling) { |
| 802 return getConstPool()->Relocatables.getOrAdd( | 799 return getConstPool()->Relocatables.getOrAdd( |
| 803 this, RelocatableTuple(Offset, Name, EmitString, SuppressMangling)); | 800 this, |
| 801 RelocatableTuple(Offset, OffsetExpr, Name, EmitString, SuppressMangling)); |
| 804 } | 802 } |
| 805 | 803 |
| 806 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, | 804 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, |
| 807 const IceString &Name, | 805 const IceString &Name, |
| 808 bool SuppressMangling) { | 806 bool SuppressMangling) { |
| 809 constexpr char EmptyEmitString[] = ""; | 807 constexpr char EmptyEmitString[] = ""; |
| 810 return getConstantSym({RelocOffset::create(this, Offset)}, Name, | 808 return getConstantSym(Offset, {}, Name, EmptyEmitString, SuppressMangling); |
| 811 EmptyEmitString, SuppressMangling); | |
| 812 } | 809 } |
| 813 | 810 |
| 814 Constant *GlobalContext::getConstantExternSym(const IceString &Name) { | 811 Constant *GlobalContext::getConstantExternSym(const IceString &Name) { |
| 815 constexpr RelocOffsetT Offset = 0; | 812 constexpr RelocOffsetT Offset = 0; |
| 816 constexpr bool SuppressMangling = true; | 813 constexpr bool SuppressMangling = true; |
| 817 return getConstPool()->ExternRelocatables.getOrAdd( | 814 return getConstPool()->ExternRelocatables.getOrAdd( |
| 818 this, RelocatableTuple({RelocOffset::create(this, Offset)}, Name, | 815 this, RelocatableTuple(Offset, {}, Name, SuppressMangling)); |
| 819 SuppressMangling)); | |
| 820 } | 816 } |
| 821 | 817 |
| 822 Constant *GlobalContext::getConstantUndef(Type Ty) { | 818 Constant *GlobalContext::getConstantUndef(Type Ty) { |
| 823 return getConstPool()->Undefs.getOrAdd(this, Ty); | 819 return getConstPool()->Undefs.getOrAdd(this, Ty); |
| 824 } | 820 } |
| 825 | 821 |
| 826 // All locking is done by the getConstant*() target function. | 822 // All locking is done by the getConstant*() target function. |
| 827 Constant *GlobalContext::getConstantZero(Type Ty) { | 823 Constant *GlobalContext::getConstantZero(Type Ty) { |
| 828 switch (Ty) { | 824 switch (Ty) { |
| 829 case IceType_i1: | 825 case IceType_i1: |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 Ctx = Func->getContext(); | 1032 Ctx = Func->getContext(); |
| 1037 Active = | 1033 Active = |
| 1038 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 1034 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 1039 if (Active) | 1035 if (Active) |
| 1040 Ctx->pushTimer(ID, StackID); | 1036 Ctx->pushTimer(ID, StackID); |
| 1041 } | 1037 } |
| 1042 | 1038 |
| 1043 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 1039 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 1044 | 1040 |
| 1045 } // end of namespace Ice | 1041 } // end of namespace Ice |
| OLD | NEW |