[cfe-commits] r126540 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CodeGenModule.h test/CodeGen/may-alias.c test/CodeGenCXX/anonymous-union-member-initializer.cpp

John McCall rjmccall at apple.com
Sat Feb 26 00:07:02 PST 2011


Author: rjmccall
Date: Sat Feb 26 02:07:02 2011
New Revision: 126540

URL: http://llvm.org/viewvc/llvm-project?rev=126540&view=rev
Log:
Pretty up the emission of field l-values and use volatile and TBAA when
loading references as part of that.  Use 'char' TBAA when accessing
(immediate!) fields of a may_alias struct;  fixes PR9307.


Modified:
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGen/may-alias.c
    cfe/trunk/test/CodeGenCXX/anonymous-union-member-initializer.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=126540&r1=126539&r2=126540&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sat Feb 26 02:07:02 2011
@@ -1610,39 +1610,67 @@
   }
 }
 
-LValue CodeGenFunction::EmitLValueForField(llvm::Value *BaseValue,
-                                           const FieldDecl *Field,
-                                           unsigned CVRQualifiers) {
-  if (Field->isBitField())
-    return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers);
-
-  const CGRecordLayout &RL =
-    CGM.getTypes().getCGRecordLayout(Field->getParent());
-  unsigned idx = RL.getLLVMFieldNo(Field);
-  llvm::Value *V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
-
-  // Match union field type.
-  if (Field->getParent()->isUnion()) {
-    const llvm::Type *FieldTy =
-      CGM.getTypes().ConvertTypeForMem(Field->getType());
-    const llvm::PointerType *BaseTy =
-      cast<llvm::PointerType>(BaseValue->getType());
-    unsigned AS = BaseTy->getAddressSpace();
-    V = Builder.CreateBitCast(V,
-                              llvm::PointerType::get(FieldTy, AS),
-                              "tmp");
+LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
+                                           const FieldDecl *field,
+                                           unsigned cvr) {
+  if (field->isBitField())
+    return EmitLValueForBitfield(baseAddr, field, cvr);
+
+  const RecordDecl *rec = field->getParent();
+  QualType type = field->getType();
+
+  bool mayAlias = rec->hasAttr<MayAliasAttr>();
+
+  llvm::Value *addr;
+  if (rec->isUnion()) {
+    // For unions, we just cast to the appropriate type.
+    assert(!type->isReferenceType() && "union has reference member");
+
+    const llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(type);
+    unsigned AS =
+      cast<llvm::PointerType>(baseAddr->getType())->getAddressSpace();
+    addr = Builder.CreateBitCast(baseAddr, llvmType->getPointerTo(AS),
+                                 field->getName());
+  } else {
+    // For structs, we GEP to the field that the record layout suggests.
+    unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
+    addr = Builder.CreateStructGEP(baseAddr, idx, field->getName());
+
+    // If this is a reference field, load the reference right now.
+    if (const ReferenceType *refType = type->getAs<ReferenceType>()) {
+      llvm::LoadInst *load = Builder.CreateLoad(addr, "ref");
+      if (cvr & Qualifiers::Volatile) load->setVolatile(true);
+
+      if (CGM.shouldUseTBAA()) {
+        llvm::MDNode *tbaa;
+        if (mayAlias)
+          tbaa = CGM.getTBAAInfo(getContext().CharTy);
+        else
+          tbaa = CGM.getTBAAInfo(type);
+        CGM.DecorateInstruction(load, tbaa);
+      }
+
+      addr = load;
+      mayAlias = false;
+      type = refType->getPointeeType();
+      cvr = 0; // qualifiers don't recursively apply to referencee
+    }
   }
-  if (Field->getType()->isReferenceType())
-    V = Builder.CreateLoad(V, "tmp");
 
-  unsigned Alignment = getContext().getDeclAlign(Field).getQuantity();
-  LValue LV = MakeAddrLValue(V, Field->getType(), Alignment);
-  LV.getQuals().addCVRQualifiers(CVRQualifiers);
+  unsigned alignment = getContext().getDeclAlign(field).getQuantity();
+  LValue LV = MakeAddrLValue(addr, type, alignment);
+  LV.getQuals().addCVRQualifiers(cvr);
 
   // __weak attribute on a field is ignored.
   if (LV.getQuals().getObjCGCAttr() == Qualifiers::Weak)
     LV.getQuals().removeObjCGCAttr();
-  
+
+  // Fields of may_alias structs act like 'char' for TBAA purposes.
+  // FIXME: this should get propagated down through anonymous structs
+  // and unions.
+  if (mayAlias && LV.getTBAAInfo())
+    LV.setTBAAInfo(CGM.getTBAAInfo(getContext().CharTy));
+
   return LV;
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=126540&r1=126539&r2=126540&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sat Feb 26 02:07:02 2011
@@ -295,6 +295,8 @@
   const TargetCodeGenInfo &getTargetCodeGenInfo();
   bool isTargetDarwin() const;
 
+  bool shouldUseTBAA() const { return TBAA != 0; }
+
   llvm::MDNode *getTBAAInfo(QualType QTy);
 
   static void DecorateInstruction(llvm::Instruction *Inst,

Modified: cfe/trunk/test/CodeGen/may-alias.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/may-alias.c?rev=126540&r1=126539&r2=126540&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/may-alias.c (original)
+++ cfe/trunk/test/CodeGen/may-alias.c Sat Feb 26 02:07:02 2011
@@ -8,12 +8,21 @@
 
 void test0(aliasing_int *ai, int *i)
 {
+// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1
   *ai = 0;
+// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3
   *i = 1;
 }
 
-// CHECK: store i32 0, i32* %{{.*}}, !tbaa !1
-// CHECK: store i32 1, i32* %{{.*}}, !tbaa !3
+// PR9307
+struct Test1 { int x; };
+struct Test1MA { int x; } __attribute__((may_alias));
+void test1(struct Test1MA *p1, struct Test1 *p2) {
+  // CHECK: store i32 2, i32* {{%.*}}, !tbaa !1
+  p1->x = 2;
+  // CHECK: store i32 3, i32* {{%.*}}, !tbaa !3
+  p2->x = 3;
+}
 
 // CHECK: !0 = metadata !{metadata !"any pointer", metadata !1}
 // CHECK: !1 = metadata !{metadata !"omnipotent char", metadata !2}

Modified: cfe/trunk/test/CodeGenCXX/anonymous-union-member-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/anonymous-union-member-initializer.cpp?rev=126540&r1=126539&r2=126540&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/anonymous-union-member-initializer.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/anonymous-union-member-initializer.cpp Sat Feb 26 02:07:02 2011
@@ -84,11 +84,11 @@
   // CHECK: define void @_ZN5test31AC2Ev(
   // CHECK: [[THIS:%.*]] = load
   // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
-  // CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
+  // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to 
   // CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
   // CHECK-NEXT: store void (i8*)* null, void (i8*)** [[CALLBACK]]
   // CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
-  // CHECK-NEXT: [[STRUCT:%.*]] = getelementptr inbounds {{.*}} [[UNION]], i32 0, i32 0
+  // CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to 
   // CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
   // CHECK-NEXT: store i8* null, i8** [[CVALUE]]
 }





More information about the cfe-commits mailing list