本文整理汇总了C++中AllocaInst::getAllocatedType方法的典型用法代码示例。如果您正苦于以下问题:C++ AllocaInst::getAllocatedType方法的具体用法?C++ AllocaInst::getAllocatedType怎么用?C++ AllocaInst::getAllocatedType使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类AllocaInst
的用法示例。
在下文中一共展示了AllocaInst::getAllocatedType方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: visitAlloca
bool CallAnalyzer::visitAlloca(AllocaInst &I) {
// Check whether inlining will turn a dynamic alloca into a static
// alloca, and handle that case.
if (I.isArrayAllocation()) {
if (Constant *Size = SimplifiedValues.lookup(I.getArraySize())) {
ConstantInt *AllocSize = dyn_cast<ConstantInt>(Size);
assert(AllocSize && "Allocation size not a constant int?");
Type *Ty = I.getAllocatedType();
AllocatedSize += Ty->getPrimitiveSizeInBits() * AllocSize->getZExtValue();
return Base::visitAlloca(I);
}
}
// Accumulate the allocated size.
if (I.isStaticAlloca()) {
Type *Ty = I.getAllocatedType();
AllocatedSize += (DL ? DL->getTypeAllocSize(Ty) :
Ty->getPrimitiveSizeInBits());
}
// We will happily inline static alloca instructions.
if (I.isStaticAlloca())
return Base::visitAlloca(I);
// FIXME: This is overly conservative. Dynamic allocas are inefficient for
// a variety of reasons, and so we would like to not inline them into
// functions which don't currently have a dynamic alloca. This simply
// disables inlining altogether in the presence of a dynamic alloca.
HasDynamicAlloca = true;
return false;
}
示例2: visitAllocaInst
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitAllocaInst(AllocaInst &I) {
if (!I.getAllocatedType()->isSized())
return unknown();
// must be a VLA
assert(I.isArrayAllocation());
Value *ArraySize = I.getArraySize();
Value *Size = ConstantInt::get(ArraySize->getType(),
TD->getTypeAllocSize(I.getAllocatedType()));
Size = Builder.CreateMul(Size, ArraySize);
return std::make_pair(Size, Zero);
}
示例3: handleAllocInstruction
// -- handle unary instruction --
void UnsafeTypeCastingCheck::handleAllocInstruction (Instruction *inst) {
AllocaInst *ainst = dyn_cast<AllocaInst>(inst);
if (ainst == NULL)
utccAbort("handleAllocInstruction cannot process with a non-alloca instruction");
Type *atype = ainst->getAllocatedType();
setPointedType(ainst, llvmT2utccT(atype, ainst));
}
示例4: visitAllocaInst
void ArrayIndexChecker::visitAllocaInst(AllocaInst& I) {
DEBUG(dbgs() << "ArrayIndexChecker: visiting alloca " << I << "\n");
if (isa<StructType>(I.getAllocatedType()) || isa<ArrayType>(I.getAllocatedType())) {
return;
}
auto pos = std::find(ptr_value_vec_.begin(), ptr_value_vec_.end(), &I);
assert(pos != ptr_value_vec_.end());
index_t varIdx = pos - ptr_value_vec_.begin();
assert(idx2addr_.find(varIdx) != idx2addr_.end());
if (addr2version_[idx2addr_[varIdx]] != 0)
throw ArrayIndexIsNotConstant;
DEBUG(dbgs() << "ArrayIndexChecker: visited alloca\n");
}
示例5: translateStaticAlloca
bool IRTranslator::translateStaticAlloca(const AllocaInst &AI) {
assert(AI.isStaticAlloca() && "only handle static allocas now");
MachineFunction &MF = MIRBuilder.getMF();
unsigned ElementSize = DL->getTypeStoreSize(AI.getAllocatedType());
unsigned Size =
ElementSize * cast<ConstantInt>(AI.getArraySize())->getZExtValue();
// Always allocate at least one byte.
Size = std::max(Size, 1u);
unsigned Alignment = AI.getAlignment();
if (!Alignment)
Alignment = DL->getABITypeAlignment(AI.getAllocatedType());
unsigned Res = getOrCreateVReg(AI);
int FI = MF.getFrameInfo().CreateStackObject(Size, Alignment, false, &AI);
MIRBuilder.buildFrameIndex(LLT::pointer(0), Res, FI);
return true;
}
示例6: getOrCreateFrameIndex
int IRTranslator::getOrCreateFrameIndex(const AllocaInst &AI) {
if (FrameIndices.find(&AI) != FrameIndices.end())
return FrameIndices[&AI];
MachineFunction &MF = MIRBuilder.getMF();
unsigned ElementSize = DL->getTypeStoreSize(AI.getAllocatedType());
unsigned Size =
ElementSize * cast<ConstantInt>(AI.getArraySize())->getZExtValue();
// Always allocate at least one byte.
Size = std::max(Size, 1u);
unsigned Alignment = AI.getAlignment();
if (!Alignment)
Alignment = DL->getABITypeAlignment(AI.getAllocatedType());
int &FI = FrameIndices[&AI];
FI = MF.getFrameInfo().CreateStackObject(Size, Alignment, false, &AI);
return FI;
}
示例7: visitAllocaInst
SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
if (!I.getAllocatedType()->isSized())
return unknown();
APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
if (!I.isArrayAllocation())
return std::make_pair(align(Size, I.getAlignment()), Zero);
Value *ArraySize = I.getArraySize();
if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
APInt NumElems = C->getValue();
if (!CheckedZextOrTrunc(NumElems))
return unknown();
bool Overflow;
Size = Size.umul_ov(NumElems, Overflow);
return Overflow ? unknown() : std::make_pair(align(Size, I.getAlignment()),
Zero);
}
return unknown();
}
示例8: InsertAutomaticGCRoots
void LowerIntrinsics::InsertAutomaticGCRoots(Function &F, GCStrategy &S) {
if (!S.usesAutomaticRoots())
return;
LLVMContext &C = F.getParent()->getContext();
for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
for (BasicBlock::iterator II = BBI->begin(),
IE = BBI->end(); II != IE; ++II) {
AllocaInst *AI = dyn_cast<AllocaInst>(&*II);
if (!AI)
continue;
Value *Index = ConstantInt::get(Type::getInt32Ty(C), 0);
ArrayRef<Value *> Indices(&Index, 1);
AutomaticallyRootValue(*AI, AI->getAllocatedType(), Indices);
}
}
}
示例9: getInsertionPoint
//
// Method: visitAllocaInst()
//
// Description:
// This method instruments an alloca instruction so that it is zero'ed out
// before any data is loaded from it.
//
void
InitAllocas::visitAllocaInst (AllocaInst & AI) {
//
// Scan for a place to insert the instruction to initialize the
// allocated memory.
//
Instruction * InsertPt = getInsertionPoint (AI);
//
// Zero the alloca with a memset. If this is done more efficiently with stores
// SelectionDAG will lower it appropriately based on target information.
//
TargetData & TD = getAnalysis<TargetData>();
//
// Get various types that we'll need.
//
Type * Int1Type = IntegerType::getInt1Ty(AI.getContext());
Type * Int8Type = IntegerType::getInt8Ty(AI.getContext());
Type * Int32Type = IntegerType::getInt32Ty(AI.getContext());
Type * VoidPtrType = getVoidPtrType (AI.getContext());
Type * AllocType = AI.getAllocatedType();
//
// Create a call to memset.
//
Module * M = AI.getParent()->getParent()->getParent();
Function * Memset = cast<Function>(M->getFunction ("llvm.memset.p0i8.i32"));
std::vector<Value *> args;
args.push_back (castTo (&AI, VoidPtrType, AI.getName().str(), InsertPt));
args.push_back (ConstantInt::get(Int8Type, 0));
args.push_back (ConstantInt::get(Int32Type,TD.getTypeAllocSize(AllocType)));
args.push_back (ConstantInt::get(Int32Type,
TD.getABITypeAlignment(AllocType)));
args.push_back (ConstantInt::get(Int1Type, 0));
CallInst::Create (Memset, args, "", InsertPt);
//
// Update statistics.
//
++InitedAllocas;
return;
}
示例10: visitAlloca
bool CallAnalyzer::visitAlloca(AllocaInst &I) {
// FIXME: Check whether inlining will turn a dynamic alloca into a static
// alloca, and handle that case.
// Accumulate the allocated size.
if (I.isStaticAlloca()) {
Type *Ty = I.getAllocatedType();
AllocatedSize += (TD ? TD->getTypeAllocSize(Ty) :
Ty->getPrimitiveSizeInBits());
}
// We will happily inline static alloca instructions.
if (I.isStaticAlloca())
return Base::visitAlloca(I);
// FIXME: This is overly conservative. Dynamic allocas are inefficient for
// a variety of reasons, and so we would like to not inline them into
// functions which don't currently have a dynamic alloca. This simply
// disables inlining altogether in the presence of a dynamic alloca.
HasDynamicAlloca = true;
return false;
}
示例11: InlineCallIfPossible
/// InlineCallIfPossible - If it is possible to inline the specified call site,
/// do so and update the CallGraph for this operation.
///
/// This function also does some basic book-keeping to update the IR. The
/// InlinedArrayAllocas map keeps track of any allocas that are already
/// available from other functions inlined into the caller. If we are able to
/// inline this call site we attempt to reuse already available allocas or add
/// any new allocas to the set if not possible.
static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
InlinedArrayAllocasTy &InlinedArrayAllocas) {
Function *Callee = CS.getCalledFunction();
Function *Caller = CS.getCaller();
// Try to inline the function. Get the list of static allocas that were
// inlined.
if (!InlineFunction(CS, IFI))
return false;
// If the inlined function had a higher stack protection level than the
// calling function, then bump up the caller's stack protection level.
if (Callee->hasFnAttr(Attribute::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtectReq);
else if (Callee->hasFnAttr(Attribute::StackProtect) &&
!Caller->hasFnAttr(Attribute::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtect);
// Look at all of the allocas that we inlined through this call site. If we
// have already inlined other allocas through other calls into this function,
// then we know that they have disjoint lifetimes and that we can merge them.
//
// There are many heuristics possible for merging these allocas, and the
// different options have different tradeoffs. One thing that we *really*
// don't want to hurt is SRoA: once inlining happens, often allocas are no
// longer address taken and so they can be promoted.
//
// Our "solution" for that is to only merge allocas whose outermost type is an
// array type. These are usually not promoted because someone is using a
// variable index into them. These are also often the most important ones to
// merge.
//
// A better solution would be to have real memory lifetime markers in the IR
// and not have the inliner do any merging of allocas at all. This would
// allow the backend to do proper stack slot coloring of all allocas that
// *actually make it to the backend*, which is really what we want.
//
// Because we don't have this information, we do this simple and useful hack.
//
SmallPtrSet<AllocaInst*, 16> UsedAllocas;
// Loop over all the allocas we have so far and see if they can be merged with
// a previously inlined alloca. If not, remember that we had it.
for (unsigned AllocaNo = 0, e = IFI.StaticAllocas.size();
AllocaNo != e; ++AllocaNo) {
AllocaInst *AI = IFI.StaticAllocas[AllocaNo];
// Don't bother trying to merge array allocations (they will usually be
// canonicalized to be an allocation *of* an array), or allocations whose
// type is not itself an array (because we're afraid of pessimizing SRoA).
const ArrayType *ATy = dyn_cast<ArrayType>(AI->getAllocatedType());
if (ATy == 0 || AI->isArrayAllocation())
continue;
// Get the list of all available allocas for this array type.
std::vector<AllocaInst*> &AllocasForType = InlinedArrayAllocas[ATy];
// Loop over the allocas in AllocasForType to see if we can reuse one. Note
// that we have to be careful not to reuse the same "available" alloca for
// multiple different allocas that we just inlined, we use the 'UsedAllocas'
// set to keep track of which "available" allocas are being used by this
// function. Also, AllocasForType can be empty of course!
bool MergedAwayAlloca = false;
for (unsigned i = 0, e = AllocasForType.size(); i != e; ++i) {
AllocaInst *AvailableAlloca = AllocasForType[i];
// The available alloca has to be in the right function, not in some other
// function in this SCC.
if (AvailableAlloca->getParent() != AI->getParent())
continue;
// If the inlined function already uses this alloca then we can't reuse
// it.
if (!UsedAllocas.insert(AvailableAlloca))
continue;
// Otherwise, we *can* reuse it, RAUW AI into AvailableAlloca and declare
// success!
DEBUG(dbgs() << " ***MERGED ALLOCA: " << *AI);
AI->replaceAllUsesWith(AvailableAlloca);
AI->eraseFromParent();
MergedAwayAlloca = true;
++NumMergedAllocas;
break;
}
// If we already nuked the alloca, we're done with it.
if (MergedAwayAlloca)
continue;
//.........这里部分代码省略.........
示例12: handleAlloca
void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) {
// Array allocations are probably not worth handling, since an allocation of
// the array type is the canonical form.
if (!I.isStaticAlloca() || I.isArrayAllocation())
return;
IRBuilder<> Builder(&I);
// First try to replace the alloca with a vector
Type *AllocaTy = I.getAllocatedType();
DEBUG(dbgs() << "Trying to promote " << I << '\n');
if (tryPromoteAllocaToVector(&I))
return;
DEBUG(dbgs() << " alloca is not a candidate for vectorization.\n");
const Function &ContainingFunction = *I.getParent()->getParent();
// FIXME: We should also try to get this value from the reqd_work_group_size
// function attribute if it is available.
unsigned WorkGroupSize = AMDGPU::getMaximumWorkGroupSize(ContainingFunction);
int AllocaSize =
WorkGroupSize * Mod->getDataLayout().getTypeAllocSize(AllocaTy);
if (AllocaSize > LocalMemAvailable) {
DEBUG(dbgs() << " Not enough local memory to promote alloca.\n");
return;
}
std::vector<Value*> WorkList;
if (!collectUsesWithPtrTypes(&I, WorkList)) {
DEBUG(dbgs() << " Do not know how to convert all uses\n");
return;
}
DEBUG(dbgs() << "Promoting alloca to local memory\n");
LocalMemAvailable -= AllocaSize;
Function *F = I.getParent()->getParent();
Type *GVTy = ArrayType::get(I.getAllocatedType(), WorkGroupSize);
GlobalVariable *GV = new GlobalVariable(
*Mod, GVTy, false, GlobalValue::InternalLinkage,
UndefValue::get(GVTy),
Twine(F->getName()) + Twine('.') + I.getName(),
nullptr,
GlobalVariable::NotThreadLocal,
AMDGPUAS::LOCAL_ADDRESS);
GV->setUnnamedAddr(true);
GV->setAlignment(I.getAlignment());
Value *TCntY, *TCntZ;
std::tie(TCntY, TCntZ) = getLocalSizeYZ(Builder);
Value *TIdX = getWorkitemID(Builder, 0);
Value *TIdY = getWorkitemID(Builder, 1);
Value *TIdZ = getWorkitemID(Builder, 2);
Value *Tmp0 = Builder.CreateMul(TCntY, TCntZ, "", true, true);
Tmp0 = Builder.CreateMul(Tmp0, TIdX);
Value *Tmp1 = Builder.CreateMul(TIdY, TCntZ, "", true, true);
Value *TID = Builder.CreateAdd(Tmp0, Tmp1);
TID = Builder.CreateAdd(TID, TIdZ);
Value *Indices[] = {
Constant::getNullValue(Type::getInt32Ty(Mod->getContext())),
TID
};
Value *Offset = Builder.CreateInBoundsGEP(GVTy, GV, Indices);
I.mutateType(Offset->getType());
I.replaceAllUsesWith(Offset);
I.eraseFromParent();
for (Value *V : WorkList) {
CallInst *Call = dyn_cast<CallInst>(V);
if (!Call) {
Type *EltTy = V->getType()->getPointerElementType();
PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS);
// The operand's value should be corrected on its own.
if (isa<AddrSpaceCastInst>(V))
continue;
// FIXME: It doesn't really make sense to try to do this for all
// instructions.
V->mutateType(NewTy);
continue;
}
IntrinsicInst *Intr = dyn_cast<IntrinsicInst>(Call);
if (!Intr) {
// FIXME: What is this for? It doesn't make sense to promote arbitrary
// function calls. If the call is to a defined function that can also be
// promoted, we should be able to do this once that function is also
// rewritten.
//.........这里部分代码省略.........
示例13: BitCastInst
Instruction *InstCombiner::visitAllocaInst(AllocaInst &AI) {
if (auto *I = simplifyAllocaArraySize(*this, AI))
return I;
if (AI.getAllocatedType()->isSized()) {
// If the alignment is 0 (unspecified), assign it the preferred alignment.
if (AI.getAlignment() == 0)
AI.setAlignment(DL.getPrefTypeAlignment(AI.getAllocatedType()));
// Move all alloca's of zero byte objects to the entry block and merge them
// together. Note that we only do this for alloca's, because malloc should
// allocate and return a unique pointer, even for a zero byte allocation.
if (DL.getTypeAllocSize(AI.getAllocatedType()) == 0) {
// For a zero sized alloca there is no point in doing an array allocation.
// This is helpful if the array size is a complicated expression not used
// elsewhere.
if (AI.isArrayAllocation()) {
AI.setOperand(0, ConstantInt::get(AI.getArraySize()->getType(), 1));
return &AI;
}
// Get the first instruction in the entry block.
BasicBlock &EntryBlock = AI.getParent()->getParent()->getEntryBlock();
Instruction *FirstInst = EntryBlock.getFirstNonPHIOrDbg();
if (FirstInst != &AI) {
// If the entry block doesn't start with a zero-size alloca then move
// this one to the start of the entry block. There is no problem with
// dominance as the array size was forced to a constant earlier already.
AllocaInst *EntryAI = dyn_cast<AllocaInst>(FirstInst);
if (!EntryAI || !EntryAI->getAllocatedType()->isSized() ||
DL.getTypeAllocSize(EntryAI->getAllocatedType()) != 0) {
AI.moveBefore(FirstInst);
return &AI;
}
// If the alignment of the entry block alloca is 0 (unspecified),
// assign it the preferred alignment.
if (EntryAI->getAlignment() == 0)
EntryAI->setAlignment(
DL.getPrefTypeAlignment(EntryAI->getAllocatedType()));
// Replace this zero-sized alloca with the one at the start of the entry
// block after ensuring that the address will be aligned enough for both
// types.
unsigned MaxAlign = std::max(EntryAI->getAlignment(),
AI.getAlignment());
EntryAI->setAlignment(MaxAlign);
if (AI.getType() != EntryAI->getType())
return new BitCastInst(EntryAI, AI.getType());
return ReplaceInstUsesWith(AI, EntryAI);
}
}
}
if (AI.getAlignment()) {
// Check to see if this allocation is only modified by a memcpy/memmove from
// a constant global whose alignment is equal to or exceeds that of the
// allocation. If this is the case, we can change all users to use
// the constant global instead. This is commonly produced by the CFE by
// constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A'
// is only subsequently read.
SmallVector<Instruction *, 4> ToDelete;
if (MemTransferInst *Copy = isOnlyCopiedFromConstantGlobal(&AI, ToDelete)) {
unsigned SourceAlign = getOrEnforceKnownAlignment(
Copy->getSource(), AI.getAlignment(), DL, &AI, AC, DT);
if (AI.getAlignment() <= SourceAlign) {
DEBUG(dbgs() << "Found alloca equal to global: " << AI << '\n');
DEBUG(dbgs() << " memcpy = " << *Copy << '\n');
for (unsigned i = 0, e = ToDelete.size(); i != e; ++i)
EraseInstFromFunction(*ToDelete[i]);
Constant *TheSrc = cast<Constant>(Copy->getSource());
Constant *Cast
= ConstantExpr::getPointerBitCastOrAddrSpaceCast(TheSrc, AI.getType());
Instruction *NewI = ReplaceInstUsesWith(AI, Cast);
EraseInstFromFunction(*Copy);
++NumGlobalCopies;
return NewI;
}
}
}
// At last, use the generic allocation site handler to aggressively remove
// unused allocas.
return visitAllocSite(AI);
}
示例14: get
// emit code to unpack a raw value from a box into registers or a stack slot
static Value *emit_unbox(jl_codectx_t &ctx, Type *to, const jl_cgval_t &x, jl_value_t *jt, Value *dest, bool volatile_store)
{
assert(to != T_void);
// TODO: fully validate that x.typ == jt?
if (x.isghost) {
// this can happen when a branch yielding a different type ends
// up being dead code, and type inference knows that the other
// branch's type is the only one that matters.
if (type_is_ghost(to)) {
return NULL;
}
//emit_error(ctx, "emit_unbox: a type mismatch error in occurred during codegen");
return UndefValue::get(to); // type mismatch error
}
Constant *c = x.constant ? julia_const_to_llvm(x.constant) : NULL;
if (!x.ispointer() || c) { // already unboxed, but sometimes need conversion
Value *unboxed = emit_unboxed_coercion(ctx, to, c ? c : x.V);
if (!dest)
return unboxed;
Type *dest_ty = unboxed->getType()->getPointerTo();
if (dest->getType() != dest_ty)
dest = emit_bitcast(ctx, dest, dest_ty);
ctx.builder.CreateStore(unboxed, dest, volatile_store);
return NULL;
}
// bools stored as int8, so an extra Trunc is needed to get an int1
Value *p = x.constant ? literal_pointer_val(ctx, x.constant) : x.V;
Type *ptype = (to == T_int1 ? T_pint8 : to->getPointerTo());
Value *unboxed = NULL;
if (to == T_int1)
unboxed = ctx.builder.CreateTrunc(tbaa_decorate(x.tbaa, ctx.builder.CreateLoad(maybe_bitcast(ctx, p, ptype))), T_int1);
else if (jt == (jl_value_t*)jl_bool_type)
unboxed = ctx.builder.CreateZExt(ctx.builder.CreateTrunc(tbaa_decorate(x.tbaa, ctx.builder.CreateLoad(maybe_bitcast(ctx, p, ptype))), T_int1), to);
if (unboxed) {
if (!dest)
return unboxed;
ctx.builder.CreateStore(unboxed, dest);
return NULL;
}
unsigned alignment = julia_alignment(jt, 0);
if (dest) {
MDNode *tbaa = x.tbaa;
// the memcpy intrinsic does not allow to specify different alias tags
// for the load part (x.tbaa) and the store part (tbaa_stack).
// since the tbaa lattice has to be a tree we have unfortunately
// x.tbaa ∪ tbaa_stack = tbaa_root if x.tbaa != tbaa_stack
if (tbaa != tbaa_stack)
tbaa = NULL;
emit_memcpy(ctx, dest, p, jl_datatype_size(jt), alignment, volatile_store, tbaa);
return NULL;
}
else {
if (p->getType() != ptype && isa<AllocaInst>(p)) {
// LLVM's mem2reg can't handle coercion if the load/store type does
// not match the type of the alloca. As such, it is better to
// perform the load using the alloca's type and then perform the
// appropriate coercion manually.
AllocaInst *AI = cast<AllocaInst>(p);
Type *AllocType = AI->getAllocatedType();
#if JL_LLVM_VERSION >= 40000
const DataLayout &DL = jl_data_layout;
#else
const DataLayout &DL = jl_ExecutionEngine->getDataLayout();
#endif
if (!AI->isArrayAllocation() &&
(AllocType->isFloatingPointTy() || AllocType->isIntegerTy() || AllocType->isPointerTy()) &&
(to->isFloatingPointTy() || to->isIntegerTy() || to->isPointerTy()) &&
DL.getTypeSizeInBits(AllocType) == DL.getTypeSizeInBits(to)) {
Instruction *load = ctx.builder.CreateAlignedLoad(p, alignment);
return emit_unboxed_coercion(ctx, to, tbaa_decorate(x.tbaa, load));
}
}
p = maybe_bitcast(ctx, p, ptype);
Instruction *load = ctx.builder.CreateAlignedLoad(p, alignment);
return tbaa_decorate(x.tbaa, load);
}
}
示例15: InlineCallIfPossible
/// If it is possible to inline the specified call site,
/// do so and update the CallGraph for this operation.
///
/// This function also does some basic book-keeping to update the IR. The
/// InlinedArrayAllocas map keeps track of any allocas that are already
/// available from other functions inlined into the caller. If we are able to
/// inline this call site we attempt to reuse already available allocas or add
/// any new allocas to the set if not possible.
static bool InlineCallIfPossible(CallSite CS, InlineFunctionInfo &IFI,
InlinedArrayAllocasTy &InlinedArrayAllocas,
int InlineHistory, bool InsertLifetime) {
Function *Callee = CS.getCalledFunction();
Function *Caller = CS.getCaller();
// Try to inline the function. Get the list of static allocas that were
// inlined.
if (!InlineFunction(CS, IFI, InsertLifetime))
return false;
AdjustCallerSSPLevel(Caller, Callee);
// Look at all of the allocas that we inlined through this call site. If we
// have already inlined other allocas through other calls into this function,
// then we know that they have disjoint lifetimes and that we can merge them.
//
// There are many heuristics possible for merging these allocas, and the
// different options have different tradeoffs. One thing that we *really*
// don't want to hurt is SRoA: once inlining happens, often allocas are no
// longer address taken and so they can be promoted.
//
// Our "solution" for that is to only merge allocas whose outermost type is an
// array type. These are usually not promoted because someone is using a
// variable index into them. These are also often the most important ones to
// merge.
//
// A better solution would be to have real memory lifetime markers in the IR
// and not have the inliner do any merging of allocas at all. This would
// allow the backend to do proper stack slot coloring of all allocas that
// *actually make it to the backend*, which is really what we want.
//
// Because we don't have this information, we do this simple and useful hack.
//
SmallPtrSet<AllocaInst*, 16> UsedAllocas;
// When processing our SCC, check to see if CS was inlined from some other
// call site. For example, if we're processing "A" in this code:
// A() { B() }
// B() { x = alloca ... C() }
// C() { y = alloca ... }
// Assume that C was not inlined into B initially, and so we're processing A
// and decide to inline B into A. Doing this makes an alloca available for
// reuse and makes a callsite (C) available for inlining. When we process
// the C call site we don't want to do any alloca merging between X and Y
// because their scopes are not disjoint. We could make this smarter by
// keeping track of the inline history for each alloca in the
// InlinedArrayAllocas but this isn't likely to be a significant win.
if (InlineHistory != -1) // Only do merging for top-level call sites in SCC.
return true;
// Loop over all the allocas we have so far and see if they can be merged with
// a previously inlined alloca. If not, remember that we had it.
for (unsigned AllocaNo = 0, e = IFI.StaticAllocas.size();
AllocaNo != e; ++AllocaNo) {
AllocaInst *AI = IFI.StaticAllocas[AllocaNo];
// Don't bother trying to merge array allocations (they will usually be
// canonicalized to be an allocation *of* an array), or allocations whose
// type is not itself an array (because we're afraid of pessimizing SRoA).
ArrayType *ATy = dyn_cast<ArrayType>(AI->getAllocatedType());
if (!ATy || AI->isArrayAllocation())
continue;
// Get the list of all available allocas for this array type.
std::vector<AllocaInst*> &AllocasForType = InlinedArrayAllocas[ATy];
// Loop over the allocas in AllocasForType to see if we can reuse one. Note
// that we have to be careful not to reuse the same "available" alloca for
// multiple different allocas that we just inlined, we use the 'UsedAllocas'
// set to keep track of which "available" allocas are being used by this
// function. Also, AllocasForType can be empty of course!
bool MergedAwayAlloca = false;
for (unsigned i = 0, e = AllocasForType.size(); i != e; ++i) {
AllocaInst *AvailableAlloca = AllocasForType[i];
unsigned Align1 = AI->getAlignment(),
Align2 = AvailableAlloca->getAlignment();
// The available alloca has to be in the right function, not in some other
// function in this SCC.
if (AvailableAlloca->getParent() != AI->getParent())
continue;
// If the inlined function already uses this alloca then we can't reuse
// it.
if (!UsedAllocas.insert(AvailableAlloca).second)
continue;
// Otherwise, we *can* reuse it, RAUW AI into AvailableAlloca and declare
// success!
DEBUG(dbgs() << " ***MERGED ALLOCA: " << *AI << "\n\t\tINTO: "
//.........这里部分代码省略.........