summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@intel.com>2014-12-02 17:42:29 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-12-15 15:04:57 +0800
commita16dbab3d7b1af20307c1fa0a061d0dd3aa9f95a (patch)
tree6c9ce77b2fdb4e2b959e0384bfd1d9fee1179207
parent3f2f6db6bfb0ac4e0ee599fa92933bf592d8f27a (diff)
GBE: eliminate duplicate GEP handling logic.
Part of GEP lowering logic in constant expression is the same as the normal GEP instruction lowering pass. This patch extract the common logic and reduce the redundant code. Signed-off-by: Zhigang Gong <zhigang.gong@intel.com> Reviewed-by: "Song, Ruiling" <ruiling.song@intel.com>
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp37
-rw-r--r--backend/src/llvm/llvm_gen_backend.hpp8
-rw-r--r--backend/src/llvm/llvm_passes.cpp66
3 files changed, 50 insertions, 61 deletions
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index c7ecc443..bbe18f49 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -1217,38 +1217,18 @@ namespace gbe
return pointer_reg;
}
else if (expr->getOpcode() == Instruction::GetElementPtr) {
- int32_t TypeIndex;
uint32_t constantOffset = 0;
Value *pointer = val;
CompositeType* CompTy = cast<CompositeType>(pointer->getType());
for(uint32_t op=1; op<expr->getNumOperands(); ++op) {
- uint32_t offset = 0;
+ int32_t TypeIndex;
ConstantInt* ConstOP = dyn_cast<ConstantInt>(expr->getOperand(op));
- GBE_ASSERT(ConstOP);
+ if (ConstOP == NULL)
+ goto error;
TypeIndex = ConstOP->getZExtValue();
GBE_ASSERT(TypeIndex >= 0);
- if (op == 1) {
- if (TypeIndex != 0) {
- Type *elementType = (cast<PointerType>(pointer->getType()))->getElementType();
- uint32_t elementSize = getTypeByteSize(unit, elementType);
- uint32_t align = getAlignmentByte(unit, elementType);
- elementSize += getPadding(elementSize, align);
- offset += elementSize * TypeIndex;
- }
- } else {
- for(int32_t ty_i=0; ty_i<TypeIndex; ty_i++)
- {
- Type* elementType = CompTy->getTypeAtIndex(ty_i);
- uint32_t align = getAlignmentByte(unit, elementType);
- offset += getPadding(offset, align);
- offset += getTypeByteSize(unit, elementType);
- }
- const uint32_t align = getAlignmentByte(unit, CompTy->getTypeAtIndex(TypeIndex));
- offset += getPadding(offset, align);
- }
-
- constantOffset += offset;
+ constantOffset += getGEPConstOffset(unit, CompTy, TypeIndex);
CompTy = dyn_cast<CompositeType>(CompTy->getTypeAtIndex(TypeIndex));
}
@@ -1264,10 +1244,11 @@ namespace gbe
ctx.ADD(ir::Type::TYPE_S32, reg, pointer_reg, offset_reg);
return reg;
}
- else {
- GBE_ASSERT(0 && "Unsupported constant expression");
- return regTranslator.getScalar(val, elemID);
- }
+
+error:
+ expr->dump();
+ GBE_ASSERT(0 && "Unsupported constant expression");
+ return regTranslator.getScalar(val, elemID);
}
ir::Register GenWriter::getConstantRegister(Constant *c, uint32_t elemID) {
diff --git a/backend/src/llvm/llvm_gen_backend.hpp b/backend/src/llvm/llvm_gen_backend.hpp
index ae0a818b..528b3c8b 100644
--- a/backend/src/llvm/llvm_gen_backend.hpp
+++ b/backend/src/llvm/llvm_gen_backend.hpp
@@ -29,6 +29,11 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/LoopPass.h"
+#if LLVM_VERSION_MINOR <= 2
+#include "llvm/Instructions.h"
+#else
+#include "llvm/IR/Instructions.h"
+#endif
#include "sys/platform.hpp"
#include "sys/map.hpp"
#include "sys/hash_map.hpp"
@@ -77,6 +82,9 @@ namespace gbe
/*! Get the type size in bytes */
uint32_t getTypeByteSize(const ir::Unit &unit, llvm::Type* Ty);
+ /*! Get GEP constant offset for the specified operand.*/
+ int32_t getGEPConstOffset(const ir::Unit &unit, llvm::CompositeType *CompTy, int32_t TypeIndex);
+
/*! whether this is a kernel function */
bool isKernelFunction(const llvm::Function &f);
diff --git a/backend/src/llvm/llvm_passes.cpp b/backend/src/llvm/llvm_passes.cpp
index cb68fe65..d315d532 100644
--- a/backend/src/llvm/llvm_passes.cpp
+++ b/backend/src/llvm/llvm_passes.cpp
@@ -220,6 +220,35 @@ namespace gbe
return size_bit/8;
}
+ int32_t getGEPConstOffset(const ir::Unit &unit, CompositeType *CompTy, int32_t TypeIndex) {
+ int32_t offset = 0;
+ SequentialType * seqType = dyn_cast<SequentialType>(CompTy);
+ if (seqType != NULL) {
+ if (TypeIndex != 0) {
+ Type *elementType = seqType->getElementType();
+ uint32_t elementSize = getTypeByteSize(unit, elementType);
+ uint32_t align = getAlignmentByte(unit, elementType);
+ elementSize += getPadding(elementSize, align);
+ offset = elementSize * TypeIndex;
+ }
+ } else {
+ int32_t step = TypeIndex > 0 ? 1 : -1;
+ GBE_ASSERT(CompTy->isStructTy());
+ for(int32_t ty_i=0; ty_i != TypeIndex; ty_i += step)
+ {
+ Type* elementType = CompTy->getTypeAtIndex(ty_i);
+ uint32_t align = getAlignmentByte(unit, elementType);
+ offset += getPadding(offset, align * step);
+ offset += getTypeByteSize(unit, elementType) * step;
+ }
+
+ //add getPaddingding for accessed type
+ const uint32_t align = getAlignmentByte(unit, CompTy->getTypeAtIndex(TypeIndex));
+ offset += getPadding(offset, align * step);
+ }
+ return offset;
+ }
+
class GenRemoveGEPPasss : public BasicBlockPass
{
@@ -268,41 +297,12 @@ namespace gbe
for(uint32_t op=1; op<GEPInst->getNumOperands(); ++op)
{
int32_t TypeIndex;
- //we have a constant struct/array acces
- if(ConstantInt* ConstOP = dyn_cast<ConstantInt>(GEPInst->getOperand(op)))
- {
- int32_t offset = 0;
+ ConstantInt* ConstOP = dyn_cast<ConstantInt>(GEPInst->getOperand(op));
+ if (ConstOP != NULL) {
TypeIndex = ConstOP->getZExtValue();
- int32_t step = TypeIndex > 0 ? 1 : -1;
- SequentialType * seqType = dyn_cast<SequentialType>(CompTy);
- if (seqType != NULL) {
- if (TypeIndex != 0) {
- Type *elementType = seqType->getElementType();
- uint32_t elementSize = getTypeByteSize(unit, elementType);
- uint32_t align = getAlignmentByte(unit, elementType);
- elementSize += getPadding(elementSize, align);
- offset += elementSize * TypeIndex;
- }
- } else {
- GBE_ASSERT(CompTy->isStructTy());
- for(int32_t ty_i=0; ty_i != TypeIndex; ty_i += step)
- {
- Type* elementType = CompTy->getTypeAtIndex(ty_i);
- uint32_t align = getAlignmentByte(unit, elementType);
- offset += getPadding(offset, align * step);
- offset += getTypeByteSize(unit, elementType) * step;
- }
-
- //add getPaddingding for accessed type
- const uint32_t align = getAlignmentByte(unit, CompTy->getTypeAtIndex(TypeIndex));
- offset += getPadding(offset, align * step);
- }
-
- constantOffset += offset;
+ constantOffset += getGEPConstOffset(unit, CompTy, TypeIndex);
}
- // none constant index (=> only array/verctor allowed)
- else
- {
+ else {
// we only have array/vectors here,
// therefore all elements have the same size
TypeIndex = 0;