Inst *ExprBuilder::buildGEP(Inst *Ptr, gep_type_iterator begin, gep_type_iterator end) { unsigned PSize = DL.getPointerSizeInBits(); for (auto i = begin; i != end; ++i) { if (StructType *ST = dyn_cast<StructType>(*i)) { const StructLayout *SL = DL.getStructLayout(ST); ConstantInt *CI = cast<ConstantInt>(i.getOperand()); uint64_t Addend = SL->getElementOffset((unsigned) CI->getZExtValue()); if (Addend != 0) { Ptr = IC.getInst(Inst::Add, PSize, {Ptr, IC.getConst(APInt(PSize, Addend))}); } } else { SequentialType *SET = cast<SequentialType>(*i); uint64_t ElementSize = DL.getTypeStoreSize(SET->getElementType()); Value *Operand = i.getOperand(); Inst *Index = get(Operand); if (PSize > Index->Width) Index = IC.getInst(Inst::SExt, PSize, {Index}); Inst *Addend = IC.getInst( Inst::Mul, PSize, {Index, IC.getConst(APInt(PSize, ElementSize))}); Ptr = IC.getInst(Inst::Add, PSize, {Ptr, Addend}); } } return Ptr; }
Value* qdp_jit_vec::get_vector_version( Value* scalar_version ) { DEBUG(dbgs() << "get_vector_version: scalar version: " << *scalar_version << "\n"); if (!isa<Instruction>(scalar_version)) { if (Constant* C = dyn_cast<Constant>(scalar_version)) { return Builder->Insert( ConstantVector::getSplat( vec_len , C ) ); } assert( 0 && "scalar version is not an instruction, and not a constant" ); return NULL; } #if 0 // We might not need this if (GetElementPtrInst* GEP = dyn_cast<GetElementPtrInst>(scalar_version)) { Instruction* GEPcl = clone_with_operands(GEP); printf("waring using built in vector size 4 here!!\n"); VectorType *VecTy = VectorType::get( GEP->getPointerOperandType() , 4 ); Value *VecPtr = Builder->CreateBitCast(GEPcl,VecTy->getPointerTo()); DEBUG(dbgs() << "it's a GEP\n"); DEBUG(dbgs() << *VecTy << "\n"); DEBUG(dbgs() << *VecPtr << "\n"); return VecPtr; } #endif if (StoreInst* SI = dyn_cast<StoreInst>(scalar_version)) { unsigned AS = SI->getPointerAddressSpace(); SequentialType* ST = cast<SequentialType>(SI->getPointerOperand()->getType()); //DEBUG(dbgs() << "store pointer operand type: " << *ST->getElementType() << "\n"); if (isa<VectorType>(ST->getElementType())) { assert( 0 && "did not expect a vector type store instruction" ); } //DEBUG(dbgs() << "store: " << *SI << "\n"); // DEBUG(dbgs() << "store value: " << *SI->getValueOperand() << "\n"); // DEBUG(dbgs() << "store pointer: " << *SI->getPointerOperand() << "\n"); Instruction* GEP = cast<Instruction>(SI->getPointerOperand()); Instruction* GEPcl = clone_with_operands( GEP ); DEBUG(dbgs() << "SI->getValueOp = " << *SI->getValueOperand() << "\n"); Value* vec_value = get_vector_version( SI->getValueOperand() ); Value *VecPtr = Builder->CreateBitCast( GEPcl , vec_value->getType()->getPointerTo(AS) ); Value* vecstore = Builder->CreateStore( vec_value , VecPtr ); DEBUG(dbgs() << "vec store created " << *vecstore << "\n"); return vecstore; } for ( std::vector<std::pair<Value*,Value*> >::iterator it = scalar_vector_pairs.begin(); it != scalar_vector_pairs.end(); ++it ) { DEBUG(dbgs() << "search: " << *it->first << "\n"); if ( it->first == scalar_version ) { DEBUG(dbgs() << "found it, it was already there!\n"); return it->second; } } Instruction* I = cast<Instruction>(scalar_version); std::vector<Value*> operands; for (Use& U : I->operands()) operands.push_back(U.get()); //I->getOperand(0); unsigned Opcode = I->getOpcode(); Value* V; switch (Opcode) { case Instruction::FMul: V = Builder->CreateFMul( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::FAdd: V = Builder->CreateFAdd( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::FSub: V = Builder->CreateFSub( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Mul: V = Builder->CreateMul( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Add: V = Builder->CreateAdd( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Sub: V = Builder->CreateSub( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::And: V = Builder->CreateAnd( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::AShr: V = Builder->CreateAShr( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::ICmp: V = Builder->CreateICmp( cast<CmpInst>(I)->getPredicate() , get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::BitCast: V = Builder->CreateBitCast( get_vector_version( operands.at(0) ) , VectorType::get( I->getType() , vec_len ) ); break; case Instruction::SExt: V = Builder->CreateSExt( get_vector_version( operands.at(0) ) , VectorType::get( I->getType() , vec_len ) ); break; case Instruction::Trunc: V = Builder->CreateTrunc( get_vector_version( operands.at(0) ) , VectorType::get( I->getType() , vec_len ) ); break; case Instruction::FRem: V = Builder->CreateFRem( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::SRem: V = Builder->CreateSRem( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Shl: V = Builder->CreateShl( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Or: V = Builder->CreateOr( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::Xor: V = Builder->CreateXor( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::SDiv: V = Builder->CreateSDiv( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; case Instruction::FDiv: V = Builder->CreateFDiv( get_vector_version( operands.at(0) ) , get_vector_version( operands.at(1) ) ); break; default: dbgs() << Instruction::getOpcodeName(Opcode) << "\n"; assert( 0 && "opcode not found!" ); V = NULL; } scalar_vector_pairs.push_back( std::make_pair( I , V ) ); return V; }