[Beignet] [PATCH 1/3] Remove useless old legalize related files.
Zhigang Gong
zhigang.gong at linux.intel.com
Thu Feb 5 21:48:11 PST 2015
Ping for review, thanks.
On Wed, Feb 04, 2015 at 12:02:09PM +0800, Zhigang Gong wrote:
> Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
> ---
> backend/src/CMakeLists.txt | 1 -
> backend/src/llvm/llvm_gen_backend.hpp | 3 -
> backend/src/llvm/llvm_legalize.cpp | 704 ----------------------------------
> 3 files changed, 708 deletions(-)
> delete mode 100644 backend/src/llvm/llvm_legalize.cpp
>
> diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
> index 861bbdd..eb36aa6 100644
> --- a/backend/src/CMakeLists.txt
> +++ b/backend/src/CMakeLists.txt
> @@ -80,7 +80,6 @@ set (GBE_SRC
> llvm/llvm_gen_backend.cpp
> llvm/llvm_passes.cpp
> llvm/llvm_scalarize.cpp
> - llvm/llvm_legalize.cpp
> llvm/llvm_intrinsic_lowering.cpp
> llvm/llvm_barrier_nodup.cpp
> llvm/llvm_printf_parser.cpp
> diff --git a/backend/src/llvm/llvm_gen_backend.hpp b/backend/src/llvm/llvm_gen_backend.hpp
> index b8ed9fa..f4eced2 100644
> --- a/backend/src/llvm/llvm_gen_backend.hpp
> +++ b/backend/src/llvm/llvm_gen_backend.hpp
> @@ -137,9 +137,6 @@ namespace gbe
> /*! Remove/add NoDuplicate function attribute for barrier functions. */
> llvm::ModulePass* createBarrierNodupPass(bool);
>
> - /*! Legalize all wide integer instructions */
> - llvm::FunctionPass* createLegalizePass();
> -
> /*! Convert the Intrinsic call to gen function */
> llvm::BasicBlockPass *createIntrinsicLoweringPass();
>
> diff --git a/backend/src/llvm/llvm_legalize.cpp b/backend/src/llvm/llvm_legalize.cpp
> deleted file mode 100644
> index 250fd11..0000000
> --- a/backend/src/llvm/llvm_legalize.cpp
> +++ /dev/null
> @@ -1,704 +0,0 @@
> -/*
> - * Copyright © 2012 Intel Corporation
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library. If not, see <http://www.gnu.org/licenses/>.
> - *
> - * Author: Ruiling, Song <ruiling.song at intel.com>
> - *
> - * Legalize unsupported integer data type i128/i256/...
> - * right now, the implementation only consider little-endian system.
> - *
> - */
> -#include "llvm/IR/Instructions.h"
> -#include "llvm/Pass.h"
> -#include "llvm/PassManager.h"
> -
> -#include "llvm/Config/llvm-config.h"
> -#include "llvm/ADT/DenseMap.h"
> -#include "llvm/ADT/PostOrderIterator.h"
> -#include "llvm/IR/Function.h"
> -#include "llvm/IR/InstrTypes.h"
> -#include "llvm/IR/Instructions.h"
> -#include "llvm/IR/IntrinsicInst.h"
> -#include "llvm/IR/Module.h"
> -#include "llvm/Pass.h"
> -#include "llvm/IR/IRBuilder.h"
> -#if LLVM_VERSION_MINOR >= 5
> -#include "llvm/IR/CFG.h"
> -#else
> -#include "llvm/Support/CFG.h"
> -#endif
> -
> -
> -#include "llvm_gen_backend.hpp"
> -
> -using namespace llvm;
> -
> -namespace gbe {
> -
> - class Legalize : public FunctionPass {
> - public:
> - Legalize() : FunctionPass(ID) {
> -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
> - initializeDominatorTreeWrapperPassPass(*PassRegistry::getPassRegistry());
> -#else
> - initializeDominatorTreePass(*PassRegistry::getPassRegistry());
> -#endif
> - }
> - bool runOnFunction(Function& F) {
> - if (!isKernelFunction(F)) return false;
> - return legalizeFunction(F);
> - }
> - Value *getComponent(Value *v, uint32_t i, Type *ty);
> - bool isIncomplete(Value *v);
> - void legalizePHI(IRBuilder <> Builder, Instruction *p);
> - void legalizeSelect(IRBuilder<> &Builder, Instruction *p);
> - void legalizeICmp(IRBuilder<> &Builder, Instruction *p);
> - void legalizeShl(IRBuilder<> &Builder, Instruction *p);
> - void legalizeLShr(IRBuilder<> &Builder, Instruction *p);
> - void legalizeAnd(IRBuilder<> &Builder, Instruction *p);
> - void legalizeOr(IRBuilder<> &Builder, Instruction *p);
> - void legalizeXor(IRBuilder<> &Builder, Instruction *p);
> - void legalizeBitCast(IRBuilder<> &Builder, Instruction *p);
> - void legalizeTrunc(IRBuilder<> &Builder, Instruction *p);
> - void legalizeZExt(IRBuilder<> &Builder, Instruction *p);
> - bool legalizeFunction(Function& F);
> - void splitLargeInteger(APInt op, Type *splitTy, SmallVector<APInt, 16> &split);
> - void splitConstantInt(ConstantInt *c, Type *splitTy, SmallVector<Value*, 16> &split);
> - static char ID;
> - private:
> - std::set<Value *> processed;
> - std::set<PHINode *> incompletePHIs;
> - std::map<Value *, SmallVector<Value*, 16>> valueMap;
> - typedef std::map<Value*, SmallVector<Value*, 16>>::iterator ValueMapIter;
> - };
> -
> - void splitAPInt(APInt &data, SmallVectorImpl<APInt> &result, int totalBits, int subBits) {
> - APInt lo = data.getLoBits(totalBits/2).trunc(totalBits/2);
> - APInt hi = data.getHiBits(totalBits/2).trunc(totalBits/2);
> -
> - if (totalBits/2 <= subBits) {
> - result.push_back(lo);
> - result.push_back(hi);
> - return;
> - }
> - splitAPInt(lo, result, totalBits/2, subBits);
> - splitAPInt(hi, result, totalBits/2, subBits);
> - }
> -
> - void Legalize::splitLargeInteger(APInt data, Type *splitTy, SmallVector<APInt, 16> &split) {
> - unsigned opSz = data.getBitWidth();
> - GBE_ASSERT(opSz > 7 && llvm::isPowerOf2_32(opSz));
> - unsigned subSz = splitTy->getPrimitiveSizeInBits();
> - splitAPInt(data, split, opSz, subSz);
> - }
> -
> - void Legalize::splitConstantInt(ConstantInt *c, Type *splitTy, SmallVector<Value*, 16> &split) {
> - SmallVector<APInt, 16> imm;
> - splitLargeInteger(c->getValue(), splitTy, imm);
> - for (unsigned i = 0; i < imm.size(); i++) {
> - split.push_back(ConstantInt::get(splitTy, imm[i]));
> - }
> - }
> -
> - bool Legalize::isIncomplete(Value *v) {
> - return valueMap.find(v) == valueMap.end() && !isa<ConstantInt>(v);
> - }
> -
> - Value *Legalize::getComponent(Value *v, uint32_t i, Type *ty) {
> - GBE_ASSERT(!isIncomplete(v));
> - if (isa<ConstantInt>(v)) {
> - GBE_ASSERT(ty);
> - ConstantInt *CI = dyn_cast<ConstantInt>(v);
> - SmallVector<APInt, 16> imm;
> - splitLargeInteger(CI->getValue(), ty, imm);
> - return ConstantInt::get(ty, imm[i]);
> - }
> - return valueMap.find(v)->second[i];
> - }
> -
> - void Legalize::legalizePHI(IRBuilder <> Builder, Instruction *p) {
> - PHINode *phi = dyn_cast<PHINode>(p);
> - bool incomplete = false, allConst = true;
> - uint32_t compNum = 0;
> - Type *splitTy = NULL;
> - for (unsigned int i = 0; i < phi->getNumIncomingValues(); ++i) {
> - Value *val = phi->getIncomingValue(i);
> - if (isIncomplete(val)) {
> - incomplete = true;
> - break;
> - }
> - if (allConst && valueMap.find(val) != valueMap.end()) {
> - allConst = false;
> - splitTy = valueMap.find(val)->second[0]->getType();
> - compNum = valueMap.find(val)->second.size();
> - }
> - }
> -
> - if (incomplete) {
> - // FIME, if a PHINode is totally incomplete which means
> - // we don't even know the base type of this instruction.
> - // Then it will be a little bit difficult to handle here.
> - // Will do it in the future.
> - incompletePHIs.insert(phi);
> - GBE_ASSERT(0 && "unsupported PHI");
> - }
> - else {
> - GBE_ASSERT(!allConst);
> - SmallVector<Value*, 16> v;
> - for (unsigned int i = 0; i < compNum; ++i) {
> - PHINode* res = Builder.CreatePHI(splitTy, phi->getNumIncomingValues());
> -
> - // Loop over pairs of operands: [Value*, BasicBlock*]
> - for (unsigned int j = 0; j < phi->getNumIncomingValues(); j++) {
> - BasicBlock* bb = phi->getIncomingBlock(j);
> - res->addIncoming(getComponent(phi->getIncomingValue(j), i, splitTy), bb);
> - }
> - v.push_back(res);
> - }
> - valueMap.insert(std::make_pair(phi, v));
> - }
> - }
> -
> - 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();
> - // I could not figure out why llvm could generate some
> - // compare instruction on large integers. so here only support equality check
> - GBE_ASSERT(IC->isEquality());
> - Value *op0 = p->getOperand(0);
> - Value *op1 = p->getOperand(1);
> -
> - if (isa<ConstantInt>(op0)) {
> - op0 = p->getOperand(1);
> - op1 = p->getOperand(0);
> - }
> -
> - if (isa<ConstantInt>(op1)) {
> - ValueMapIter iter = valueMap.find(op0);
> - SmallVectorImpl<Value*> &opVec = iter->second;
> - SmallVector<APInt, 16> imm;
> -
> - Value *res = NULL;
> - Type *splitTy = opVec[0]->getType();
> - ConstantInt *CI = dyn_cast<ConstantInt>(op1);
> -
> - splitLargeInteger(CI->getValue(), splitTy, imm);
> - for (unsigned i = 0; i < opVec.size(); i++) {
> - Value *tmp = Builder.CreateICmp(pred, opVec[i], ConstantInt::get(splitTy, imm[i]));
> - if (res != NULL) {
> - if (pred == CmpInst::ICMP_EQ)
> - tmp = Builder.CreateAnd(tmp, res);
> - else
> - tmp = Builder.CreateOr(tmp, res);
> - }
> - res = tmp;
> - }
> - p->replaceAllUsesWith(res);
> - } else {
> - ValueMapIter iter0 = valueMap.find(op0);
> - ValueMapIter iter1 = valueMap.find(op1);
> - SmallVectorImpl<Value*> &opVec0 = iter0->second;
> - SmallVectorImpl<Value*> &opVec1 = iter1->second;
> -
> - Value *res = NULL;
> - for (unsigned i = 0; i < opVec0.size(); i++) {
> - Value *tmp = Builder.CreateICmp(pred, opVec0[i], opVec1[i]);
> - if (res != NULL) {
> - if (pred == CmpInst::ICMP_EQ)
> - tmp = Builder.CreateAnd(tmp, res);
> - else
> - tmp = Builder.CreateOr(tmp, res);
> - }
> - res = tmp;
> - }
> - p->replaceAllUsesWith(res);
> - }
> - }
> -
> - void Legalize::legalizeShl(IRBuilder<> &Builder, Instruction *p) {
> - // only support known bits shift
> - GBE_ASSERT(isa<ConstantInt>(p->getOperand(1)));
> -
> - ValueMapIter iter = valueMap.find(p->getOperand(0));
> - GBE_ASSERT(iter != valueMap.end());
> - SmallVectorImpl<Value*> &v0 = iter->second;
> -
> - uint64_t shiftBits = dyn_cast<ConstantInt>(p->getOperand(1))->getZExtValue();
> - Type *splitTy = v0[0]->getType();
> -
> - unsigned elemNum = v0.size();
> - unsigned szSplit = splitTy->getPrimitiveSizeInBits();
> - unsigned shift = shiftBits / szSplit;
> - unsigned unaligned = shiftBits % szSplit;
> -
> - if (unaligned == 0) {
> - SmallVector<Value*, 16> v1;
> - // fill lower bits with zero
> - for (unsigned i = 0; i < shift; i++) {
> - v1.push_back(ConstantInt::get(splitTy, 0));
> - }
> - // do the shift
> - for (unsigned j =0; j < elemNum - shift; j++)
> - v1.push_back(v0[j]);
> -
> - valueMap.insert(std::make_pair(p, v1));
> - } else {
> - SmallVector<Value*, 16> v1;
> - // fill lower bits with zero
> - for (unsigned i = 0; i < shift; i++) {
> - v1.push_back(ConstantInt::get(splitTy, 0));
> - }
> - // first one is special, shl is enough.
> - v1.push_back(Builder.CreateShl(v0[0], unaligned));
> -
> - for (unsigned i = 0; i < elemNum - shift - 1; i++) {
> - Value *t0 = Builder.CreateLShr(v0[i], ConstantInt::get(v0[0]->getType(), szSplit-unaligned));
> - Value *t1 = Builder.CreateShl(v0[i + 1], ConstantInt::get(v0[i + 1]->getType(), unaligned));
> - Value *t2 = Builder.CreateOr(t0, t1);
> - v1.push_back(t2);
> - }
> - valueMap.insert(std::make_pair(p, v1));
> - }
> - }
> -
> - void Legalize::legalizeLShr(IRBuilder<> &Builder, Instruction *p) {
> - Value *op0 = p->getOperand(0);
> - Value *op1 = p->getOperand(1);
> - SmallVector<Value*, 16> result;
> -
> - GBE_ASSERT(isa<ConstantInt>(p->getOperand(1)));
> -
> - ValueMapIter iter = valueMap.find(op0);
> - GBE_ASSERT(iter != valueMap.end());
> - SmallVectorImpl<Value*> &opVec = iter->second;
> -
> - unsigned szTotal = op1->getType()->getPrimitiveSizeInBits();
> - unsigned elemNum = opVec.size();
> - unsigned szSplit = szTotal / elemNum;
> - int64_t shift = dyn_cast<ConstantInt>(op1)->getSExtValue();
> - GBE_ASSERT(shift > 0);
> - unsigned elemShift = shift / szSplit;
> - unsigned unalign = shift % szSplit;
> -
> - if (unalign == 0) {
> - // the shift bits is aligned with the split size
> - Constant *zero = ConstantInt::getSigned(opVec[0]->getType(), 0);
> - for (unsigned s = 0; s < elemNum - elemShift; s++)
> - result.push_back(opVec[s + elemShift]);
> -
> - for (unsigned s = 0; s < elemShift; s++)
> - result.push_back(zero);
> -
> - valueMap.insert(std::make_pair(p, result));
> - } else {
> - // not aligned case
> - for (unsigned s = elemShift; s < elemNum-1; s++) {
> - Value *t0 = Builder.CreateLShr(opVec[s], ConstantInt::get(opVec[s]->getType(), unalign));
> - Value *t1 = Builder.CreateShl(opVec[s + 1], ConstantInt::get(opVec[s + 1]->getType(), szSplit - unalign));
> - Value *t2 = Builder.CreateOr(t0, t1);
> - result.push_back(t2);
> - }
> - // last element only need lshr
> - result.push_back(Builder.CreateLShr(opVec[elemNum-1], ConstantInt::get(opVec[elemNum - 1]->getType(), unalign)));
> -
> - for (unsigned s = 0; s < elemShift; s++) {
> - result.push_back(ConstantInt::getSigned(opVec[0]->getType(), 0));
> - }
> - valueMap.insert(std::make_pair(p, result));
> - }
> - }
> -
> - void Legalize::legalizeAnd(IRBuilder<> &Builder, Instruction *p) {
> - Value *op0 = p->getOperand(0);
> - Value *op1 = p->getOperand(1);
> -
> - if ((isa<UndefValue>(op0) || isa<UndefValue>(op1))) {
> - // I meet some special case as below:
> - // %82 = zext i32 %81 to i512
> - // %mask148 = and i512 undef, -4294967296
> - // %ins149 = or i512 %mask148, %82
> - // I don't know how to split this kind of i512 instruction in a good way,
> - // to simplify the situation, I directly optimize it to zero.
> - // And in later instructions like and/or/shr... that operates on
> - // the value can be optimized.
> - p->replaceAllUsesWith(ConstantInt::get(p->getType(), 0));
> - return;
> - }
> -
> - if ((isa<ConstantInt>(op0) && dyn_cast<ConstantInt>(op0)->isZero())
> - || (isa<ConstantInt>(op1) && dyn_cast<ConstantInt>(op1)->isZero())) {
> - // zero & anyValue ==> zero
> - p->replaceAllUsesWith(ConstantInt::get(p->getType(), 0));
> - return;
> - }
> -
> - if (isa<ConstantInt>(op0)) {
> - op0 = p->getOperand(1);
> - op1 = p->getOperand(0);
> - }
> -
> - ValueMapIter iter = valueMap.find(op0);
> - SmallVector<Value*, 16> v0 = iter->second;
> - SmallVector<Value*, 16> v1;
> - SmallVector<Value*, 16> v2;
> -
> - if (isa<ConstantInt>(op1)) {
> - splitConstantInt(dyn_cast<ConstantInt>(op1), v0[0]->getType(), v1);
> - } else {
> - v1 = valueMap.find(op1)->second;
> - }
> -
> - for (unsigned i = 0; i < v0.size(); i++) {
> - ConstantInt *c0 = NULL, *c1 = NULL;
> - if (isa<ConstantInt>(v0[i])) c0 = dyn_cast<ConstantInt>(v0[i]);
> - if (isa<ConstantInt>(v1[i])) c1 = dyn_cast<ConstantInt>(v1[i]);
> -
> - if ((c0 &&c0->isZero()) || (c1 && c1->isZero())) {
> - // zero & anyvalue ==> zero
> - v2.push_back(ConstantInt::get(v0[i]->getType(), 0));
> - } else if (c0 && c0->isMinusOne()) {
> - // 1111s & anyvalue ==> anyvalue
> - v2.push_back(v1[i]);
> - } else if (c1 && c1->isMinusOne()) {
> - // 1111s & anyvalue ==> anyvalue
> - v2.push_back(v0[i]);
> - } else {
> - v2.push_back(Builder.CreateAnd(v0[i], v1[i]));
> - }
> - }
> - valueMap.insert(std::make_pair(p, v2));
> - }
> -
> - void Legalize::legalizeOr(IRBuilder<> &Builder, Instruction *p) {
> - Value *op0 = p->getOperand(0);
> - Value *op1 = p->getOperand(1);
> -
> - if (isa<ConstantInt>(op0)) {
> - op0 = p->getOperand(1);
> - op1 = p->getOperand(0);
> - }
> -
> - if (isa<ConstantInt>(op1) && dyn_cast<ConstantInt>(op1)->isZero()) {
> - ValueMapIter iter = valueMap.find(op0);
> - valueMap.insert(std::make_pair(p, iter->second));
> - return;
> - }
> -
> - ValueMapIter iter = valueMap.find(op0);
> - SmallVector<Value*, 16> v0 = iter->second;
> - SmallVector<Value*, 16> v1;
> - SmallVector<Value*, 16> v2;
> -
> - if (isa<ConstantInt>(op1)) {
> - splitConstantInt(dyn_cast<ConstantInt>(op1), v0[0]->getType(), v1);
> - } else {
> - v1 = valueMap.find(op1)->second;
> - }
> -
> - for (unsigned i = 0; i < v0.size(); i++) {
> - ConstantInt *c0 = NULL, *c1 = NULL;
> - if (isa<ConstantInt>(v0[i])) c0 = dyn_cast<ConstantInt>(v0[i]);
> - if (isa<ConstantInt>(v1[i])) c1 = dyn_cast<ConstantInt>(v1[i]);
> -
> - if ((c0 &&c0->isZero())) {
> - // zero | anyvalue ==> anyvalue
> - v2.push_back(v1[i]);
> - } else if (c1 && c1->isZero()) {
> - // zero | anyvalue ==> anyvalue
> - v2.push_back(v0[i]);
> - } else if (c0 && c0->isMinusOne()) {
> - // 1111 | anyvalue ==> 1111
> - v2.push_back(c0);
> - } else if (c1 && c1->isMinusOne()) {
> - // 1111 | anyvalue ==> 1111
> - v2.push_back(c1);
> - } else {
> - v2.push_back(Builder.CreateOr(v0[i], v1[i]));
> - }
> - }
> - valueMap.insert(std::make_pair(p, v2));
> - }
> -
> - void Legalize::legalizeXor(IRBuilder<> &Builder, Instruction *p) {
> - Value *op0 = p->getOperand(0);
> - Value *op1 = p->getOperand(1);
> -
> - if (isa<ConstantInt>(op0)) {
> - op0 = p->getOperand(1);
> - op1 = p->getOperand(0);
> - }
> -
> - ValueMapIter iter = valueMap.find(op0);
> - SmallVector<Value*, 16> v0 = iter->second;
> - SmallVector<Value*, 16> v1;
> - SmallVector<Value*, 16> v2;
> -
> - if (isa<ConstantInt>(op1)) {
> - splitConstantInt(dyn_cast<ConstantInt>(op1), v0[0]->getType(), v1);
> - } else {
> - v1 = valueMap.find(op1)->second;
> - }
> -
> - for (unsigned i = 0; i < v0.size(); i++) {
> - v2.push_back(Builder.CreateXor(v0[i], v1[i]));
> - }
> - valueMap.insert(std::make_pair(p, v2));
> - }
> -
> - void Legalize::legalizeBitCast(IRBuilder<> &Builder, Instruction *p) {
> - SmallVector<Value*, 16> split;
> - Type *dstTy = p->getType();
> - Type *srcTy = dyn_cast<CastInst>(p)->getSrcTy();
> -
> - if(srcTy->isVectorTy()) {
> - VectorType *vecTy = dyn_cast<VectorType>(srcTy);
> - Type *splitTy = vecTy->getElementType();
> - unsigned elements = srcTy->getPrimitiveSizeInBits()/splitTy->getPrimitiveSizeInBits();
> - // bitcast large integer from vector, so we do extractElement to get split integer
> - unsigned splitSz = splitTy->getPrimitiveSizeInBits();
> - Value *src = p->getOperand(0);
> - // if it is cast from <4 x float> to i128
> - // we cast <4 x float> to <4 x i32> first
> - if (!splitTy->isIntegerTy())
> - src = Builder.CreateBitCast(src, VectorType::get(IntegerType::get(p->getContext(), splitSz), elements));
> -
> - for (unsigned i = 0; i < elements; i++) {
> - Value *NV = Builder.CreateExtractElement(src,
> - ConstantInt::get(IntegerType::get(p->getContext(), 32), i));
> - split.push_back(NV);
> - }
> - valueMap.insert(std::make_pair(p, split));
> - } else if (dstTy->isVectorTy()) {
> - //bitcast from large integer to vector, so we do insertElement to build the vector
> - ValueMapIter iter = valueMap.find(p->getOperand(0));
> - SmallVectorImpl<Value*> &opVec = iter->second;
> - Type *splitTy = opVec[0]->getType();
> - GBE_ASSERT(dstTy->getPrimitiveSizeInBits() % splitTy->getPrimitiveSizeInBits() == 0);
> - GBE_ASSERT(dstTy->getPrimitiveSizeInBits() / splitTy->getPrimitiveSizeInBits() == opVec.size());
> - Value *vec = NULL;
> - Type *idxTy = IntegerType::get(p->getContext(), 32);
> - for (unsigned i = 0; i < opVec.size(); ++i) {
> - Value *tmp = vec ? vec : UndefValue::get(VectorType::get(splitTy, opVec.size()));
> - Value *idx = ConstantInt::get(idxTy, i);
> - vec = Builder.CreateInsertElement(tmp, opVec[i], idx);
> - }
> - Type *elemTy = cast<VectorType>(dstTy)->getElementType();
> - if (elemTy == opVec[0]->getType())
> - p->replaceAllUsesWith(vec);
> - else {
> - Value *newVec = Builder.CreateBitCast(vec, dstTy);
> - p->replaceAllUsesWith(newVec);
> - }
> - } else {
> - p->dump(); GBE_ASSERT(0 && "Unsupported bitcast");
> - }
> - }
> -
> - void Legalize::legalizeTrunc(IRBuilder<> &Builder, Instruction *p) {
> - Type *dstTy = p->getType();
> -
> - ValueMapIter iter = valueMap.find(p->getOperand(0));
> - SmallVector<Value*, 16> &opVec = iter->second;
> - unsigned szSplit = opVec[0]->getType()->getPrimitiveSizeInBits();
> - unsigned szResult = dstTy->getPrimitiveSizeInBits();
> -
> - if(szResult > szSplit) {
> - // the needed bits is larger than what is already split,
> - // we have to merge the split Value, use Shl/Or to do it.
> - int endIdx = (szResult + szSplit-1 )/szSplit;
> - Value * prev = ConstantInt::get(dstTy, 0);
> - for (int i = endIdx - 1; i >=0; i--) {
> - Value * res = Builder.CreateZExt(opVec[i], dstTy);
> - if (i > 0)
> - res = Builder.CreateShl(res, i*szSplit);
> - prev = Builder.CreateOr(res, prev);
> - }
> - Value *newValue = Builder.CreateTrunc(prev, dstTy);
> - p->replaceAllUsesWith(newValue);
> - } else if (szResult == szSplit) {
> - // same bit width, should use bitcast instead of trunc.
> - Value *newValue = Builder.CreateBitCast(opVec[0], dstTy);
> - p->replaceAllUsesWith(newValue);
> - } else {
> - // normal case, trunc to a shorter bit width
> - Value *newValue = Builder.CreateTrunc(opVec[0], dstTy);
> - p->replaceAllUsesWith(newValue);
> - }
> - }
> -
> - void Legalize::legalizeZExt(IRBuilder<> &Builder, Instruction *p) {
> - SmallVector<Value*, 16> split;
> - Type *dstTy = dyn_cast<CastInst>(p)->getDestTy();
> - Type *srcTy = p->getOperand(0)->getType();
> - int elements = dstTy->getPrimitiveSizeInBits() / srcTy->getPrimitiveSizeInBits();
> -
> - split.push_back(p->getOperand(0));
> - for (int i = 0; i < elements - 1; i++)
> - split.push_back(ConstantInt::getSigned(srcTy, 0));
> -
> - valueMap.insert(std::make_pair(p, split));
> - }
> -
> - bool Legalize::legalizeFunction(Function &F) {
> - bool changed = false;
> -
> - typedef ReversePostOrderTraversal<Function*> RPOTType;
> - RPOTType rpot(&F);
> -
> - for (RPOTType::rpo_iterator bb = rpot.begin(), bbE = rpot.end(); bb != bbE; ++bb) {
> - IRBuilder<> Builder(*bb);
> - for (BasicBlock::iterator it = (*bb)->begin(), itE = (*bb)->end(); it != itE; ++it) {
> - Instruction *insn = it;
> - Type *ty = insn->getType();
> - if(ty->isIntegerTy() && ty->getIntegerBitWidth() > 64) {
> - // result is large integer, push back itself and its users
> - changed = true;
> -
> - processed.insert(insn);
> -
> - for(Value::use_iterator iter = insn->use_begin(); iter != insn->use_end(); ++iter) {
> - // After LLVM 3.5, use_iterator points to 'Use' instead of 'User', which is more straightforward.
> - #if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 5)
> - User *theUser = *iter;
> - #else
> - User *theUser = iter->getUser();
> - #endif
> - processed.insert(theUser);
> - }
> - }
> -
> - if(processed.empty() || processed.find(insn) == processed.end())
> - continue;
> -
> - Builder.SetInsertPoint(insn);
> - switch(insn->getOpcode()) {
> - default: { insn->dump(); GBE_ASSERT(false && "Illegal instruction\n"); break;}
> - case Instruction::PHI:
> - legalizePHI(Builder, insn);
> - break;
> - case Instruction::Select:
> - legalizeSelect(Builder, insn);
> - break;
> - case Instruction::ICmp:
> - legalizeICmp(Builder, insn);
> - break;
> -
> - case Instruction::Shl:
> - legalizeShl(Builder, insn);
> - break;
> -
> - case Instruction::LShr:
> - legalizeLShr(Builder, insn);
> - break;
> -
> - case Instruction::And:
> - legalizeAnd(Builder, insn);
> - break;
> -
> - case Instruction::Or:
> - legalizeOr(Builder, insn);
> - break;
> -
> - case Instruction::Xor:
> - legalizeXor(Builder, insn);
> - break;
> -
> - case Instruction::BitCast:
> - legalizeBitCast(Builder, insn);
> - break;
> -
> - case Instruction::Trunc:
> - legalizeTrunc(Builder, insn);
> - break;
> -
> - case Instruction::ZExt:
> - legalizeZExt(Builder, insn);
> - break;
> - }
> - }
> - }
> -
> - for (Value *v : processed) {
> - if (isa<Instruction>(v)) {
> - dyn_cast<Instruction>(v)->dropAllReferences();
> - }
> - }
> -
> - for (Value *v : processed) {
> - if (isa<Instruction>(v)) {
> - dyn_cast<Instruction>(v)->eraseFromParent();
> - }
> - }
> -
> - processed.clear();
> - valueMap.clear();
> - incompletePHIs.clear();
> - return changed;
> - }
> -
> - FunctionPass* createLegalizePass() {
> - return new Legalize();
> - }
> - char Legalize::ID = 0;
> -};
> --
> 1.8.3.2
>
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet
More information about the Beignet
mailing list