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:
if (const auto GV = dyn_cast<GlobalValue>(Const)) {
Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
const Ice::RelocOffsetT Offset = 0;
return Ctx->getConstantSym(TypeConverter.getIcePointerType(),
Offset, Decl->getName(),
return Ctx->getConstantSym(Offset, Decl->getName(),
Decl->getSuppressMangling());
} else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) {
return Ctx->getConstantInt64(Ty, CI->getSExtValue());
} else {
return Ctx->getConstantInt32(Ty, CI->getSExtValue());
}
return Ctx->getConstantInt(Ty, CI->getSExtValue());
} else if (const auto CFP = dyn_cast<ConstantFP>(Const)) {
Ice::Type Type = convertToIceType(CFP->getType());
if (Type == Ice::IceType_f32)
......
......@@ -14,6 +14,7 @@
#include <ctype.h> // isdigit(), isupper()
#include <locale> // locale
#include <unordered_map>
#include "IceCfg.h"
#include "IceClFlags.h"
......@@ -25,29 +26,29 @@
#include "IceTimerTree.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 {
// 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.
// 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 {
// type ValueType (e.g. ConstantFloat).
template <Type Ty, typename KeyType, typename ValueType> class TypePool {
TypePool(const TypePool &) = delete;
TypePool &operator=(const TypePool &) = delete;
public:
TypePool() : NextPoolID(0) {}
ValueType *getOrAdd(GlobalContext *Ctx, Type Ty, KeyType Key) {
TupleType TupleKey = std::make_pair(Ty, Key);
auto Iter = Pool.find(TupleKey);
ValueType *getOrAdd(GlobalContext *Ctx, KeyType Key) {
auto Iter = Pool.find(Key);
if (Iter != Pool.end())
return Iter->second;
ValueType *Result = ValueType::create(Ctx, Ty, Key, NextPoolID++);
Pool[TupleKey] = Result;
Pool[Key] = Result;
return Result;
}
ConstantList getConstantPool() const {
......@@ -59,17 +60,7 @@ public:
}
private:
typedef std::pair<Type, KeyType> TupleType;
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;
typedef std::unordered_map<KeyType, ValueType *> ContainerType;
ContainerType Pool;
uint32_t NextPoolID;
};
......@@ -80,21 +71,17 @@ class UndefPool {
UndefPool &operator=(const UndefPool &) = delete;
public:
UndefPool() : NextPoolID(0) {}
UndefPool() : NextPoolID(0), Pool(IceType_NUM) {}
ConstantUndef *getOrAdd(GlobalContext *Ctx, Type Ty) {
auto I = Pool.find(Ty);
if (I != Pool.end())
return I->second;
ConstantUndef *Undef = ConstantUndef::create(Ctx, Ty, NextPoolID++);
Pool[Ty] = Undef;
return Undef;
if (Pool[Ty] == NULL)
Pool[Ty] = ConstantUndef::create(Ctx, Ty, NextPoolID++);
return Pool[Ty];
}
private:
uint32_t NextPoolID;
typedef std::map<Type, ConstantUndef *> ContainerType;
ContainerType Pool;
std::vector<ConstantUndef *> Pool;
};
// The global constant pool bundles individual pools of each type of
......@@ -105,11 +92,14 @@ class ConstantPool {
public:
ConstantPool() {}
TypePool<float, ConstantFloat, true> Floats;
TypePool<double, ConstantDouble, true> Doubles;
TypePool<uint32_t, ConstantInteger32> Integers32;
TypePool<uint64_t, ConstantInteger64> Integers64;
TypePool<RelocatableTuple, ConstantRelocatable> Relocatables;
TypePool<IceType_f32, float, ConstantFloat> Floats;
TypePool<IceType_f64, double, ConstantDouble> Doubles;
TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1;
TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
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;
};
......@@ -294,30 +284,58 @@ GlobalContext::~GlobalContext() {
llvm::DeleteContainerPointers(GlobalDeclarations);
}
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) {
assert(Ty == IceType_i64);
return ConstPool->Integers64.getOrAdd(this, Ty, ConstantInt64);
Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
switch (Ty) {
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) {
if (Ty == IceType_i1)
ConstantInt32 &= UINT32_C(1);
return ConstPool->Integers32.getOrAdd(this, Ty, ConstantInt32);
Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) {
return ConstPool->Integers64.getOrAdd(this, ConstantInt64);
}
Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
return ConstPool->Floats.getOrAdd(this, IceType_f32, ConstantFloat);
return ConstPool->Floats.getOrAdd(this, ConstantFloat);
}
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,
bool SuppressMangling) {
return ConstPool->Relocatables.getOrAdd(
this, Ty, RelocatableTuple(Offset, Name, SuppressMangling));
this, RelocatableTuple(Offset, Name, SuppressMangling));
}
Constant *GlobalContext::getConstantUndef(Type Ty) {
......@@ -327,12 +345,15 @@ Constant *GlobalContext::getConstantUndef(Type Ty) {
Constant *GlobalContext::getConstantZero(Type Ty) {
switch (Ty) {
case IceType_i1:
return getConstantInt1(0);
case IceType_i8:
return getConstantInt8(0);
case IceType_i16:
return getConstantInt16(0);
case IceType_i32:
return getConstantInt32(Ty, 0);
return getConstantInt32(0);
case IceType_i64:
return getConstantInt64(Ty, 0);
return getConstantInt64(0);
case IceType_f32:
return getConstantFloat(0);
case IceType_f64:
......
......@@ -113,14 +113,17 @@ public:
// Manage Constants.
// getConstant*() functions are not const because they might add
// something to the constant pool.
Constant *getConstantInt32(Type Ty, uint32_t ConstantInt32);
Constant *getConstantInt64(Type Ty, uint64_t ConstantInt64);
Constant *getConstantInt(Type Ty, int64_t Value);
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 *getConstantDouble(double Value);
// Returns a symbolic constant.
Constant *getConstantSym(Type Ty, RelocOffsetT Offset,
const IceString &Name = "",
bool SuppressMangling = false);
Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling);
// Returns an undef.
Constant *getConstantUndef(Type Ty);
// Returns a zero value.
......
......@@ -20,12 +20,8 @@
namespace Ice {
bool operator<(const RelocatableTuple &A, const RelocatableTuple &B) {
if (A.Offset != B.Offset)
return A.Offset < B.Offset;
if (A.SuppressMangling != B.SuppressMangling)
return A.SuppressMangling < B.SuppressMangling;
return A.Name < B.Name;
bool operator==(const RelocatableTuple &A, const RelocatableTuple &B) {
return A.Offset == B.Offset && A.Name == B.Name;
}
bool operator<(const RegWeight &A, const RegWeight &B) {
......
......@@ -169,8 +169,8 @@ private:
const T Value;
};
typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32;
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64;
typedef ConstantPrimitive<int32_t, Operand::kConstInteger32> ConstantInteger32;
typedef ConstantPrimitive<int64_t, Operand::kConstInteger64> ConstantInteger64;
typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
......@@ -195,20 +195,20 @@ template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
// ConstantRelocatable can fit into the global constant pool
// template mechanism.
class RelocatableTuple {
// RelocatableTuple(const RelocatableTuple &) = delete;
RelocatableTuple &operator=(const RelocatableTuple &) = delete;
public:
RelocatableTuple(const RelocOffsetT Offset, const IceString &Name,
bool SuppressMangling)
: Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {}
RelocatableTuple(const RelocatableTuple &) = default;
const RelocOffsetT Offset;
const IceString Name;
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
// a fixed offset.
......
......@@ -161,11 +161,12 @@ protected:
Variable *makeReg(Type Ty, int32_t RegNum = Variable::NoRegister);
InstCall *makeHelperCall(const IceString &Name, Variable *Dest,
SizeT MaxSrcs) {
bool SuppressMangling = true;
const Type FunctionPointerType = IceType_i32;
Constant *CallTarget =
Ctx->getConstantSym(FunctionPointerType, 0, Name, SuppressMangling);
InstCall *Call = InstCall::create(Func, MaxSrcs, Dest, CallTarget, false);
const bool SuppressMangling = true;
const bool HasTailCall = false;
const RelocOffsetT Offset = 0;
Constant *CallTarget = Ctx->getConstantSym(Offset, Name, SuppressMangling);
InstCall *Call =
InstCall::create(Func, MaxSrcs, Dest, CallTarget, HasTailCall);
return Call;
}
static Type stackSlotType();
......
......@@ -325,8 +325,8 @@ public:
SuppressMangling = false;
}
const Ice::RelocOffsetT Offset = 0;
C = getTranslator().getContext()->getConstantSym(
getIcePointerType(), Offset, Name, SuppressMangling);
C = getTranslator().getContext()->getConstantSym(Offset, Name,
SuppressMangling);
ValueIDConstants[ID] = C;
return C;
}
......@@ -1440,7 +1440,7 @@ private:
const auto *C = dyn_cast<Ice::ConstantInteger32>(Index);
if (C == nullptr)
return VectorIndexNotConstant;
if (C->getValue() >= typeNumElements(VecType))
if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType))
return VectorIndexNotInRange;
if (Index->getType() != Ice::IceType_i32)
return VectorIndexNotI32;
......@@ -2496,16 +2496,14 @@ void ConstantsParser::ProcessRecord() {
FuncParser->setNextConstantID(nullptr);
return;
}
if (IntegerType *IType = dyn_cast<IntegerType>(
if (auto IType = dyn_cast<IntegerType>(
Context->convertToLLVMType(NextConstantType))) {
APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Ice::Constant *C = (NextConstantType == Ice::IceType_i64)
? getContext()->getConstantInt64(
NextConstantType, Value.getSExtValue())
: getContext()->getConstantInt32(
NextConstantType, Value.getSExtValue());
FuncParser->setNextConstantID(C);
return;
if (Ice::Constant *C = getContext()->getConstantInt(
NextConstantType, Value.getSExtValue())) {
FuncParser->setNextConstantID(C);
return;
}
}
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
......
......@@ -60,8 +60,7 @@ Address Address::ofConstPool(GlobalContext *Ctx, Assembler *Asm,
StrBuf << ".L$" << Ty << "$" << Imm->getPoolEntryID();
const RelocOffsetT Offset = 0;
const bool SuppressMangling = true;
Constant *Sym =
Ctx->getConstantSym(Ty, Offset, StrBuf.str(), SuppressMangling);
Constant *Sym = Ctx->getConstantSym(Offset, StrBuf.str(), SuppressMangling);
AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
Asm, FK_Abs_4, llvm::cast<ConstantRelocatable>(Sym));
return x86::Address::Absolute(Fixup);
......
......@@ -33,7 +33,7 @@ define float @undef_float() {
entry:
ret float undef
; CHECK-LABEL: undef_float
; CHECK: fld dword ptr [0]
; CHECK: fld dword ptr [4]
}
define <4 x i1> @undef_v4i1() {
......@@ -186,7 +186,7 @@ entry:
%val = insertelement <4 x float> %arg, float undef, i32 0
ret <4 x float> %val
; CHECK-LABEL: vector_insertelement_arg2
; CHECK: movss {{.*}}, dword ptr [0]
; CHECK: movss {{.*}}, dword ptr [4]
}
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