]> granicus.if.org Git - clang/commitdiff
Fixup codegen for volatile structs in the trivial cases (a a=a and a=a=a).
authorMike Stump <mrs@apple.com>
Tue, 26 May 2009 22:03:21 +0000 (22:03 +0000)
committerMike Stump <mrs@apple.com>
Tue, 26 May 2009 22:03:21 +0000 (22:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72439 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/volatile.c

index 559bd4c60bcf825018c3b7cbcd017fe1e6b7da0b..ad96d2e573dda902306f6754a71d97b8b4087f7d 100644 (file)
@@ -49,13 +49,13 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
 /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
 /// the result should be returned.
 RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc, 
-                                    bool isAggLocVolatile) {
+                                    bool isAggLocVolatile, bool IgnoreResult) {
   if (!hasAggregateLLVMType(E->getType()))
     return RValue::get(EmitScalarExpr(E));
   else if (E->getType()->isAnyComplexType())
     return RValue::getComplex(EmitComplexExpr(E));
   
-  EmitAggExpr(E, AggLoc, isAggLocVolatile);
+  EmitAggExpr(E, AggLoc, isAggLocVolatile, IgnoreResult);
   return RValue::getAggregate(AggLoc, isAggLocVolatile);
 }
 
index c558d137e2c8edaaa932c756704149e0a53b35f2..2a3e21f806d26d08d8bb40a011bae78a1edb4d80 100644 (file)
@@ -34,10 +34,13 @@ class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
   CGBuilderTy &Builder;
   llvm::Value *DestPtr;
   bool VolatileDest;
+  bool IgnoreResult;
+
 public:
-  AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest)
+  AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool volatileDest,
+                 bool IgnoreResult)
     : CGF(cgf), Builder(CGF.Builder),
-      DestPtr(destPtr), VolatileDest(volatileDest) {
+      DestPtr(destPtr), VolatileDest(volatileDest), IgnoreResult(IgnoreResult) {
   }
 
   //===--------------------------------------------------------------------===//
@@ -50,8 +53,8 @@ public:
   void EmitAggLoadOfLValue(const Expr *E);
 
   /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-  void EmitFinalDestCopy(const Expr *E, LValue Src);
-  void EmitFinalDestCopy(const Expr *E, RValue Src);
+  void EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore = false);
+  void EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore = false);
 
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
@@ -127,17 +130,16 @@ void AggExprEmitter::EmitAggLoadOfLValue(const Expr *E) {
 }
 
 /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src) {
+void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
   assert(Src.isAggregate() && "value must be aggregate value!");
 
   // If the result is ignored, don't copy from the value.
   if (DestPtr == 0) {
-    if (Src.isVolatileQualified())
-      // If the source is volatile, we must read from it; to do that, we need
-      // some place to put it.
-      DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp");
-    else
+    if (!Src.isVolatileQualified() || (IgnoreResult && Ignore))
       return;
+    // If the source is volatile, we must read from it; to do that, we need
+    // some place to put it.
+    DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp");
   }
 
   // If the result of the assignment is used, copy the LHS there also.
@@ -149,11 +151,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src) {
 }
 
 /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
-void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src) {
+void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
   assert(Src.isSimple() && "Can't have aggregate bitfield, vector, etc");
 
   EmitFinalDestCopy(E, RValue::getAggregate(Src.getAddress(),
-                                            Src.isVolatileQualified()));
+                                            Src.isVolatileQualified()),
+                    Ignore);
 }
 
 //===----------------------------------------------------------------------===//
@@ -244,7 +247,7 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
   } else {
     // Codegen the RHS so that it stores directly into the LHS.
     CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified());
-    EmitFinalDestCopy(E, LHS);
+    EmitFinalDestCopy(E, LHS, true);
   }
 }
 
@@ -470,13 +473,14 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
 /// the value of the aggregate expression is not needed.  If VolatileDest is
 /// true, DestPtr cannot be 0.
 void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
-                                  bool VolatileDest) {
+                                  bool VolatileDest, bool IgnoreResult) {
   assert(E && hasAggregateLLVMType(E->getType()) &&
          "Invalid aggregate expression to emit");
   assert ((DestPtr != 0 || VolatileDest == false)
           && "volatile aggregate can't be 0");
   
-  AggExprEmitter(*this, DestPtr, VolatileDest).Visit(const_cast<Expr*>(E));
+  AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult)
+    .Visit(const_cast<Expr*>(E));
 }
 
 void CodeGenFunction::EmitAggregateClear(llvm::Value *DestPtr, QualType Ty) {
@@ -522,9 +526,8 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
   //   a = b;
   // }
   //
-  // either, we need to use a differnt call here, or the backend needs to be
-  // taught to not do this.  We use isVolatile to indicate when either the
-  // source or the destination is volatile.
+  // we need to use a differnt call here.  We use isVolatile to indicate when
+  // either the source or the destination is volatile.
   Builder.CreateCall4(CGM.getMemCpyFn(),
                       DestPtr, SrcPtr,
                       // TypeInfo.first describes size in bits.
index da586b1d74c917dccc67b3d9112e2fef91bf2dfd..b13b9e529d3c7e8a65c2e54858a52a6c1f578ba6 100644 (file)
@@ -58,7 +58,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
     // Must be an expression in a stmt context.  Emit the value (to get
     // side-effects) and ignore the result.
     if (const Expr *E = dyn_cast<Expr>(S)) {
-      EmitAnyExpr(E);
+      EmitAnyExpr(E, 0, false, true);
     } else {
       ErrorUnsupported(S, "statement");
     }
index 9a9ca05768670a255a06f42469b346514dca8e4b..d87fbcdeb5d344ed3e8cddff639232004bfd3a80 100644 (file)
@@ -407,8 +407,10 @@ public:
   /// any type.  The result is returned as an RValue struct.  If this is an
   /// aggregate expression, the aggloc/agglocvolatile arguments indicate where
   /// the result should be returned.
+  ///
+  /// \param IgnoreResult - True if the resulting value isn't used.
   RValue EmitAnyExpr(const Expr *E, llvm::Value *AggLoc = 0,
-                     bool isAggLocVolatile = false);
+                     bool isAggLocVolatile = false, bool IgnoreResult = false);
 
   // EmitVAListRef - Emit a "reference" to a va_list; this is either the address
   // or the value of the expression, depending on how va_list is defined.
@@ -741,7 +743,8 @@ public:
   /// EmitAggExpr - Emit the computation of the specified expression of
   /// aggregate type.  The result is computed into DestPtr.  Note that if
   /// DestPtr is null, the value of the aggregate expression is not needed.
-  void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest);
+  void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest,
+                   bool IgnoreResult = false);
 
   /// EmitComplexExpr - Emit the computation of the specified expression of
   /// complex type, returning the result.
index 9ee4de601cefadb4ba445348997fa3b9e6533b4b..c89a72bfeff55ac4b5e16e3dc87a94fad594070c 100644 (file)
@@ -1,4 +1,6 @@
-// RUN: clang-cc -emit-llvm < %s | grep volatile | count 25
+// RUN: clang-cc -emit-llvm < %s -o %t &&
+// RUN: grep volatile %t | count 25 &&
+// RUN: grep memcpy %t | count 5
 
 // The number 26 comes from the current codegen for volatile loads;
 // if this number changes, it's not necessarily something wrong, but
@@ -85,4 +87,7 @@ void main() {
   ++vS;
   i+=S;
   i+=vS;
+  (void)vF2;
+  vF2 = vF2;
+  vF2 = vF2 = vF2;
 }