summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp74
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp109
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp3
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h7
5 files changed, 54 insertions, 143 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index f027ab941ac..db18ac49c6e 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1077,16 +1077,17 @@ static llvm::Constant *constWithPadding(CodeGenModule &CGM, IsPattern isPattern,
return constant;
}
-Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
- llvm::Constant *Constant,
- CharUnits Align) {
+static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
+ CGBuilderTy &Builder,
+ llvm::Constant *Constant,
+ CharUnits Align) {
auto FunctionName = [&](const DeclContext *DC) -> std::string {
if (const auto *FD = dyn_cast<FunctionDecl>(DC)) {
if (const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
return CC->getNameAsString();
if (const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
return CD->getNameAsString();
- return getMangledName(FD);
+ return CGM.getMangledName(FD);
} else if (const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
return OM->getNameAsString();
} else if (isa<BlockDecl>(DC)) {
@@ -1098,39 +1099,22 @@ Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
}
};
- // Form a simple per-variable cache of these values in case we find we
- // want to reuse them.
- llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];
- if (!CacheEntry || CacheEntry->getInitializer() != Constant) {
- auto *Ty = Constant->getType();
- bool isConstant = true;
- llvm::GlobalVariable *InsertBefore = nullptr;
- unsigned AS =
- getContext().getTargetAddressSpace(getStringLiteralAddressSpace());
- llvm::GlobalVariable *GV = new llvm::GlobalVariable(
- getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
- Constant,
- "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
- D.getName(),
- InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
- GV->setAlignment(Align.getQuantity());
- GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CacheEntry = GV;
- } else if (CacheEntry->getAlignment() < Align.getQuantity()) {
- CacheEntry->setAlignment(Align.getQuantity());
- }
-
- return Address(CacheEntry, Align);
-}
-
-static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM,
- const VarDecl &D,
- CGBuilderTy &Builder,
- llvm::Constant *Constant,
- CharUnits Align) {
- Address SrcPtr = CGM.createUnnamedGlobalFrom(D, Constant, Align);
- llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(),
- SrcPtr.getAddressSpace());
+ auto *Ty = Constant->getType();
+ bool isConstant = true;
+ llvm::GlobalVariable *InsertBefore = nullptr;
+ unsigned AS = CGM.getContext().getTargetAddressSpace(
+ CGM.getStringLiteralAddressSpace());
+ llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+ CGM.getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
+ Constant,
+ "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
+ D.getName(),
+ InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
+ GV->setAlignment(Align.getQuantity());
+ GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+
+ Address SrcPtr = Address(GV, Align);
+ llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(), AS);
if (SrcPtr.getType() != BP)
SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
return SrcPtr;
@@ -1213,10 +1197,10 @@ static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
}
// Copy from a global.
- Builder.CreateMemCpy(Loc,
- createUnnamedGlobalForMemcpyFrom(
- CGM, D, Builder, constant, Loc.getAlignment()),
- SizeVal, isVolatile);
+ Builder.CreateMemCpy(
+ Loc,
+ createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()),
+ SizeVal, isVolatile);
}
static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
@@ -1779,10 +1763,10 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
Cur->addIncoming(Begin.getPointer(), OriginBB);
CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
- Builder.CreateMemCpy(Address(Cur, CurAlign),
- createUnnamedGlobalForMemcpyFrom(
- CGM, D, Builder, Constant, ConstantAlign),
- BaseSizeInChars, isVolatile);
+ Builder.CreateMemCpy(
+ Address(Cur, CurAlign),
+ createUnnamedGlobalFrom(CGM, D, Builder, Constant, ConstantAlign),
+ BaseSizeInChars, isVolatile);
llvm::Value *Next =
Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index f0d8619faa3..d5ce4870f18 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1422,11 +1422,10 @@ static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
}
/// Try to emit a reference to the given value without producing it as
-/// an l-value. This is just an optimization, but it avoids us needing
-/// to emit global copies of variables if they're named without triggering
-/// a formal use in a context where we can't emit a direct reference to them,
-/// for instance if a block or lambda or a member of a local class uses a
-/// const int variable or constexpr variable from an enclosing function.
+/// an l-value. This is actually more than an optimization: we can't
+/// produce an l-value for variables that we never actually captured
+/// in a block or lambda, which means const int variables or constexpr
+/// literals or similar.
CodeGenFunction::ConstantEmission
CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
ValueDecl *value = refExpr->getDecl();
@@ -2451,97 +2450,33 @@ static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM) {
return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
}
-/// Determine whether we can emit a reference to \p VD from the current
-/// context, despite not necessarily having seen an odr-use of the variable in
-/// this context.
-static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
- const DeclRefExpr *E,
- const VarDecl *VD,
- bool IsConstant) {
- // For a variable declared in an enclosing scope, do not emit a spurious
- // reference even if we have a capture, as that will emit an unwarranted
- // reference to our capture state, and will likely generate worse code than
- // emitting a local copy.
- if (E->refersToEnclosingVariableOrCapture())
- return false;
-
- // For a local declaration declared in this function, we can always reference
- // it even if we don't have an odr-use.
- if (VD->hasLocalStorage()) {
- return VD->getDeclContext() ==
- dyn_cast_or_null<DeclContext>(CGF.CurCodeDecl);
- }
-
- // For a global declaration, we can emit a reference to it if we know
- // for sure that we are able to emit a definition of it.
- VD = VD->getDefinition(CGF.getContext());
- if (!VD)
- return false;
-
- // Don't emit a spurious reference if it might be to a variable that only
- // exists on a different device / target.
- // FIXME: This is unnecessarily broad. Check whether this would actually be a
- // cross-target reference.
- if (CGF.getLangOpts().OpenMP || CGF.getLangOpts().CUDA ||
- CGF.getLangOpts().OpenCL) {
- return false;
- }
-
- // We can emit a spurious reference only if the linkage implies that we'll
- // be emitting a non-interposable symbol that will be retained until link
- // time.
- switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
- case llvm::GlobalValue::ExternalLinkage:
- case llvm::GlobalValue::LinkOnceODRLinkage:
- case llvm::GlobalValue::WeakODRLinkage:
- case llvm::GlobalValue::InternalLinkage:
- case llvm::GlobalValue::PrivateLinkage:
- return true;
- default:
- return false;
- }
-}
-
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const NamedDecl *ND = E->getDecl();
QualType T = E->getType();
- assert(E->isNonOdrUse() != NOUR_Unevaluated &&
- "should not emit an unevaluated operand");
-
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
// Global Named registers access via intrinsics only
if (VD->getStorageClass() == SC_Register &&
VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
return EmitGlobalNamedRegister(VD, CGM);
- // If this DeclRefExpr does not constitute an odr-use of the variable,
- // we're not permitted to emit a reference to it in general, and it might
- // not be captured if capture would be necessary for a use. Emit the
- // constant value directly instead.
- if (E->isNonOdrUse() == NOUR_Constant &&
- (VD->getType()->isReferenceType() ||
- !canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
- VD->getAnyInitializer(VD);
- llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
- E->getLocation(), *VD->evaluateValue(), VD->getType());
- assert(Val && "failed to emit constant expression");
-
- Address Addr = Address::invalid();
- if (!VD->getType()->isReferenceType()) {
- // Spill the constant value to a global.
- Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
- getContext().getDeclAlign(VD));
- } else {
- // Should we be using the alignment of the constant pointer we emitted?
- CharUnits Alignment =
- getNaturalTypeAlignment(E->getType(),
- /* BaseInfo= */ nullptr,
- /* TBAAInfo= */ nullptr,
- /* forPointeeType= */ true);
- Addr = Address(Val, Alignment);
- }
- return MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+ // A DeclRefExpr for a reference initialized by a constant expression can
+ // appear without being odr-used. Directly emit the constant initializer.
+ VD->getAnyInitializer(VD);
+ if (E->isNonOdrUse() == NOUR_Constant && VD->getType()->isReferenceType()) {
+ llvm::Constant *Val =
+ ConstantEmitter(*this).emitAbstract(E->getLocation(),
+ *VD->evaluateValue(),
+ VD->getType());
+ assert(Val && "failed to emit reference constant expression");
+ // FIXME: Eventually we will want to emit vector element references.
+
+ // Should we be using the alignment of the constant pointer we emitted?
+ CharUnits Alignment = getNaturalTypeAlignment(E->getType(),
+ /* BaseInfo= */ nullptr,
+ /* TBAAInfo= */ nullptr,
+ /* forPointeeType= */ true);
+ return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl);
}
// FIXME: Handle other kinds of non-odr-use DeclRefExprs.
@@ -2577,7 +2512,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// FIXME: We should be able to assert this for FunctionDecls as well!
// FIXME: We should be able to assert this for all DeclRefExprs, not just
// those with a valid source location.
- assert((ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
+ assert((ND->isUsed(false) || !isa<VarDecl>(ND) ||
!E->getLocation().isValid()) &&
"Should not use decl without marking it used!");
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 3b1c5bf876e..a76058c1472 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -1352,8 +1352,7 @@ static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) {
// (int*)0 - Null pointer expressions.
if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
return ICE->getCastKind() == CK_NullToPointer &&
- CGF.getTypes().isPointerZeroInitializable(E->getType()) &&
- !E->HasSideEffects(CGF.getContext());
+ CGF.getTypes().isPointerZeroInitializable(E->getType());
// '\0'
if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
return CL->getValue() == 0;
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index c4167537e79..267402dbef4 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2148,14 +2148,14 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
case CK_NullToPointer:
if (MustVisitNullValue(E))
- CGF.EmitIgnoredExpr(E);
+ (void) Visit(E);
return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
DestTy);
case CK_NullToMemberPointer: {
if (MustVisitNullValue(E))
- CGF.EmitIgnoredExpr(E);
+ (void) Visit(E);
const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 95964afed4e..8c1bc0777de 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -362,10 +362,6 @@ private:
llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8>
GlobalValReplacements;
- /// Variables for which we've emitted globals containing their constant
- /// values along with the corresponding globals, for opportunistic reuse.
- llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants;
-
/// Set of global decls for which we already diagnosed mangled name conflict.
/// Required to not issue a warning (on a mangling conflict) multiple times
/// for the same decl.
@@ -627,9 +623,6 @@ public:
StaticLocalDeclGuardMap[D] = C;
}
- Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant,
- CharUnits Align);
-
bool lookupRepresentativeDecl(StringRef MangledName,
GlobalDecl &Result) const;
OpenPOWER on IntegriCloud