Esempio n. 1
0
static void appendToGlobalArray(const char *Array, 
                                Module &M, Function *F, int Priority) {
  IRBuilder<> IRB(M.getContext());
  FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);

  // Get the current set of static global constructors and add the new ctor
  // to the list.
  SmallVector<Constant *, 16> CurrentCtors;
  StructType *EltTy;
  if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
    // If there is a global_ctors array, use the existing struct type, which can
    // have 2 or 3 fields.
    ArrayType *ATy = cast<ArrayType>(GVCtor->getType()->getElementType());
    EltTy = cast<StructType>(ATy->getElementType());
    if (Constant *Init = GVCtor->getInitializer()) {
      unsigned n = Init->getNumOperands();
      CurrentCtors.reserve(n + 1);
      for (unsigned i = 0; i != n; ++i)
        CurrentCtors.push_back(cast<Constant>(Init->getOperand(i)));
    }
    GVCtor->eraseFromParent();
  } else {
    // Use a simple two-field struct if there isn't one already.
    EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
                            nullptr);
  }

  // Build a 2 or 3 field global_ctor entry.  We don't take a comdat key.
  Constant *CSVals[3];
  CSVals[0] = IRB.getInt32(Priority);
  CSVals[1] = F;
  // FIXME: Drop support for the two element form in LLVM 4.0.
  if (EltTy->getNumElements() >= 3)
    CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
  Constant *RuntimeCtorInit =
      ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));

  CurrentCtors.push_back(RuntimeCtorInit);

  // Create a new initializer.
  ArrayType *AT = ArrayType::get(EltTy, CurrentCtors.size());
  Constant *NewInit = ConstantArray::get(AT, CurrentCtors);

  // Create the new global variable and replace all uses of
  // the old global variable with the new one.
  (void)new GlobalVariable(M, NewInit->getType(), false,
                           GlobalValue::AppendingLinkage, NewInit, Array);
}
Esempio n. 2
0
ConstantInt* Variables::getAlignmentInBits(Type *type) {
  ConstantInt *alignment = NULL;
  ArrayType *arrayType = dyn_cast<ArrayType>(type);
  switch (arrayType->getElementType()->getTypeID()) {
  case Type::FloatTyID:
    alignment = getInt64(32);
    break;
  case Type::DoubleTyID:
    alignment = getInt64(64);
    break;
  default:
    errs() << "WARNING: Unhandled type @ getAlignmentInBits\n";
    exit(1);
  }
  return alignment;
}
Esempio n. 3
0
void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) const
{
	if (_arrayType.getLocation() == ArrayType::Location::Storage)
	{
		if (_arrayType.isByteArray())
			m_context << u256(31) << eth::Instruction::ADD
				<< u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV;
		else if (_arrayType.getBaseType()->getStorageSize() <= 1)
		{
			unsigned baseBytes = _arrayType.getBaseType()->getStorageBytes();
			if (baseBytes == 0)
				m_context << eth::Instruction::POP << u256(1);
			else if (baseBytes <= 16)
			{
				unsigned itemsPerSlot = 32 / baseBytes;
				m_context
					<< u256(itemsPerSlot - 1) << eth::Instruction::ADD
					<< u256(itemsPerSlot) << eth::Instruction::SWAP1 << eth::Instruction::DIV;
			}
		}
		else
			m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
	}
	else
	{
		if (!_arrayType.isByteArray())
			m_context << _arrayType.getBaseType()->getCalldataEncodedSize() << eth::Instruction::MUL;
		else if (_pad)
			m_context << u256(31) << eth::Instruction::ADD
				<< u256(32) << eth::Instruction::DUP1
				<< eth::Instruction::SWAP2 << eth::Instruction::DIV << eth::Instruction::MUL;
	}
}
Esempio n. 4
0
Type* IndexExpression::GetType()
{
    Type *containerType =  Container->GetType();
    if (typeid(*containerType) == typeid(ArrayType))
    {
        ArrayType *arrayType = dynamic_cast<ArrayType *>(containerType);
        return arrayType->GetElementType();
    }
    else if (typeid(*containerType) == typeid(PointerType))
    {
        PointerType *pointerType = dynamic_cast<PointerType *>(containerType);
        return pointerType->GetUnderlyingType();
    }
    else
    {
        abort();
    }
}
Esempio n. 5
0
int ArrayConv::ToV8Array(JNIEnv *jniEnv, jobject jVal, int expectedType, Handle<Object> *val) {
  int result = conv->UnwrapObject(jniEnv, jVal, val);
  if(result == ErrorNotfound) {
    int componentType = getComponentType(expectedType);
    ArrayType *arr;
    result = GetRefsForComponentType(jniEnv, componentType, &arr);
    if(result == OK) {
      Handle<Object> vInst;
      result = arr->PlatformNew(jniEnv, &vInst);
      if(result == OK) {
        result = conv->BindToJavaObject(jniEnv, jVal, vInst, arr->sHiddenKey);
        if(result == OK)
          *val = vInst;
      }
    }
  }
  return result;
}
/** Rearrange an array such that ‘arr[j]’ becomes ‘i’ if ‘arr[i]’ is ‘j’ | Set 1
 *
 * @reference   https://www.geeksforgeeks.org/rearrange-array-arrj-becomes-arri-j/
 *
 * Given an array of size n where all elements are distinct and in range from 0 to n-1,
 * change contents of arr[] so that arr[i] = j is changed to arr[j] = i.
 */
