summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/ConstantInitBuilder.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2017-03-04 21:26:29 +0000
committerJohn McCall <rjmccall@apple.com>2017-03-04 21:26:29 +0000
commit32e0d18605c260ad9a19b1f58c85f53606e0e142 (patch)
tree496fc7ab2e8e8ef53d47256e5fddce62704c2849 /clang/lib/CodeGen/ConstantInitBuilder.cpp
parentb974be5ef49680b3cfee484a91da9b11169c3f68 (diff)
downloadbcm5719-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.cpp98
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);
}
OpenPOWER on IntegriCloud