[cfe-commits] r124483 - in /cfe/trunk/lib/CodeGen: CGExprCXX.cpp CodeGenFunction.h

John McCall rjmccall at apple.com
Fri Jan 28 02:53:53 PST 2011


Author: rjmccall
Date: Fri Jan 28 04:53:53 2011
New Revision: 124483

URL: http://llvm.org/viewvc/llvm-project?rev=124483&view=rev
Log:
Reorganize the value-dominance metaprogram and introduce a specialization
for CodeGen's RValue type.


Modified:
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=124483&r1=124482&r2=124483&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Fri Jan 28 04:53:53 2011
@@ -721,101 +721,65 @@
   StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
 }
 
-namespace {
-/// A utility class for saving an rvalue.
-class SavedRValue {
-public:
-  enum Kind { ScalarLiteral, ScalarAddress,
-              AggregateLiteral, AggregateAddress,
-              Complex };
-
-private:
-  llvm::Value *Value;
-  Kind K;
-
-  SavedRValue(llvm::Value *V, Kind K) : Value(V), K(K) {}
-
-public:
-  SavedRValue() {}
-
-  static SavedRValue forScalarLiteral(llvm::Value *V) {
-    return SavedRValue(V, ScalarLiteral);
-  }
-
-  static SavedRValue forScalarAddress(llvm::Value *Addr) {
-    return SavedRValue(Addr, ScalarAddress);
-  }
-
-  static SavedRValue forAggregateLiteral(llvm::Value *V) {
-    return SavedRValue(V, AggregateLiteral);
-  }
-
-  static SavedRValue forAggregateAddress(llvm::Value *Addr) {
-    return SavedRValue(Addr, AggregateAddress);
-  }
-
-  static SavedRValue forComplexAddress(llvm::Value *Addr) {
-    return SavedRValue(Addr, Complex);
-  }
-
-  Kind getKind() const { return K; }
-  llvm::Value *getValue() const { return Value; }
-};
-} // end anonymous namespace
+bool DominatingValue<RValue>::saved_type::needsSaving(RValue rv) {
+  if (rv.isScalar())
+    return DominatingLLVMValue::needsSaving(rv.getScalarVal());
+  if (rv.isAggregate())
+    return DominatingLLVMValue::needsSaving(rv.getAggregateAddr());
+  return true;
+}
 
