arphaman updated this revision to Diff 112149.
arphaman added a comment.
Revert most of the changes and use temporary DREs as suggested by John.
Repository:
rL LLVM
https://reviews.llvm.org/D36876
Files:
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp
test/CodeGenCXX/member-expr-references-variable.cpp
Index: test/CodeGenCXX/member-expr-references-variable.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Struct {
+ constexpr static const char *name = "foo";
+
+ constexpr static __complex float complexValue = 42.0;
+
+ Struct();
+ Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ Struct s;
+ use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+ use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+ use(1, Struct::complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+ Struct s;
+ use(2, s.complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+ use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+ use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+ use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.200000e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+ use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.200000e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -429,13 +429,19 @@
}
// l-values.
- Value *VisitDeclRefExpr(DeclRefExpr *E) {
+ Value *tryEmitDeclRefExprAsConstant(DeclRefExpr *E) {
if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
if (result.isReference())
return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
E->getExprLoc());
return result.getValue();
}
+ return nullptr;
+ }
+
+ Value *VisitDeclRefExpr(DeclRefExpr *E) {
+ if (Value *V = tryEmitDeclRefExprAsConstant(E))
+ return V;
return EmitLoadOfLValue(E);
}
@@ -1299,13 +1305,28 @@
}
Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
- llvm::APSInt Value;
- if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects)) {
+ Value *ConstantMemberValue;
+ if (auto *VD = dyn_cast<VarDecl>(E->getMemberDecl())) {
+ // Try emitting static variable member expressions as constant DREs.
+ DeclRefExpr *DRE = DeclRefExpr::Create(
+ CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
+ /*RefersToEnclosingVariableOrCapture=*/false, E->getExprLoc(),
+ E->getType(), E->getValueKind());
+ ConstantMemberValue = tryEmitDeclRefExprAsConstant(DRE);
+ } else {
+ llvm::APSInt Value;
+ if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects))
+ ConstantMemberValue = Builder.getInt(Value);
+ else
+ ConstantMemberValue = nullptr;
+ }
+
+ if (ConstantMemberValue) {
if (E->isArrow())
CGF.EmitScalarExpr(E->getBase());
else
EmitLValue(E->getBase());
- return Builder.getInt(Value);
+ return ConstantMemberValue;
}
return EmitLoadOfLValue(E);
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -122,7 +122,7 @@
// l-values.
- ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
+ Optional<ComplexPairTy> tryEmitDeclRefExprAsConstant(DeclRefExpr *E) {
if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
if (result.isReference())
return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
@@ -132,6 +132,13 @@
return ComplexPairTy(pair->getAggregateElement(0U),
pair->getAggregateElement(1U));
}
+ return None;
+ }
+
+ ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
+ auto Constant = tryEmitDeclRefExprAsConstant(E);
+ if (Constant)
+ return *Constant;
return EmitLoadOfLValue(E);
}
ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
@@ -141,7 +148,24 @@
return CGF.EmitObjCMessageExpr(E).getComplexVal();
}
ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+ ComplexPairTy VisitMemberExpr(MemberExpr *ME) {
+ if (auto *VD = dyn_cast<VarDecl>(ME->getMemberDecl())) {
+ // Try emitting static variable member expressions as constant DREs.
+ DeclRefExpr *DRE = DeclRefExpr::Create(
+ CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
+ /*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
+ ME->getType(), ME->getValueKind());
+ auto Constant = tryEmitDeclRefExprAsConstant(DRE);
+ if (Constant) {
+ if (ME->isArrow())
+ CGF.EmitScalarExpr(ME->getBase());
+ else
+ CGF.EmitLValue(ME->getBase());
+ return *Constant;
+ }
+ }
+ return EmitLoadOfLValue(ME);
+ }
ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {
if (E->isGLValue())
return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits