summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-03-24 00:28:06 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-03-24 00:28:06 +0000
commit54355820e84776324dc9ea652718ca0571625ae9 (patch)
tree332c1eaf8d0a95d07fe10c9b891f288c966f20bf /clang/lib/CodeGen/CGExpr.cpp
parentef9f5504eaf0c2f8a365c75d9ed7bc6ff363a52e (diff)
downloadbcm5719-llvm-54355820e84776324dc9ea652718ca0571625ae9.tar.gz
bcm5719-llvm-54355820e84776324dc9ea652718ca0571625ae9.zip
Second part of PR12251. Produce the range metadata in clang for booleans and
c++ enums. llvm-svn: 153360
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp69
1 files changed, 61 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 30e3e7ad2cf..5a847a3b965 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -860,6 +860,61 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) {
lvalue.getType(), lvalue.getTBAAInfo());
}
+static bool hasBooleanRepresentation(QualType Ty) {
+ if (Ty->isBooleanType())
+ return true;
+
+ if (const EnumType *ET = Ty->getAs<EnumType>())
+ return ET->getDecl()->getIntegerType()->isBooleanType();
+
+ return false;
+}
+
+llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
+ const EnumType *ET = Ty->getAs<EnumType>();
+ bool IsRegularCPlusPlusEnum = getLangOpts().CPlusPlus && ET &&
+ !ET->getDecl()->isFixed();
+ bool IsBool = hasBooleanRepresentation(Ty);
+ llvm::Type *LTy;
+ if (!IsBool && !IsRegularCPlusPlusEnum)
+ return NULL;
+
+ uint64_t Min;
+ uint64_t End;
+ if (IsBool) {
+ Min = 0;
+ End = 2;
+ LTy = Int8Ty;
+ } else {
+ const EnumDecl *ED = ET->getDecl();
+ LTy = ConvertTypeForMem(ED->getIntegerType());
+ unsigned NumNegativeBits = ED->getNumNegativeBits();
+ unsigned NumPositiveBits = ED->getNumPositiveBits();
+
+ if (NumNegativeBits) {
+ unsigned NumBits = std::max(NumNegativeBits, NumPositiveBits + 1);
+ assert(NumBits <= 64);
+ End = 1ULL << (NumBits - 1);
+ Min = -End;
+ } else {
+ assert(NumPositiveBits <= 64);
+ if (NumPositiveBits == 64)
+ return NULL;
+ End = 1ULL << NumPositiveBits;
+ Min = 0;
+ }
+ }
+
+ assert(End != Min);
+ llvm::Value *LowAndHigh[2];
+ LowAndHigh[0] = llvm::ConstantInt::get(LTy, Min);
+ LowAndHigh[1] = llvm::ConstantInt::get(LTy, End);
+
+ llvm::LLVMContext &C = getLLVMContext();
+ llvm::MDNode *Range = llvm::MDNode::get(C, LowAndHigh);
+ return Range;
+}
+
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
unsigned Alignment, QualType Ty,
llvm::MDNode *TBAAInfo) {
@@ -874,18 +929,16 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
if (Ty->isAtomicType())
Load->setAtomic(llvm::SequentiallyConsistent);
- return EmitFromMemory(Load, Ty);
-}
+ if (CGM.getCodeGenOpts().OptimizationLevel > 0)
+ if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
+ Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
-static bool isBooleanUnderlyingType(QualType Ty) {
- if (const EnumType *ET = dyn_cast<EnumType>(Ty))
- return ET->getDecl()->getIntegerType()->isBooleanType();
- return false;
+ return EmitFromMemory(Load, Ty);
}
llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
// Bool has a different representation in memory than in registers.
- if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
+ if (hasBooleanRepresentation(Ty)) {
// This should really always be an i1, but sometimes it's already
// an i8, and it's awkward to track those cases down.
if (Value->getType()->isIntegerTy(1))
@@ -898,7 +951,7 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
// Bool has a different representation in memory than in registers.
- if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
+ if (hasBooleanRepresentation(Ty)) {
assert(Value->getType()->isIntegerTy(8) && "memory rep of bool not i8");
return Builder.CreateTrunc(Value, Builder.getInt1Ty(), "tobool");
}
OpenPOWER on IntegriCloud