auto RearrangeArraySimple(const ArrayType &elements) {
    auto output = elements;

    for (ArrayType::size_type i = 0; i < elements.size(); ++i) {
        const auto j = elements[i];
        output[j] = i;
    }

    return output;
}
 std::c14::enable_if_t<is_amv_value_or_view_class<ArrayType>::value && !has_scalar_or_string_value_type<ArrayType>::value>
 h5_read(h5::group gr, std::string name, ArrayType& a) {
  static_assert(!std::is_const<ArrayType>::value, "Cannot read in const object");
  auto gr2 = gr.open_group(name);
  // TODO checking scheme...
  // load the shape
  auto sha2 = a.shape();
  array<int, 1> sha;
  h5_read(gr2, "shape", sha);
  if (first_dim(sha) != sha2.size())
   TRIQS_RUNTIME_ERROR << " array<array<...>> load : rank mismatch. Expected " << sha2.size()<< " Got " << first_dim(sha);
  for (int u = 0; u < sha2.size(); ++u) sha2[u] = sha(u);
  if (a.shape() != sha2) a.resize(sha2);
#ifndef __cpp_generic_lambdas
  foreach(a, h5_impl::_load_lambda<ArrayType>{a, gr2});
#else
  foreach(a, [&](auto... is) { h5_read(gr2, h5_impl::_h5_name(is...), a(is...)); });
#endif
 }
