зеркало из https://github.com/microsoft/clang-1.git
Fixup codegen for volatile structs in the trivial cases (a a=a and a=a=a).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2f1735c643
Коммит
49d1cd5a09
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче