[cfe-commits] r152455 - in /cfe/trunk: include/clang/AST/APValue.h lib/AST/APValue.cpp lib/AST/ExprConstant.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Fri Mar 9 16:28:11 PST 2012
Author: rsmith
Date: Fri Mar 9 18:28:11 2012
New Revision: 152455
URL: http://llvm.org/viewvc/llvm-project?rev=152455&view=rev
Log:
Assign APValues by swapping from a temporary. Removes a bunch of unnecessary
copy-construction, which Daniel Dunbar reports as giving a 0.75% speedup on
403.gcc/combine.c. The performance differences on my constexpr torture tests
are below the noise floor.
Modified:
cfe/trunk/include/clang/AST/APValue.h
cfe/trunk/lib/AST/APValue.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
Modified: cfe/trunk/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=152455&r1=152454&r2=152455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/APValue.h (original)
+++ cfe/trunk/include/clang/AST/APValue.h Fri Mar 9 18:28:11 2012
@@ -135,9 +135,7 @@
APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
MakeComplexFloat(); setComplexFloat(R, I);
}
- APValue(const APValue &RHS) : Kind(Uninitialized) {
- *this = RHS;
- }
+ APValue(const APValue &RHS);
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, N, CallIndex);
@@ -170,6 +168,9 @@
MakeUninit();
}
+ /// \brief Swaps the contents of this and the given APValue.
+ void swap(APValue &RHS);
+
ValueKind getKind() const { return Kind; }
bool isUninit() const { return Kind == Uninitialized; }
bool isInt() const { return Kind == Int; }
@@ -382,7 +383,11 @@
((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
}
- const APValue &operator=(const APValue &RHS);
+ /// Assign by swapping from a copy of the RHS.
+ APValue &operator=(APValue RHS) {
+ swap(RHS);
+ return *this;
+ }
private:
void DestroyDataAndMakeUninit();
Modified: cfe/trunk/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=152455&r1=152454&r2=152455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/APValue.cpp (original)
+++ cfe/trunk/lib/AST/APValue.cpp Fri Mar 9 18:28:11 2012
@@ -122,71 +122,68 @@
delete Value;
}
-const APValue &APValue::operator=(const APValue &RHS) {
- if (this == &RHS)
- return *this;
- if (Kind != RHS.Kind || Kind == Array || Kind == Struct ||
- Kind == MemberPointer) {
- MakeUninit();
- if (RHS.isInt())
- MakeInt();
- else if (RHS.isFloat())
- MakeFloat();
- else if (RHS.isVector())
- MakeVector();
- else if (RHS.isComplexInt())
- MakeComplexInt();
- else if (RHS.isComplexFloat())
- MakeComplexFloat();
- else if (RHS.isLValue())
- MakeLValue();
- else if (RHS.isArray())
- MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
- else if (RHS.isStruct())
- MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
- else if (RHS.isUnion())
- MakeUnion();
- else if (RHS.isMemberPointer())
- MakeMemberPointer(RHS.getMemberPointerDecl(),
- RHS.isMemberPointerToDerivedMember(),
- RHS.getMemberPointerPath());
- else if (RHS.isAddrLabelDiff())
- MakeAddrLabelDiff();
- }
- if (isInt())
+APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
+ switch (RHS.getKind()) {
+ case Uninitialized:
+ break;
+ case Int:
+ MakeInt();
setInt(RHS.getInt());
- else if (isFloat())
+ break;
+ case Float:
+ MakeFloat();
setFloat(RHS.getFloat());
- else if (isVector())
+ break;
+ case Vector:
+ MakeVector();
setVector(((const Vec *)(const char *)RHS.Data)->Elts,
RHS.getVectorLength());
- else if (isComplexInt())
+ break;
+ case ComplexInt:
+ MakeComplexInt();
setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
- else if (isComplexFloat())
+ break;
+ case ComplexFloat:
+ MakeComplexFloat();
setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
- else if (isLValue()) {
+ break;
+ case LValue:
+ MakeLValue();
if (RHS.hasLValuePath())
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
else
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
RHS.getLValueCallIndex());
- } else if (isArray()) {
+ break;
+ case Array:
+ MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
if (RHS.hasArrayFiller())
getArrayFiller() = RHS.getArrayFiller();
- } else if (isStruct()) {
+ break;
+ case Struct:
+ MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
getStructBase(I) = RHS.getStructBase(I);
for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
getStructField(I) = RHS.getStructField(I);
- } else if (isUnion()) {
+ break;
+ case Union:
+ MakeUnion();
setUnion(RHS.getUnionField(), RHS.getUnionValue());
- } else if (isAddrLabelDiff()) {
+ break;
+ case MemberPointer:
+ MakeMemberPointer(RHS.getMemberPointerDecl(),
+ RHS.isMemberPointerToDerivedMember(),
+ RHS.getMemberPointerPath());
+ break;
+ case AddrLabelDiff:
+ MakeAddrLabelDiff();
setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
+ break;
}
- return *this;
}
void APValue::DestroyDataAndMakeUninit() {
@@ -215,6 +212,14 @@
Kind = Uninitialized;
}
+void APValue::swap(APValue &RHS) {
+ std::swap(Kind, RHS.Kind);
+ char TmpData[MaxSize];
+ memcpy(TmpData, Data, MaxSize);
+ memcpy(Data, RHS.Data, MaxSize);
+ memcpy(RHS.Data, TmpData, MaxSize);
+}
+
void APValue::dump() const {
dump(llvm::errs());
llvm::errs() << '\n';
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=152455&r1=152454&r2=152455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Mar 9 18:28:11 2012
@@ -1518,7 +1518,7 @@
// This object might be initialized later.
return false;
- const APValue *O = &Obj;
+ APValue *O = &Obj;
// Walk the designator's path to find the subobject.
for (unsigned I = 0, N = Sub.Entries.size(); I != N; ++I) {
if (ObjType->isArrayType()) {
@@ -1616,7 +1616,13 @@
}
}
- Obj = APValue(*O);
+ // This may look super-stupid, but it serves an important purpose: if we just
+ // swapped Obj and *O, we'd create an object which had itself as a subobject.
+ // To avoid the leak, we ensure that Tmp ends up owning the original complete
+ // object, which is destroyed by Tmp's destructor.
+ APValue Tmp;
+ O->swap(Tmp);
+ Obj.swap(Tmp);
return true;
}
More information about the cfe-commits
mailing list