diff options
author | Zhigang Gong <zhigang.gong@linux.intel.com> | 2014-12-04 18:12:03 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-12-15 16:07:53 +0800 |
commit | 096390e01c89c3d7231dbe78b3af9d7f08f2c59d (patch) | |
tree | a0bcd29c8ec8bc8050cfa272ae022547cb5d5e89 | |
parent | 47ebe2e96c777d9fd2ba07cef0e681eaff243fa1 (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.hpp | 4 | ||||
-rw-r--r-- | backend/src/ir/immediate.cpp | 34 | ||||
-rw-r--r-- | backend/src/ir/immediate.hpp | 70 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_backend.cpp | 38 |
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); |