Esempio n. 8
0
void delete_line(ArrayType & stencil, long line_nb)
{
   for (long ci = 0; ci < stencil.size_2(); ++ci)
   {
      stencil(line_nb, ci) = 0.0;
      if (line_nb == long(ci))
         stencil(line_nb, ci) = 1.0;
         
   }
}
Esempio n. 9
0
DataType* ExportPass::CloneDataType(DataType* t)
{
  assert(t != NULL) ;
  PointerType* pointerClone = dynamic_cast<PointerType*>(t) ;
  ReferenceType* referenceClone = dynamic_cast<ReferenceType*>(t) ;
  ArrayType* arrayClone = dynamic_cast<ArrayType*>(t) ;
  if (pointerClone != NULL)
  {
    QualifiedType* refType = 
      dynamic_cast<QualifiedType*>(pointerClone->get_reference_type()) ;
    assert(refType != NULL) ;
    DataType* cloneType = CloneDataType(refType->get_base_type()) ;
    assert(cloneType != NULL) ;

    return create_pointer_type(theEnv, 
			       IInteger(32),
			       0,
			       create_qualified_type(theEnv, cloneType)) ;
  }
  if (referenceClone != NULL)
  {
    QualifiedType* refType = 
      dynamic_cast<QualifiedType*>(referenceClone->get_reference_type()) ;
    assert(refType != NULL) ;
    DataType* clonedType = CloneDataType(refType->get_base_type()) ;
    
    return create_reference_type(theEnv,
				 IInteger(32),
				 0,
				 create_qualified_type(theEnv, clonedType)) ;
  }
  if (arrayClone != NULL)
  {
    QualifiedType* elementType = arrayClone->get_element_type() ;
    DataType* internalType = CloneDataType(elementType->get_base_type()) ;
    QualifiedType* finalQual = create_qualified_type(theEnv, internalType) ;
    return create_pointer_type(theEnv,
			       IInteger(32),
			       0, 
			       finalQual) ;    
  }
  return dynamic_cast<DataType*>(t->deep_clone()) ;
}
status_t
ArrayValueNodeChild::ResolveLocation(ValueLoader* valueLoader,
	ValueLocation*& _location)
{
	// get the parent (== array) location
	ValueLocation* parentLocation = fParent->Location();
	if (parentLocation == NULL)
		return B_BAD_VALUE;

	// create an array index path
	ArrayType* arrayType = fParent->GetArrayType();
	int32 dimensionCount = arrayType->CountDimensions();

	// add dummy indices first -- we'll replace them on our way back through
	// our ancestors
	ArrayIndexPath indexPath;
	for (int32 i = 0; i < dimensionCount; i++) {
		if (!indexPath.AddIndex(0))
			return B_NO_MEMORY;
	}

	AbstractArrayValueNodeChild* child = this;
	for (int32 i = dimensionCount - 1; i >= 0; i--) {
		indexPath.SetIndexAt(i, child->ElementIndex());

		child = dynamic_cast<AbstractArrayValueNodeChild*>(
			child->ArrayParent()->NodeChild());
	}

	// resolve the element location
	ValueLocation* location;
	status_t error = arrayType->ResolveElementLocation(indexPath,
		*parentLocation, location);
	if (error != B_OK) {
		TRACE_LOCALS("ArrayValueNodeChild::ResolveLocation(): "
			"ResolveElementLocation() failed: %s\n", strerror(error));
		return error;
	}

	_location = location;
	return B_OK;
}
Esempio n. 11
0
void Stream::WriteMembers(const uint8* object, ClassType* pType)
{
	for (uint i = 0; i < pType->m_pScope->m_orderedDecls.size(); i++)
	{
		Declarator* decl = pType->m_pScope->m_orderedDecls[i];

		if (!decl->get_IsStatic() && !decl->get_IsTypedef())
		{
			Type* pType = decl->m_pType->GetStripped();
			Type_type kind = pType->get_Kind();

			if (kind == type_array)
			{
				ArrayType* array = static_cast<ArrayType*>(pType);

				size_t count = array->get_ElemCount();

				for (size_t i = 0; i < count; ++i)
				{
					WriteMember(object + decl->m_offset + i*array->get_ElemType()->get_sizeof(), array->get_ElemType());
				}
			}
			else if (kind != type_function)
			{
				WriteMember(object + decl->m_offset, pType);
				/*
				switch (kind)
				{
				case type_int:
				case type_long:
				case type_unsigned_int:
				case type_unsigned_long:
				case type_float:

				case type_double:
				case type_long_long:
				}
				*/
			}
		}
	}
}
Esempio n. 12
0
MultiDimArrayType* OneDimArrayConverter::array_type2multi_array_type(ArrayType* at){
    suif_vector<ArrayType*> array_types;

    suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter =
            type_map->find(to<ArrayType>(at));

    if (type_iter == type_map->end()) {
        suif_vector<Expression*> lower_bounds;
        suif_vector<Expression*> upper_bounds;
        suif_vector<ArrayType*> array_types;
        Type *type = at->get_element_type()->get_base_type();

        array_types.push_back(at);                      // sub-types for this array type
        all_array_types->push_back(at);                 // all array types

        while (is_kind_of<ArrayType>(type)) {           // unwrap array access
            ArrayType *atyp = to<ArrayType>(type);
            array_types.push_back(atyp);
            type = atyp->get_element_type()->get_base_type();
        }

        // save lower and upper bounds
        for (int i = array_types.size()-1;i >=0;i--) {
            ArrayType *atyp = array_types[i];
            lower_bounds.push_back(deep_suif_clone(atyp->get_lower_bound()));
            upper_bounds.push_back(deep_suif_clone(atyp->get_upper_bound()));
        }

        IInteger bit_size = to<DataType>(type)->get_bit_size();
        IInteger bit_alignment = to<DataType>(type)->get_bit_alignment();

        MultiDimArrayType* multi_type = tb->get_multi_dim_array_type(
                bit_size, bit_alignment.c_int(), 
                tb->get_qualified_type(type),
                lower_bounds, upper_bounds);

        // save the translation in the map
        type_map->enter_value(at, multi_type);
        return multi_type;
    }else
        return (*type_iter).second;
}
std::pair<int, int> FindSubarrayWithGivenSum(const ArrayType &integers,
        const ArrayType::value_type SUM) {
    assert(not integers.empty());

    auto start = integers.cbegin();
    auto current_sum = *start;
    for (auto i = start + 1; i != integers.cend(); ++i) {
        while (current_sum > SUM and start < i - 1) {
            current_sum -= *start++;
        }

        if (current_sum == SUM) {
            return std::make_pair(start - integers.cbegin(), i - integers.cbegin() - 1);
        }

        current_sum += *i;
    }

    return NOT_FOUND;
}
Esempio n. 14
0
ConstantInt* Variables::getSizeInBits(Type *type) {
  ConstantInt *size = NULL;
  ArrayType *arrayType = dyn_cast<ArrayType>(type);
  switch (arrayType->getElementType()->getTypeID()) {
  case Type::FloatTyID: {
    int isize = arrayType->getNumElements() * 32;
    size = getInt64(isize);
    break;
  }
  case Type::DoubleTyID: {
    int isize = arrayType->getNumElements() * 64;
    size = getInt64(isize);
    break;
  }
  default:
    errs() << "WARNING: Unhandled type @ getSizeInBits\n";
    exit(1);
  }
  return size;
}
Esempio n. 15
0
void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const
{
	if (!_arrayType.isDynamicallySized())
		m_context << _arrayType.getLength();
	else
	{
		m_context << eth::Instruction::DUP1;
		switch (_arrayType.getLocation())
		{
		case ArrayType::Location::CallData:
			// length is stored on the stack
			break;
		case ArrayType::Location::Memory:
			m_context << eth::Instruction::MLOAD;
			break;
		case ArrayType::Location::Storage:
			m_context << eth::Instruction::SLOAD;
			break;
		}
	}
}
auto RearrangeArrayInPlace(ArrayType elements) {
    for (ArrayType::size_type i = 0; i < elements.size(); ++i) {
        elements[elements[i] % elements.size()] += i * elements.size();
    }

    std::transform(elements.cbegin(), elements.cend(),
    elements.begin(), [&elements](const ArrayType::value_type v) {
        return v / elements.size();
    });

    return elements;
}
Esempio n. 17
0
void generateRepresentation(ConvertOrientations* filter, typename DataArray<T>::Pointer inputOrientations,
                            typename DataArray<T>::Pointer outputOrientations)
{
  typedef typename DataArray<T>::Pointer ArrayType;
  typedef OrientationConverter<T> OCType;
  QVector<typename OCType::Pointer> converters(7);

  converters[0] = EulerConverter<T>::New();
  converters[1] = OrientationMatrixConverter<T>::New();
  converters[2] = QuaternionConverter<T>::New();
  converters[3] = AxisAngleConverter<T>::New();
  converters[4] = RodriguesConverter<T>::New();
  converters[5] = HomochoricConverter<T>::New();
  converters[6] = CubochoricConverter<T>::New();

  QVector<typename OCType::OrientationType> ocTypes = OCType::GetOrientationTypes();

  converters[filter->getInputType()]->setInputData(inputOrientations);
  converters[filter->getInputType()]->convertRepresentationTo(ocTypes[filter->getOutputType()]);

  ArrayType output = converters[filter->getInputType()]->getOutputData();
  if(NULL == output.get())
  {
    QString ss = QObject::tr("There was an error converting the input data using convertor %1").arg(converters[filter->getInputType()]->getNameOfClass());
    filter->setErrorCondition(-1004);
    filter->notifyErrorMessage(filter->getHumanLabel(), ss, filter->getErrorCondition());
    return;
  }

  if(!output->copyIntoArray(outputOrientations) )
  {
    QString ss = QObject::tr("There was an error copying the final results into the output array.");
    filter->setErrorCondition(-1003);
    filter->notifyErrorMessage(filter->getHumanLabel(), ss, filter->getErrorCondition());
  }

}
Esempio n. 18
0
uint64_t TargetData::getTypeSizeInBits(Type *Ty) const {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getTypeID()) {
  case Type::LabelTyID:
  case Type::PointerTyID:
    return getPointerSizeInBits();
  case Type::ArrayTyID: {
    ArrayType *ATy = cast<ArrayType>(Ty);
    return getTypeAllocSizeInBits(ATy->getElementType())*ATy->getNumElements();
  }
  case Type::StructTyID:
    // Get the layout annotation... which is lazily created on demand.
    return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
  case Type::IntegerTyID:
    return cast<IntegerType>(Ty)->getBitWidth();
  case Type::VoidTyID:
    return 8;
  case Type::HalfTyID:
    return 16;
  case Type::FloatTyID:
    return 32;
  case Type::DoubleTyID:
  case Type::X86_MMXTyID:
    return 64;
  case Type::PPC_FP128TyID:
  case Type::FP128TyID:
    return 128;
  // In memory objects this is always aligned to a higher boundary, but
  // only 80 bits contain information.
  case Type::X86_FP80TyID:
    return 80;
  case Type::VectorTyID:
    return cast<VectorType>(Ty)->getBitWidth();
  default:
    llvm_unreachable("TargetData::getTypeSizeInBits(): Unsupported type");
  }
}
Esempio n. 19
0
bool DevirtModule::tryFindVirtualCallTargets(
    std::vector<VirtualCallTarget> &TargetsForSlot,
    const std::set<BitSetInfo> &BitSetInfos, uint64_t ByteOffset) {
  for (const BitSetInfo &BS : BitSetInfos) {
    if (!BS.Bits->GV->isConstant())
      return false;

    auto Init = dyn_cast<ConstantArray>(BS.Bits->GV->getInitializer());
    if (!Init)
      return false;
    ArrayType *VTableTy = Init->getType();

    uint64_t ElemSize =
        M.getDataLayout().getTypeAllocSize(VTableTy->getElementType());
    uint64_t GlobalSlotOffset = BS.Offset + ByteOffset;
    if (GlobalSlotOffset % ElemSize != 0)
      return false;

    unsigned Op = GlobalSlotOffset / ElemSize;
    if (Op >= Init->getNumOperands())
      return false;

    auto Fn = dyn_cast<Function>(Init->getOperand(Op)->stripPointerCasts());
    if (!Fn)
      return false;

    // We can disregard __cxa_pure_virtual as a possible call target, as
    // calls to pure virtuals are UB.
    if (Fn->getName() == "__cxa_pure_virtual")
      continue;

    TargetsForSlot.push_back({Fn, &BS});
  }

  // Give up if we couldn't find any targets.
  return !TargetsForSlot.empty();
}
bool ConstantArrayPropagationPass::ValidSymbol(VariableSymbol* var)
{
  assert(var != NULL) ;
  // The variable should be an array type and have the const qualifier.
  if (dynamic_cast<ArrayType*>(var->get_type()->get_base_type()) == NULL)
  {
    return false ;
  }
  QualifiedType* qualType = var->get_type() ;
  while (dynamic_cast<ArrayType*>(qualType->get_base_type()) != NULL)
  {
    ArrayType* array = dynamic_cast<ArrayType*>(qualType->get_base_type()) ;
    qualType = array->get_element_type() ;
  }
  assert(qualType != NULL) ;
  for (int i = 0 ; i < qualType->get_qualification_count(); ++i)
  {
    if (qualType->get_qualification(i) == LString("const"))
    {
      return true ;
    }
  }
  return false ;
}
Esempio n. 21
0
ArrayStoreAll::ArrayStoreAll(const ArrayType& type, const Expr& expr)
    : d_type(), d_expr() {
  // this check is stronger than the assertion check in the expr manager that
  // ArrayTypes are actually array types
  // because this check is done in production builds too
  PrettyCheckArgument(
      type.isArray(), type,
      "array store-all constants can only be created for array types, not `%s'",
      type.toString().c_str());

  PrettyCheckArgument(
      expr.getType().isComparableTo(type.getConstituentType()), expr,
      "expr type `%s' does not match constituent type of array type `%s'",
      expr.getType().toString().c_str(), type.toString().c_str());

  PrettyCheckArgument(expr.isConst(), expr,
                      "ArrayStoreAll requires a constant expression");

  // Delay allocation until the checks above have been performed. If these fail,
  // the memory for d_type and d_expr should not leak. The alternative is catch,
  // delete and re-throw.
  d_type.reset(new ArrayType(type));
  d_expr.reset(new Expr(expr));
}
Esempio n. 22
0
bool
Type::Compare(Type *left, Type *right)
{
  if (left == right)
    return true;

  if (left->kind_ != right->kind_)
    return false;

  switch (left->kind_) {
    case Kind::Primitive:
      return left->primitive() == right->primitive();

    case Kind::Array:
    {
      ArrayType *aleft = left->toArray();
      ArrayType *aright = right->toArray();
      return aleft->equalTo(aright);
    }

    case Kind::Function:
      // :TODO:
      return false;

    case Kind::Enum:
    case Kind::Typedef:
      return false;

    case Kind::Void:
      return true;

    default:
      assert(false);
      return false;
  }
}
Esempio n. 23
0
void ArrayUtils::resizeDynamicArray(const ArrayType& _type) const
{
	solAssert(_type.getLocation() == ArrayType::Location::Storage, "");
	solAssert(_type.isDynamicallySized(), "");
	if (!_type.isByteArray() && _type.getBaseType()->getStorageBytes() < 32)
		solAssert(_type.getBaseType()->isValueType(), "Invalid storage size for non-value type.");

	unsigned stackHeightStart = m_context.getStackHeight();
	eth::AssemblyItem resizeEnd = m_context.newTag();

	// stack: ref new_length
	// fetch old length
	m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD;
	// stack: ref new_length old_length
	// store new length
	m_context << eth::Instruction::DUP2 << eth::Instruction::DUP4 << eth::Instruction::SSTORE;
	// skip if size is not reduced
	m_context << eth::Instruction::DUP2 << eth::Instruction::DUP2
		<< eth::Instruction::ISZERO << eth::Instruction::GT;
	m_context.appendConditionalJumpTo(resizeEnd);

	// size reduced, clear the end of the array
	// stack: ref new_length old_length
	convertLengthToSize(_type);
	m_context << eth::Instruction::DUP2;
	convertLengthToSize(_type);
	// stack: ref new_length old_size new_size
	// compute data positions
	m_context << eth::Instruction::DUP4;
	CompilerUtils(m_context).computeHashStatic();
	// stack: ref new_length old_size new_size data_pos
	m_context << eth::Instruction::SWAP2 << eth::Instruction::DUP3 << eth::Instruction::ADD;
	// stack: ref new_length data_pos new_size delete_end
	m_context << eth::Instruction::SWAP2 << eth::Instruction::ADD;
	// stack: ref new_length delete_end delete_start
	if (_type.isByteArray() || _type.getBaseType()->getStorageBytes() < 32)
		clearStorageLoop(IntegerType(256));
	else
		clearStorageLoop(*_type.getBaseType());

	m_context << resizeEnd;
	// cleanup
	m_context << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP;
	solAssert(m_context.getStackHeight() == stackHeightStart - 2, "");
}
QualifiedType* TransformUnrolledArraysPass::OneLessDimension(QualifiedType* original, int dimensionality)
{
  ArrayType* topLevelType = 
    dynamic_cast<ArrayType*>(original->get_base_type()) ;
  assert(topLevelType != NULL) ;

  if (dynamic_cast<ArrayType*>(topLevelType->get_element_type()->get_base_type()) != NULL)
  {
    ArrayType* nextLevel = 
      dynamic_cast<ArrayType*>(topLevelType->get_element_type()->get_base_type()) ;
    return nextLevel->get_element_type() ;
  }
  else
  {
    return topLevelType->get_element_type() ;
  }
  
}
Esempio n. 25
0
/// cmpType - compares two types,
/// defines total ordering among the types set.
/// See method declaration comments for more details.
int FunctionComparator::cmpType(Type *TyL, Type *TyR) const {

  PointerType *PTyL = dyn_cast<PointerType>(TyL);
  PointerType *PTyR = dyn_cast<PointerType>(TyR);

  if (DL) {
    if (PTyL && PTyL->getAddressSpace() == 0) TyL = DL->getIntPtrType(TyL);
    if (PTyR && PTyR->getAddressSpace() == 0) TyR = DL->getIntPtrType(TyR);
  }

  if (TyL == TyR)
    return 0;

  if (int Res = cmpNumbers(TyL->getTypeID(), TyR->getTypeID()))
    return Res;

  switch (TyL->getTypeID()) {
  default:
    llvm_unreachable("Unknown type!");
    // Fall through in Release mode.
  case Type::IntegerTyID:
  case Type::VectorTyID:
    // TyL == TyR would have returned true earlier.
    return cmpNumbers((uint64_t)TyL, (uint64_t)TyR);

  case Type::VoidTyID:
  case Type::FloatTyID:
  case Type::DoubleTyID:
  case Type::X86_FP80TyID:
  case Type::FP128TyID:
  case Type::PPC_FP128TyID:
  case Type::LabelTyID:
  case Type::MetadataTyID:
    return 0;

  case Type::PointerTyID: {
    assert(PTyL && PTyR && "Both types must be pointers here.");
    return cmpNumbers(PTyL->getAddressSpace(), PTyR->getAddressSpace());
  }

  case Type::StructTyID: {
    StructType *STyL = cast<StructType>(TyL);
    StructType *STyR = cast<StructType>(TyR);
    if (STyL->getNumElements() != STyR->getNumElements())
      return cmpNumbers(STyL->getNumElements(), STyR->getNumElements());

    if (STyL->isPacked() != STyR->isPacked())
      return cmpNumbers(STyL->isPacked(), STyR->isPacked());

    for (unsigned i = 0, e = STyL->getNumElements(); i != e; ++i) {
      if (int Res = cmpType(STyL->getElementType(i),
                            STyR->getElementType(i)))
        return Res;
    }
    return 0;
  }

  case Type::FunctionTyID: {
    FunctionType *FTyL = cast<FunctionType>(TyL);
    FunctionType *FTyR = cast<FunctionType>(TyR);
    if (FTyL->getNumParams() != FTyR->getNumParams())
      return cmpNumbers(FTyL->getNumParams(), FTyR->getNumParams());

    if (FTyL->isVarArg() != FTyR->isVarArg())
      return cmpNumbers(FTyL->isVarArg(), FTyR->isVarArg());

    if (int Res = cmpType(FTyL->getReturnType(), FTyR->getReturnType()))
      return Res;

    for (unsigned i = 0, e = FTyL->getNumParams(); i != e; ++i) {
      if (int Res = cmpType(FTyL->getParamType(i), FTyR->getParamType(i)))
        return Res;
    }
    return 0;
  }

  case Type::ArrayTyID: {
    ArrayType *ATyL = cast<ArrayType>(TyL);
    ArrayType *ATyR = cast<ArrayType>(TyR);
    if (ATyL->getNumElements() != ATyR->getNumElements())
      return cmpNumbers(ATyL->getNumElements(), ATyR->getNumElements());
    return cmpType(ATyL->getElementType(), ATyR->getElementType());
  }
  }
}
Esempio n. 26
0
array_view<typename ArrayType::value_type, ArrayType::rank-1> sum0 (ArrayType const & A) {
 array<typename ArrayType::value_type, ArrayType::rank-1> res = A(0,ellipsis());
 for (size_t u =1; u< A.shape()[0]; ++u) res += A(u,ellipsis());
 return res;
}
Esempio n. 27
0
static bool tryPromoteAllocaToVector(AllocaInst *Alloca) {
  ArrayType *AllocaTy = dyn_cast<ArrayType>(Alloca->getAllocatedType());

  DEBUG(dbgs() << "Alloca candidate for vectorization\n");

  // FIXME: There is no reason why we can't support larger arrays, we
  // are just being conservative for now.
  if (!AllocaTy ||
      AllocaTy->getElementType()->isVectorTy() ||
      AllocaTy->getNumElements() > 4) {
    DEBUG(dbgs() << "  Cannot convert type to vector\n");
    return false;
  }

  std::map<GetElementPtrInst*, Value*> GEPVectorIdx;
  std::vector<Value*> WorkList;
  for (User *AllocaUser : Alloca->users()) {
    GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(AllocaUser);
    if (!GEP) {
      if (!canVectorizeInst(cast<Instruction>(AllocaUser), Alloca))
        return false;

      WorkList.push_back(AllocaUser);
      continue;
    }

    Value *Index = GEPToVectorIndex(GEP);

    // If we can't compute a vector index from this GEP, then we can't
    // promote this alloca to vector.
    if (!Index) {
      DEBUG(dbgs() << "  Cannot compute vector index for GEP " << *GEP << '\n');
      return false;
    }

    GEPVectorIdx[GEP] = Index;
    for (User *GEPUser : AllocaUser->users()) {
      if (!canVectorizeInst(cast<Instruction>(GEPUser), AllocaUser))
        return false;

      WorkList.push_back(GEPUser);
    }
  }

  VectorType *VectorTy = arrayTypeToVecType(AllocaTy);

  DEBUG(dbgs() << "  Converting alloca to vector "
        << *AllocaTy << " -> " << *VectorTy << '\n');

  for (Value *V : WorkList) {
    Instruction *Inst = cast<Instruction>(V);
    IRBuilder<> Builder(Inst);
    switch (Inst->getOpcode()) {
    case Instruction::Load: {
      Value *Ptr = Inst->getOperand(0);
      Value *Index = calculateVectorIndex(Ptr, GEPVectorIdx);
      Value *BitCast = Builder.CreateBitCast(Alloca, VectorTy->getPointerTo(0));
      Value *VecValue = Builder.CreateLoad(BitCast);
      Value *ExtractElement = Builder.CreateExtractElement(VecValue, Index);
      Inst->replaceAllUsesWith(ExtractElement);
      Inst->eraseFromParent();
      break;
    }
    case Instruction::Store: {
      Value *Ptr = Inst->getOperand(1);
      Value *Index = calculateVectorIndex(Ptr, GEPVectorIdx);
      Value *BitCast = Builder.CreateBitCast(Alloca, VectorTy->getPointerTo(0));
      Value *VecValue = Builder.CreateLoad(BitCast);
      Value *NewVecValue = Builder.CreateInsertElement(VecValue,
                                                       Inst->getOperand(0),
                                                       Index);
      Builder.CreateStore(NewVecValue, BitCast);
      Inst->eraseFromParent();
      break;
    }
    case Instruction::BitCast:
    case Instruction::AddrSpaceCast:
      break;

    default:
      Inst->dump();
      llvm_unreachable("Inconsistency in instructions promotable to vector");
    }
  }
  return true;
}
Esempio n. 28
0
StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, const ArrayType& _arrayType):
	LValue(_compilerContext, _arrayType.memberType("length").get()),
	m_arrayType(_arrayType)
{
	solAssert(m_arrayType.isDynamicallySized(), "");
}
Esempio n. 29
0
 /**
  * @brief   Construct an ArrayComparisonFunctor for an array.
  *
  * @param   array   Array to compare values against
  * @param   strict  Flag to use strict type comparison
  */
 ArrayComparisonFunctor(const ArrayType &array, bool strict)
   : itr(array.begin()),
     end(array.end()),
     strict(strict) { }
