r312835 - CodeGen: correct arguments for NSFastEnumeration
Saleem Abdulrasool via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 8 16:41:17 PDT 2017
Author: compnerd
Date: Fri Sep 8 16:41:17 2017
New Revision: 312835
URL: http://llvm.org/viewvc/llvm-project?rev=312835&view=rev
Log:
CodeGen: correct arguments for NSFastEnumeration
When performing a NSFastEnumeration, the compiler synthesizes a call to
`countByEnumeratingWithState:objects:count:` where the `count` parameter
is of type `NSUInteger` and the return type is a `NSUInteger`. We would
previously always use a `UnsignedLongTy` for the `NSUInteger` type. On
32-bit targets, `long` is 32-bits which is the same as `unsigned int`.
Most 64-bit targets are LP64, where `long` is 64-bits. However, on
LLP64 targets, such as Windows, `long` is 32-bits. Introduce new
`getNSUIntegerType` and `getNSIntegerType` helpers to allow us to
determine the correct type for the `NSUInteger` type. Wire those
through into the generation of the message dispatch to the selector.
Added:
cfe/trunk/test/CodeGenObjC/NSFastEnumeration.m
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/CodeGen/CGObjC.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=312835&r1=312834&r2=312835&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Sep 8 16:41:17 2017
@@ -39,6 +39,7 @@
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/XRayLists.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
@@ -89,7 +90,6 @@ class DiagnosticsEngine;
class Expr;
class MangleNumberingContext;
class MaterializeTemporaryExpr;
-class TargetInfo;
// Decls
class MangleContext;
class ObjCIvarDecl;
@@ -1582,6 +1582,24 @@ public:
return NSCopyingName;
}
+ CanQualType getNSUIntegerType() const {
+ assert(Target && "Expected target to be initialized");
+ const llvm::Triple &T = Target->getTriple();
+ // Windows is LLP64 rather than LP64
+ if (T.isOSWindows() && T.isArch64Bit())
+ return UnsignedLongLongTy;
+ return UnsignedLongTy;
+ }
+
+ CanQualType getNSIntegerType() const {
+ assert(Target && "Expected target to be initialized");
+ const llvm::Triple &T = Target->getTriple();
+ // Windows is LLP64 rather than LP64
+ if (T.isOSWindows() && T.isArch64Bit())
+ return LongLongTy;
+ return LongTy;
+ }
+
/// Retrieve the identifier 'bool'.
IdentifierInfo *getBoolName() const {
if (!BoolName)
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=312835&r1=312834&r2=312835&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Fri Sep 8 16:41:17 2017
@@ -1546,16 +1546,15 @@ void CodeGenFunction::EmitObjCForCollect
getContext().getPointerType(ItemsTy));
// The third argument is the capacity of that temporary array.
- llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
- llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
- Args.add(RValue::get(Count), getContext().UnsignedLongTy);
+ llvm::Type *NSUIntegerTy = ConvertType(getContext().getNSUIntegerType());
+ llvm::Constant *Count = llvm::ConstantInt::get(NSUIntegerTy, NumItems);
+ Args.add(RValue::get(Count), getContext().getNSUIntegerType());
// Start the enumeration.
RValue CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
- getContext().UnsignedLongTy,
- FastEnumSel,
- Collection, Args);
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+ getContext().getNSUIntegerType(),
+ FastEnumSel, Collection, Args);
// The initial number of objects that were returned in the buffer.
llvm::Value *initialBufferLimit = CountRV.getScalarVal();
@@ -1563,7 +1562,7 @@ void CodeGenFunction::EmitObjCForCollect
llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
- llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
+ llvm::Value *zero = llvm::Constant::getNullValue(NSUIntegerTy);
// If the limit pointer was zero to begin with, the collection is
// empty; skip all this. Set the branch weight assuming this has the same
@@ -1595,11 +1594,11 @@ void CodeGenFunction::EmitObjCForCollect
EmitBlock(LoopBodyBB);
// The current index into the buffer.
- llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
+ llvm::PHINode *index = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.index");
index->addIncoming(zero, LoopInitBB);
// The current buffer size.
- llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
+ llvm::PHINode *count = Builder.CreatePHI(NSUIntegerTy, 3, "forcoll.count");
count->addIncoming(initialBufferLimit, LoopInitBB);
incrementProfileCounter(&S);
@@ -1709,8 +1708,8 @@ void CodeGenFunction::EmitObjCForCollect
llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
// First we check in the local buffer.
- llvm::Value *indexPlusOne
- = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
+ llvm::Value *indexPlusOne =
+ Builder.CreateAdd(index, llvm::ConstantInt::get(NSUIntegerTy, 1));
// If we haven't overrun the buffer yet, we can continue.
// Set the branch weights based on the simplifying assumption that this is
@@ -1727,10 +1726,9 @@ void CodeGenFunction::EmitObjCForCollect
EmitBlock(FetchMoreBB);
CountRV =
- CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
- getContext().UnsignedLongTy,
- FastEnumSel,
- Collection, Args);
+ CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
+ getContext().getNSUIntegerType(),
+ FastEnumSel, Collection, Args);
// If we got a zero count, we're done.
llvm::Value *refetchCount = CountRV.getScalarVal();
Added: cfe/trunk/test/CodeGenObjC/NSFastEnumeration.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/NSFastEnumeration.m?rev=312835&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/NSFastEnumeration.m (added)
+++ cfe/trunk/test/CodeGenObjC/NSFastEnumeration.m Fri Sep 8 16:41:17 2017
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple i686--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK32
+// RUN: %clang_cc1 -triple x86_64-apple-ios10.3 -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+// RUN: %clang_cc1 -triple x86_64--windows-msvc -fobjc-runtime=ios-6.0 -Os -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK64
+
+void f(id a) {
+ for (id i in a)
+ (void)i;
+}
+
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+// CHECK32: call i32 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i32)*)
+
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+// CHECK64: call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*, %struct.__objcFastEnumerationState*, [16 x i8*]*, i64)*)
+
More information about the cfe-commits
mailing list