Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(620)

Side by Side Diff: src/IceGlobalContext.cpp

Issue 1341423002: Reflow comments to use the full width. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix spelling and rebase Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceGlobalInits.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 /// This file defines aspects of the compilation that persist across 11 /// This file defines aspects of the compilation that persist across multiple
12 /// multiple functions. 12 /// functions.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "IceGlobalContext.h" 16 #include "IceGlobalContext.h"
17 17
18 #include "IceCfg.h" 18 #include "IceCfg.h"
19 #include "IceCfgNode.h" 19 #include "IceCfgNode.h"
20 #include "IceClFlags.h" 20 #include "IceClFlags.h"
21 #include "IceDefs.h" 21 #include "IceDefs.h"
22 #include "IceELFObjectWriter.h" 22 #include "IceELFObjectWriter.h"
(...skipping 18 matching lines...) Expand all
41 return hash<Ice::IceString>()(Key.Name) + 41 return hash<Ice::IceString>()(Key.Name) +
42 hash<Ice::RelocOffsetT>()(Key.Offset); 42 hash<Ice::RelocOffsetT>()(Key.Offset);
43 } 43 }
44 }; 44 };
45 } // end of namespace std 45 } // end of namespace std
46 46
47 namespace Ice { 47 namespace Ice {
48 48
49 namespace { 49 namespace {
50 50
51 // Define the key comparison function for the constant pool's 51 // Define the key comparison function for the constant pool's unordered_map,
52 // unordered_map, but only for key types of interest: integer types, 52 // but only for key types of interest: integer types, floating point types, and
53 // floating point types, and the special RelocatableTuple. 53 // the special RelocatableTuple.
54 template <typename KeyType, class Enable = void> struct KeyCompare {}; 54 template <typename KeyType, class Enable = void> struct KeyCompare {};
55 55
56 template <typename KeyType> 56 template <typename KeyType>
57 struct KeyCompare<KeyType, 57 struct KeyCompare<KeyType,
58 typename std::enable_if< 58 typename std::enable_if<
59 std::is_integral<KeyType>::value || 59 std::is_integral<KeyType>::value ||
60 std::is_same<KeyType, RelocatableTuple>::value>::type> { 60 std::is_same<KeyType, RelocatableTuple>::value>::type> {
61 bool operator()(const KeyType &Value1, const KeyType &Value2) const { 61 bool operator()(const KeyType &Value1, const KeyType &Value2) const {
62 return Value1 == Value2; 62 return Value1 == Value2;
63 } 63 }
64 }; 64 };
65 template <typename KeyType> 65 template <typename KeyType>
66 struct KeyCompare<KeyType, typename std::enable_if< 66 struct KeyCompare<KeyType, typename std::enable_if<
67 std::is_floating_point<KeyType>::value>::type> { 67 std::is_floating_point<KeyType>::value>::type> {
68 bool operator()(const KeyType &Value1, const KeyType &Value2) const { 68 bool operator()(const KeyType &Value1, const KeyType &Value2) const {
69 return !memcmp(&Value1, &Value2, sizeof(KeyType)); 69 return !memcmp(&Value1, &Value2, sizeof(KeyType));
70 } 70 }
71 }; 71 };
72 72
73 // Define a key comparison function for sorting the constant pool's 73 // Define a key comparison function for sorting the constant pool's values
74 // values after they are dumped to a vector. This covers integer 74 // after they are dumped to a vector. This covers integer types, floating point
75 // types, floating point types, and ConstantRelocatable values. 75 // types, and ConstantRelocatable values.
76 template <typename ValueType, class Enable = void> struct KeyCompareLess {}; 76 template <typename ValueType, class Enable = void> struct KeyCompareLess {};
77 77
78 template <typename ValueType> 78 template <typename ValueType>
79 struct KeyCompareLess<ValueType, 79 struct KeyCompareLess<ValueType,
80 typename std::enable_if<std::is_floating_point< 80 typename std::enable_if<std::is_floating_point<
81 typename ValueType::PrimType>::value>::type> { 81 typename ValueType::PrimType>::value>::type> {
82 bool operator()(const Constant *Const1, const Constant *Const2) const { 82 bool operator()(const Constant *Const1, const Constant *Const2) const {
83 using CompareType = uint64_t; 83 using CompareType = uint64_t;
84 static_assert(sizeof(typename ValueType::PrimType) <= sizeof(CompareType), 84 static_assert(sizeof(typename ValueType::PrimType) <= sizeof(CompareType),
85 "Expected floating-point type of width 64-bit or less"); 85 "Expected floating-point type of width 64-bit or less");
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 } 594 }
595 } 595 }
596 if (Found) { 596 if (Found) {
597 NewName[NewPos++] = OldName[OldPos++]; // 'S' 597 NewName[NewPos++] = OldName[OldPos++]; // 'S'
598 size_t Length = Last - OldPos; 598 size_t Length = Last - OldPos;
599 // NewPos and OldPos point just past the 'S'. 599 // NewPos and OldPos point just past the 'S'.
600 assert(NewName[NewPos - 1] == 'S'); 600 assert(NewName[NewPos - 1] == 'S');
601 assert(OldName[OldPos - 1] == 'S'); 601 assert(OldName[OldPos - 1] == 'S');
602 assert(OldName[OldPos + Length] == '_'); 602 assert(OldName[OldPos + Length] == '_');
603 if (AllZs) { 603 if (AllZs) {
604 // Replace N 'Z' characters with a '0' (if N=0) or '1' (if 604 // Replace N 'Z' characters with a '0' (if N=0) or '1' (if N>0)
605 // N>0) followed by N '0' characters. 605 // followed by N '0' characters.
606 NewName[NewPos++] = (Length ? '1' : '0'); 606 NewName[NewPos++] = (Length ? '1' : '0');
607 for (size_t i = 0; i < Length; ++i) { 607 for (size_t i = 0; i < Length; ++i) {
608 NewName[NewPos++] = '0'; 608 NewName[NewPos++] = '0';
609 } 609 }
610 } else { 610 } else {
611 // Iterate right-to-left and increment the base-36 number. 611 // Iterate right-to-left and increment the base-36 number.
612 bool Carry = true; 612 bool Carry = true;
613 for (size_t i = 0; i < Length; ++i) { 613 for (size_t i = 0; i < Length; ++i) {
614 size_t Offset = Length - 1 - i; 614 size_t Offset = Length - 1 - i;
615 char Ch = OldName[OldPos + Offset]; 615 char Ch = OldName[OldPos + Offset];
(...skipping 19 matching lines...) Expand all
635 OldPos = Last; 635 OldPos = Last;
636 // Fall through and let the '_' be copied across. 636 // Fall through and let the '_' be copied across.
637 } 637 }
638 } 638 }
639 NewName[NewPos] = OldName[OldPos]; 639 NewName[NewPos] = OldName[OldPos];
640 } 640 }
641 assert(NewName[NewPos] == '\0'); 641 assert(NewName[NewPos] == '\0');
642 OldName = NewName; 642 OldName = NewName;
643 } 643 }
644 644
645 // In this context, name mangling means to rewrite a symbol using a 645 // In this context, name mangling means to rewrite a symbol using a given
646 // given prefix. For a C++ symbol, nest the original symbol inside 646 // prefix. For a C++ symbol, nest the original symbol inside the "prefix"
647 // the "prefix" namespace. For other symbols, just prepend the 647 // namespace. For other symbols, just prepend the prefix.
648 // prefix.
649 IceString GlobalContext::mangleName(const IceString &Name) const { 648 IceString GlobalContext::mangleName(const IceString &Name) const {
650 // An already-nested name like foo::bar() gets pushed down one 649 // An already-nested name like foo::bar() gets pushed down one level, making
651 // level, making it equivalent to Prefix::foo::bar(). 650 // it equivalent to Prefix::foo::bar().
652 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz 651 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
653 // A non-nested but mangled name like bar() gets nested, making it 652 // A non-nested but mangled name like bar() gets nested, making it equivalent
654 // equivalent to Prefix::bar(). 653 // to Prefix::bar().
655 // _Z3barxyz ==> ZN6Prefix3barExyz 654 // _Z3barxyz ==> ZN6Prefix3barExyz
656 // An unmangled, extern "C" style name, gets a simple prefix: 655 // An unmangled, extern "C" style name, gets a simple prefix:
657 // bar ==> Prefixbar 656 // bar ==> Prefixbar
658 if (!BuildDefs::dump() || getFlags().getTestPrefix().empty()) 657 if (!BuildDefs::dump() || getFlags().getTestPrefix().empty())
659 return Name; 658 return Name;
660 659
661 const IceString &TestPrefix = getFlags().getTestPrefix(); 660 const IceString &TestPrefix = getFlags().getTestPrefix();
662 unsigned PrefixLength = TestPrefix.length(); 661 unsigned PrefixLength = TestPrefix.length();
663 ManglerVector NameBase(1 + Name.length()); 662 ManglerVector NameBase(1 + Name.length());
664 const size_t BufLen = 30 + Name.length() + PrefixLength; 663 const size_t BufLen = 30 + Name.length() + PrefixLength;
665 ManglerVector NewName(BufLen); 664 ManglerVector NewName(BufLen);
666 uint32_t BaseLength = 0; // using uint32_t due to sscanf format string 665 uint32_t BaseLength = 0; // using uint32_t due to sscanf format string
667 666
668 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase.data()); 667 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase.data());
669 if (ItemsParsed == 1) { 668 if (ItemsParsed == 1) {
670 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz 669 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
671 // (splice in "6Prefix") ^^^^^^^ 670 // (splice in "6Prefix") ^^^^^^^
672 snprintf(NewName.data(), BufLen, "_ZN%u%s%s", PrefixLength, 671 snprintf(NewName.data(), BufLen, "_ZN%u%s%s", PrefixLength,
673 TestPrefix.c_str(), NameBase.data()); 672 TestPrefix.c_str(), NameBase.data());
674 // We ignore the snprintf return value (here and below). If we 673 // We ignore the snprintf return value (here and below). If we somehow
675 // somehow miscalculated the output buffer length, the output will 674 // miscalculated the output buffer length, the output will be truncated,
676 // be truncated, but it will be truncated consistently for all 675 // but it will be truncated consistently for all mangleName() calls on the
677 // mangleName() calls on the same input string. 676 // same input string.
678 incrementSubstitutions(NewName); 677 incrementSubstitutions(NewName);
679 return NewName.data(); 678 return NewName.data();
680 } 679 }
681 680
682 // Artificially limit BaseLength to 9 digits (less than 1 billion) 681 // Artificially limit BaseLength to 9 digits (less than 1 billion) because
683 // because sscanf behavior is undefined on integer overflow. If 682 // sscanf behavior is undefined on integer overflow. If there are more than 9
684 // there are more than 9 digits (which we test by looking at the 683 // digits (which we test by looking at the beginning of NameBase), then we
685 // beginning of NameBase), then we consider this a failure to parse 684 // consider this a failure to parse a namespace mangling, and fall back to
686 // a namespace mangling, and fall back to the simple prefixing. 685 // the simple prefixing.
687 ItemsParsed = sscanf(Name.c_str(), "_Z%9u%s", &BaseLength, NameBase.data()); 686 ItemsParsed = sscanf(Name.c_str(), "_Z%9u%s", &BaseLength, NameBase.data());
688 if (ItemsParsed == 2 && BaseLength <= strlen(NameBase.data()) && 687 if (ItemsParsed == 2 && BaseLength <= strlen(NameBase.data()) &&
689 !isdigit(NameBase[0])) { 688 !isdigit(NameBase[0])) {
690 // Transform _Z3barxyz ==> _ZN6Prefix3barExyz 689 // Transform _Z3barxyz ==> _ZN6Prefix3barExyz
691 // ^^^^^^^^ ^ 690 // ^^^^^^^^ ^
692 // (splice in "N6Prefix", and insert "E" after "3bar") 691 // (splice in "N6Prefix", and insert "E" after "3bar") But an "I" after the
693 // But an "I" after the identifier indicates a template argument 692 // identifier indicates a template argument list terminated with "E";
694 // list terminated with "E"; insert the new "E" before/after the 693 // insert the new "E" before/after the old "E". E.g.:
695 // old "E". E.g.:
696 // Transform _Z3barIabcExyz ==> _ZN6Prefix3barIabcEExyz 694 // Transform _Z3barIabcExyz ==> _ZN6Prefix3barIabcEExyz
697 // ^^^^^^^^ ^ 695 // ^^^^^^^^ ^
698 // (splice in "N6Prefix", and insert "E" after "3barIabcE") 696 // (splice in "N6Prefix", and insert "E" after "3barIabcE")
699 ManglerVector OrigName(Name.length()); 697 ManglerVector OrigName(Name.length());
700 ManglerVector OrigSuffix(Name.length()); 698 ManglerVector OrigSuffix(Name.length());
701 uint32_t ActualBaseLength = BaseLength; 699 uint32_t ActualBaseLength = BaseLength;
702 if (NameBase[ActualBaseLength] == 'I') { 700 if (NameBase[ActualBaseLength] == 'I') {
703 ++ActualBaseLength; 701 ++ActualBaseLength;
704 while (NameBase[ActualBaseLength] != 'E' && 702 while (NameBase[ActualBaseLength] != 'E' &&
705 NameBase[ActualBaseLength] != '\0') 703 NameBase[ActualBaseLength] != '\0')
(...skipping 17 matching lines...) Expand all
723 GlobalContext::~GlobalContext() { 721 GlobalContext::~GlobalContext() {
724 llvm::DeleteContainerPointers(AllThreadContexts); 722 llvm::DeleteContainerPointers(AllThreadContexts);
725 LockedPtr<DestructorArray> Dtors = getDestructors(); 723 LockedPtr<DestructorArray> Dtors = getDestructors();
726 // Destructors are invoked in the opposite object construction order. 724 // Destructors are invoked in the opposite object construction order.
727 for (auto DtorIter = Dtors->crbegin(); DtorIter != Dtors->crend(); 725 for (auto DtorIter = Dtors->crbegin(); DtorIter != Dtors->crend();
728 ++DtorIter) { 726 ++DtorIter) {
729 (*DtorIter)(); 727 (*DtorIter)();
730 } 728 }
731 } 729 }
732 730
733 // TODO(stichnot): Consider adding thread-local caches of constant 731 // TODO(stichnot): Consider adding thread-local caches of constant pool entries
734 // pool entries to reduce contention. 732 // to reduce contention.
735 733
736 // All locking is done by the getConstantInt[0-9]+() target function. 734 // All locking is done by the getConstantInt[0-9]+() target function.
737 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) { 735 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
738 switch (Ty) { 736 switch (Ty) {
739 case IceType_i1: 737 case IceType_i1:
740 return getConstantInt1(Value); 738 return getConstantInt1(Value);
741 case IceType_i8: 739 case IceType_i8:
742 return getConstantInt8(Value); 740 return getConstantInt8(Value);
743 case IceType_i16: 741 case IceType_i16:
744 return getConstantInt16(Value); 742 return getConstantInt16(Value);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 } 866 }
869 llvm_unreachable("Unknown type"); 867 llvm_unreachable("Unknown type");
870 } 868 }
871 869
872 ConstantList GlobalContext::getConstantExternSyms() { 870 ConstantList GlobalContext::getConstantExternSyms() {
873 return getConstPool()->ExternRelocatables.getConstantPool(); 871 return getConstPool()->ExternRelocatables.getConstantPool();
874 } 872 }
875 873
876 JumpTableDataList GlobalContext::getJumpTables() { 874 JumpTableDataList GlobalContext::getJumpTables() {
877 JumpTableDataList JumpTables(*getJumpTableList()); 875 JumpTableDataList JumpTables(*getJumpTableList());
878 // Make order deterministic by sorting into functions and then ID of the 876 // Make order deterministic by sorting into functions and then ID of the jump
879 // jump table within that function. 877 // table within that function.
880 std::sort(JumpTables.begin(), JumpTables.end(), 878 std::sort(JumpTables.begin(), JumpTables.end(),
881 [](const JumpTableData &A, const JumpTableData &B) { 879 [](const JumpTableData &A, const JumpTableData &B) {
882 if (A.getFunctionName() != B.getFunctionName()) 880 if (A.getFunctionName() != B.getFunctionName())
883 return A.getFunctionName() < B.getFunctionName(); 881 return A.getFunctionName() < B.getFunctionName();
884 return A.getId() < B.getId(); 882 return A.getId() < B.getId();
885 }); 883 });
886 884
887 if (getFlags().shouldReorderPooledConstants()) { 885 if (getFlags().shouldReorderPooledConstants()) {
888 // If reorder-pooled-constants option is set to true, we also shuffle the 886 // If reorder-pooled-constants option is set to true, we also shuffle the
889 // jump tables before emitting them. 887 // jump tables before emitting them.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 Timers->at(StackID).reset(); 937 Timers->at(StackID).reset();
940 } 938 }
941 939
942 void GlobalContext::setTimerName(TimerStackIdT StackID, 940 void GlobalContext::setTimerName(TimerStackIdT StackID,
943 const IceString &NewName) { 941 const IceString &NewName) {
944 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; 942 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers;
945 assert(StackID < Timers->size()); 943 assert(StackID < Timers->size());
946 Timers->at(StackID).setName(NewName); 944 Timers->at(StackID).setName(NewName);
947 } 945 }
948 946
949 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr 947 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the
950 // at the interface to take and transfer ownership, but they 948 // interface to take and transfer ownership, but they internally store the raw
951 // internally store the raw Cfg pointer in the work queue. This 949 // Cfg pointer in the work queue. This allows e.g. future queue optimizations
952 // allows e.g. future queue optimizations such as the use of atomics 950 // such as the use of atomics to modify queue elements.
953 // to modify queue elements.
954 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { 951 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) {
955 assert(Func); 952 assert(Func);
956 OptQ.blockingPush(Func.release()); 953 OptQ.blockingPush(Func.release());
957 if (getFlags().isSequential()) 954 if (getFlags().isSequential())
958 translateFunctions(); 955 translateFunctions();
959 } 956 }
960 957
961 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { 958 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() {
962 return std::unique_ptr<Cfg>(OptQ.blockingPop()); 959 return std::unique_ptr<Cfg>(OptQ.blockingPop());
963 } 960 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 Ctx = Func->getContext(); 1009 Ctx = Func->getContext();
1013 Active = 1010 Active =
1014 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 1011 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
1015 if (Active) 1012 if (Active)
1016 Ctx->pushTimer(ID, StackID); 1013 Ctx->pushTimer(ID, StackID);
1017 } 1014 }
1018 1015
1019 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 1016 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
1020 1017
1021 } // end of namespace Ice 1018 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceGlobalInits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698