aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp16
-rw-r--r--lib/Basic/TargetInfo.cpp1
-rw-r--r--lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.h4
4 files changed, 28 insertions, 3 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e6dfd445ad..8d40a6a299 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1283,6 +1283,10 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) const {
T = getBaseElementType(arrayType);
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (VD->hasGlobalStorage())
+ Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
+ }
}
// Fields can be subject to extra alignment constraints, like if
@@ -1725,6 +1729,18 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
return ABIAlign;
}
+/// getAlignOfGlobalVar - Return the alignment in bits that should be given
+/// to a global variable of the specified type.
+unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
+ return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign());
+}
+
+/// getAlignOfGlobalVarInChars - Return the alignment in characters that
+/// should be given to a global variable of the specified type.
+CharUnits ASTContext::getAlignOfGlobalVarInChars(QualType T) const {
+ return toCharUnitsFromBits(getAlignOfGlobalVar(T));
+}
+
/// DeepCollectObjCIvars -
/// This routine first collects all declared, but not synthesized, ivars in
/// super class and then collects all ivars, including those synthesized for
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index ff72f495c8..0d44dc010e 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -37,6 +37,7 @@ TargetInfo::TargetInfo(const std::string &T) : TargetOpts(), Triple(T)
LongWidth = LongAlign = 32;
LongLongWidth = LongLongAlign = 64;
SuitableAlign = 64;
+ MinGlobalAlign = 0;
HalfWidth = 16;
HalfAlign = 16;
FloatWidth = 32;
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index ff183c96e0..0b03a3c4b6 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -2339,6 +2339,8 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) {
new llvm::GlobalVariable(getModule(), C->getType(), /*isConstant=*/true,
Linkage, C, ".str");
GV->setUnnamedAddr(true);
+ // Don't enforce the target's minimum global alignment, since the only use
+ // of the string is via this class initializer.
if (isUTF16) {
CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy);
GV->setAlignment(Align.getQuantity());
@@ -2472,6 +2474,8 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
".str");
GV->setUnnamedAddr(true);
+ // Don't enforce the target's minimum global alignment, since the only use
+ // of the string is via this class initializer.
CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy);
GV->setAlignment(Align.getQuantity());
Fields[1] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
@@ -2576,7 +2580,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
/// constant array for the given string literal.
llvm::Constant *
CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
- CharUnits Align = getContext().getTypeAlignInChars(S->getType());
+ CharUnits Align = getContext().getAlignOfGlobalVarInChars(S->getType());
if (S->isAscii() || S->isUTF8()) {
SmallString<64> Str(S->getString());
@@ -2645,6 +2649,10 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
if (!GlobalName)
GlobalName = ".str";
+ if (Alignment == 0)
+ Alignment = getContext().getAlignOfGlobalVarInChars(getContext().CharTy)
+ .getQuantity();
+
// Don't share any string literals if strings aren't constant.
if (LangOpts.WritableStrings)
return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 7bbca80bf4..91138c607c 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -713,7 +713,7 @@ public:
/// (if one is created).
llvm::Constant *GetAddrOfConstantString(StringRef Str,
const char *GlobalName=0,
- unsigned Alignment=1);
+ unsigned Alignment=0);
/// GetAddrOfConstantCString - Returns a pointer to a character array
/// containing the literal and a terminating '\0' character. The result has
@@ -723,7 +723,7 @@ public:
/// created).
llvm::Constant *GetAddrOfConstantCString(const std::string &str,
const char *GlobalName=0,
- unsigned Alignment=1);
+ unsigned Alignment=0);
/// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global
/// variable for the given file-scope compound literal expression.