[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