summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@linux.intel.com>2014-12-04 18:12:03 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-12-15 16:07:53 +0800
commit096390e01c89c3d7231dbe78b3af9d7f08f2c59d (patch)
treea0bcd29c8ec8bc8050cfa272ae022547cb5d5e89
parent47ebe2e96c777d9fd2ba07cef0e681eaff243fa1 (diff)
GBE: Add some missing constant expression cases.
Major for two types of constant expression cases: 1. The destination is a vector. 2. Some missing operators. Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com> Reviewed-by: "Song, Ruiling" <ruiling.song@intel.com>
-rw-r--r--backend/src/ir/context.hpp4
-rw-r--r--backend/src/ir/immediate.cpp34
-rw-r--r--backend/src/ir/immediate.hpp70
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp38
4 files changed, 135 insertions, 11 deletions
diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp
index 485d5587..cf5109d0 100644
--- a/backend/src/ir/context.hpp
+++ b/backend/src/ir/context.hpp
@@ -74,11 +74,11 @@ namespace ir {
return fn->newImmediate(imm);
}
/*! Create a new immediate value */
- INLINE ImmediateIndex newImmediate(vector<ImmediateIndex>indexVector) {
+ INLINE ImmediateIndex newImmediate(vector<ImmediateIndex>indexVector, Type dstType) {
vector<const Immediate*> immVector;
for( uint32_t i = 0; i < indexVector.size(); i++)
immVector.push_back(&fn->getImmediate(indexVector[i]));
- const Immediate imm(immVector);
+ const Immediate imm(immVector, dstType);
return fn->newImmediate(imm);
}
/*! Create an integer immediate value */
diff --git a/backend/src/ir/immediate.cpp b/backend/src/ir/immediate.cpp
index 7d26925c..1aac9bc5 100644
--- a/backend/src/ir/immediate.cpp
+++ b/backend/src/ir/immediate.cpp
@@ -132,7 +132,7 @@ using namespace ir;
}
Immediate Immediate::less (const Immediate &left, const Immediate &right) {
- GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_U64);
+ GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_DOUBLE);
switch (left.getType()) {
default:
GBE_ASSERT(0);
@@ -149,6 +149,30 @@ using namespace ir;
}
}
+ Immediate Immediate::extract (const Immediate &left, const Immediate &right, Type dstType) {
+ GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_DOUBLE);
+ GBE_ASSERT(dstType == left.getType());
+ uint32_t index = right.getIntegerValue();
+ GBE_ASSERT(index >= 0 && index < left.getElemNum());
+ if (left.type != IMM_TYPE_COMP) {
+ switch (left.getType()) {
+ default:
+ GBE_ASSERT(0);
+ case TYPE_BOOL: return Immediate(left.data.b[index]);
+ case TYPE_S8: return Immediate(left.data.s8[index]);
+ case TYPE_U8: return Immediate(left.data.u8[index]);
+ case TYPE_S16: return Immediate(left.data.s16[index]);
+ case TYPE_U16: return Immediate(left.data.u16[index]);
+ case TYPE_S32: return Immediate(left.data.s32[index]);
+ case TYPE_U32: return Immediate(left.data.u32[index]);
+ case TYPE_S64: return Immediate(left.data.s64[index]);
+ case TYPE_U64: return Immediate(left.data.u64[index]);
+ case TYPE_FLOAT: return Immediate(left.data.f32[index]);
+ case TYPE_DOUBLE: return Immediate(left.data.f64[index]);
+ }
+ } else
+ return *left.data.immVec[index];
+ }
Immediate::Immediate(ImmOpCode op, const Immediate &left, const Immediate &right, Type dstType) {
switch (op) {
@@ -180,7 +204,7 @@ using namespace ir;
case IMM_LSHR:
{
if (left.getElemNum() == 1)
- lshr(left, right);
+ *this = lshr(left, right);
else {
GBE_ASSERT(right.getIntegerValue() <= (left.getElemNum() * left.getTypeSize() * 8));
GBE_ASSERT(right.getIntegerValue() % (left.getTypeSize() * 8) == 0);
@@ -216,16 +240,17 @@ using namespace ir;
case IMM_OLT: *this = less(left, right); break;
case IMM_OGT: *this = left > right; break;
case IMM_ORD: *this = (left == left) && (right == right); break;
+ case IMM_EXTRACT: *this = extract(left, right, dstType); break;
}
// If the dst type is large int, we will not change the imm type to large int.
GBE_ASSERT(type == (ImmType)dstType || dstType == TYPE_LARGE_INT || dstType == TYPE_BOOL);
}
- Immediate::Immediate(const vector<const Immediate*> immVec) {
+ Immediate::Immediate(const vector<const Immediate*> immVec, Type dstType) {
if (immVec.size() == 1) {
*this = *immVec[0];
} else if (!(immVec[0]->isCompType()) && immVec[0]->elemNum == 1) {
- this->type = immVec[0]->type;
+ this->type = (ImmType)dstType;
this->elemNum = immVec.size();
if (immVec[0]->getTypeSize() * immVec.size() < 8)
this->data.p = &this->defaultData;
@@ -238,6 +263,7 @@ using namespace ir;
p += immVec[i]->getTypeSize();
}
} else {
+ GBE_ASSERT(0);
this->type = IMM_TYPE_COMP;
if (immVec.size() * sizeof(Immediate*) < 8)
this->data.p = &this->defaultData;
diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp
index 1f18a4c8..7b6ba34f 100644
--- a/backend/src/ir/immediate.hpp
+++ b/backend/src/ir/immediate.hpp
@@ -56,7 +56,11 @@ namespace ir {
IMM_FPTOUI,
IMM_FPTOSI,
IMM_SITOFP,
- IMM_UITOFP
+ IMM_UITOFP,
+ IMM_EXTRACT,
+ IMM_SEXT,
+ IMM_ZEXT,
+ IMM_FPEXT
} ImmOpCode;
typedef enum {
@@ -158,7 +162,7 @@ namespace ir {
DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE, elemNum)
#undef DECL_CONSTRUCTOR
- Immediate(const vector<const Immediate*> immVec);
+ Immediate(const vector<const Immediate*> immVec, Type dstType);
INLINE int64_t getIntegerValue(void) const {
switch (type) {
@@ -176,6 +180,22 @@ namespace ir {
}
}
+ INLINE uint64_t getUnsignedIntegerValue(void) const {
+ switch (type) {
+ default:
+ GBE_ASSERT(0 && "Invalid immediate type.\n");
+ case TYPE_BOOL: return *data.b;
+ case TYPE_S8: return *data.s8;
+ case TYPE_U8: return *data.u8;
+ case TYPE_S16: return *data.s16;
+ case TYPE_U16: return *data.u16;
+ case TYPE_S32: return *data.s32;
+ case TYPE_U32: return *data.u32;
+ case TYPE_S64: return *data.s64;
+ case TYPE_U64: return *data.u64;
+ }
+ }
+
INLINE float getFloatValue(void) const {
GBE_ASSERT(type == IMM_TYPE_FLOAT);
return *data.f32;
@@ -208,13 +228,54 @@ namespace ir {
copy(other, 0, 1);
break;
case IMM_BITCAST:
- *this = other;
- type = (ImmType)dstType;
+ if (other.type != IMM_TYPE_COMP) {
+ *this = other;
+ type = (ImmType)dstType;
+ } else {
+ vector<const Immediate*> immVec;
+ for(uint32_t i = 0; i < other.getElemNum(); i++)
+ immVec.push_back(other.data.immVec[i]);
+ *this = Immediate(immVec, dstType);
+ }
break;
case IMM_FPTOUI: *this = Immediate((uint32_t)*other.data.f32); break;
case IMM_FPTOSI: *this = Immediate((int32_t)*other.data.f32); break;
case IMM_UITOFP: *this = Immediate((float)*other.data.u32); break;
case IMM_SITOFP: *this = Immediate((float)*other.data.s32); break;
+ case IMM_SEXT:
+ {
+ int64_t value = other.getIntegerValue();
+ if (other.getType() == TYPE_BOOL)
+ value = -value;
+ switch (dstType) {
+ default:
+ GBE_ASSERT(0 && "Illegal sext constant expression");
+ case TYPE_S8: *this = Immediate((int8_t)value); break;
+ case TYPE_S16: *this = Immediate((int16_t)value); break;
+ case TYPE_S32: *this = Immediate((int32_t)value); break;
+ case TYPE_S64: *this = Immediate((int64_t)value); break;
+ }
+ }
+ case IMM_ZEXT:
+ {
+ uint64_t value = other.getUnsignedIntegerValue();
+ switch (dstType) {
+ default:
+ GBE_ASSERT(0 && "Illegal sext constant expression");
+ case TYPE_U8: *this = Immediate((uint8_t)value); break;
+ case TYPE_U16: *this = Immediate((uint16_t)value); break;
+ case TYPE_U32: *this = Immediate((uint32_t)value); break;
+ case TYPE_U64: *this = Immediate((uint64_t)value); break;
+ }
+ break;
+ }
+ case IMM_FPEXT:
+ {
+ GBE_ASSERT(other.getType() == TYPE_FLOAT && dstType == TYPE_DOUBLE);
+ double value = other.getFloatValue();
+ *this = Immediate(value);
+ break;
+ }
}
}
@@ -265,6 +326,7 @@ namespace ir {
Immediate operator>> (const Immediate &) const;
static Immediate lshr (const Immediate &left, const Immediate &right);
static Immediate less (const Immediate &left, const Immediate &right);
+ static Immediate extract (const Immediate &left, const Immediate &right, Type dstType);
void copy(const Immediate &other, int32_t offset, uint32_t num);
GBE_CLASS(Immediate);
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index bbe18f49..1ea1f339 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -902,7 +902,7 @@ namespace gbe
vector<ir::ImmediateIndex> immVector;
for (uint32_t i = 0; i < cv->getNumOperands(); i++)
immVector.push_back(processConstantImmIndex(cv->getOperand(i)));
- return ctx.newImmediate(immVector);
+ return ctx.newImmediate(immVector, getType(ctx, cv->getType()->getElementType()));
}
}
@@ -1045,11 +1045,25 @@ namespace gbe
if (dyn_cast<ConstantExpr>(CPV)) {
ConstantExpr *ce = dyn_cast<ConstantExpr>(CPV);
+
+ if (!isScalarType(ce->getType())) {
+ VectorType *vecType = cast<VectorType>(ce->getType());
+ GBE_ASSERT(ce->getOpcode() == Instruction::BitCast);
+ GBE_ASSERT(isScalarType(vecType->getElementType()));
+ ir::Type elemType = getType(ctx, vecType->getElementType());
+
+ const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
+ const ir::Immediate imm = ctx.getImmediate(immIndex);
+ GBE_ASSERT(vecType->getNumElements() == imm.getElemNum() &&
+ getTypeByteSize(unit, vecType->getElementType()) == imm.getTypeSize());
+ return ctx.processImm(ir::IMM_BITCAST, immIndex, elemType);
+ }
ir::Type type = getType(ctx, ce->getType());
switch (ce->getOpcode()) {
default:
ce->dump();
GBE_ASSERT(0 && "unsupported ce opcode.\n");
+ case Instruction::FPTrunc:
case Instruction::Trunc:
{
const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
@@ -1066,6 +1080,9 @@ namespace gbe
case Instruction::FPToSI:
case Instruction::SIToFP:
case Instruction::UIToFP:
+ case Instruction::SExt:
+ case Instruction::ZExt:
+ case Instruction::FPExt:
{
const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
switch (ce->getOpcode()) {
@@ -1075,15 +1092,26 @@ namespace gbe
case Instruction::FPToSI: return ctx.processImm(ir::IMM_FPTOSI, immIndex, type);
case Instruction::SIToFP: return ctx.processImm(ir::IMM_SITOFP, immIndex, type);
case Instruction::UIToFP: return ctx.processImm(ir::IMM_UITOFP, immIndex, type);
+ case Instruction::SExt: return ctx.processImm(ir::IMM_SEXT, immIndex, type);
+ case Instruction::ZExt: return ctx.processImm(ir::IMM_ZEXT, immIndex, type);
+ case Instruction::FPExt: return ctx.processImm(ir::IMM_FPEXT, immIndex, type);
}
}
+
+ case Instruction::ExtractElement:
case Instruction::FCmp:
case Instruction::ICmp:
+ case Instruction::FAdd:
case Instruction::Add:
case Instruction::Sub:
+ case Instruction::FSub:
case Instruction::Mul:
+ case Instruction::FMul:
case Instruction::SDiv:
+ case Instruction::UDiv:
+ case Instruction::FDiv:
case Instruction::SRem:
+ case Instruction::FRem:
case Instruction::Shl:
case Instruction::AShr:
case Instruction::LShr:
@@ -1096,15 +1124,23 @@ namespace gbe
default:
//ce->dump();
GBE_ASSERTM(0, "Unsupported constant expression.\n");
+
+ case Instruction::ExtractElement:
+ return ctx.processImm(ir::IMM_EXTRACT, lhs, rhs, type);
case Instruction::Add:
+ case Instruction::FAdd:
return ctx.processImm(ir::IMM_ADD, lhs, rhs, type);
+ case Instruction::FSub:
case Instruction::Sub:
return ctx.processImm(ir::IMM_SUB, lhs, rhs, type);
case Instruction::Mul:
+ case Instruction::FMul:
return ctx.processImm(ir::IMM_MUL, lhs, rhs, type);
case Instruction::SDiv:
+ case Instruction::FDiv:
return ctx.processImm(ir::IMM_DIV, lhs, rhs, type);
case Instruction::SRem:
+ case Instruction::FRem:
return ctx.processImm(ir::IMM_REM, lhs, rhs, type);
case Instruction::Shl:
return ctx.processImm(ir::IMM_SHL, lhs, rhs, type);