Improve non-const initializer implementation.

llvm-svn: 47347
This commit is contained in:
Lauro Ramos Venancio 2008-02-19 22:04:22 +00:00
parent 91fdb9ec43
commit ca0fd02cdd
1 changed files with 51 additions and 31 deletions

View File

@ -48,6 +48,10 @@ public:
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
QualType EltTy);
void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
void EmitNonConstInit(InitListExpr *E);
//===--------------------------------------------------------------------===//
// Visitor Methods
@ -83,9 +87,6 @@ public:
void VisitInitListExpr(InitListExpr *E);
// case Expr::ChooseExprClass:
private:
void EmitNonConstInit(Expr *E, llvm::Value *Dest, const llvm::Type *DestType);
};
} // end anonymous namespace.
@ -93,6 +94,32 @@ private:
// Utilities
//===----------------------------------------------------------------------===//
void AggExprEmitter::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
assert(!Ty->isComplexType() && "Shouldn't happen for complex");
// Aggregate assignment turns into llvm.memset.
const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
if (DestPtr->getType() != BP)
DestPtr = Builder.CreateBitCast(DestPtr, BP, "tmp");
// Get size and alignment info for this aggregate.
std::pair<uint64_t, unsigned> TypeInfo =
CGF.getContext().getTypeInfo(Ty, SourceLocation());
// FIXME: Handle variable sized types.
const llvm::Type *IntPtr = llvm::IntegerType::get(CGF.LLVMPointerWidth);
llvm::Value *MemSetOps[4] = {
DestPtr,
llvm::ConstantInt::getNullValue(llvm::Type::Int8Ty),
// TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second/8)
};
Builder.CreateCall(CGF.CGM.getMemSetFn(), MemSetOps, MemSetOps+4);
}
void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
llvm::Value *SrcPtr, QualType Ty) {
assert(!Ty->isComplexType() && "Shouldn't happen for complex");
@ -115,7 +142,7 @@ void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr,
DestPtr, SrcPtr,
// TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second)
llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second/8)
};
Builder.CreateCall(CGF.CGM.getMemCpyFn(), MemCpyOps, MemCpyOps+4);
@ -234,17 +261,14 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) {
CGF.EmitBlock(ContBlock);
}
void AggExprEmitter::EmitNonConstInit(Expr *E, llvm::Value *DestPtr,
const llvm::Type *DestType) {
void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
const llvm::PointerType *APType =
cast<llvm::PointerType>(DestPtr->getType());
const llvm::Type *DestType = APType->getElementType();
if (const llvm::ArrayType *AType = dyn_cast<llvm::ArrayType>(DestType)) {
unsigned NumInitElements = 0;
InitListExpr *InitList = NULL;
if (E) {
InitList = cast<InitListExpr>(E);
NumInitElements = InitList->getNumInits();
}
unsigned NumInitElements = E->getNumInits();
llvm::Value *Idxs[] = {
llvm::Constant::getNullValue(llvm::Type::Int32Ty),
@ -255,25 +279,27 @@ void AggExprEmitter::EmitNonConstInit(Expr *E, llvm::Value *DestPtr,
for (i = 0; i != NumInitElements; ++i) {
Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
EmitNonConstInit(InitList->getInit(i), NextVal, AType->getElementType());
Expr *Init = E->getInit(i);
if (isa<InitListExpr>(Init))
CGF.EmitAggExpr(Init, NextVal, VolatileDest);
else
Builder.CreateStore(CGF.EmitScalarExpr(Init), NextVal);
}
// Emit remaining default initializers
unsigned NumArrayElements = AType->getNumElements();
QualType QType = E->getInit(0)->getType();
const llvm::Type *EType = AType->getElementType();
for (/*Do not initialize i*/; i < NumArrayElements; ++i) {
Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2,".array");
EmitNonConstInit(NULL, NextVal, AType->getElementType());
if (EType->isFirstClassType())
Builder.CreateStore(llvm::Constant::getNullValue(EType), NextVal);
else
EmitAggregateClear(NextVal, QType);
}
} else {
llvm::Value *V;
if (E)
V = CGF.EmitScalarExpr(E);
else
V = llvm::Constant::getNullValue(DestType);
Builder.CreateStore(V, DestPtr);
}
} else
assert(false && "Invalid initializer");
}
void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
@ -293,13 +319,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
CGF.WarnUnsupported(E, "aggregate init-list expression");
return;
}
const llvm::PointerType *APType =
cast<llvm::PointerType>(DestPtr->getType());
const llvm::ArrayType *AType =
cast<llvm::ArrayType>(APType->getElementType());
EmitNonConstInit(E, DestPtr, AType);
EmitNonConstInit(E);
}
}