本文整理汇总了C++中ArrayType::getNumElements方法的典型用法代码示例。如果您正苦于以下问题:C++ ArrayType::getNumElements方法的具体用法?C++ ArrayType::getNumElements怎么用?C++ ArrayType::getNumElements使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ArrayType
的用法示例。
在下文中一共展示了ArrayType::getNumElements方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: readFuncList
static void readFuncList(GlobalVariable *Array, std::vector<Constant*> *Funcs) {
if (!Array->hasInitializer())
return;
Constant *Init = Array->getInitializer();
ArrayType *Ty = dyn_cast<ArrayType>(Init->getType());
if (!Ty) {
errs() << "Initializer: " << *Array->getInitializer() << "\n";
report_fatal_error("ExpandCtors: Initializer is not of array type");
}
if (Ty->getNumElements() == 0)
return;
ConstantArray *InitList = dyn_cast<ConstantArray>(Init);
if (!InitList) {
errs() << "Initializer: " << *Array->getInitializer() << "\n";
report_fatal_error("ExpandCtors: Unexpected initializer ConstantExpr");
}
std::vector<FuncArrayEntry> FuncsToSort;
for (unsigned Index = 0; Index < InitList->getNumOperands(); ++Index) {
ConstantStruct *CS = cast<ConstantStruct>(InitList->getOperand(Index));
FuncArrayEntry Entry;
Entry.priority = cast<ConstantInt>(CS->getOperand(0))->getZExtValue();
Entry.func = CS->getOperand(1);
FuncsToSort.push_back(Entry);
}
std::sort(FuncsToSort.begin(), FuncsToSort.end(), compareEntries);
for (std::vector<FuncArrayEntry>::iterator Iter = FuncsToSort.begin();
Iter != FuncsToSort.end();
++Iter) {
Funcs->push_back(Iter->func);
}
}
示例2: SplitUpArrayLoad
static bool SplitUpArrayLoad(LoadInst *Load, const DataLayout *DL) {
ArrayType *ATy = cast<ArrayType>(Load->getType());
Value *NewStruct = UndefValue::get(ATy);
bool NeedsAnotherPass = false;
// Create a separate load instruction for each struct field.
for (unsigned Index = 0; Index < ATy->getNumElements(); ++Index) {
SmallVector<Value *, 2> Indexes;
Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, 0)));
Indexes.push_back(ConstantInt::get(Load->getContext(), APInt(32, Index)));
Value *GEP =
CopyDebug(GetElementPtrInst::Create(ATy, Load->getPointerOperand(), Indexes,
Load->getName() + ".index", Load),
Load);
LoadInst *NewLoad = new LoadInst(GEP, Load->getName() + ".field", Load);
NeedsAnotherPass = NeedsAnotherPass || DoAnotherPass(NewLoad);
ProcessArrayLoadOrStoreAttrs(NewLoad, Load, ATy, Index, DL);
// Reconstruct the struct value.
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
NewStruct =
CopyDebug(InsertValueInst::Create(NewStruct, NewLoad, EVIndexes,
Load->getName() + ".insert", Load),
Load);
}
Load->replaceAllUsesWith(NewStruct);
Load->eraseFromParent();
return NeedsAnotherPass;
}
示例3: SplitUpArrayStore
static bool SplitUpArrayStore(StoreInst *Store, const DataLayout *DL) {
ArrayType *ATy = cast<ArrayType>(Store->getValueOperand()->getType());
bool NeedsAnotherPass = false;
// Create a separate store instruction for each struct field.
for (unsigned Index = 0; Index < ATy->getNumElements(); ++Index) {
SmallVector<Value *, 2> Indexes;
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, 0)));
Indexes.push_back(ConstantInt::get(Store->getContext(), APInt(32, Index)));
Value *GEP =
CopyDebug(GetElementPtrInst::Create(ATy,
Store->getPointerOperand(), Indexes,
Store->getPointerOperand()->getName() + ".index", Store),
Store);
NeedsAnotherPass =
NeedsAnotherPass || DoAnotherPass(GEP->getType()->getContainedType(0));
SmallVector<unsigned, 1> EVIndexes;
EVIndexes.push_back(Index);
Value *Field = ExtractValueInst::Create(Store->getValueOperand(), EVIndexes,
"", Store);
StoreInst *NewStore = new StoreInst(Field, GEP, Store);
ProcessArrayLoadOrStoreAttrs(NewStore, Store, ATy, Index, DL);
}
Store->eraseFromParent();
return NeedsAnotherPass;
}
示例4: isDereferenceablePointer
/// isDereferenceablePointer - Test if this value is always a pointer to
/// allocated and suitably aligned memory for a simple load or store.
static bool isDereferenceablePointer(const Value *V,
SmallPtrSet<const Value *, 32> &Visited) {
// Note that it is not safe to speculate into a malloc'd region because
// malloc may return null.
// It's also not always safe to follow a bitcast, for example:
// bitcast i8* (alloca i8) to i32*
// would result in a 4-byte load from a 1-byte alloca. Some cases could
// be handled using DataLayout to check sizes and alignments though.
// These are obviously ok.
if (isa<AllocaInst>(V)) return true;
// Global variables which can't collapse to null are ok.
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return !GV->hasExternalWeakLinkage();
// byval arguments are ok.
if (const Argument *A = dyn_cast<Argument>(V))
return A->hasByValAttr();
// For GEPs, determine if the indexing lands within the allocated object.
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
// Conservatively require that the base pointer be fully dereferenceable.
if (!Visited.insert(GEP->getOperand(0)))
return false;
if (!isDereferenceablePointer(GEP->getOperand(0), Visited))
return false;
// Check the indices.
gep_type_iterator GTI = gep_type_begin(GEP);
for (User::const_op_iterator I = GEP->op_begin()+1,
E = GEP->op_end(); I != E; ++I) {
Value *Index = *I;
Type *Ty = *GTI++;
// Struct indices can't be out of bounds.
if (isa<StructType>(Ty))
continue;
ConstantInt *CI = dyn_cast<ConstantInt>(Index);
if (!CI)
return false;
// Zero is always ok.
if (CI->isZero())
continue;
// Check to see that it's within the bounds of an array.
ArrayType *ATy = dyn_cast<ArrayType>(Ty);
if (!ATy)
return false;
if (CI->getValue().getActiveBits() > 64)
return false;
if (CI->getZExtValue() >= ATy->getNumElements())
return false;
}
// Indices check out; this is dereferenceable.
return true;
}
// If we don't know, assume the worst.
return false;
}
示例5: getSizeInBits
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;
}
示例6: getTypeSizeInBits
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");
}
}
示例7: get
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;
}
//.........这里部分代码省略.........
示例8: tryPromoteAllocaToVector
static bool tryPromoteAllocaToVector(AllocaInst *Alloca, AMDGPUAS AS) {
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.
// FIXME: We also reject alloca's of the form [ 2 x [ 2 x i32 ]] or equivalent. Potentially these
// could also be promoted but we don't currently handle this case
if (!AllocaTy ||
AllocaTy->getNumElements() > 4 ||
AllocaTy->getNumElements() < 2 ||
!VectorType::isValidElementType(AllocaTy->getElementType())) {
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: {
Type *VecPtrTy = VectorTy->getPointerTo(AS.PRIVATE_ADDRESS);
Value *Ptr = cast<LoadInst>(Inst)->getPointerOperand();
Value *Index = calculateVectorIndex(Ptr, GEPVectorIdx);
Value *BitCast = Builder.CreateBitCast(Alloca, VecPtrTy);
Value *VecValue = Builder.CreateLoad(BitCast);
Value *ExtractElement = Builder.CreateExtractElement(VecValue, Index);
Inst->replaceAllUsesWith(ExtractElement);
Inst->eraseFromParent();
break;
}
case Instruction::Store: {
Type *VecPtrTy = VectorTy->getPointerTo(AS.PRIVATE_ADDRESS);
StoreInst *SI = cast<StoreInst>(Inst);
Value *Ptr = SI->getPointerOperand();
Value *Index = calculateVectorIndex(Ptr, GEPVectorIdx);
Value *BitCast = Builder.CreateBitCast(Alloca, VecPtrTy);
Value *VecValue = Builder.CreateLoad(BitCast);
Value *NewVecValue = Builder.CreateInsertElement(VecValue,
SI->getValueOperand(),
Index);
Builder.CreateStore(NewVecValue, BitCast);
Inst->eraseFromParent();
break;
}
case Instruction::BitCast:
case Instruction::AddrSpaceCast:
break;
default:
llvm_unreachable("Inconsistency in instructions promotable to vector");
}
}
return true;
}
示例9: isZeroLengthArray
static bool isZeroLengthArray(Type *Ty) {
ArrayType *AT = dyn_cast<ArrayType>(Ty);
return AT && (AT->getNumElements() == 0);
}
示例10: isDereferenceablePointer
/// isDereferenceablePointer - Test if this value is always a pointer to
/// allocated and suitably aligned memory for a simple load or store.
static bool isDereferenceablePointer(const Value *V, const DataLayout *DL,
SmallPtrSetImpl<const Value *> &Visited) {
// Note that it is not safe to speculate into a malloc'd region because
// malloc may return null.
// These are obviously ok.
if (isa<AllocaInst>(V)) return true;
// It's not always safe to follow a bitcast, for example:
// bitcast i8* (alloca i8) to i32*
// would result in a 4-byte load from a 1-byte alloca. However,
// if we're casting from a pointer from a type of larger size
// to a type of smaller size (or the same size), and the alignment
// is at least as large as for the resulting pointer type, then
// we can look through the bitcast.
if (DL)
if (const BitCastInst* BC = dyn_cast<BitCastInst>(V)) {
Type *STy = BC->getSrcTy()->getPointerElementType(),
*DTy = BC->getDestTy()->getPointerElementType();
if (STy->isSized() && DTy->isSized() &&
(DL->getTypeStoreSize(STy) >=
DL->getTypeStoreSize(DTy)) &&
(DL->getABITypeAlignment(STy) >=
DL->getABITypeAlignment(DTy)))
return isDereferenceablePointer(BC->getOperand(0), DL, Visited);
}
// Global variables which can't collapse to null are ok.
if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return !GV->hasExternalWeakLinkage();
// byval arguments are okay. Arguments specifically marked as
// dereferenceable are okay too.
if (const Argument *A = dyn_cast<Argument>(V)) {
if (A->hasByValAttr())
return true;
else if (uint64_t Bytes = A->getDereferenceableBytes()) {
Type *Ty = V->getType()->getPointerElementType();
if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes)
return true;
}
return false;
}
// Return values from call sites specifically marked as dereferenceable are
// also okay.
if (ImmutableCallSite CS = V) {
if (uint64_t Bytes = CS.getDereferenceableBytes(0)) {
Type *Ty = V->getType()->getPointerElementType();
if (Ty->isSized() && DL && DL->getTypeStoreSize(Ty) <= Bytes)
return true;
}
}
// For GEPs, determine if the indexing lands within the allocated object.
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
// Conservatively require that the base pointer be fully dereferenceable.
if (!Visited.insert(GEP->getOperand(0)))
return false;
if (!isDereferenceablePointer(GEP->getOperand(0), DL, Visited))
return false;
// Check the indices.
gep_type_iterator GTI = gep_type_begin(GEP);
for (User::const_op_iterator I = GEP->op_begin()+1,
E = GEP->op_end(); I != E; ++I) {
Value *Index = *I;
Type *Ty = *GTI++;
// Struct indices can't be out of bounds.
if (isa<StructType>(Ty))
continue;
ConstantInt *CI = dyn_cast<ConstantInt>(Index);
if (!CI)
return false;
// Zero is always ok.
if (CI->isZero())
continue;
// Check to see that it's within the bounds of an array.
ArrayType *ATy = dyn_cast<ArrayType>(Ty);
if (!ATy)
return false;
if (CI->getValue().getActiveBits() > 64)
return false;
if (CI->getZExtValue() >= ATy->getNumElements())
return false;
}
// Indices check out; this is dereferenceable.
return true;
}
if (const AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(V))
return isDereferenceablePointer(ASC->getOperand(0), DL, Visited);
// If we don't know, assume the worst.
return false;
}
示例11: visitAll
void visitAll( const ArrayType& a ) {
const ValueType *v = static_cast< const ValueType* >( a.getDataPointer() );
unsigned int size = a.getNumElements();
for( unsigned int i=0; i<size; i++ )
valueVisitor->apply( v[i] );
}
示例12: stringErr
/// If there were any appending global variables, link them together now.
Expected<Constant *>
IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
const GlobalVariable *SrcGV) {
Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
->getElementType();
// FIXME: This upgrade is done during linking to support the C API. Once the
// old form is deprecated, we should move this upgrade to
// llvm::UpgradeGlobalVariable() and simplify the logic here and in
// Mapper::mapAppendingVariable() in ValueMapper.cpp.
StringRef Name = SrcGV->getName();
bool IsNewStructor = false;
bool IsOldStructor = false;
if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") {
if (cast<StructType>(EltTy)->getNumElements() == 3)
IsNewStructor = true;
else
IsOldStructor = true;
}
PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo();
if (IsOldStructor) {
auto &ST = *cast<StructType>(EltTy);
Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
EltTy = StructType::get(SrcGV->getContext(), Tys, false);
}
uint64_t DstNumElements = 0;
if (DstGV) {
ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
DstNumElements = DstTy->getNumElements();
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
return stringErr(
"Linking globals named '" + SrcGV->getName() +
"': can only link appending global with another appending "
"global!");
// Check to see that they two arrays agree on type.
if (EltTy != DstTy->getElementType())
return stringErr("Appending variables with different element types!");
if (DstGV->isConstant() != SrcGV->isConstant())
return stringErr("Appending variables linked with different const'ness!");
if (DstGV->getAlignment() != SrcGV->getAlignment())
return stringErr(
"Appending variables with different alignment need to be linked!");
if (DstGV->getVisibility() != SrcGV->getVisibility())
return stringErr(
"Appending variables with different visibility need to be linked!");
if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
return stringErr(
"Appending variables with different unnamed_addr need to be linked!");
if (DstGV->getSection() != SrcGV->getSection())
return stringErr(
"Appending variables with different section name need to be linked!");
}
SmallVector<Constant *, 16> SrcElements;
getArrayElements(SrcGV->getInitializer(), SrcElements);
if (IsNewStructor) {
auto It = remove_if(SrcElements, [this](Constant *E) {
auto *Key =
dyn_cast<GlobalValue>(E->getAggregateElement(2)->stripPointerCasts());
if (!Key)
return false;
GlobalValue *DGV = getLinkedToGlobal(Key);
return !shouldLink(DGV, *Key);
});
SrcElements.erase(It, SrcElements.end());
}
uint64_t NewSize = DstNumElements + SrcElements.size();
ArrayType *NewType = ArrayType::get(EltTy, NewSize);
// Create the new global variable.
GlobalVariable *NG = new GlobalVariable(
DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(),
/*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(),
SrcGV->getType()->getAddressSpace());
NG->copyAttributesFrom(SrcGV);
forceRenaming(NG, SrcGV->getName());
Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
Mapper.scheduleMapAppendingVariable(*NG,
DstGV ? DstGV->getInitializer() : nullptr,
IsOldStructor, SrcElements);
// Replace any uses of the two global variables with uses of the new
// global.
if (DstGV) {
DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
DstGV->eraseFromParent();
}
//.........这里部分代码省略.........
示例13: linkAppendingVarProto
/// linkAppendingVarProto - If there were any appending global variables, link
/// them together now. Return true on error.
bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV,
GlobalVariable *SrcGV) {
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage())
return emitError("Linking globals named '" + SrcGV->getName() +
"': can only link appending global with another appending global!");
ArrayType *DstTy = cast<ArrayType>(DstGV->getType()->getElementType());
ArrayType *SrcTy =
cast<ArrayType>(TypeMap.get(SrcGV->getType()->getElementType()));
Type *EltTy = DstTy->getElementType();
// Check to see that they two arrays agree on type.
if (EltTy != SrcTy->getElementType())
return emitError("Appending variables with different element types!");
if (DstGV->isConstant() != SrcGV->isConstant())
return emitError("Appending variables linked with different const'ness!");
if (DstGV->getAlignment() != SrcGV->getAlignment())
return emitError(
"Appending variables with different alignment need to be linked!");
if (DstGV->getVisibility() != SrcGV->getVisibility())
return emitError(
"Appending variables with different visibility need to be linked!");
if (DstGV->getSection() != SrcGV->getSection())
return emitError(
"Appending variables with different section name need to be linked!");
uint64_t NewSize = DstTy->getNumElements() + SrcTy->getNumElements();
ArrayType *NewType = ArrayType::get(EltTy, NewSize);
// Create the new global variable.
GlobalVariable *NG =
new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(),
DstGV->getLinkage(), /*init*/0, /*name*/"", DstGV,
DstGV->isThreadLocal(),
DstGV->getType()->getAddressSpace());
// Propagate alignment, visibility and section info.
CopyGVAttributes(NG, DstGV);
AppendingVarInfo AVI;
AVI.NewGV = NG;
AVI.DstInit = DstGV->getInitializer();
AVI.SrcInit = SrcGV->getInitializer();
AppendingVars.push_back(AVI);
// Replace any uses of the two global variables with uses of the new
// global.
ValueMap[SrcGV] = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
DstGV->eraseFromParent();
// Track the source variable so we don't try to link it.
DoNotLinkFromSource.insert(SrcGV);
return false;
}
示例14: tryPromoteAllocaToVector
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;
}
示例15: runOnModule
//.........这里部分代码省略.........
II->replaceAllUsesWith(NewCall);
ToErase.push_back(II);
CallInst *Post = CallInst::Create(PostInvoke, "", II);
Instruction *Post1 = new TruncInst(Post, i1, "", II);
// Insert a branch based on the postInvoke
BranchInst::Create(II->getUnwindDest(), II->getNormalDest(), Post1, II);
} else {
// This can't throw, and we don't need this invoke, just replace it with a call+branch
SmallVector<Value*,16> CallArgs(II->op_begin(), II->op_end() - 3);
CallInst *NewCall = CallInst::Create(II->getCalledValue(),
CallArgs, "", II);
NewCall->takeName(II);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
NewCall->setDebugLoc(II->getDebugLoc());
II->replaceAllUsesWith(NewCall);
ToErase.push_back(II);
BranchInst::Create(II->getNormalDest(), II);
// Remove any PHI node entries from the exception destination.
II->getUnwindDest()->removePredecessor(BB);
}
Changed = true;
}
// scan the body of the basic block for resumes
for (BasicBlock::iterator Iter = BB->begin(), E = BB->end();
Iter != E; ) {
Instruction *I = Iter++;
if (ResumeInst *R = dyn_cast<ResumeInst>(I)) {
// split the input into legal values
Value *Input = R->getValue();
ExtractValueInst *Low = ExtractValueInst::Create(Input, 0, "", R);
ExtractValueInst *High = ExtractValueInst::Create(Input, 1, "", R);
// create a resume call
SmallVector<Value*,2> CallArgs;
CallArgs.push_back(Low);
CallArgs.push_back(High);
CallInst::Create(Resume, CallArgs, "", R);
new UnreachableInst(TheModule->getContext(), R); // add a terminator to the block
ToErase.push_back(R);
}
}
}
// Look for orphan landingpads, can occur in blocks with no predecesors
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
Instruction *I = BB->getFirstNonPHI();
if (LandingPadInst *LP = dyn_cast<LandingPadInst>(I)) {
LandingPads.insert(LP);
}
}
// Handle all the landingpad for this function together, as multiple invokes may share a single lp
for (std::set<LandingPadInst*>::iterator I = LandingPads.begin(); I != LandingPads.end(); I++) {
// Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high
LandingPadInst *LP = *I;
unsigned Num = LP->getNumClauses();
SmallVector<Value*,16> NewLPArgs;
NewLPArgs.push_back(LP->getPersonalityFn());
for (unsigned i = 0; i < Num; i++) {
Value *Arg = LP->getClause(i);
// As a temporary workaround for the lack of aggregate varargs support
// in the varargs lowering code, break out filter operands into their
// component elements.
if (LP->isFilter(i)) {
ArrayType *ATy = cast<ArrayType>(Arg->getType());
for (unsigned elem = 0, elemEnd = ATy->getNumElements(); elem != elemEnd; ++elem) {
Instruction *EE = ExtractValueInst::Create(Arg, makeArrayRef(elem), "", LP);
NewLPArgs.push_back(EE);
}
} else {
NewLPArgs.push_back(Arg);
}
}
NewLPArgs.push_back(LP->isCleanup() ? ConstantInt::getTrue(i1) : ConstantInt::getFalse(i1));
CallInst *NewLP = CallInst::Create(LandingPad, NewLPArgs, "", LP);
Instruction *High = CallInst::Create(GetHigh, "", LP);
// New recreate an aggregate for them, which will be all simplified later (simplification cannot handle landingpad, hence all this)
InsertValueInst *IVA = InsertValueInst::Create(UndefValue::get(LP->getType()), NewLP, 0, "", LP);
InsertValueInst *IVB = InsertValueInst::Create(IVA, High, 1, "", LP);
LP->replaceAllUsesWith(IVB);
ToErase.push_back(LP);
}
// erase everything we no longer need in this function
for (unsigned i = 0; i < ToErase.size(); i++) ToErase[i]->eraseFromParent();
}
return Changed;
}