diff options
| author | John McCall <rjmccall@apple.com> | 2017-03-04 21:26:29 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2017-03-04 21:26:29 +0000 |
| commit | 32e0d18605c260ad9a19b1f58c85f53606e0e142 (patch) | |
| tree | 496fc7ab2e8e8ef53d47256e5fddce62704c2849 /clang/lib/CodeGen/ConstantInitBuilder.cpp | |
| parent | b974be5ef49680b3cfee484a91da9b11169c3f68 (diff) | |
| download | bcm5719-llvm-32e0d18605c260ad9a19b1f58c85f53606e0e142.tar.gz bcm5719-llvm-32e0d18605c260ad9a19b1f58c85f53606e0e142.zip | |
Refactor ConstantInitBuilder to allow other frontends to more
easily extend the aggregate-builder API. Stupid missing language
features.
Also add APIs for constructing a relative reference and computing
the offset of a position from the start of the initializer.
llvm-svn: 296979
Diffstat (limited to 'clang/lib/CodeGen/ConstantInitBuilder.cpp')
| -rw-r--r-- | clang/lib/CodeGen/ConstantInitBuilder.cpp | 98 |
1 files changed, 79 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/ConstantInitBuilder.cpp b/clang/lib/CodeGen/ConstantInitBuilder.cpp index 772391e77db..d1a707b3239 100644 --- a/clang/lib/CodeGen/ConstantInitBuilder.cpp +++ b/clang/lib/CodeGen/ConstantInitBuilder.cpp @@ -20,12 +20,12 @@ using namespace clang; using namespace CodeGen; llvm::GlobalVariable * -ConstantInitBuilder::createGlobal(llvm::Constant *initializer, - const llvm::Twine &name, - CharUnits alignment, - bool constant, - llvm::GlobalValue::LinkageTypes linkage, - unsigned addressSpace) { +ConstantInitBuilderBase::createGlobal(llvm::Constant *initializer, + const llvm::Twine &name, + CharUnits alignment, + bool constant, + llvm::GlobalValue::LinkageTypes linkage, + unsigned addressSpace) { auto GV = new llvm::GlobalVariable(CGM.getModule(), initializer->getType(), constant, @@ -40,15 +40,15 @@ ConstantInitBuilder::createGlobal(llvm::Constant *initializer, return GV; } -void ConstantInitBuilder::setGlobalInitializer(llvm::GlobalVariable *GV, - llvm::Constant *initializer) { +void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV, + llvm::Constant *initializer){ GV->setInitializer(initializer); if (!SelfReferences.empty()) resolveSelfReferences(GV); } -void ConstantInitBuilder::resolveSelfReferences(llvm::GlobalVariable *GV) { +void ConstantInitBuilderBase::resolveSelfReferences(llvm::GlobalVariable *GV) { for (auto &entry : SelfReferences) { llvm::Constant *resolvedReference = llvm::ConstantExpr::getInBoundsGetElementPtr( @@ -58,13 +58,31 @@ void ConstantInitBuilder::resolveSelfReferences(llvm::GlobalVariable *GV) { } } -void ConstantInitBuilder::AggregateBuilderBase::addSize(CharUnits size) { +void ConstantAggregateBuilderBase::addSize(CharUnits size) { add(Builder.CGM.getSize(size)); } llvm::Constant * -ConstantInitBuilder::AggregateBuilderBase::getAddrOfCurrentPosition( - llvm::Type *type) { +ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType, + llvm::Constant *target) { + // Compute the address of the relative-address slot. + auto base = getAddrOfCurrentPosition(offsetType); + + // Subtract. + base = llvm::ConstantExpr::getPtrToInt(base, Builder.CGM.IntPtrTy); + target = llvm::ConstantExpr::getPtrToInt(target, Builder.CGM.IntPtrTy); + llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base); + + // Truncate to the relative-address type if necessary. + if (Builder.CGM.IntPtrTy != offsetType) { + offset = llvm::ConstantExpr::getTrunc(offset, offsetType); + } + + return offset; +} + +llvm::Constant * +ConstantAggregateBuilderBase::getAddrOfCurrentPosition(llvm::Type *type) { // Make a global variable. We will replace this with a GEP to this // position after installing the initializer. auto dummy = @@ -77,7 +95,7 @@ ConstantInitBuilder::AggregateBuilderBase::getAddrOfCurrentPosition( return dummy; } -void ConstantInitBuilder::AggregateBuilderBase::getGEPIndicesTo( +void ConstantAggregateBuilderBase::getGEPIndicesTo( llvm::SmallVectorImpl<llvm::Constant*> &indices, size_t position) const { // Recurse on the parent builder if present. @@ -97,22 +115,64 @@ void ConstantInitBuilder::AggregateBuilderBase::getGEPIndicesTo( position - Begin)); } -llvm::Constant *ConstantArrayBuilder::finishImpl() { +CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(size_t end) const{ + size_t cacheEnd = CachedOffsetEnd; + assert(cacheEnd <= end); + + // Fast path: if the cache is valid, just use it. + if (cacheEnd == end) { + return CachedOffsetFromGlobal; + } + + // If the cached range ends before the index at which the current + // aggregate starts, recurse for the parent. + CharUnits offset; + if (cacheEnd < Begin) { + assert(cacheEnd == 0); + assert(Parent && "Begin != 0 for root builder"); + cacheEnd = Begin; + offset = Parent->getOffsetFromGlobalTo(Begin); + } else { + offset = CachedOffsetFromGlobal; + } + + // Perform simple layout on the elements in cacheEnd..<end. + if (cacheEnd != end) { + auto &layout = Builder.CGM.getDataLayout(); + do { + llvm::Constant *element = Builder.Buffer[cacheEnd]; + assert(element != nullptr && + "cannot compute offset when a placeholder is present"); + llvm::Type *elementType = element->getType(); + offset = offset.alignTo(CharUnits::fromQuantity( + layout.getABITypeAlignment(elementType))); + offset += CharUnits::fromQuantity(layout.getTypeStoreSize(elementType)); + } while (++cacheEnd != end); + } + + // Cache and return. + CachedOffsetEnd = cacheEnd; + CachedOffsetFromGlobal = offset; + return offset; +} + +llvm::Constant *ConstantAggregateBuilderBase::finishArray(llvm::Type *eltTy) { markFinished(); auto &buffer = getBuffer(); assert((Begin < buffer.size() || - (Begin == buffer.size() && EltTy)) + (Begin == buffer.size() && eltTy)) && "didn't add any array elements without element type"); auto elts = llvm::makeArrayRef(buffer).slice(Begin); - auto eltTy = EltTy ? EltTy : elts[0]->getType(); + if (!eltTy) eltTy = elts[0]->getType(); auto type = llvm::ArrayType::get(eltTy, elts.size()); auto constant = llvm::ConstantArray::get(type, elts); buffer.erase(buffer.begin() + Begin, buffer.end()); return constant; } -llvm::Constant *ConstantStructBuilder::finishImpl() { +llvm::Constant * +ConstantAggregateBuilderBase::finishStruct(llvm::StructType *ty) { markFinished(); auto &buffer = getBuffer(); @@ -120,8 +180,8 @@ llvm::Constant *ConstantStructBuilder::finishImpl() { auto elts = llvm::makeArrayRef(buffer).slice(Begin); llvm::Constant *constant; - if (Ty) { - constant = llvm::ConstantStruct::get(Ty, elts); + if (ty) { + constant = llvm::ConstantStruct::get(ty, elts); } else { constant = llvm::ConstantStruct::getAnon(elts, /*packed*/ false); } |

