From 636c3d04673da8c8605d7e45640a2ff7aec648f1 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 26 Oct 2007 17:44:44 +0000 Subject: [PATCH] Codegen array initializers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43385 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CGExprAgg.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++- test/CodeGen/array.c | 8 +++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/CodeGen/CGExprAgg.cpp b/CodeGen/CGExprAgg.cpp index 743c2486d3..5f353edcf0 100644 --- a/CodeGen/CGExprAgg.cpp +++ b/CodeGen/CGExprAgg.cpp @@ -16,6 +16,7 @@ #include "clang/AST/AST.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Support/Compiler.h" using namespace clang; using namespace CodeGen; @@ -73,6 +74,7 @@ public: void VisitConditionalOperator(const ConditionalOperator *CO); + void VisitInitListExpr(InitListExpr *E); // case Expr::ChooseExprClass: }; } // end anonymous namespace. @@ -101,7 +103,8 @@ void AggExprEmitter::EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *MemCpyOps[4] = { DestPtr, SrcPtr, - llvm::ConstantInt::get(IntPtr, TypeInfo.first), + // TypeInfo.first describes size in bits. + llvm::ConstantInt::get(IntPtr, TypeInfo.first/8), llvm::ConstantInt::get(llvm::Type::Int32Ty, TypeInfo.second) }; @@ -178,6 +181,79 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) { CGF.EmitBlock(ContBlock); } +void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { + + unsigned NumInitElements = E->getNumInits(); + + assert ( E->getType()->isArrayType() + && "Only Array initializers are supported"); + + std::vector ArrayElts; + const llvm::PointerType *APType = cast(DestPtr->getType()); + const llvm::ArrayType *AType = cast(APType->getElementType()); + + // Copy initializer elements. + bool AllConstElements = true; + unsigned i = 0; + for (i = 0; i < NumInitElements; ++i) { + if (llvm::Constant *C = dyn_cast(CGF.EmitScalarExpr(E->getInit(i)))) + ArrayElts.push_back(C); + else { + AllConstElements = false; + break; + } + } + + unsigned NumArrayElements = AType->getNumElements(); + const llvm::Type *ElementType = CGF.ConvertType(E->getInit(0)->getType()); + + if (AllConstElements) { + // Initialize remaining array elements. + for (/*Do not initialize i*/; i < NumArrayElements; ++i) + ArrayElts.push_back(llvm::Constant::getNullValue(ElementType)); + + // Create global value to hold this array. + llvm::Constant *V = llvm::ConstantArray::get(AType, ArrayElts); + V = new llvm::GlobalVariable(V->getType(), true, + llvm::GlobalValue::InternalLinkage, + V, ".array", + &CGF.CGM.getModule()); + + EmitAggregateCopy(DestPtr, V , E->getType()); + return; + } + + // Emit indiviudal array element stores. + unsigned index = 0; + llvm::Value *NextVal = NULL; + llvm::Value *Idxs[] = { + llvm::Constant::getNullValue(llvm::Type::Int32Ty), + NULL + }; + + // Emit already seen constants initializers. + for (i = 0; i < ArrayElts.size(); i++) { + Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++); + NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array"); + Builder.CreateStore(ArrayElts[i], NextVal); + } + + // Emit remaining initializers + for (/*Do not initizalize i*/; i < NumInitElements; ++i) { + Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++); + NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array"); + llvm::Value *V = CGF.EmitScalarExpr(E->getInit(i)); + Builder.CreateStore(V, NextVal); + } + + // Emit remaining default initializers + for (/*Do not initialize i*/; i < NumArrayElements; ++i) { + Idxs[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, index++); + NextVal = Builder.CreateGEP(DestPtr, Idxs, Idxs + 2, ".array"); + Builder.CreateStore(llvm::Constant::getNullValue(ElementType), NextVal); + } +} + //===----------------------------------------------------------------------===// // Entry Points into this File //===----------------------------------------------------------------------===// diff --git a/test/CodeGen/array.c b/test/CodeGen/array.c index dfbd10ddad..58efce7fd7 100644 --- a/test/CodeGen/array.c +++ b/test/CodeGen/array.c @@ -4,3 +4,11 @@ int f() { int a[2]; a[0] = 0; } + +int f2() { + int x = 0; + int y = 1; + int a[10] = { y, x, 2, 3}; + int b[10] = { 2,4,x,6,y,8}; + int c[5] = { 0,1,2,3}; +} -- 2.40.0