// Helper to find the set of values described by a TSpecifier std::set<const Value*> getValues(const ImmutableCallSite cs, TSpecifier TS) { std::set<const Value*> Values; switch (TS) { case Ret: assert(!cs.getInstruction()->getType()->isVoidTy()); Values.insert(cs.getInstruction()); break; case Arg0: assert(0 < cs.arg_size()); Values.insert(cs.getArgument(0)); break; case Arg1: assert(1 < cs.arg_size()); Values.insert(cs.getArgument(1)); break; case Arg2: assert(2 < cs.arg_size()); Values.insert(cs.getArgument(2)); break; case Arg3: assert(3 < cs.arg_size()); Values.insert(cs.getArgument(3)); break; case Arg4: assert(4 < cs.arg_size()); Values.insert(cs.getArgument(4)); break; case AllArgs: assert(!cs.arg_empty()); for (unsigned i = 0; i < cs.arg_size(); ++i) Values.insert(cs.getArgument(i)); break; case VarArgs: { const Value *Callee = cs.getCalledValue()->stripPointerCasts(); FunctionType *CalleeType = dyn_cast<FunctionType>( dyn_cast<PointerType>(Callee->getType())->getElementType() ); for (unsigned i = CalleeType->getNumParams(); i < cs.arg_size(); ++i) Values.insert(cs.getArgument(i)); break; } } return Values; }
MemoryLocation MemoryLocation::getForArgument(ImmutableCallSite CS, unsigned ArgIdx, const TargetLibraryInfo &TLI) { AAMDNodes AATags; CS->getAAMetadata(AATags); const Value *Arg = CS.getArgument(ArgIdx); // We may be able to produce an exact size for known intrinsics. if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { const DataLayout &DL = II->getModule()->getDataLayout(); switch (II->getIntrinsicID()) { default: break; case Intrinsic::memset: case Intrinsic::memcpy: case Intrinsic::memmove: assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memory intrinsic"); if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2))) return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); break; case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::invariant_start: assert(ArgIdx == 1 && "Invalid argument index"); return MemoryLocation( Arg, cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AATags); case Intrinsic::invariant_end: // The first argument to an invariant.end is a "descriptor" type (e.g. a // pointer to a empty struct) which is never actually dereferenced. if (ArgIdx == 0) return MemoryLocation(Arg, 0, AATags); assert(ArgIdx == 2 && "Invalid argument index"); return MemoryLocation( Arg, cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AATags); case Intrinsic::arm_neon_vld1: assert(ArgIdx == 0 && "Invalid argument index"); // LLVM's vld1 and vst1 intrinsics currently only support a single // vector register. return MemoryLocation(Arg, DL.getTypeStoreSize(II->getType()), AATags); case Intrinsic::arm_neon_vst1: assert(ArgIdx == 0 && "Invalid argument index"); return MemoryLocation( Arg, DL.getTypeStoreSize(II->getArgOperand(1)->getType()), AATags); } } // We can bound the aliasing properties of memset_pattern16 just as we can // for memcpy/memset. This is particularly important because the // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 // whenever possible. LibFunc F; if (CS.getCalledFunction() && TLI.getLibFunc(*CS.getCalledFunction(), F) && F == LibFunc_memset_pattern16 && TLI.has(F)) { assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for memset_pattern16"); if (ArgIdx == 1) return MemoryLocation(Arg, 16, AATags); if (const ConstantInt *LenCI = dyn_cast<ConstantInt>(CS.getArgument(2))) return MemoryLocation(Arg, LenCI->getZExtValue(), AATags); } // FIXME: Handle memset_pattern4 and memset_pattern8 also. return MemoryLocation(CS.getArgument(ArgIdx), UnknownSize, AATags); }