Index: src/IceGlobalContext.cpp |
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp |
index 5f9b620121aac0e7185d26235a57c0d01174ba97..c9b97861c36ea1b32700d2f1b68fc7d64dcec258 100644 |
--- a/src/IceGlobalContext.cpp |
+++ b/src/IceGlobalContext.cpp |
@@ -25,6 +25,22 @@ |
namespace Ice { |
+namespace { |
+ |
+template <class MapTy, class ListTy> |
+ListTy makeListOfValues(const MapTy &Pool) { |
+ ListTy Values; |
+ Values.reserve(Pool.size()); |
+ // TODO: replace the loop with std::transform + lambdas. |
+ for (typename MapTy::const_iterator I = Pool.begin(), E = Pool.end(); I != E; |
+ ++I) { |
+ Values.push_back(I->second); |
+ } |
+ return Values; |
+} |
+ |
+} // end of anonymous namespace |
+ |
// TypePool maps constants of type KeyType (e.g. float) to pointers to |
// type ValueType (e.g. ConstantFloat). KeyType values are compared |
// using memcmp() because of potential NaN values in KeyType values. |
@@ -49,15 +65,7 @@ public: |
return Result; |
} |
ConstantList getConstantPool() const { |
- ConstantList Constants; |
- Constants.reserve(Pool.size()); |
- // TODO: replace the loop with std::transform + lambdas. |
- for (typename ContainerType::const_iterator I = Pool.begin(), |
- E = Pool.end(); |
- I != E; ++I) { |
- Constants.push_back(I->second); |
- } |
- return Constants; |
+ return makeListOfValues<ContainerType, ConstantList>(Pool); |
} |
private: |
@@ -76,6 +84,27 @@ private: |
uint32_t NextPoolID; |
}; |
+// ImmediatePool is used for pooling constants that are typically used |
+// as immediate operands but have been pooled for code randomization |
+// purposes. The pool maps strings to constants of any type. The |
+// string is a unique label for a given immediate. |
+class ImmediatePool { |
+ ImmediatePool(const ImmediatePool &) LLVM_DELETED_FUNCTION; |
+ ImmediatePool &operator=(const ImmediatePool &) LLVM_DELETED_FUNCTION; |
+ |
+public: |
+ ImmediatePool() {} |
+ |
+ void add(const IceString &Name, Constant *Value) { Pool[Name] = Value; } |
+ ConstantList getConstantPool() const { |
+ return makeListOfValues<ContainerType, ConstantList>(Pool); |
+ } |
+ |
+private: |
+ typedef std::map<IceString, Constant *> ContainerType; |
+ ContainerType Pool; |
+}; |
+ |
// UndefPool maps ICE types to the corresponding ConstantUndef values. |
class UndefPool { |
UndefPool(const UndefPool &) LLVM_DELETED_FUNCTION; |
@@ -111,6 +140,7 @@ public: |
TypePool<double, ConstantDouble, true> Doubles; |
TypePool<uint64_t, ConstantInteger> Integers; |
TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; |
+ ImmediatePool Immediates; |
UndefPool Undefs; |
}; |
@@ -343,6 +373,11 @@ Constant *GlobalContext::getConstantZero(Type Ty) { |
llvm_unreachable("Unknown type"); |
} |
+void GlobalContext::addConstantPooledImmediate(const IceString &Name, |
+ Constant *Immediate) { |
+ ConstPool->Immediates.add(Name, Immediate); |
+} |
+ |
ConstantList GlobalContext::getConstantPool(Type Ty) const { |
switch (Ty) { |
case IceType_i1: |
@@ -374,6 +409,10 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const { |
llvm_unreachable("Unknown type"); |
} |
+ConstantList GlobalContext::getImmediatePool() const { |
+ return ConstPool->Immediates.getConstantPool(); |
+} |
+ |
void Timer::printElapsedUs(GlobalContext *Ctx, const IceString &Tag) const { |
if (Ctx->isVerbose(IceV_Timing)) { |
// Prefixing with '#' allows timing strings to be included |