| OLD | NEW |
| 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===// | 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===// |
| 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 // This file defines aspects of the compilation that persist across | 10 // This file defines aspects of the compilation that persist across |
| 11 // multiple functions. | 11 // multiple functions. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #include "IceDefs.h" | 15 #include "IceDefs.h" |
| 16 #include "IceTypes.h" | 16 #include "IceTypes.h" |
| 17 #include "IceCfg.h" | 17 #include "IceCfg.h" |
| 18 #include "IceGlobalContext.h" | 18 #include "IceGlobalContext.h" |
| 19 #include "IceOperand.h" | 19 #include "IceOperand.h" |
| 20 #include "IceTargetLowering.h" |
| 20 | 21 |
| 21 namespace Ice { | 22 namespace Ice { |
| 22 | 23 |
| 23 // TypePool maps constants of type KeyType (e.g. float) to pointers to | 24 // TypePool maps constants of type KeyType (e.g. float) to pointers to |
| 24 // type ValueType (e.g. ConstantFloat). KeyType values are compared | 25 // type ValueType (e.g. ConstantFloat). KeyType values are compared |
| 25 // using memcmp() because of potential NaN values in KeyType values. | 26 // using memcmp() because of potential NaN values in KeyType values. |
| 26 // KeyTypeHasFP indicates whether KeyType is a floating-point type | 27 // KeyTypeHasFP indicates whether KeyType is a floating-point type |
| 27 // whose values need to be compared using memcmp() for NaN | 28 // whose values need to be compared using memcmp() for NaN |
| 28 // correctness. TODO: use std::is_floating_point<KeyType> instead of | 29 // correctness. TODO: use std::is_floating_point<KeyType> instead of |
| 29 // KeyTypeHasFP with C++11. | 30 // KeyTypeHasFP with C++11. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 public: | 69 public: |
| 69 ConstantPool() {} | 70 ConstantPool() {} |
| 70 TypePool<float, ConstantFloat, true> Floats; | 71 TypePool<float, ConstantFloat, true> Floats; |
| 71 TypePool<double, ConstantDouble, true> Doubles; | 72 TypePool<double, ConstantDouble, true> Doubles; |
| 72 TypePool<uint64_t, ConstantInteger> Integers; | 73 TypePool<uint64_t, ConstantInteger> Integers; |
| 73 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; | 74 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; |
| 74 }; | 75 }; |
| 75 | 76 |
| 76 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, | 77 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump, |
| 77 llvm::raw_ostream *OsEmit, VerboseMask Mask, | 78 llvm::raw_ostream *OsEmit, VerboseMask Mask, |
| 79 TargetArch Arch, OptLevel Opt, |
| 78 IceString TestPrefix) | 80 IceString TestPrefix) |
| 79 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), | 81 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), |
| 80 ConstPool(new ConstantPool()), TestPrefix(TestPrefix) {} | 82 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), |
| 83 TestPrefix(TestPrefix), HasEmittedFirstMethod(false) {} |
| 81 | 84 |
| 82 // In this context, name mangling means to rewrite a symbol using a | 85 // In this context, name mangling means to rewrite a symbol using a |
| 83 // given prefix. For a C++ symbol, nest the original symbol inside | 86 // given prefix. For a C++ symbol, nest the original symbol inside |
| 84 // the "prefix" namespace. For other symbols, just prepend the | 87 // the "prefix" namespace. For other symbols, just prepend the |
| 85 // prefix. | 88 // prefix. |
| 86 IceString GlobalContext::mangleName(const IceString &Name) const { | 89 IceString GlobalContext::mangleName(const IceString &Name) const { |
| 87 // TODO: Add explicit tests (beyond the implicit tests in the linker | 90 // TODO: Add explicit tests (beyond the implicit tests in the linker |
| 88 // that come from the cross tests). | 91 // that come from the cross tests). |
| 89 // | 92 // |
| 90 // An already-nested name like foo::bar() gets pushed down one | 93 // An already-nested name like foo::bar() gets pushed down one |
| 91 // level, making it equivalent to Prefix::foo::bar(). | 94 // level, making it equivalent to Prefix::foo::bar(). |
| 92 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz | 95 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz |
| 93 // A non-nested but mangled name like bar() gets nested, making it | 96 // A non-nested but mangled name like bar() gets nested, making it |
| 94 // equivalent to Prefix::bar(). | 97 // equivalent to Prefix::bar(). |
| 95 // _Z3barxyz ==> ZN6Prefix3barExyz | 98 // _Z3barxyz ==> ZN6Prefix3barExyz |
| 96 // An unmangled, extern "C" style name, gets a simple prefix: | 99 // An unmangled, extern "C" style name, gets a simple prefix: |
| 97 // bar ==> Prefixbar | 100 // bar ==> Prefixbar |
| 98 if (getTestPrefix().empty()) | 101 if (getTestPrefix().empty()) |
| 99 return Name; | 102 return Name; |
| 100 | 103 |
| 101 unsigned PrefixLength = getTestPrefix().length(); | 104 unsigned PrefixLength = getTestPrefix().length(); |
| 102 char NameBase[1 + Name.length()]; | 105 char NameBase[1 + Name.length()]; |
| 103 const size_t BufLen = 30 + Name.length() + getTestPrefix().length(); | 106 const size_t BufLen = 30 + Name.length() + PrefixLength; |
| 104 char NewName[BufLen]; | 107 char NewName[BufLen]; |
| 105 uint32_t BaseLength = 0; | 108 uint32_t BaseLength = 0; // using uint32_t due to sscanf format string |
| 106 | 109 |
| 107 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase); | 110 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase); |
| 108 if (ItemsParsed == 1) { | 111 if (ItemsParsed == 1) { |
| 109 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz | 112 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz |
| 110 // (splice in "6Prefix") ^^^^^^^ | 113 // (splice in "6Prefix") ^^^^^^^ |
| 111 snprintf(NewName, BufLen, "_ZN%u%s%s", PrefixLength, | 114 snprintf(NewName, BufLen, "_ZN%u%s%s", PrefixLength, |
| 112 getTestPrefix().c_str(), NameBase); | 115 getTestPrefix().c_str(), NameBase); |
| 113 // We ignore the snprintf return value (here and below). If we | 116 // We ignore the snprintf return value (here and below). If we |
| 114 // somehow miscalculated the output buffer length, the output will | 117 // somehow miscalculated the output buffer length, the output will |
| 115 // be truncated, but it will be truncated consistently for all | 118 // be truncated, but it will be truncated consistently for all |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 | 163 |
| 161 void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const { | 164 void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const { |
| 162 if (Ctx->isVerbose(IceV_Timing)) { | 165 if (Ctx->isVerbose(IceV_Timing)) { |
| 163 // Prefixing with '#' allows timing strings to be included | 166 // Prefixing with '#' allows timing strings to be included |
| 164 // without error in textual assembly output. | 167 // without error in textual assembly output. |
| 165 Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n"; | 168 Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n"; |
| 166 } | 169 } |
| 167 } | 170 } |
| 168 | 171 |
| 169 } // end of namespace Ice | 172 } // end of namespace Ice |
| OLD | NEW |