const Type* Getelementptr::getSelectedType() const { const Type* selected = a()->type(); for(auto read = reads.begin() + 2; read != reads.end(); ++read) { assert(selected->isAggregate()); auto aggregate = static_cast<const AggregateType*>(selected); if((*read)->isImmediate()) { auto immediate = static_cast<const ImmediateOperand*>(*read); selected = aggregate->getTypeAtIndex(immediate->uint); continue; } assert((*read)->isRegister()); selected = aggregate->getTypeAtIndex(0); } return selected; }
llvm::Value* CreateExpr::build(FuncBuilder& builder) { auto llvmTypePtr = ctor->getLlvmType(builder.modBuilder); auto llvmType = llvmTypePtr->getTypeAtIndex(0u); auto BB = builder.ir.GetInsertBlock(); auto sizeOf = llvm::ConstantExpr::getSizeOf(llvmType); auto alloc = llvm::CallInst::CreateMalloc( BB, sizeOf->getType(), llvmType, sizeOf); BB->getInstList().push_back(alloc); for(auto i = 0u; i < parameters.size(); ++i) { auto slot = builder.ir.CreateStructGEP(alloc, i + 2); auto value = parameters[i]->build(builder); builder.ir.CreateStore(value, slot); } auto rcSlot = builder.ir.CreateStructGEP(alloc, 0); builder.ir.CreateStore(builder.ir.getInt32(1), rcSlot); auto tagSlot = builder.ir.CreateStructGEP(alloc, 1); builder.ir.CreateStore(builder.ir.getInt32(ctor->tag), tagSlot); return builder.ir.CreateBitCast(alloc, type->llvmType(builder.modBuilder)); }
/** * @brief Generates access to aggregate type as a part of conversion of LLVM * instruction insertvalue or extractvalue. * * @param[in] type Type of aggregate type. * @param[in] base Base expression. * @param[in] indices Array of indices. */ ShPtr<Expression> LLVMInstructionConverter::generateAccessToAggregateType( llvm::CompositeType *type, const ShPtr<Expression> &base, const llvm::ArrayRef<unsigned> &indices) { auto typeIt = type; auto access = base; for (const auto &index: indices) { auto indexBir = ConstInt::create(index, COMPOSITE_TYPE_INDEX_SIZE_BITS); if (typeIt->isStructTy()) { access = StructIndexOpExpr::create(access, indexBir); } else if (typeIt->isArrayTy()) { access = ArrayIndexOpExpr::create(access, indexBir); } typeIt = llvm::dyn_cast<llvm::CompositeType>(typeIt->getTypeAtIndex(index)); } return access; }