diff options
author | Zhigang Gong <zhigang.gong@intel.com> | 2014-10-21 16:04:28 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-10-23 09:43:28 +0800 |
commit | 5bf1dc503e51344ae149fb08df0602b4d2b8c2a7 (patch) | |
tree | 43837197ce48ccc8a71f7abaf1e13b5de66b2528 | |
parent | 0d6405ab35734f8aafa213b791b87dbde43af7e3 (diff) |
GBE: add Selection instruction handler at legalize pass.
Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
Tested-by: "Meng, Mengmeng" <mengmeng.meng@intel.com>
-rw-r--r-- | backend/src/llvm/llvm_legalize.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/backend/src/llvm/llvm_legalize.cpp b/backend/src/llvm/llvm_legalize.cpp index 3a2cabb5..c86793b8 100644 --- a/backend/src/llvm/llvm_legalize.cpp +++ b/backend/src/llvm/llvm_legalize.cpp @@ -60,6 +60,7 @@ namespace gbe { if (!isKernelFunction(F)) return false; return legalizeFunction(F); } + void legalizeSelect(IRBuilder<> &Builder, Instruction *p); void legalizeICmp(IRBuilder<> &Builder, Instruction *p); void legalizeShl(IRBuilder<> &Builder, Instruction *p); void legalizeLShr(IRBuilder<> &Builder, Instruction *p); @@ -107,6 +108,56 @@ namespace gbe { } } + + void Legalize::legalizeSelect(IRBuilder<> &Builder, Instruction *p) { + SelectInst *sel = dyn_cast<SelectInst>(p); + Value *op0 = sel->getOperand(0); + Value *op1 = sel->getOperand(1); + Value *op2 = sel->getOperand(2); + + ValueMapIter iter1 = valueMap.find(op1); + ValueMapIter iter2 = valueMap.find(op2); + SmallVector<Value*, 16> v; + if (iter1 != valueMap.end() && iter2 != valueMap.end()) { + SmallVectorImpl<Value*> &opVec1 = iter1->second; + SmallVectorImpl<Value*> &opVec2 = iter2->second; + + GBE_ASSERT(opVec1.size() == opVec2.size()); + + for (unsigned i = 0; i < opVec1.size(); i++) { + Value *elemV = Builder.CreateSelect(op0, opVec1[i], opVec2[i]); + v.push_back(elemV); + } + } else if (iter1 != valueMap.end()) { + SmallVectorImpl<Value*> &opVec1 = iter1->second; + Type *splitTy = opVec1[0]->getType(); + GBE_ASSERT(isa<ConstantInt>(op2)); + ConstantInt *CI = dyn_cast<ConstantInt>(op2); + SmallVector<APInt, 16> imm; + + splitLargeInteger(CI->getValue(), splitTy, imm); + for (unsigned i = 0; i < opVec1.size(); i++) { + Value *elemV = Builder.CreateSelect(op0, opVec1[i], ConstantInt::get(splitTy, imm[i])); + v.push_back(elemV); + } + } else if (iter2 != valueMap.end()) { + SmallVectorImpl<Value*> &opVec2 = iter2->second; + Type *splitTy = opVec2[0]->getType(); + GBE_ASSERT(isa<ConstantInt>(op1)); + ConstantInt *CI = dyn_cast<ConstantInt>(op1); + SmallVector<APInt, 16> imm; + + splitLargeInteger(CI->getValue(), splitTy, imm); + for (unsigned i = 0; i < opVec2.size(); i++) { + Value *elemV = Builder.CreateSelect(op0, ConstantInt::get(splitTy, imm[i]), opVec2[i]) ; + v.push_back(elemV); + } + } else { + p->dump(); GBE_ASSERT(0 && "unsupported select."); + } + valueMap.insert(std::make_pair(p, v)); + } + void Legalize::legalizeICmp(IRBuilder<> &Builder, Instruction *p) { ICmpInst *IC = dyn_cast<ICmpInst>(p); ICmpInst::Predicate pred = IC->getPredicate(); @@ -514,6 +565,9 @@ namespace gbe { Builder.SetInsertPoint(insn); switch(insn->getOpcode()) { default: { insn->dump(); GBE_ASSERT(false && "Illegal instruction\n"); break;} + case Instruction::Select: + legalizeSelect(Builder, insn); + break; case Instruction::ICmp: legalizeICmp(Builder, insn); break; |