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

Side by Side Diff: src/IceGlobalContext.cpp

Issue 205613002: Initial skeleton of Subzero. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Fix omissions from previous patchset. Created 6 years, 8 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
OLDNEW
(Empty)
1 //===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines aspects of the compilation that persist across
11 // multiple functions.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "IceDefs.h"
16 #include "IceTypes.h"
17 #include "IceCfg.h"
18 #include "IceGlobalContext.h"
19 #include "IceOperand.h"
20
21 namespace Ice {
22
23 // TypePool maps constants of type KeyType (e.g. float) to pointers
24 // to type ValueType (e.g. ConstantFloat). KeyType values are
25 // compared using memcmp() because of potential NaN values in KeyType
26 // values. TODO: allow a custom KeyType comparator for a KeyType
27 // containing e.g. a non-pooled string.
28 template <typename KeyType, typename ValueType> class TypePool {
29 TypePool(const TypePool &) LLVM_DELETED_FUNCTION;
30 TypePool &operator=(const TypePool &) LLVM_DELETED_FUNCTION;
31
32 public:
33 TypePool() {}
34 ValueType *getOrAdd(GlobalContext *Ctx, IceType Type, KeyType Key) {
35 IceSize_t Index = KeyToIndex.translate(std::make_pair(Type, Key));
36 if (Index >= Pool.size()) {
37 assert(Index == Pool.size());
38 Pool.resize(Index + 1);
39 Pool[Index] = ValueType::create(Ctx, Type, Key);
40 }
41 ValueType *Constant = Pool[Index];
42 assert(Constant);
43 return Constant;
44 }
45
46 private:
47 typedef std::pair<IceType, KeyType> TupleType;
48 struct TupleCompare {
49 bool operator()(const TupleType &A, const TupleType &B) {
50 if (A.first != B.first)
JF 2014/04/23 03:51:28 Ditto on static_assert for !FP.
Jim Stichnoth 2014/04/26 15:02:11 This isn't necessary, since the type of A.first an
51 return A.first < B.first;
52 return memcmp(&A.second, &B.second, sizeof(KeyType)) < 0;
53 }
54 };
55 ValueTranslation<TupleType, TupleCompare> KeyToIndex;
56 std::vector<ValueType *> Pool;
57 };
58
59 // The global constant pool bundles individual pools of each type of
60 // interest.
61 class ConstantPool {
62 ConstantPool(const ConstantPool &) LLVM_DELETED_FUNCTION;
63 ConstantPool &operator=(const ConstantPool &) LLVM_DELETED_FUNCTION;
64
65 public:
66 ConstantPool() {}
67 TypePool<float, ConstantFloat> Floats;
68 TypePool<double, ConstantDouble> Doubles;
69 TypePool<uint64_t, ConstantInteger> Integers;
70 TypePool<RelocatableTuple, ConstantRelocatable> Relocatables;
71 };
72
73 GlobalContext::GlobalContext(llvm::raw_ostream *OsDump,
74 llvm::raw_ostream *OsEmit,
75 IceVerboseMask VerboseMask, IceString TestPrefix)
76 : StrDump(OsDump), StrEmit(OsEmit), VerboseMask(VerboseMask),
77 ConstPool(new ConstantPool()), TestPrefix(TestPrefix) {}
78
79 // In this context, name mangling means to rewrite a symbol using a
80 // given prefix. For a C++ symbol, nest the original symbol inside
81 // the "prefix" namespace. For other symbols, just prepend the
82 // prefix.
83 IceString GlobalContext::mangleName(const IceString &Name) const {
84 // An already-nested name like foo::bar() gets pushed down one
85 // level, making it equivalent to Prefix::foo::bar().
86 // _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
87 // A non-nested but mangled name like bar() gets nested, making it
88 // equivalent to Prefix::bar().
89 // _Z3barxyz ==> ZN6Prefix3barExyz
90 // An unmangled, extern "C" style name, gets a simple prefix:
91 // bar ==> Prefixbar
92 if (getTestPrefix() == "")
93 return Name;
94
95 unsigned PrefixLength = getTestPrefix().length();
96 char NameBase[1 + Name.length()];
97 const size_t BufLen = 30 + Name.length() + getTestPrefix().length();
98 char NewName[BufLen];
99 uint32_t BaseLength = 0;
100
101 int ItemsParsed = sscanf(Name.c_str(), "_ZN%s", NameBase);
102 if (ItemsParsed == 1) {
103 // Transform _ZN3foo3barExyz ==> _ZN6Prefix3foo3barExyz
104 // (splice in "6Prefix") ^^^^^^^
105 snprintf(NewName, BufLen, "_ZN%u%s%s", PrefixLength,
106 getTestPrefix().c_str(), NameBase);
107 // We ignore the snprintf return value (here and below). If we
108 // somehow miscalculated the output buffer length, the output will
109 // be truncated, but it will be truncated consistently for all
110 // mangleName() calls on the same input string.
111 return NewName;
112 }
113
114 ItemsParsed = sscanf(Name.c_str(), "_Z%u%s", &BaseLength, NameBase);
115 if (ItemsParsed == 2) {
116 // Transform _Z3barxyz ==> ZN6Prefix3barExyz
117 // ^^^^^^^^ ^
118 // (splice in "N6Prefix", and insert "E" after "3bar")
119 char OrigName[Name.length()];
120 char OrigSuffix[Name.length()];
121 strncpy(OrigName, NameBase, BaseLength);
122 OrigName[BaseLength] = '\0';
123 strcpy(OrigSuffix, NameBase + BaseLength);
124 snprintf(NewName, BufLen, "_ZN%u%s%u%sE%s", PrefixLength,
125 getTestPrefix().c_str(), BaseLength, OrigName, OrigSuffix);
126 return NewName;
127 }
128
129 // Transform bar ==> Prefixbar
130 // ^^^^^^
131 return getTestPrefix() + Name;
132 }
JF 2014/04/23 03:51:28 Could you add tests for this function? It gave me
Jim Stichnoth 2014/04/26 15:02:11 How about a TODO for the next CL? I probably shou
133
134 GlobalContext::~GlobalContext() {}
135
136 Constant *GlobalContext::getConstantInt(IceType Type, uint64_t ConstantInt64) {
137 return ConstPool->Integers.getOrAdd(this, Type, ConstantInt64);
138 }
139
140 Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
141 return ConstPool->Floats.getOrAdd(this, IceType_f32, ConstantFloat);
142 }
143
144 Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
145 return ConstPool->Doubles.getOrAdd(this, IceType_f64, ConstantDouble);
146 }
147
148 Constant *GlobalContext::getConstantSym(IceType Type, int64_t Offset,
149 const IceString &Name,
150 bool SuppressMangling) {
151 return ConstPool->Relocatables.getOrAdd(
152 this, Type, RelocatableTuple(Offset, Name, SuppressMangling));
153 }
154
155 void IceTimer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const {
156 if (Ctx->isVerbose(IceV_Timing)) {
157 // Prefixing with '#' allows timing strings to be included
158 // without error in textual assembly output.
159 Ctx->getStrDump() << "# " << getElapsedUs() << " usec " << Tag << "\n";
160 }
161 }
162
163 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698