From 1ee0ecf84a07693c3a517ba030fac8ac1f9f3fbc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Jan 2012 13:41:11 +0000 Subject: [PATCH] add more support for ConstantDataSequential git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148802 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constants.h | 3 ++ .../SelectionDAG/SelectionDAGBuilder.cpp | 21 +++++++++- lib/ExecutionEngine/ExecutionEngine.cpp | 38 ++++++++++++------ lib/Linker/LinkModules.cpp | 39 ++++++++++--------- lib/VMCore/Constants.cpp | 11 ++++-- 5 files changed, 78 insertions(+), 34 deletions(-) diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 510847ff23c..3dc0ec3de00 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -623,6 +623,9 @@ public: /// getElementType - Return the element type of the array/vector. Type *getElementType() const; + + /// getNumElements - Return the number of elements in the array or vector. + unsigned getNumElements() const; /// getElementByteSize - Return the size (in bytes) of each element in the /// array/vector. The size of the elements is known to be a multiple of one diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index ee60a9f8154..cd9bec11bd0 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1055,6 +1055,23 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { return DAG.getMergeValues(&Constants[0], Constants.size(), getCurDebugLoc()); } + + if (const ConstantDataSequential *CDS = + dyn_cast(C)) { + SmallVector Ops; + for (unsigned i = 0, e = CDS->getType()->getNumElements(); i != e; ++i) { + SDNode *Val = getValue(CDS->getElementAsConstant(i)).getNode(); + // Add each leaf value from the operand to the Constants list + // to form a flattened list of all the values. + for (unsigned i = 0, e = Val->getNumValues(); i != e; ++i) + Ops.push_back(SDValue(Val, i)); + } + + if (isa(CDS->getType())) + return DAG.getMergeValues(&Ops[0], Ops.size(), getCurDebugLoc()); + return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), + VT, &Ops[0], Ops.size()); + } if (C->getType()->isStructTy() || C->getType()->isArrayTy()) { assert((isa(C) || isa(C)) && @@ -1089,9 +1106,9 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { // Now that we know the number and type of the elements, get that number of // elements into the Ops array based on what kind of constant it is. SmallVector Ops; - if (const ConstantVector *CP = dyn_cast(C)) { + if (const ConstantVector *CV = dyn_cast(C)) { for (unsigned i = 0; i != NumElements; ++i) - Ops.push_back(getValue(CP->getOperand(i))); + Ops.push_back(getValue(CV->getOperand(i))); } else { assert(isa(C) && "Unknown vector constant!"); EVT EltVT = TLI.getValueType(VecTy->getElementType()); diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 7829a2986bb..b9356dcd0a7 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -307,13 +307,12 @@ void ExecutionEngine::runStaticConstructorsDestructors(Module *module, // Should be an array of '{ i32, void ()* }' structs. The first value is // the init priority, which we ignore. - if (isa(GV->getInitializer())) + ConstantArray *InitList = dyn_cast(GV->getInitializer()); + if (InitList == 0) return; - ConstantArray *InitList = cast(GV->getInitializer()); for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { - if (isa(InitList->getOperand(i))) - continue; - ConstantStruct *CS = cast(InitList->getOperand(i)); + ConstantStruct *CS = dyn_cast(InitList->getOperand(i)); + if (CS == 0) continue; Constant *FP = CS->getOperand(1); if (FP->isNullValue()) @@ -954,30 +953,47 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) { DEBUG(dbgs() << "JIT: Initializing " << Addr << " "); DEBUG(Init->dump()); - if (isa(Init)) { + if (isa(Init)) return; - } else if (const ConstantVector *CP = dyn_cast(Init)) { + + if (const ConstantVector *CP = dyn_cast(Init)) { unsigned ElementSize = getTargetData()->getTypeAllocSize(CP->getType()->getElementType()); for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize); return; - } else if (isa(Init)) { + } + + if (isa(Init)) { memset(Addr, 0, (size_t)getTargetData()->getTypeAllocSize(Init->getType())); return; - } else if (const ConstantArray *CPA = dyn_cast(Init)) { + } + + if (const ConstantArray *CPA = dyn_cast(Init)) { unsigned ElementSize = getTargetData()->getTypeAllocSize(CPA->getType()->getElementType()); for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); return; - } else if (const ConstantStruct *CPS = dyn_cast(Init)) { + } + + if (const ConstantStruct *CPS = dyn_cast(Init)) { const StructLayout *SL = getTargetData()->getStructLayout(cast(CPS->getType())); for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->getElementOffset(i)); return; - } else if (Init->getType()->isFirstClassType()) { + } + + if (const ConstantDataSequential *CDS = + dyn_cast(Init)) { + // CDS is already laid out in host memory order. + StringRef Data = CDS->getRawDataValues(); + memcpy(Addr, Data.data(), Data.size()); + return; + } + + if (Init->getType()->isFirstClassType()) { GenericValue Val = getConstantValue(Init); StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType()); return; diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 46a76a25993..563aed5daa0 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -843,29 +843,32 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { return false; } +static void getArrayElements(Constant *C, SmallVectorImpl &Dest) { + if (ConstantArray *I = dyn_cast(C)) { + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) + Dest.push_back(I->getOperand(i)); + return; + } + + if (ConstantDataSequential *CDS = dyn_cast(C)) { + for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) + Dest.push_back(CDS->getElementAsConstant(i)); + return; + } + + ConstantAggregateZero *CAZ = cast(C); + Dest.append(cast(C->getType())->getNumElements(), + CAZ->getSequentialElement()); +} + void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) { // Merge the initializer. SmallVector Elements; - if (ConstantArray *I = dyn_cast(AVI.DstInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa(AVI.DstInit)); - ArrayType *DstAT = cast(AVI.DstInit->getType()); - Type *EltTy = DstAT->getElementType(); - Elements.append(DstAT->getNumElements(), Constant::getNullValue(EltTy)); - } + getArrayElements(AVI.DstInit, Elements); Constant *SrcInit = MapValue(AVI.SrcInit, ValueMap, RF_None, &TypeMap); - if (const ConstantArray *I = dyn_cast(SrcInit)) { - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - Elements.push_back(I->getOperand(i)); - } else { - assert(isa(SrcInit)); - ArrayType *SrcAT = cast(SrcInit->getType()); - Type *EltTy = SrcAT->getElementType(); - Elements.append(SrcAT->getNumElements(), Constant::getNullValue(EltTy)); - } + getArrayElements(SrcInit, Elements); + ArrayType *NewType = cast(AVI.NewGV->getType()->getElementType()); AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements)); } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 9f1abbd17bb..d329c67af0e 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1995,8 +1995,7 @@ Type *ConstantDataSequential::getElementType() const { } StringRef ConstantDataSequential::getRawDataValues() const { - return StringRef(DataElements, - getType()->getNumElements()*getElementByteSize()); + return StringRef(DataElements, getNumElements()*getElementByteSize()); } /// isElementTypeCompatible - Return true if a ConstantDataSequential can be @@ -2018,6 +2017,12 @@ bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) { return false; } +/// getNumElements - Return the number of elements in the array or vector. +unsigned ConstantDataSequential::getNumElements() const { + return getType()->getNumElements(); +} + + /// getElementByteSize - Return the size in bytes of the elements in the data. uint64_t ConstantDataSequential::getElementByteSize() const { return getElementType()->getPrimitiveSizeInBits()/8; @@ -2025,7 +2030,7 @@ uint64_t ConstantDataSequential::getElementByteSize() const { /// getElementPointer - Return the start of the specified element. const char *ConstantDataSequential::getElementPointer(unsigned Elt) const { - assert(Elt < getElementType()->getNumElements() && "Invalid Elt"); + assert(Elt < getNumElements() && "Invalid Elt"); return DataElements+Elt*getElementByteSize(); } -- 2.34.1