-/// Given an r-value, perform the code necessary to make sure that a
-/// future RestoreRValue will be able to load the value without
-/// domination concerns.
-static SavedRValue SaveRValue(CodeGenFunction &CGF, RValue RV) {
-  if (RV.isScalar()) {
-    llvm::Value *V = RV.getScalarVal();
+DominatingValue<RValue>::saved_type
+DominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {
+  if (rv.isScalar()) {
+    llvm::Value *V = rv.getScalarVal();
 
     // These automatically dominate and don't need to be saved.
-    if (isa<llvm::Constant>(V) || isa<llvm::AllocaInst>(V))
-      return SavedRValue::forScalarLiteral(V);
+    if (!DominatingLLVMValue::needsSaving(V))
+      return saved_type(V, ScalarLiteral);
 
     // Everything else needs an alloca.
-    llvm::Value *Addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
-    CGF.Builder.CreateStore(V, Addr);
-    return SavedRValue::forScalarAddress(Addr);
+    llvm::Value *addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
+    CGF.Builder.CreateStore(V, addr);
+    return saved_type(addr, ScalarAddress);
   }
 
-  if (RV.isComplex()) {
-    CodeGenFunction::ComplexPairTy V = RV.getComplexVal();
+  if (rv.isComplex()) {
+    CodeGenFunction::ComplexPairTy V = rv.getComplexVal();
     const llvm::Type *ComplexTy =
       llvm::StructType::get(CGF.getLLVMContext(),
                             V.first->getType(), V.second->getType(),
                             (void*) 0);
-    llvm::Value *Addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex");
-    CGF.StoreComplexToAddr(V, Addr, /*volatile*/ false);
-    return SavedRValue::forComplexAddress(Addr);
+    llvm::Value *addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex");
+    CGF.StoreComplexToAddr(V, addr, /*volatile*/ false);
+    return saved_type(addr, ComplexAddress);
   }
 
-  assert(RV.isAggregate());
-  llvm::Value *V = RV.getAggregateAddr(); // TODO: volatile?
-  if (isa<llvm::Constant>(V) || isa<llvm::AllocaInst>(V))
-    return SavedRValue::forAggregateLiteral(V);
-
-  llvm::Value *Addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
-  CGF.Builder.CreateStore(V, Addr);
-  return SavedRValue::forAggregateAddress(Addr);
+  assert(rv.isAggregate());
+  llvm::Value *V = rv.getAggregateAddr(); // TODO: volatile?
+  if (!DominatingLLVMValue::needsSaving(V))
+    return saved_type(V, AggregateLiteral);
+
+  llvm::Value *addr = CGF.CreateTempAlloca(V->getType(), "saved-rvalue");
+  CGF.Builder.CreateStore(V, addr);
+  return saved_type(addr, AggregateAddress);  
 }
 
 /// Given a saved r-value produced by SaveRValue, perform the code
 /// necessary to restore it to usability at the current insertion
 /// point.
-static RValue RestoreRValue(CodeGenFunction &CGF, SavedRValue RV) {
-  switch (RV.getKind()) {
-  case SavedRValue::ScalarLiteral:
-    return RValue::get(RV.getValue());
-  case SavedRValue::ScalarAddress:
-    return RValue::get(CGF.Builder.CreateLoad(RV.getValue()));
-  case SavedRValue::AggregateLiteral:
-    return RValue::getAggregate(RV.getValue());
-  case SavedRValue::AggregateAddress:
-    return RValue::getAggregate(CGF.Builder.CreateLoad(RV.getValue()));
-  case SavedRValue::Complex:
-    return RValue::getComplex(CGF.LoadComplexFromAddr(RV.getValue(), false));
+RValue DominatingValue<RValue>::saved_type::restore(CodeGenFunction &CGF) {
+  switch (K) {
+  case ScalarLiteral:
+    return RValue::get(Value);
+  case ScalarAddress:
+    return RValue::get(CGF.Builder.CreateLoad(Value));
+  case AggregateLiteral:
+    return RValue::getAggregate(Value);
+  case AggregateAddress:
+    return RValue::getAggregate(CGF.Builder.CreateLoad(Value));
+  case ComplexAddress:
+    return RValue::getComplex(CGF.LoadComplexFromAddr(Value, false));
   }
 
   llvm_unreachable("bad saved r-value kind");
@@ -883,26 +847,26 @@
   class CallDeleteDuringConditionalNew : public EHScopeStack::Cleanup {
     size_t NumPlacementArgs;
     const FunctionDecl *OperatorDelete;
-    SavedRValue Ptr;
-    SavedRValue AllocSize;
+    DominatingValue<RValue>::saved_type Ptr;
+    DominatingValue<RValue>::saved_type AllocSize;
 
-    SavedRValue *getPlacementArgs() {
-      return reinterpret_cast<SavedRValue*>(this+1);
+    DominatingValue<RValue>::saved_type *getPlacementArgs() {
+      return reinterpret_cast<DominatingValue<RValue>::saved_type*>(this+1);
     }
 
   public:
     static size_t getExtraSize(size_t NumPlacementArgs) {
-      return NumPlacementArgs * sizeof(SavedRValue);
+      return NumPlacementArgs * sizeof(DominatingValue<RValue>::saved_type);
     }
 
     CallDeleteDuringConditionalNew(size_t NumPlacementArgs,
                                    const FunctionDecl *OperatorDelete,
-                                   SavedRValue Ptr,
-                                   SavedRValue AllocSize) 
+                                   DominatingValue<RValue>::saved_type Ptr,
+                              DominatingValue<RValue>::saved_type AllocSize)
       : NumPlacementArgs(NumPlacementArgs), OperatorDelete(OperatorDelete),
         Ptr(Ptr), AllocSize(AllocSize) {}
 
-    void setPlacementArg(unsigned I, SavedRValue Arg) {
+    void setPlacementArg(unsigned I, DominatingValue<RValue>::saved_type Arg) {
       assert(I < NumPlacementArgs && "index out of range");
       getPlacementArgs()[I] = Arg;
     }
@@ -917,17 +881,17 @@
 
       // The first argument is always a void*.
       FunctionProtoType::arg_type_iterator AI = FPT->arg_type_begin();
-      DeleteArgs.push_back(std::make_pair(RestoreRValue(CGF, Ptr), *AI++));
+      DeleteArgs.push_back(std::make_pair(Ptr.restore(CGF), *AI++));
 
       // A member 'operator delete' can take an extra 'size_t' argument.
       if (FPT->getNumArgs() == NumPlacementArgs + 2) {
-        RValue RV = RestoreRValue(CGF, AllocSize);
+        RValue RV = AllocSize.restore(CGF);
         DeleteArgs.push_back(std::make_pair(RV, *AI++));
       }
 
       // Pass the rest of the arguments, which must match exactly.
       for (unsigned I = 0; I != NumPlacementArgs; ++I) {
-        RValue RV = RestoreRValue(CGF, getPlacementArgs()[I]);
+        RValue RV = getPlacementArgs()[I].restore(CGF);
         DeleteArgs.push_back(std::make_pair(RV, *AI++));
       }
 
@@ -961,8 +925,10 @@
   }
 
   // Otherwise, we need to save all this stuff.
-  SavedRValue SavedNewPtr = SaveRValue(CGF, RValue::get(NewPtr));
-  SavedRValue SavedAllocSize = SaveRValue(CGF, RValue::get(AllocSize));
+  DominatingValue<RValue>::saved_type SavedNewPtr =
+    DominatingValue<RValue>::save(CGF, RValue::get(NewPtr));
+  DominatingValue<RValue>::saved_type SavedAllocSize =
+    DominatingValue<RValue>::save(CGF, RValue::get(AllocSize));
 
   CallDeleteDuringConditionalNew *Cleanup = CGF.EHStack
     .pushCleanupWithExtra<CallDeleteDuringConditionalNew>(InactiveEHCleanup,
@@ -971,7 +937,8 @@
                                                  SavedNewPtr,
                                                  SavedAllocSize);
   for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I)
-    Cleanup->setPlacementArg(I, SaveRValue(CGF, NewArgs[I+1].first));
+    Cleanup->setPlacementArg(I,
+                     DominatingValue<RValue>::save(CGF, NewArgs[I+1].first));
 
   CGF.ActivateCleanupBlock(CGF.EHStack.stable_begin());
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=124483&r1=124482&r2=124483&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Jan 28 04:53:53 2011
@@ -97,26 +97,27 @@
   llvm::BranchInst *InitialBranch;
 };
 
-/// A metaprogramming class which decides whether a type is a subclass
-/// of llvm::Value that needs to be saved if it's used in a
-/// conditional cleanup.
-template
-  <class T,
-   bool mustSave =
-     llvm::is_base_of<llvm::Value,
-                      typename llvm::remove_pointer<T>::type>::value
-     && !llvm::is_base_of<llvm::Constant,
-                          typename llvm::remove_pointer<T>::type>::value
-     && !llvm::is_base_of<llvm::BasicBlock,
-                          typename llvm::remove_pointer<T>::type>::value>
-struct SavedValueInCond {
+template <class T> struct InvariantValue {
   typedef T type;
   typedef T saved_type;
   static bool needsSaving(type value) { return false; }
   static saved_type save(CodeGenFunction &CGF, type value) { return value; }
   static type restore(CodeGenFunction &CGF, saved_type value) { return value; }
 };
-// Partial specialization for true arguments at end of file.
+
+/// A metaprogramming class for ensuring that a value will dominate an
+/// arbitrary position in a function.
+template <class T> struct DominatingValue : InvariantValue<T> {};
+
+template <class T, bool mightBeInstruction =
+            llvm::is_base_of<llvm::Value, T>::value &&
+            !llvm::is_base_of<llvm::Constant, T>::value &&
+            !llvm::is_base_of<llvm::BasicBlock, T>::value>
+struct DominatingPointer;
+template <class T> struct DominatingPointer<T,false> : InvariantValue<T*> {};
+// template <class T> struct DominatingPointer<T,true> at end of file
+
+template <class T> struct DominatingValue<T*> : DominatingPointer<T> {};
 
 enum CleanupKind {
   EHCleanup = 0x1,
@@ -222,11 +223,11 @@
   /// then restores them and performs the cleanup.
   template <class T, class A0>
   class ConditionalCleanup1 : public Cleanup {
-    typedef typename SavedValueInCond<A0>::saved_type A0_saved;
+    typedef typename DominatingValue<A0>::saved_type A0_saved;
     A0_saved a0_saved;
 
     void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
-      A0 a0 = SavedValueInCond<A0>::restore(CGF, a0_saved);
+      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
       T::Emit(CGF, IsForEHCleanup, a0);
     }
 
@@ -237,14 +238,14 @@
 
   template <class T, class A0, class A1>
   class ConditionalCleanup2 : public Cleanup {
-    typedef typename SavedValueInCond<A0>::saved_type A0_saved;
-    typedef typename SavedValueInCond<A1>::saved_type A1_saved;
+    typedef typename DominatingValue<A0>::saved_type A0_saved;
+    typedef typename DominatingValue<A1>::saved_type A1_saved;
     A0_saved a0_saved;
     A1_saved a1_saved;
 
     void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
-      A0 a0 = SavedValueInCond<A0>::restore(CGF, a0_saved);
-      A1 a1 = SavedValueInCond<A1>::restore(CGF, a1_saved);
+      A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
+      A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
       T::Emit(CGF, IsForEHCleanup, a0, a1);
     }
 
@@ -619,8 +620,8 @@
   void initFullExprCleanup();
 
   template <class T>
-  typename SavedValueInCond<T>::saved_type saveValueInCond(T value) {
-    return SavedValueInCond<T>::save(*this, value);
+  typename DominatingValue<T>::saved_type saveValueInCond(T value) {
+    return DominatingValue<T>::save(*this, value);
   }
 
 public:
@@ -651,7 +652,7 @@
       return EHStack.pushCleanup<CleanupType>(kind, a0);
     }
 
-    typename SavedValueInCond<A0>::saved_type a0_saved = saveValueInCond(a0);
+    typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
 
     typedef EHScopeStack::ConditionalCleanup1<T, A0> CleanupType;
     EHStack.pushCleanup<CleanupType>(kind, a0_saved);
@@ -670,8 +671,8 @@
       return EHStack.pushCleanup<CleanupType>(kind, a0, a1);
     }
 
-    typename SavedValueInCond<A0>::saved_type a0_saved = saveValueInCond(a0);
-    typename SavedValueInCond<A1>::saved_type a1_saved = saveValueInCond(a1);
+    typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
+    typename DominatingValue<A1>::saved_type a1_saved = saveValueInCond(a1);
 
     typedef EHScopeStack::ConditionalCleanup2<T, A0, A1> CleanupType;
     EHStack.pushCleanup<CleanupType>(kind, a0_saved, a1_saved);
@@ -1946,7 +1947,7 @@
 
 /// Helper class with most of the code for saving a value for a
 /// conditional expression cleanup.
-struct SavedValueInCondImpl {
+struct DominatingLLVMValue {
   typedef llvm::PointerIntPair<llvm::Value*, 1, bool> saved_type;
 
   /// Answer whether the given value needs extra work to be saved.
@@ -1977,12 +1978,42 @@
   }
 };
 
-/// Partial specialization of SavedValueInCond for when a value really
-/// requires saving.
-template <class T> struct SavedValueInCond<T,true> : SavedValueInCondImpl {
-  typedef T type;
+/// A partial specialization of DominatingValue for llvm::Values that
+/// might be llvm::Instructions.
+template <class T> struct DominatingPointer<T,true> : DominatingLLVMValue {
+  typedef T *type;
+  static type restore(CodeGenFunction &CGF, saved_type value) {
+    return static_cast<T*>(DominatingLLVMValue::restore(CGF, value));
+  }
+};
+
+/// A specialization of DominatingValue for RValue.
+template <> struct DominatingValue<RValue> {
+  typedef RValue type;
+  class saved_type {
+    enum Kind { ScalarLiteral, ScalarAddress, AggregateLiteral,
+                AggregateAddress, ComplexAddress };
+
+    llvm::Value *Value;
+    Kind K;
+    saved_type(llvm::Value *v, Kind k) : Value(v), K(k) {}
+
+  public:
+    static bool needsSaving(RValue value);
+    static saved_type save(CodeGenFunction &CGF, RValue value);
+    RValue restore(CodeGenFunction &CGF);
+
+    // implementations in CGExprCXX.cpp
+  };
+
+  static bool needsSaving(type value) {
+    return saved_type::needsSaving(value);
+  }
+  static saved_type save(CodeGenFunction &CGF, type value) {
+    return saved_type::save(CGF, value);
+  }
   static type restore(CodeGenFunction &CGF, saved_type value) {
-    return static_cast<T>(SavedValueInCondImpl::restore(CGF, value));
+    return value.restore(CGF);
   }
 };
 





More information about the cfe-commits mailing list