Commit bc004630 by Jan Voung

Split ConstantInteger into ConstantInteger32 and ConstantInteger64.

In many cases, we expect a constant to be 32-bits or less. This simplifies range checking for x86 memory operand displacements (can only be 32-bit), or immediates in instructions (also 32-bit), since we only store 32-bits (so it trivially fits in 32-bits). Checks for whether a constant fits in 8-bits can be done on the 32-bit value instead of the 64-bit value. When TargetLowering sees a 64-bit immediate as an operand on a 64-bit instruction, it should have split the 64-bit immediate into a 32-bit loOperand(), and a 32-bit hiOperand(). So what's left for the Emit pass should be 32-bit constants. Other places which work with constants: - intrinsic operands (the ABI only allows i32 params for atomic mem order, or atomic is lock free byte-size, or the longjmp param). - addressing mode optimization (gep expansion should be working with i32 constants). - insertelement, and extractelement constant indices (bitcode reader restricts the type of the index to be i32 also). I guess now you may end up with multiple copies of what may be the "same" constant (i64 0 vs i32 0). BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/569033002
parent 97501839
......@@ -102,8 +102,12 @@ public:
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0,
GV->getName());
} else if (const ConstantInt *CI = dyn_cast<ConstantInt>(Const)) {
return Ctx->getConstantInt(convertToIceType(CI->getType()),
CI->getSExtValue());
Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) {
return Ctx->getConstantInt64(Ty, CI->getSExtValue());
} else {
return Ctx->getConstantInt32(Ty, CI->getSExtValue());
}
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Const)) {
Ice::Type Type = convertToIceType(CFP->getType());
if (Type == Ice::IceType_f32)
......
......@@ -21,6 +21,7 @@
#include <cassert>
#include <cstdio> // snprintf
#include <functional> // std::less
#include <limits>
#include <list>
#include <map>
#include <set>
......@@ -128,6 +129,11 @@ private:
Timer &operator=(const Timer &) LLVM_DELETED_FUNCTION;
};
template <typename T> bool WouldOverflowAdd(T X, T Y) {
return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
(X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
}
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEDEFS_H
......@@ -109,7 +109,8 @@ public:
ConstantPool() {}
TypePool<float, ConstantFloat, true> Floats;
TypePool<double, ConstantDouble, true> Doubles;
TypePool<uint64_t, ConstantInteger> Integers;
TypePool<uint32_t, ConstantInteger32> Integers32;
TypePool<uint64_t, ConstantInteger64> Integers64;
TypePool<RelocatableTuple, ConstantRelocatable> Relocatables;
UndefPool Undefs;
};
......@@ -289,10 +290,15 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
GlobalContext::~GlobalContext() {}
Constant *GlobalContext::getConstantInt(Type Ty, uint64_t ConstantInt64) {
Constant *GlobalContext::getConstantInt64(Type Ty, uint64_t ConstantInt64) {
assert(Ty == IceType_i64);
return ConstPool->Integers64.getOrAdd(this, Ty, ConstantInt64);
}
Constant *GlobalContext::getConstantInt32(Type Ty, uint32_t ConstantInt32) {
if (Ty == IceType_i1)
ConstantInt64 &= UINT64_C(1);
return ConstPool->Integers.getOrAdd(this, Ty, ConstantInt64);
ConstantInt32 &= UINT32_C(1);
return ConstPool->Integers32.getOrAdd(this, Ty, ConstantInt32);
}
Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
......@@ -320,8 +326,9 @@ Constant *GlobalContext::getConstantZero(Type Ty) {
case IceType_i8:
case IceType_i16:
case IceType_i32:
return getConstantInt32(Ty, 0);
case IceType_i64:
return getConstantInt(Ty, 0);
return getConstantInt64(Ty, 0);
case IceType_f32:
return getConstantFloat(0);
case IceType_f64:
......@@ -351,8 +358,9 @@ ConstantList GlobalContext::getConstantPool(Type Ty) const {
case IceType_i8:
case IceType_i16:
case IceType_i32:
return ConstPool->Integers32.getConstantPool();
case IceType_i64:
return ConstPool->Integers.getConstantPool();
return ConstPool->Integers64.getConstantPool();
case IceType_f32:
return ConstPool->Floats.getConstantPool();
case IceType_f64:
......
......@@ -75,7 +75,8 @@ public:
// Manage Constants.
// getConstant*() functions are not const because they might add
// something to the constant pool.
Constant *getConstantInt(Type Ty, uint64_t ConstantInt64);
Constant *getConstantInt32(Type Ty, uint32_t ConstantInt32);
Constant *getConstantInt64(Type Ty, uint64_t ConstantInt64);
Constant *getConstantFloat(float Value);
Constant *getConstantDouble(double Value);
// Returns a symbolic constant.
......
......@@ -1383,9 +1383,12 @@ void OperandX8632Mem::emit(const Cfg *Func) const {
bool OffsetIsNegative = false;
if (Offset == NULL) {
OffsetIsZero = true;
} else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) {
} else if (ConstantInteger32 *CI =
llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
assert(llvm::isa<ConstantRelocatable>(Offset));
}
if (Dumped) {
if (!OffsetIsZero) { // Suppress if Offset is known to be 0
......@@ -1430,9 +1433,12 @@ void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
bool OffsetIsNegative = false;
if (Offset == NULL) {
OffsetIsZero = true;
} else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) {
} else if (ConstantInteger32 *CI =
llvm::dyn_cast<ConstantInteger32>(Offset)) {
OffsetIsZero = (CI->getValue() == 0);
OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0);
OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
} else {
assert(llvm::isa<ConstantRelocatable>(Offset));
}
if (Dumped) {
if (!OffsetIsZero) { // Suppress if Offset is known to be 0
......
......@@ -27,7 +27,8 @@ class Operand {
public:
enum OperandKind {
kConst_Base,
kConstInteger,
kConstInteger32,
kConstInteger64,
kConstFloat,
kConstDouble,
kConstRelocatable,
......@@ -152,15 +153,21 @@ private:
const T Value;
};
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger> ConstantInteger;
typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32;
typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64;
typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
template <> inline void ConstantInteger::dump(const Cfg *, Ostream &Str) const {
template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const {
if (getType() == IceType_i1)
Str << (getValue() ? "true" : "false");
else
Str << static_cast<int64_t>(getValue());
Str << static_cast<int32_t>(getValue());
}
template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const {
assert(getType() == IceType_i64);
Str << static_cast<int64_t>(getValue());
}
// RelocatableTuple bundles the parameters that are used to
......
......@@ -509,7 +509,8 @@ private:
virtual ~TargetGlobalInitX8632() {}
};
template <> void ConstantInteger::emit(GlobalContext *Ctx) const;
template <> void ConstantInteger32::emit(GlobalContext *Ctx) const;
template <> void ConstantInteger64::emit(GlobalContext *Ctx) const;
template <> void ConstantFloat::emit(GlobalContext *Ctx) const;
template <> void ConstantDouble::emit(GlobalContext *Ctx) const;
......
......@@ -1777,8 +1777,11 @@ void ConstantsParser::ProcessRecord() {
if (IntegerType *IType = dyn_cast<IntegerType>(
Context->convertToLLVMType(NextConstantType))) {
APInt Value(IType->getBitWidth(), NaClDecodeSignRotatedValue(Values[0]));
Ice::Constant *C =
getContext()->getConstantInt(NextConstantType, Value.getSExtValue());
Ice::Constant *C = (NextConstantType == Ice::IceType_i64)
? getContext()->getConstantInt64(
NextConstantType, Value.getSExtValue())
: getContext()->getConstantInt32(
NextConstantType, Value.getSExtValue());
FuncParser->setNextConstantID(C);
return;
}
......
......@@ -61,4 +61,66 @@ entry:
; CHECK: movss xmm0, dword ptr [eax + 8]
}
define float @address_mode_opt_chaining_overflow(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = add i32 2147483640, %arg.int
%addr2.int = add i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_overflow:
; CHECK: 2147483640
; CHECK: movss xmm0, dword ptr [{{.*}} + 2147483643]
}
define float @address_mode_opt_chaining_overflow_sub(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483640
%addr2.int = sub i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_overflow_sub:
; CHECK: 2147483640
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483643]
}
define float @address_mode_opt_chaining_no_overflow(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483640
%addr2.int = add i32 %addr1.int, 2147483643
%addr2.ptr = inttoptr i32 %addr2.int to float*
%addr2.load = load float* %addr2.ptr, align 4
ret float %addr2.load
; CHECK-LABEL: address_mode_opt_chaining_no_overflow:
; CHECK: movss xmm0, dword ptr [{{.*}} + 3]
}
define float @address_mode_opt_add_pos_min_int(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = add i32 %arg.int, 2147483648
%addr1.ptr = inttoptr i32 %addr1.int to float*
%addr1.load = load float* %addr1.ptr, align 4
ret float %addr1.load
; CHECK-LABEL: address_mode_opt_add_pos_min_int:
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483648]
}
define float @address_mode_opt_sub_min_int(float* %arg) {
entry:
%arg.int = ptrtoint float* %arg to i32
%addr1.int = sub i32 %arg.int, 2147483648
%addr1.ptr = inttoptr i32 %addr1.int to float*
%addr1.load = load float* %addr1.ptr, align 4
ret float %addr1.load
; CHECK-LABEL: address_mode_opt_sub_min_int:
; CHECK: movss xmm0, dword ptr [{{.*}} - 2147483648]
}
; ERRORS-NOT: ICE translation error
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