Constant expression evaluation refactoring:
- Remodel Expr::EvaluateAsInt to behave like the other EvaluateAs* functions,
and add Expr::EvaluateKnownConstInt to capture the current fold-or-assert
behaviour.
- Factor out evaluation of bitfield bit widths.
- Fix a few places which would evaluate an expression twice: once to determine
whether it is a constant expression, then again to get the value.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141561 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 3ec4efe..f7179be 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -548,11 +548,10 @@
case Builtin::BI__builtin___memcpy_chk: {
// fold __builtin_memcpy_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
- if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
- !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ llvm::APSInt Size, DstSize;
+ if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
+ !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
break;
- llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
- llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
if (Size.ugt(DstSize))
break;
Value *Dest = EmitScalarExpr(E->getArg(0));
@@ -573,11 +572,10 @@
case Builtin::BI__builtin___memmove_chk: {
// fold __builtin_memmove_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
- if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
- !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ llvm::APSInt Size, DstSize;
+ if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
+ !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
break;
- llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
- llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
if (Size.ugt(DstSize))
break;
Value *Dest = EmitScalarExpr(E->getArg(0));
@@ -606,11 +604,10 @@
}
case Builtin::BI__builtin___memset_chk: {
// fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
- if (!E->getArg(2)->isEvaluatable(CGM.getContext()) ||
- !E->getArg(3)->isEvaluatable(CGM.getContext()))
+ llvm::APSInt Size, DstSize;
+ if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
+ !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
break;
- llvm::APSInt Size = E->getArg(2)->EvaluateAsInt(CGM.getContext());
- llvm::APSInt DstSize = E->getArg(3)->EvaluateAsInt(CGM.getContext());
if (Size.ugt(DstSize))
break;
Value *Address = EmitScalarExpr(E->getArg(0));
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index eda7325..313c02d 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -603,7 +603,7 @@
llvm::DIType CGDebugInfo::createFieldType(StringRef name,
QualType type,
- Expr *bitWidth,
+ uint64_t sizeInBitsOverride,
SourceLocation loc,
AccessSpecifier AS,
uint64_t offsetInBits,
@@ -620,8 +620,8 @@
if (!type->isIncompleteArrayType()) {
llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
- if (bitWidth)
- sizeInBits = bitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+ if (sizeInBitsOverride)
+ sizeInBits = sizeInBitsOverride;
}
unsigned flags = 0;
@@ -667,8 +667,14 @@
continue;
}
+ uint64_t SizeInBitsOverride = 0;
+ if (field->isBitField()) {
+ SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
+ assert(SizeInBitsOverride && "found named 0-width bitfield");
+ }
+
llvm::DIType fieldType
- = createFieldType(name, type, field->getBitWidth(),
+ = createFieldType(name, type, SizeInBitsOverride,
field->getLocation(), field->getAccess(),
layout.getFieldOffset(fieldNo), tunit, RecordTy);
@@ -1215,12 +1221,10 @@
if (!FType->isIncompleteArrayType()) {
// Bit size, align and offset of the type.
- FieldSize = CGM.getContext().getTypeSize(FType);
- Expr *BitWidth = Field->getBitWidth();
- if (BitWidth)
- FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
-
- FieldAlign = CGM.getContext().getTypeAlign(FType);
+ FieldSize = Field->isBitField()
+ ? Field->getBitWidthValue(CGM.getContext())
+ : CGM.getContext().getTypeSize(FType);
+ FieldAlign = CGM.getContext().getTypeAlign(FType);
}
// We can't know the offset of our ivar in the structure if we're using
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 68b3985..e6c701a 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -139,7 +139,7 @@
llvm::DIFile F);
llvm::DIType createFieldType(StringRef name, QualType type,
- Expr *bitWidth, SourceLocation loc,
+ uint64_t sizeInBitsOverride, SourceLocation loc,
AccessSpecifier AS, uint64_t offsetInBits,
llvm::DIFile tunit,
llvm::DIDescriptor scope);
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 1176eb1..30c978e 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -143,8 +143,7 @@
AppendPadding(PadSize);
}
- uint64_t FieldSize =
- Field->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+ uint64_t FieldSize = Field->getBitWidthValue(Context);
llvm::APInt FieldValue = CI->getValue();
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 1b317c4..308e0c7 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -3710,9 +3710,8 @@
if (LastFieldBitfieldOrUnnamed) {
if (LastFieldBitfieldOrUnnamed->isBitField()) {
// Last field was a bitfield. Must update skip info.
- Expr *BitWidth = LastFieldBitfieldOrUnnamed->getBitWidth();
- uint64_t BitFieldSize =
- BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+ uint64_t BitFieldSize
+ = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
GC_IVAR skivar;
skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index f1e49ac..ef426ce 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -119,8 +119,7 @@
uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
uint64_t ContainingTypeAlign = CGF.CGM.getContext().getTargetInfo().getCharAlign();
uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset);
- uint64_t BitFieldSize =
- Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
+ uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());
// Allocate a new CGBitFieldInfo object to describe this access.
//
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index d55ea51..6475cca 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -363,8 +363,7 @@
void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
uint64_t fieldOffset) {
- uint64_t fieldSize =
- D->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
+ uint64_t fieldSize = D->getBitWidthValue(Types.getContext());
if (fieldSize == 0)
return;
@@ -492,8 +491,7 @@
CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
const ASTRecordLayout &Layout) {
if (Field->isBitField()) {
- uint64_t FieldSize =
- Field->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
+ uint64_t FieldSize = Field->getBitWidthValue(Types.getContext());
// Ignore zero sized bit fields.
if (FieldSize == 0)
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index ec876a4..06a045f 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -834,8 +834,8 @@
void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
assert(S.getRHS() && "Expected RHS value in CaseStmt");
- llvm::APSInt LHS = S.getLHS()->EvaluateAsInt(getContext());
- llvm::APSInt RHS = S.getRHS()->EvaluateAsInt(getContext());
+ llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext());
+ llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext());
// Emit the code for this case. We do this first to make sure it is
// properly chained from our predecessor before generating the
@@ -894,7 +894,7 @@
}
llvm::ConstantInt *CaseVal =
- Builder.getInt(S.getLHS()->EvaluateAsInt(getContext()));
+ Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
// If the body of the case is just a 'break', and if there was no fallthrough,
// try to not emit an empty block.
@@ -935,7 +935,7 @@
while (NextCase && NextCase->getRHS() == 0) {
CurCase = NextCase;
llvm::ConstantInt *CaseVal =
- Builder.getInt(CurCase->getLHS()->EvaluateAsInt(getContext()));
+ Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext()));
SwitchInsn->addCase(CaseVal, CaseDest);
NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt());
}
@@ -1125,7 +1125,7 @@
if (CS->getRHS()) return false;
// If we found our case, remember it as 'case'.
- if (CS->getLHS()->EvaluateAsInt(C) == ConstantCondValue)
+ if (CS->getLHS()->EvaluateKnownConstInt(C) == ConstantCondValue)
break;
}
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index ce729ce..97f9b71 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -1337,8 +1337,7 @@
continue;
uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
- uint64_t Size =
- i->getBitWidth()->EvaluateAsInt(getContext()).getZExtValue();
+ uint64_t Size = i->getBitWidthValue(getContext());
uint64_t EB_Lo = Offset / 64;
uint64_t EB_Hi = (Offset + Size - 1) / 64;