Fixup codegen for volatile structs in the trivial cases (a a=a and a=a=a).

llvm-svn: 72439
This commit is contained in:
Mike Stump 2009-05-26 22:03:21 +00:00
parent c44ba89397
commit ec3cbfe8c6
5 changed files with 35 additions and 24 deletions

View 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);
}

View 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.

View 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");
}

View 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.

View 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;
}