Commit d2cb4361 by Jim Stichnoth

Subzero: Simplify the constant pools.

Internally, create a separate constant pool for each integer type, instead of a single i64 pool that uses the Ice::Type value as part of the key. This means each constant pool key can be a simple primitive value, rather than a tuple. Represent the pools using std::unordered_map instead of std::map since we're using C++11 now. Use signed integers instead of unsigned integers for the integer constant pools, to benefit from sign extension and to be more consistent. Remove the SuppressMangling field from hash and comparison functions on RelocatableTuple, since we'll never have two symbols with the same name but different values of SuppressMangling. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/737513008
parent 144a393b
...@@ -116,16 +116,11 @@ public: ...@@ -116,16 +116,11 @@ public:
if (const auto GV = dyn_cast<GlobalValue>(Const)) { if (const auto GV = dyn_cast<GlobalValue>(Const)) {
Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV); Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
const Ice::RelocOffsetT Offset = 0; const Ice::RelocOffsetT Offset = 0;
return Ctx->getConstantSym(TypeConverter.getIcePointerType(), return Ctx->getConstantSym(Offset, Decl->getName(),
Offset, Decl->getName(),
Decl->getSuppressMangling()); Decl->getSuppressMangling());
} else if (const auto CI = dyn_cast<ConstantInt>(Const)) { } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Ice::Type Ty = convertToIceType(CI->getType()); Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) { return Ctx->getConstantInt(Ty, CI->getSExtValue());
return Ctx->getConstantInt64(Ty, CI->getSExtValue());
} else {
return Ctx->getConstantInt32(Ty, CI->getSExtValue());
}
} else if (const auto CFP = dyn_cast<ConstantFP>(Const)) { } else if (const auto CFP = dyn_cast<ConstantFP>(Const)) {
Ice::Type Type = convertToIceType(CFP->getType()); Ice::Type Type = convertToIceType(CFP->getType());
if (Type == Ice::IceType_f32) if (Type == Ice::IceType_f32)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <ctype.h> // isdigit(), isupper() #include <ctype.h> // isdigit(), isupper()
#include <locale> // locale #include <locale> // locale
#include <unordered_map>
#include "IceCfg.h" #include "IceCfg.h"
#include "IceClFlags.h" #include "IceClFlags.h"
...@@ -25,29 +26,29 @@ ...@@ -25,29 +26,29 @@
#include "IceTimerTree.h" #include "IceTimerTree.h"
#include "IceTypes.h" #include "IceTypes.h"
template <> struct std::hash<Ice::RelocatableTuple> {
std::size_t operator()(const Ice::RelocatableTuple &Key) const {
return std::hash<Ice::IceString>()(Key.Name) +
std::hash<Ice::RelocOffsetT>()(Key.Offset);
}
};
namespace Ice { namespace Ice {
// TypePool maps constants of type KeyType (e.g. float) to pointers to // TypePool maps constants of type KeyType (e.g. float) to pointers to
// type ValueType (e.g. ConstantFloat). KeyType values are compared // type ValueType (e.g. ConstantFloat).
// using memcmp() because of potential NaN values in KeyType values. template <Type Ty, typename KeyType, typename ValueType> class TypePool {
// KeyTypeHasFP indicates whether KeyType is a floating-point type
// whose values need to be compared using memcmp() for NaN
// correctness. TODO: use std::is_floating_point<KeyType> instead of
// KeyTypeHasFP with C++11.
template <typename KeyType, typename ValueType, bool KeyTypeHasFP = false>
class TypePool {
TypePool(const TypePool &) = delete; TypePool(const TypePool &) = delete;
TypePool &operator=(const TypePool &) = delete; TypePool &operator=(const TypePool &) = delete;
public: public:
TypePool() : NextPoolID(0) {} TypePool() : NextPoolID(0) {}
ValueType *getOrAdd(GlobalContext *Ctx, Type Ty, KeyType Key) { ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) {
TupleType TupleKey = std::make_pair(Ty, Key); auto Iter = Pool.find(Key);
auto Iter = Pool.find(TupleKey);
if (Iter != Pool.end()) if (Iter != Pool.end())
return Iter->second; return Iter->second;
ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++); ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++);
Pool[TupleKey] = Result; Pool[Key] = Result;
return Result; return Result;
} }
ConstantList getConstantPool() const { ConstantList getConstantPool() const {
...@@ -59,17 +60,7 @@ public: ...@@ -59,17 +60,7 @@ public:
} }
private: private:
typedef std::pair<Type, KeyType> TupleType; typedef std::unordered_map<KeyType, ValueType *> ContainerType;
struct TupleCompare {
bool operator()(const TupleType &A, const TupleType &B) const {
if (A.first != B.first)
return A.first < B.first;
if (KeyTypeHasFP)
return memcmp(&A.second, &B.second, sizeof(KeyType)) < 0;
return A.second < B.second;
}
};
typedef std::map<const TupleType, ValueType *, TupleCompare> ContainerType;
ContainerType Pool; ContainerType Pool;
uint32_t NextPoolID; uint32_t NextPoolID;
}; };
...@@ -80,21 +71,17 @@ class UndefPool { ...@@ -80,21 +71,17 @@ class UndefPool {
UndefPool &operator=(const UndefPool &) = delete; UndefPool &operator=(const UndefPool &) = delete;
public: public:
UndefPool() : NextPoolID(0) {} UndefPool() : NextPoolID(0), Pool(IceType_NUM) {}
ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) { ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) {
auto I = Pool.find(Ty); if (Pool[Ty] == NULL)
if (I != Pool.end()) Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++);
return I->second; return Pool[Ty];
ConstantUndef *Undef = ConstantUndef::create(Ctx, Ty, NextPoolID++);
Pool[Ty] = Undef;
return Undef;
} }
private: private:
uint32_t NextPoolID; uint32_t NextPoolID;
typedef std::map<Type, ConstantUndef *> ContainerType; std::vector<ConstantUndef *> Pool;
ContainerType Pool;
}; };
// The global constant pool bundles individual pools of each type of // The global constant pool bundles individual pools of each type of
...@@ -105,11 +92,14 @@ class ConstantPool { ...@@ -105,11 +92,14 @@ class ConstantPool {
public: public:
ConstantPool() {} ConstantPool() {}
TypePool<float, ConstantFloat, true> Floats; TypePool<IceType_f32, float, ConstantFloat> Floats;
TypePool<double, ConstantDouble, true> Doubles; TypePool<IceType_f64, double, ConstantDouble> Doubles;
TypePool<uint32_t, ConstantInteger32> Integers32; TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1;
TypePool<uint64_t, ConstantInteger64> Integers64; TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
TypePool<RelocatableTuple, ConstantRelocatable> Relocatables; TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16;
TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
UndefPool Undefs; UndefPool Undefs;
}; };
...@@ -294,30 +284,58 @@ GlobalContext::~GlobalContext() { ...@@ -294,30 +284,58 @@ GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(GlobalDeclarations); llvm::DeleteContainerPointers(GlobalDeclarations);
} }
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) { Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
assert(Ty == IceType_i64); switch (Ty) {
return ConstPool->Integers64.getOrAdd(this, Ty, ConstantInt64); case IceType_i1:
return getConstantInt1(Value);
case IceType_i8:
return getConstantInt8(Value);
case IceType_i16:
return getConstantInt16(Value);
case IceType_i32:
return getConstantInt32(Value);
case IceType_i64:
return getConstantInt64(Value);
default:
llvm_unreachable("Bad integer type for getConstant");
}
return NULL;
}
Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) {
ConstantInt1 &= INT8_C(1);
return ConstPool->Integers1.getOrAdd(this, ConstantInt1);
}
Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) {
return ConstPool->Integers8.getOrAdd(this, ConstantInt8);
}
Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) {
return ConstPool->Integers16.getOrAdd(this, ConstantInt16);
}
Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) {
return ConstPool->Integers32.getOrAdd(this, ConstantInt32);
} }
Constant *GlobalContext::getConstantInt32(Type Ty, uint32_t ConstantInt32) { Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) {
if (Ty == IceType_i1) return ConstPool->Integers64.getOrAdd(this, ConstantInt64);
ConstantInt32 &= UINT32_C(1);
return ConstPool->Integers32.getOrAdd(this, Ty, ConstantInt32);
} }
Constant *GlobalContext::getConstantFloat(float ConstantFloat) { Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
return ConstPool->Floats.getOrAdd(this, IceType_f32, ConstantFloat); return ConstPool->Floats.getOrAdd(this, ConstantFloat);
} }
Constant *GlobalContext::getConstantDouble(double ConstantDouble) { Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
return ConstPool->Doubles.getOrAdd(this, IceType_f64, ConstantDouble); return ConstPool->Doubles.getOrAdd(this, ConstantDouble);
} }
Constant *GlobalContext::getConstantSym(Type Ty, RelocOffsetT Offset, Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
const IceString &Name, const IceString &Name,
bool SuppressMangling) { bool SuppressMangling) {
return ConstPool->Relocatables.getOrAdd( return ConstPool->Relocatables.getOrAdd(
this, Ty, RelocatableTuple(Offset, Name, SuppressMangling)); this, RelocatableTuple(Offset, Name, SuppressMangling));
} }
Constant *GlobalContext::getConstantUndef(Type Ty) { Constant *GlobalContext::getConstantUndef(Type Ty) {
...@@ -327,12 +345,15 @@ Constant *GlobalContext::getConstantUndef(Type Ty) { ...@@ -327,12 +345,15 @@ Constant *GlobalContext::getConstantUndef(Type Ty) {
Constant *GlobalContext::getConstantZero(Type Ty) { Constant *GlobalContext::getConstantZero(Type Ty) {
switch (Ty) { switch (Ty) {
case IceType_i1: case IceType_i1:
return getConstantInt1(0);
case IceType_i8: case IceType_i8:
return getConstantInt8(0);
case IceType_i16: case IceType_i16:
return getConstantInt16(0);
case IceType_i32: case IceType_i32:
return getConstantInt32(Ty, 0); return getConstantInt32(0);
case IceType_i64: case IceType_i64:
return getConstantInt64(Ty, 0); return getConstantInt64(0);
case IceType_f32: case IceType_f32:
return getConstantFloat(0); return getConstantFloat(0);
case IceType_f64: case IceType_f64:
......
...@@ -113,14 +113,17 @@ public: ...@@ -113,14 +113,17 @@ public:
// Manage Constants. // Manage Constants.
// getConstant*() functions are not const because they might add // getConstant*() functions are not const because they might add
// something to the constant pool. // something to the constant pool.
Constant *getConstantInt32(Type Ty, uint32_t ConstantInt32); Constant *getConstantInt(Type Ty, int64_t Value);
Constant *getConstantInt64(Type Ty, uint64_t ConstantInt64); Constant *getConstantInt1(int8_t ConstantInt1);
Constant *getConstantInt8(int8_t ConstantInt8);
Constant *getConstantInt16(int16_t ConstantInt16);
Constant *getConstantInt32(int32_t ConstantInt32);
Constant *getConstantInt64(int64_t ConstantInt64);
Constant *getConstantFloat(float Value); Constant *getConstantFloat(float Value);
Constant *getConstantDouble(double Value); Constant *getConstantDouble(double Value);
// Returns a symbolic constant. // Returns a symbolic constant.
Constant *getConstantSym(Type Ty, RelocOffsetT Offset, Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name,
const IceString &Name = "", bool SuppressMangling);
bool SuppressMangling = false);
// Returns an undef. // Returns an undef.
Constant *getConstantUndef(Type Ty); Constant *getConstantUndef(Type Ty);
// Returns a zero value. // Returns a zero value.
......
...@@ -20,12 +20,8 @@ ...@@ -20,12 +20,8 @@
namespace Ice { namespace Ice {
bool operator<(const RelocatableTuple &A, const RelocatableTuple &B) { bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) {
if (A.Offset != B.Offset) return A.Offset == B.Offset && A.Name == B.Name;
return A.Offset < B.Offset;
if (A.SuppressMangling != B.SuppressMangling)
return A.SuppressMangling < B.SuppressMangling;
return A.Name < B.Name;
} }
bool operator<(const RegWeight &A, const RegWeight &B) { bool operator<(const RegWeight &A, const RegWeight &B) {
......
...@@ -169,8 +169,8 @@ private: ...@@ -169,8 +169,8 @@ private:
const T Value; const T Value;
}; };
typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32; typedef ConstantPrimitive<int32_t, Operand::kConstInteger32> ConstantInteger32;
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64; typedef ConstantPrimitive<int64_t, Operand::kConstInteger64> ConstantInteger64;
typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat; typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble; typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
...@@ -195,20 +195,20 @@ template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const ...@@ -195,20 +195,20 @@ template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
// ConstantRelocatable can fit into the global constant pool // ConstantRelocatable can fit into the global constant pool
// template mechanism. // template mechanism.
class RelocatableTuple { class RelocatableTuple {
// RelocatableTuple(const RelocatableTuple &) = delete;
RelocatableTuple &operator=(const RelocatableTuple &) = delete; RelocatableTuple &operator=(const RelocatableTuple &) = delete;
public: public:
RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, RelocatableTuple(const RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling) bool SuppressMangling)
: Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {}
RelocatableTuple(const RelocatableTuple &) = default;
const RelocOffsetT Offset; const RelocOffsetT Offset;
const IceString Name; const IceString Name;
bool SuppressMangling; bool SuppressMangling;
}; };
bool operator<(const RelocatableTuple &A, const RelocatableTuple &B); bool operator==(const RelocatableTuple &A, const RelocatableTuple &B);
// ConstantRelocatable represents a symbolic constant combined with // ConstantRelocatable represents a symbolic constant combined with
// a fixed offset. // a fixed offset.
......
...@@ -161,11 +161,12 @@ protected: ...@@ -161,11 +161,12 @@ protected:
Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister); Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
InstCall *makeHelperCall(const IceString &Name, Variable *Dest, InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
SizeT MaxSrcs) { SizeT MaxSrcs) {
bool SuppressMangling = true; const bool SuppressMangling = true;
const Type FunctionPointerType = IceType_i32; const bool HasTailCall = false;
Constant *CallTarget = const RelocOffsetT Offset = 0;
Ctx->getConstantSym(FunctionPointerType, 0, Name, SuppressMangling); Constant *CallTarget = Ctx->getConstantSym(Offset, Name, SuppressMangling);
InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget, false); InstCall *Call =
InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
return Call; return Call;
} }
static Type stackSlotType(); static Type stackSlotType();
......
...@@ -325,8 +325,8 @@ public: ...@@ -325,8 +325,8 @@ public:
SuppressMangling = false; SuppressMangling = false;
} }
const Ice::RelocOffsetT Offset = 0; const Ice::RelocOffsetT Offset = 0;
C = getTranslator().getContext()->getConstantSym( C = getTranslator().getContext()->getConstantSym(Offset, Name,
getIcePointerType(), Offset, Name, SuppressMangling); SuppressMangling);
ValueIDConstants[ID] = C; ValueIDConstants[ID] = C;
return C; return C;
} }
...@@ -1440,7 +1440,7 @@ private: ...@@ -1440,7 +1440,7 @@ private:
const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
if (C == nullptr) if (C == nullptr)
return VectorIndexNotConstant; return VectorIndexNotConstant;
if (C->getValue() >= typeNumElements(VecType)) if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
return VectorIndexNotInRange; return VectorIndexNotInRange;
if (Index->getType() != Ice::IceType_i32) if (Index->getType() != Ice::IceType_i32)
return VectorIndexNotI32; return VectorIndexNotI32;
...@@ -2496,16 +2496,14 @@ void ConstantsParser::ProcessRecord() { ...@@ -2496,16 +2496,14 @@ void ConstantsParser::ProcessRecord() {
FuncParser->setNextConstantID(nullptr); FuncParser->setNextConstantID(nullptr);
return; return;
} }
if (IntegerType *IType = dyn_cast<IntegerType>( if (auto IType = dyn_cast<IntegerType>(
Context->convertToLLVMType(NextConstantType))) { Context->convertToLLVMType(NextConstantType))) {
APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0])); APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Ice::Constant *C = (NextConstantType == Ice::IceType_i64) if (Ice::Constant *C = getContext()->getConstantInt(
? getContext()->getConstantInt64( NextConstantType, Value.getSExtValue())) {
NextConstantType, Value.getSExtValue()) FuncParser->setNextConstantID(C);
: getContext()->getConstantInt32( return;
NextConstantType, Value.getSExtValue()); }
FuncParser->setNextConstantID(C);
return;
} }
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
......
...@@ -60,8 +60,7 @@ Address Address::ofConstPool(GlobalContext *Ctx, Assembler *Asm, ...@@ -60,8 +60,7 @@ Address Address::ofConstPool(GlobalContext *Ctx, Assembler *Asm,
StrBuf << ".L$" << Ty << "$" << Imm->getPoolEntryID(); StrBuf << ".L$" << Ty << "$" << Imm->getPoolEntryID();
const RelocOffsetT Offset = 0; const RelocOffsetT Offset = 0;
const bool SuppressMangling = true; const bool SuppressMangling = true;
Constant *Sym = Constant *Sym = Ctx->getConstantSym(Offset, StrBuf.str(), SuppressMangling);
Ctx->getConstantSym(Ty, Offset, StrBuf.str(), SuppressMangling);
AssemblerFixup *Fixup = x86::DisplacementRelocation::create( AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
Asm, FK_Abs_4, llvm::cast<ConstantRelocatable>(Sym)); Asm, FK_Abs_4, llvm::cast<ConstantRelocatable>(Sym));
return x86::Address::Absolute(Fixup); return x86::Address::Absolute(Fixup);
......
...@@ -33,7 +33,7 @@ define float @undef_float() { ...@@ -33,7 +33,7 @@ define float @undef_float() {
entry: entry:
ret float undef ret float undef
; CHECK-LABEL: undef_float ; CHECK-LABEL: undef_float
; CHECK: fld dword ptr [0] ; CHECK: fld dword ptr [4]
} }
define <4 x i1> @undef_v4i1() { define <4 x i1> @undef_v4i1() {
...@@ -186,7 +186,7 @@ entry: ...@@ -186,7 +186,7 @@ entry:
%val = insertelement <4 x float> %arg, float undef, i32 0 %val = insertelement <4 x float> %arg, float undef, i32 0
ret <4 x float> %val ret <4 x float> %val
; CHECK-LABEL: vector_insertelement_arg2 ; CHECK-LABEL: vector_insertelement_arg2
; CHECK: movss {{.*}}, dword ptr [0] ; CHECK: movss {{.*}}, dword ptr [4]
} }
define float @vector_extractelement_v4f32_index_0() { define float @vector_extractelement_v4f32_index_0() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment