Simplify mem{cpy, move, set} creation with IRBuilder.

llvm-svn: 122634
This commit is contained in:
Benjamin Kramer 2010-12-30 00:13:21 +00:00
parent 7bcde197d7
commit acc6b4e2fd
8 changed files with 30 additions and 108 deletions

View File

@ -526,12 +526,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BI__builtin_bzero: {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *SizeVal = EmitScalarExpr(E->getArg(1));
Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
Address,
llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
SizeVal,
llvm::ConstantInt::get(Int32Ty, 1),
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
Builder.CreateMemSet(Address, Builder.getInt8(0), SizeVal, 1, false);
return RValue::get(Address);
}
case Builtin::BImemcpy:
@ -539,11 +534,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *Address = EmitScalarExpr(E->getArg(0));
Value *SrcAddr = EmitScalarExpr(E->getArg(1));
Value *SizeVal = EmitScalarExpr(E->getArg(2));
Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(),
SizeVal->getType()),
Address, SrcAddr, SizeVal,
llvm::ConstantInt::get(Int32Ty, 1),
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
Builder.CreateMemCpy(Address, SrcAddr, SizeVal, 1, false);
return RValue::get(Address);
}
@ -561,24 +552,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *Address = EmitScalarExpr(E->getArg(0));
Value *SrcAddr = EmitScalarExpr(E->getArg(1));
Value *SizeVal = EmitScalarExpr(E->getArg(2));
Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(),
SizeVal->getType()),
Address, SrcAddr, SizeVal,
llvm::ConstantInt::get(Int32Ty, 1),
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
Builder.CreateMemMove(Address, SrcAddr, SizeVal, 1, false);
return RValue::get(Address);
}
case Builtin::BImemset:
case Builtin::BI__builtin_memset: {
Value *Address = EmitScalarExpr(E->getArg(0));
Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
Builder.getInt8Ty());
Value *SizeVal = EmitScalarExpr(E->getArg(2));
Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
Address,
Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
llvm::Type::getInt8Ty(VMContext)),
SizeVal,
llvm::ConstantInt::get(Int32Ty, 1),
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
Builder.CreateMemSet(Address, ByteVal, SizeVal, 1, false);
return RValue::get(Address);
}
case Builtin::BI__builtin_dwarf_cfa: {

View File

@ -878,15 +878,13 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
//
// FIXME: We should have a common utility for generating an aggregate
// copy.
const llvm::Type *I8PtrTy = llvm::Type::getInt8PtrTy(VMContext, 0);
const llvm::Type *I8PtrTy = Builder.getInt8PtrTy();
unsigned Size = getContext().getTypeSize(Ty) / 8;
Builder.CreateCall5(CGM.getMemCpyFn(I8PtrTy, I8PtrTy, IntPtrTy),
Builder.CreateBitCast(AlignedTemp, I8PtrTy),
Builder.CreateBitCast(V, I8PtrTy),
llvm::ConstantInt::get(IntPtrTy, Size),
Builder.getInt32(ArgI.getIndirectAlign()),
/*Volatile=*/Builder.getInt1(false));
Builder.CreateMemCpy(Builder.CreateBitCast(AlignedTemp, I8PtrTy),
Builder.CreateBitCast(V, I8PtrTy),
llvm::ConstantInt::get(IntPtrTy, Size),
ArgI.getIndirectAlign(),
false);
V = AlignedTemp;
}
} else {

View File

@ -810,26 +810,20 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D,
llvm::Constant *Init = CGM.EmitConstantExpr(D.getInit(), Ty,this);
assert(Init != 0 && "Wasn't a simple constant init?");
llvm::Value *AlignVal = Builder.getInt32(Align.getQuantity());
llvm::Value *SizeVal =
llvm::ConstantInt::get(CGF.IntPtrTy,
getContext().getTypeSizeInChars(Ty).getQuantity());
const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
const llvm::Type *BP = Builder.getInt8PtrTy();
if (Loc->getType() != BP)
Loc = Builder.CreateBitCast(Loc, BP, "tmp");
llvm::Value *NotVolatile = Builder.getFalse();
// If the initializer is all or mostly zeros, codegen with memset then do
// a few stores afterward.
if (shouldUseMemSetPlusStoresToInitialize(Init,
CGM.getTargetData().getTypeAllocSize(Init->getType()))) {
const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
Builder.CreateCall5(CGM.getMemSetFn(BP, SizeVal->getType()),
Loc, Builder.getInt8(0), SizeVal, AlignVal,
NotVolatile);
Builder.CreateMemSet(Loc, Builder.getInt8(0), SizeVal,
Align.getQuantity(), false);
if (!Init->isNullValue()) {
Loc = Builder.CreateBitCast(Loc, Init->getType()->getPointerTo());
emitStoresForInitAfterMemset(Init, Loc, Builder);
@ -849,9 +843,7 @@ void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D,
if (SrcPtr->getType() != BP)
SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
Builder.CreateCall5(CGM.getMemCpyFn(Loc->getType(), SrcPtr->getType(),
SizeVal->getType()),
Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);
Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, Align.getQuantity(), false);
}
} else if (Ty->isReferenceType()) {
RValue RV = EmitReferenceBindingToExpr(Init, &D);

View File

@ -806,16 +806,13 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
// Okay, it seems like a good idea to use an initial memset, emit the call.
llvm::Constant *SizeVal = CGF.Builder.getInt64(TypeInfo.first/8);
llvm::ConstantInt *AlignVal = CGF.Builder.getInt32(TypeInfo.second/8);
unsigned Align = TypeInfo.second/8;
llvm::Value *Loc = Slot.getAddr();
const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
Loc = CGF.Builder.CreateBitCast(Loc, BP);
CGF.Builder.CreateCall5(CGF.CGM.getMemSetFn(Loc->getType(),
SizeVal->getType()),
Loc, CGF.Builder.getInt8(0), SizeVal, AlignVal,
CGF.Builder.getFalse());
CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal, Align, false);
// Tell the AggExprEmitter that the slot is known zero.
Slot.setZeroed();
@ -935,11 +932,7 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
}
}
Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
IntPtrTy),
DestPtr, SrcPtr,
// TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
Builder.getInt32(TypeInfo.second/8),
Builder.getInt1(isVolatile));
Builder.CreateMemCpy(DestPtr, SrcPtr,
llvm::ConstantInt::get(IntPtrTy, TypeInfo.first/8),
TypeInfo.second/8, isVolatile);
}