Esempio n. 30
0
static Constant *julia_const_to_llvm(const void *ptr, jl_datatype_t *bt)
{
    // assumes `jl_isbits(bt)`.
    // `ptr` can point to a inline field, do not read the tag from it.
    // make sure to return exactly the type specified by
    // julia_type_to_llvm as this will be assumed by the callee.
    if (bt == jl_bool_type)
        return ConstantInt::get(T_int8, (*(const uint8_t*)ptr) ? 1 : 0);

    if (jl_is_vecelement_type((jl_value_t*)bt))
        bt = (jl_datatype_t*)jl_tparam0(bt);

    Type *lt = julia_struct_to_llvm((jl_value_t*)bt, NULL, NULL);

    if (type_is_ghost(lt))
        return UndefValue::get(NoopType);

    if (jl_is_primitivetype(bt)) {
        if (lt->isFloatTy()) {
            uint32_t data32 = *(const uint32_t*)ptr;
            return ConstantFP::get(jl_LLVMContext,
                    APFloat(lt->getFltSemantics(), APInt(32, data32)));
        }
        if (lt->isDoubleTy()) {
            uint64_t data64 = *(const uint64_t*)ptr;
            return ConstantFP::get(jl_LLVMContext,
                    APFloat(lt->getFltSemantics(), APInt(64, data64)));
        }
        int nb = jl_datatype_size(bt);
        APInt val(8 * nb, 0);
        void *bits = const_cast<uint64_t*>(val.getRawData());
        assert(sys::IsLittleEndianHost);
        memcpy(bits, ptr, nb);
        if (lt->isFloatingPointTy()) {
            return ConstantFP::get(jl_LLVMContext,
                    APFloat(lt->getFltSemantics(), val));
        }
        assert(cast<IntegerType>(lt)->getBitWidth() == 8u * nb);
        return ConstantInt::get(lt, val);
    }

    CompositeType *lct = cast<CompositeType>(lt);
    size_t nf = jl_datatype_nfields(bt);
    std::vector<Constant*> fields(nf);
    for (size_t i = 0; i < nf; i++) {
        size_t offs = jl_field_offset(bt, i);
        assert(!jl_field_isptr(bt, i));
        jl_value_t *ft = jl_field_type(bt, i);
        Type *lft = lct->getTypeAtIndex(i);
        const uint8_t *ov = (const uint8_t*)ptr + offs;
        Constant *val;
        if (jl_is_uniontype(ft)) {
            // compute the same type layout as julia_struct_to_llvm
            size_t fsz = jl_field_size(bt, i);
            size_t al = jl_field_align(bt, i);
            uint8_t sel = ((const uint8_t*)ptr)[offs + fsz - 1];
            jl_value_t *active_ty = jl_nth_union_component(ft, sel);
            size_t active_sz = jl_datatype_size(active_ty);
            ArrayType *aty = cast<ArrayType>(cast<StructType>(lft)->getTypeAtIndex(0u));
            assert(aty->getElementType() == IntegerType::get(jl_LLVMContext, 8 * al) &&
                   aty->getNumElements() == (fsz - 1) / al);
            std::vector<Constant*> ArrayElements(0);
            for (unsigned j = 0; j < aty->getNumElements(); j++) {
                APInt Elem(8 * al, 0);
                void *bits = const_cast<uint64_t*>(Elem.getRawData());
                if (active_sz > al) {
                    memcpy(bits, ov, al);
                    active_sz -= al;
                }
                else if (active_sz > 0) {
                    memcpy(bits, ov, active_sz);
                    active_sz = 0;
                }
                ov += al;
                ArrayElements.push_back(ConstantInt::get(aty->getElementType(), Elem));
            }
            std::vector<Constant*> Elements(0);
            Elements.push_back(ConstantArray::get(aty, ArrayElements));
            unsigned remainder = (fsz - 1) % al;
            while (remainder--) {
                uint8_t byte;
                if (active_sz > 0) {
                    byte = *ov;
                    active_sz -= 1;
                }
                else {
                    byte = 0;
                }
                ov += 1;
                APInt Elem(8, byte);
                Elements.push_back(ConstantInt::get(T_int8, Elem));
            }
            Elements.push_back(ConstantInt::get(T_int8, sel));
            val = ConstantStruct::get(cast<StructType>(lft), Elements);
        }
        else {
            val = julia_const_to_llvm(ov, (jl_datatype_t*)ft);
        }
        fields[i] = val;
    }

    if (lct->isVectorTy())
        return ConstantVector::get(fields);
    if (StructType *st = dyn_cast<StructType>(lct))
        return ConstantStruct::get(st, fields);
    ArrayType *at = cast<ArrayType>(lct);
    return ConstantArray::get(at, fields);
}