Index: src/IceGlobalContext.cpp |
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7e389f2cbcfc9eaf504ff9b3169145f5b7b9a5ed |
--- /dev/null |
+++ b/src/IceGlobalContext.cpp |
@@ -0,0 +1,156 @@ |
+//===- subzero/src/IceGlobalContext.cpp - Global context defs ---*- C++ -*-===// |
+// |
+// The Subzero Code Generator |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// This file defines aspects of the compilation that persist across |
+// multiple functions. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#include "IceDefs.h" |
+#include "IceTypes.h" |
+#include "IceCfg.h" |
+#include "IceGlobalContext.h" |
+#include "IceOperand.h" |
+ |
+class IceConstantPool { |
+ // TODO: Try to refactor the getOrAdd*() methods. |
JF
2014/04/16 01:27:32
Yes please!
Jim Stichnoth
2014/04/21 20:26:40
Done.
|
+public: |
+ IceConstantPool(IceGlobalContext *Ctx) : Ctx(Ctx) {} |
+ IceConstantRelocatable *getOrAddRelocatable(IceType Type, const void *Handle, |
+ int64_t Offset, |
+ const IceString &Name) { |
+ uint32_t Index = NameToIndexReloc.translate( |
+ KeyTypeReloc(Type, std::pair<IceString, int64_t>(Name, Offset))); |
JF
2014/04/16 01:27:32
std::make_pair
Jim Stichnoth
2014/04/21 20:26:40
Done.
|
+ if (Index >= RelocatablePool.size()) { |
+ RelocatablePool.resize(Index + 1); |
+ void *Handle = NULL; |
+ RelocatablePool[Index] = IceConstantRelocatable::create( |
+ Ctx, Index, Type, Handle, Offset, Name); |
+ } |
+ IceConstantRelocatable *Constant = RelocatablePool[Index]; |
+ assert(Constant); |
+ return Constant; |
+ } |
+ uint32_t getRelocatableSize() const { return RelocatablePool.size(); } |
+ IceConstantRelocatable *getEntry(uint32_t Index) const { |
+ assert(Index < RelocatablePool.size()); |
+ return RelocatablePool[Index]; |
+ } |
+ IceConstantInteger *getOrAddInteger(IceType Type, uint64_t Value) { |
+ uint32_t Index = NameToIndexInteger.translate(KeyTypeInteger(Type, Value)); |
+ if (Index >= IntegerPool.size()) { |
+ IntegerPool.resize(Index + 1); |
+ IntegerPool[Index] = IceConstantInteger::create(Ctx, Type, Value); |
+ } |
+ IceConstantInteger *Constant = IntegerPool[Index]; |
+ assert(Constant); |
+ return Constant; |
+ } |
+ IceConstantFloat *getOrAddFloat(float Value) { |
+ uint32_t Index = NameToIndexFloat.translate(Value); |
+ if (Index >= FloatPool.size()) { |
+ FloatPool.resize(Index + 1); |
+ FloatPool[Index] = IceConstantFloat::create(Ctx, IceType_f32, Value); |
+ } |
+ IceConstantFloat *Constant = FloatPool[Index]; |
+ assert(Constant); |
+ return Constant; |
+ } |
+ IceConstantDouble *getOrAddDouble(double Value) { |
+ uint32_t Index = NameToIndexDouble.translate(Value); |
+ if (Index >= DoublePool.size()) { |
+ DoublePool.resize(Index + 1); |
+ DoublePool[Index] = IceConstantDouble::create(Ctx, IceType_f64, Value); |
+ } |
+ IceConstantDouble *Constant = DoublePool[Index]; |
+ assert(Constant); |
+ return Constant; |
+ } |
+ |
+private: |
+ // KeyTypeReloc is a triple of {Type, Name, Offset}. |
JF
2014/04/16 01:27:32
TODO: use tuple when we move to C++11.
Jim Stichnoth
2014/04/21 20:26:40
Done.
|
+ typedef std::pair<IceType, std::pair<IceString, int64_t> > KeyTypeReloc; |
+ typedef std::pair<IceType, int64_t> KeyTypeInteger; |
+ IceGlobalContext *Ctx; |
+ // Use IceValueTranslation<> to map (Name,Type) pairs to an index. |
+ IceValueTranslation<KeyTypeReloc> NameToIndexReloc; |
+ IceValueTranslation<KeyTypeInteger> NameToIndexInteger; |
+ IceValueTranslation<float> NameToIndexFloat; |
+ IceValueTranslation<double> NameToIndexDouble; |
+ std::vector<IceConstantRelocatable *> RelocatablePool; |
+ std::vector<IceConstantInteger *> IntegerPool; |
+ std::vector<IceConstantFloat *> FloatPool; |
+ std::vector<IceConstantDouble *> DoublePool; |
JF
2014/04/16 01:27:32
I find the map/vector duality really weird: the ma
Jim Stichnoth
2014/04/21 20:26:40
The latest patchset makes this map/vector duality
JF
2014/04/23 03:51:28
Could you make sure the tests have NaN values in t
JF
2014/04/23 03:51:28
The whole duality still seems weird. I really thin
Jim Stichnoth
2014/04/26 15:02:11
Done - see fpconst.pnacl.ll, which includes duplic
Jim Stichnoth
2014/04/26 15:02:11
You are right - it's good enough to keep a simple
|
+}; |
+ |
+IceGlobalContext::IceGlobalContext(llvm::raw_ostream *OsDump, |
+ llvm::raw_ostream *OsEmit, |
+ IceVerboseMask VerboseMask, |
+ IceString TestPrefix) |
+ : StrDump(OsDump), StrEmit(OsEmit), VerboseMask(VerboseMask), |
+ ConstantPool(new IceConstantPool(this)), TestPrefix(TestPrefix) {} |
+ |
+// In this context, name mangling means to rewrite a symbol using a |
+// given prefix. For a C++ symbol, we'd like to demangle it, prepend |
+// the prefix to the original symbol, and remangle it for C++. For |
+// other symbols, just prepend the prefix. |
+IceString IceGlobalContext::mangleName(const IceString &Name) const { |
+ // TODO: This handles only non-nested C++ symbols, and not ones that |
+ // begin with "_ZN". For the latter, we need to rewrite only the |
+ // last name component. |
+ if (getTestPrefix() == "") |
+ return Name; |
+ IceString Default = getTestPrefix() + Name; |
+ uint32_t BaseLength = 0; |
+ char Buffer[1 + Name.length()]; |
+ int ItemsParsed = sscanf(Name.c_str(), "_Z%u%s", &BaseLength, Buffer); |
+ if (ItemsParsed != 2) |
+ return Default; |
+ if (strlen(Buffer) < BaseLength) |
JF
2014/04/16 01:27:32
Could you explain what this case is?
Jim Stichnoth
2014/04/21 20:26:40
Done. I actually rolled in a better version of ma
|
+ return Default; |
+ |
+ BaseLength += getTestPrefix().length(); |
+ char NewNumber[30 + Name.length() + getTestPrefix().length()]; |
+ sprintf(NewNumber, "_Z%u%s%s", BaseLength, getTestPrefix().c_str(), Buffer); |
JF
2014/04/16 01:27:32
snprintf, and check for errors.
Jim Stichnoth
2014/04/21 20:26:40
Done. I don't think error (or snprintf return val
|
+ return NewNumber; |
+} |
+ |
+IceGlobalContext::~IceGlobalContext() {} |
+ |
+IceConstant *IceGlobalContext::getConstantInt(IceType Type, |
+ uint64_t ConstantInt64) { |
+ return ConstantPool->getOrAddInteger(Type, ConstantInt64); |
+} |
+ |
+IceConstant *IceGlobalContext::getConstantFloat(float ConstantFloat) { |
+ return ConstantPool->getOrAddFloat(ConstantFloat); |
+} |
+ |
+IceConstant *IceGlobalContext::getConstantDouble(double ConstantDouble) { |
+ return ConstantPool->getOrAddDouble(ConstantDouble); |
+} |
+ |
+IceConstant *IceGlobalContext::getConstantSym(IceType Type, const void *Handle, |
+ int64_t Offset, |
+ const IceString &Name, |
+ bool SuppressMangling) { |
+ IceConstantRelocatable *Const = |
+ ConstantPool->getOrAddRelocatable(Type, Handle, Offset, Name); |
+ Const->setSuppressMangling(SuppressMangling); |
JF
2014/04/16 01:27:32
Doesn't this change the manging if e.g. the symbol
Jim Stichnoth
2014/04/21 20:26:40
True. The code has been changed to add SuppressMa
|
+ return Const; |
+} |
+ |
+void IceTimer::printElapsedUs(IceGlobalContext *Ctx, |
+ const IceString &Tag) const { |
+ if (Ctx->isVerbose(IceV_Timing)) { |
+ // Prefixing with '#' allows timing strings to be included |
+ // without error in textual assembly output. |
+ Ctx->StrDump << "# " << getElapsedUs() << " usec " << Tag << "\n"; |
+ } |
+} |