View File

@ -617,14 +617,9 @@ static void EmitZeroMemSet(CodeGenFunction &CGF, QualType T,
const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
if (NewPtr->getType() != BP)
NewPtr = CGF.Builder.CreateBitCast(NewPtr, BP, "tmp");
CGF.Builder.CreateCall5(CGF.CGM.getMemSetFn(BP, CGF.IntPtrTy), NewPtr,
llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
Size,
llvm::ConstantInt::get(CGF.Int32Ty,
CGF.getContext().getTypeAlign(T)/8),
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
0));
CGF.Builder.CreateMemSet(NewPtr, CGF.Builder.getInt8(0), Size,
CGF.getContext().getTypeAlign(T)/8, false);
}
static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,

View File

@ -534,22 +534,20 @@ CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
// Cast the dest ptr to the appropriate i8 pointer type.
unsigned DestAS =
cast<llvm::PointerType>(DestPtr->getType())->getAddressSpace();
const llvm::Type *BP =
llvm::Type::getInt8PtrTy(VMContext, DestAS);
const llvm::Type *BP = Builder.getInt8PtrTy(DestAS);
if (DestPtr->getType() != BP)
DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
// Get size and alignment info for this aggregate.
std::pair<uint64_t, unsigned> TypeInfo = getContext().getTypeInfo(Ty);
uint64_t Size = TypeInfo.first;
unsigned Align = TypeInfo.second;
uint64_t Size = TypeInfo.first / 8;
unsigned Align = TypeInfo.second / 8;
// Don't bother emitting a zero-byte memset.
if (Size == 0)
return;
llvm::ConstantInt *SizeVal = llvm::ConstantInt::get(IntPtrTy, Size / 8);
llvm::ConstantInt *AlignVal = Builder.getInt32(Align / 8);
llvm::ConstantInt *SizeVal = llvm::ConstantInt::get(IntPtrTy, Size);
// If the type contains a pointer to data member we can't memset it to zero.
// Instead, create a null constant and copy it to the destination.
@ -567,10 +565,7 @@ CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
// FIXME: variable-size types?
// Get and call the appropriate llvm.memcpy overload.
llvm::Constant *Memcpy =
CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(), IntPtrTy);
Builder.CreateCall5(Memcpy, DestPtr, SrcPtr, SizeVal, AlignVal,
/*volatile*/ Builder.getFalse());
Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal, Align, false);
return;
}
@ -579,9 +574,7 @@ CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
// handled above) are guaranteed to have a bit pattern of all zeros.
// FIXME: Handle variable sized types.
Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtrTy), DestPtr,
Builder.getInt8(0),
SizeVal, AlignVal, /*volatile*/ Builder.getFalse());
Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, Align, false);
}
llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {

View File

@ -1465,27 +1465,6 @@ llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
(llvm::Intrinsic::ID)IID, Tys, NumTys);
}
llvm::Function *CodeGenModule::getMemCpyFn(const llvm::Type *DestType,
const llvm::Type *SrcType,
const llvm::Type *SizeType) {
const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
return getIntrinsic(llvm::Intrinsic::memcpy, ArgTypes, 3);
}
llvm::Function *CodeGenModule::getMemMoveFn(const llvm::Type *DestType,
const llvm::Type *SrcType,
const llvm::Type *SizeType) {
const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
return getIntrinsic(llvm::Intrinsic::memmove, ArgTypes, 3);
}
llvm::Function *CodeGenModule::getMemSetFn(const llvm::Type *DestType,
const llvm::Type *SizeType) {
const llvm::Type *ArgTypes[2] = { DestType, SizeType };
return getIntrinsic(llvm::Intrinsic::memset, ArgTypes, 2);
}
static llvm::StringMapEntry<llvm::Constant*> &
GetConstantCFStringEntry(llvm::StringMap<llvm::Constant*> &Map,
const StringLiteral *Literal,

View File

@ -369,17 +369,6 @@ public:
llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
unsigned BuiltinID);
llvm::Function *getMemCpyFn(const llvm::Type *DestType,
const llvm::Type *SrcType,
const llvm::Type *SizeType);
llvm::Function *getMemMoveFn(const llvm::Type *DestType,
const llvm::Type *SrcType,
const llvm::Type *SizeType);
llvm::Function *getMemSetFn(const llvm::Type *DestType,
const llvm::Type *SizeType);
llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
unsigned NumTys = 0);