summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGBuiltin.cpp46
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp4
-rw-r--r--lib/CodeGen/CGDecl.cpp14
-rw-r--r--lib/CodeGen/CGExpr.cpp41
-rw-r--r--lib/CodeGen/CGExprAgg.cpp23
-rw-r--r--lib/CodeGen/CGExprScalar.cpp4
-rw-r--r--lib/CodeGen/CGObjC.cpp7
-rw-r--r--lib/CodeGen/CGObjCMac.cpp45
-rw-r--r--lib/CodeGen/CGObjCRuntime.h3
-rw-r--r--lib/CodeGen/CGRecordLayout.h30
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp42
-rw-r--r--lib/CodeGen/CGValue.h38
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp6
-rw-r--r--lib/CodeGen/CodeGenModule.cpp30
-rw-r--r--lib/CodeGen/CodeGenModule.h18
15 files changed, 189 insertions, 162 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index a9b0b64..38c40ed 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -338,38 +338,50 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BIbzero:
case Builtin::BI__builtin_bzero: {
Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemSetFn(), Address,
- llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
- EmitScalarExpr(E->getArg(1)),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
+ Value *SizeVal = EmitScalarExpr(E->getArg(1));
+ Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
+ Address,
+ llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0),
+ SizeVal,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
return RValue::get(Address);
}
case Builtin::BImemcpy:
case Builtin::BI__builtin_memcpy: {
Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemCpyFn(), Address,
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
+ Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+ Value *SizeVal = EmitScalarExpr(E->getArg(2));
+ Builder.CreateCall5(CGM.getMemCpyFn(Address->getType(), SrcAddr->getType(),
+ SizeVal->getType()),
+ Address, SrcAddr, SizeVal,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
return RValue::get(Address);
}
case Builtin::BImemmove:
case Builtin::BI__builtin_memmove: {
Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemMoveFn(), Address,
- EmitScalarExpr(E->getArg(1)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
+ Value *SrcAddr = EmitScalarExpr(E->getArg(1));
+ Value *SizeVal = EmitScalarExpr(E->getArg(2));
+ Builder.CreateCall5(CGM.getMemMoveFn(Address->getType(), SrcAddr->getType(),
+ SizeVal->getType()),
+ Address, SrcAddr, SizeVal,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
return RValue::get(Address);
}
case Builtin::BImemset:
case Builtin::BI__builtin_memset: {
Value *Address = EmitScalarExpr(E->getArg(0));
- Builder.CreateCall4(CGM.getMemSetFn(), Address,
- Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
- llvm::Type::getInt8Ty(VMContext)),
- EmitScalarExpr(E->getArg(2)),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1));
+ Value *SizeVal = EmitScalarExpr(E->getArg(2));
+ Builder.CreateCall5(CGM.getMemSetFn(Address->getType(), SizeVal->getType()),
+ Address,
+ Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
+ llvm::Type::getInt8Ty(VMContext)),
+ SizeVal,
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 1),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0));
return RValue::get(Address);
}
case Builtin::BI__builtin_dwarf_cfa: {
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 4f14f94..bcbda8a 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1380,7 +1380,9 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
|| (SM.getInstantiationLineNumber(CurLoc) ==
SM.getInstantiationLineNumber(PrevLoc)
&& SM.isFromSameFile(CurLoc, PrevLoc)))
- return;
+ // New Builder may not be in sync with CGDebugInfo.
+ if (!Builder.getCurrentDebugLocation().isUnknown())
+ return;
// Update last state.
PrevLoc = CurLoc;
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 4eb95af..07d219f 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -564,11 +564,15 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
if (Loc->getType() != BP)
Loc = Builder.CreateBitCast(Loc, BP, "tmp");
+ llvm::Value *NotVolatile =
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), 0);
+
// If the initializer is all zeros, codegen with memset.
if (isa<llvm::ConstantAggregateZero>(Init)) {
llvm::Value *Zero =
- llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0);
- Builder.CreateCall4(CGM.getMemSetFn(), Loc, Zero, SizeVal, AlignVal);
+ llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 0);
+ Builder.CreateCall5(CGM.getMemSetFn(Loc->getType(), SizeVal->getType()),
+ Loc, Zero, SizeVal, AlignVal, NotVolatile);
} else {
// Otherwise, create a temporary global with the initializer then
// memcpy from the global to the alloca.
@@ -582,8 +586,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
llvm::Value *SrcPtr = GV;
if (SrcPtr->getType() != BP)
SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
-
- Builder.CreateCall4(CGM.getMemCpyFn(), Loc, SrcPtr, SizeVal, AlignVal);
+
+ Builder.CreateCall5(CGM.getMemCpyFn(Loc->getType(), SrcPtr->getType(),
+ SizeVal->getType()),
+ Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);
}
} else if (Ty->isReferenceType()) {
RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true);
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 87ec159..0aa4438 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -345,7 +345,7 @@ EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
}
// Store the updated result through the lvalue.
- if (LV.isBitfield())
+ if (LV.isBitField())
EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal);
else
EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy);
@@ -429,7 +429,7 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
LValue LV = EmitLValue(E);
- if (!isa<DeclRefExpr>(E) && !LV.isBitfield() && LV.isSimple())
+ if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);
return LV;
}
@@ -593,7 +593,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
if (LV.isExtVectorElt())
return EmitLoadOfExtVectorElementLValue(LV, ExprType);
- if (LV.isBitfield())
+ if (LV.isBitField())
return EmitLoadOfBitfieldLValue(LV, ExprType);
if (LV.isPropertyRef())
@@ -605,9 +605,10 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
QualType ExprType) {
- unsigned StartBit = LV.getBitfieldStartBit();
- unsigned BitfieldSize = LV.getBitfieldSize();
- llvm::Value *Ptr = LV.getBitfieldAddr();
+ const CGBitFieldInfo &Info = LV.getBitFieldInfo();
+ unsigned StartBit = Info.Start;
+ unsigned BitfieldSize = Info.Size;
+ llvm::Value *Ptr = LV.getBitFieldAddr();
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -650,7 +651,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
}
// Sign extend if necessary.
- if (LV.isBitfieldSigned()) {
+ if (Info.IsSigned) {
llvm::Value *ExtraBits = llvm::ConstantInt::get(EltTy,
EltTySize - BitfieldSize);
Val = Builder.CreateAShr(Builder.CreateShl(Val, ExtraBits),
@@ -733,7 +734,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
if (Dst.isExtVectorElt())
return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty);
- if (Dst.isBitfield())
+ if (Dst.isBitField())
return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
if (Dst.isPropertyRef())
@@ -781,9 +782,10 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
QualType Ty,
llvm::Value **Result) {
- unsigned StartBit = Dst.getBitfieldStartBit();
- unsigned BitfieldSize = Dst.getBitfieldSize();
- llvm::Value *Ptr = Dst.getBitfieldAddr();
+ const CGBitFieldInfo &Info = Dst.getBitFieldInfo();
+ unsigned StartBit = Info.Start;
+ unsigned BitfieldSize = Info.Size;
+ llvm::Value *Ptr = Dst.getBitFieldAddr();
const llvm::Type *EltTy =
cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -805,7 +807,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
"bf.reload.val");
// Sign extend if necessary.
- if (Dst.isBitfieldSigned()) {
+ if (Info.IsSigned) {
unsigned SrcTySize = CGM.getTargetData().getTypeSizeInBits(SrcTy);
llvm::Value *ExtraBits = llvm::ConstantInt::get(SrcTy,
SrcTySize - BitfieldSize);
@@ -1471,7 +1473,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
unsigned CVRQualifiers) {
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(Field->getParent());
- const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);
+ const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
// FIXME: CodeGenTypes should expose a method to get the appropriate type for
// FieldTy (the appropriate type is ABI-dependent).
@@ -1481,16 +1483,11 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
cast<llvm::PointerType>(BaseValue->getType());
unsigned AS = BaseTy->getAddressSpace();
BaseValue = Builder.CreateBitCast(BaseValue,
- llvm::PointerType::get(FieldTy, AS),
- "tmp");
+ llvm::PointerType::get(FieldTy, AS));
+ llvm::Value *V = Builder.CreateConstGEP1_32(BaseValue, Info.FieldNo);
- llvm::Value *Idx =
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), Info.FieldNo);
- llvm::Value *V = Builder.CreateGEP(BaseValue, Idx, "tmp");
-
- return LValue::MakeBitfield(V, Info.Start, Info.Size,
- Field->getType()->isSignedIntegerType(),
- Field->getType().getCVRQualifiers()|CVRQualifiers);
+ return LValue::MakeBitfield(V, Info,
+ Field->getType().getCVRQualifiers()|CVRQualifiers);
}
LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index e2e2cd0..4d5160f 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -771,12 +771,27 @@ void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
// a = b;
// }
//
- // we need to use a differnt call here. We use isVolatile to indicate when
+ // we need to use a different call here. We use isVolatile to indicate when
// either the source or the destination is volatile.
- Builder.CreateCall4(CGM.getMemCpyFn(),
+ const llvm::Type *I1Ty = llvm::Type::getInt1Ty(VMContext);
+ const llvm::Type *I8Ty = llvm::Type::getInt8Ty(VMContext);
+ const llvm::Type *I32Ty = llvm::Type::getInt32Ty(VMContext);
+
+ const llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
+ const llvm::Type *DBP = llvm::PointerType::get(I8Ty, DPT->getAddressSpace());
+ if (DestPtr->getType() != DBP)
+ DestPtr = Builder.CreateBitCast(DestPtr, DBP, "tmp");
+
+ const llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
+ const llvm::Type *SBP = llvm::PointerType::get(I8Ty, SPT->getAddressSpace());
+ if (SrcPtr->getType() != SBP)
+ SrcPtr = Builder.CreateBitCast(SrcPtr, SBP, "tmp");
+
+ Builder.CreateCall5(CGM.getMemCpyFn(DestPtr->getType(), SrcPtr->getType(),
+ IntPtr),
DestPtr, SrcPtr,
// TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
- TypeInfo.second/8));
+ llvm::ConstantInt::get(I32Ty, TypeInfo.second/8),
+ llvm::ConstantInt::get(I1Ty, isVolatile));
}
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 42bf68e..d1c0f8d 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1140,7 +1140,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
// specially because the result is altered by the store, i.e., [C99 6.5.16p1]
// 'An assignment expression has the value of the left operand after the
// assignment...'.
- if (LHSLV.isBitfield()) {
+ if (LHSLV.isBitField()) {
if (!LHSLV.isVolatileQualified()) {
CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy,
&Result);
@@ -1575,7 +1575,7 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
// because the result is altered by the store, i.e., [C99 6.5.16p1]
// 'An assignment expression has the value of the left operand after
// the assignment...'.
- if (LHS.isBitfield()) {
+ if (LHS.isBitField()) {
if (!LHS.isVolatileQualified()) {
CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(),
&RHS);
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 9eaf57c..206d438 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -108,6 +108,10 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
const ObjCContainerDecl *CD) {
FunctionArgList Args;
+ // Check if we should generate debug info for this method.
+ if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
+ DebugInfo = CGM.getDebugInfo();
+
llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
@@ -128,9 +132,6 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
/// Generate an Objective-C method. An Objective-C method is a C function with
/// its pointer, name, and types registered in the class struture.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
- // Check if we should generate debug info for this method.
- if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
- DebugInfo = CGM.getDebugInfo();
StartObjCMethod(OMD, OMD->getClassInterface());
EmitStmt(OMD->getBody());
FinishFunction(OMD->getBodyRBrace());
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 5373390..ac8fa05 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -107,24 +107,31 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF,
Qualifiers Quals = CGF.MakeQualifiers(IvarTy);
Quals.addCVRQualifiers(CVRQualifiers);
- if (Ivar->isBitField()) {
- // We need to compute the bit offset for the bit-field, the offset
- // is to the byte. Note, there is a subtle invariant here: we can
- // only call this routine on non-sythesized ivars but we may be
- // called for synthesized ivars. However, a synthesized ivar can
- // never be a bit-field so this is safe.
- uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8;
-
- uint64_t BitFieldSize =
- Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
- return LValue::MakeBitfield(V, BitOffset, BitFieldSize,
- IvarTy->isSignedIntegerType(),
- Quals.getCVRQualifiers());
- }
-
-
- LValue LV = LValue::MakeAddr(V, Quals);
- return LV;
+ if (!Ivar->isBitField())
+ return LValue::MakeAddr(V, Quals);
+
+ // We need to compute the bit offset for the bit-field, the offset is to the
+ // byte. Note, there is a subtle invariant here: we can only call this routine
+ // on non-synthesized ivars but we may be called for synthesized ivars.
+ // However, a synthesized ivar can never be a bit-field, so this is safe.
+ uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8;
+ uint64_t BitFieldSize =
+ Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue();
+
+ // Allocate a new CGBitFieldInfo object to describe this access.
+ //
+ // FIXME: This is incredibly wasteful, these should be uniqued or part of some
+ // layout object. However, this is blocked on other cleanups to the
+ // Objective-C code, so for now we just live with allocating a bunch of these
+ // objects.
+ unsigned FieldNo = 0; // This value is unused.
+ CGBitFieldInfo *Info =
+ new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize,
+ IvarTy->isSignedIntegerType());
+
+ // FIXME: We need to set a very conservative alignment on this, or make sure
+ // that the runtime is doing the right thing.
+ return LValue::MakeBitfield(V, *Info, Quals.getCVRQualifiers());
}
///
@@ -3128,7 +3135,7 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(Field->getParent());
if (Field->isBitField()) {
- const CGRecordLayout::BitFieldInfo &Info = RL.getBitFieldInfo(Field);
+ const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field);
const llvm::Type *Ty =
CGM.getTypes().ConvertTypeForMemRecursive(Field->getType());
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index b781940..e478394 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -61,12 +61,11 @@ namespace CodeGen {
/// Implements runtime-specific code generation functions.
class CGObjCRuntime {
-public:
+protected:
// Utility functions for unified ivar access. These need to
// eventually be folded into other places (the structure layout
// code).
-protected:
/// Compute an offset to the given ivar, suitable for passing to
/// EmitValueForIvarAtOffset. Note that the correct handling of
/// bit-fields is carefully coordinated by these two, use caution!
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h
index d0d8f98..fd1775e 100644
--- a/lib/CodeGen/CGRecordLayout.h
+++ b/lib/CodeGen/CGRecordLayout.h
@@ -19,6 +19,18 @@ namespace llvm {
namespace clang {
namespace CodeGen {
+class CGBitFieldInfo {
+public:
+ CGBitFieldInfo(unsigned FieldNo, unsigned Start, unsigned Size,
+ bool IsSigned)
+ : FieldNo(FieldNo), Start(Start), Size(Size), IsSigned(IsSigned) {}
+
+ unsigned FieldNo;
+ unsigned Start;
+ unsigned Size;
+ bool IsSigned : 1;
+};
+
/// CGRecordLayout - This class handles struct and union layout info while
/// lowering AST types to LLVM types.
///
@@ -29,18 +41,6 @@ class CGRecordLayout {
CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT
void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT
-public:
- struct BitFieldInfo {
- BitFieldInfo(unsigned FieldNo,
- unsigned Start,
- unsigned Size)
- : FieldNo(FieldNo), Start(Start), Size(Size) {}
-
- unsigned FieldNo;
- unsigned Start;
- unsigned Size;
- };
-
private:
/// The LLVMType corresponding to this record layout.
const llvm::Type *LLVMType;
@@ -51,7 +51,7 @@ private:
/// Map from (bit-field) struct field to the corresponding llvm struct type
/// field no. This info is populated by record builder.
- llvm::DenseMap<const FieldDecl *, BitFieldInfo> BitFields;
+ llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
/// Whether one of the fields in this record layout is a pointer to data
/// member, or a struct that contains pointer to data member.
@@ -80,9 +80,9 @@ public:
/// \brief Return llvm::StructType element number that corresponds to the
/// field FD.
- const BitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
+ const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
assert(FD->isBitField() && "Invalid call for non bit-field decl!");
- llvm::DenseMap<const FieldDecl *, BitFieldInfo>::const_iterator
+ llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
it = BitFields.find(FD);
assert(it != BitFields.end() && "Unable to find bitfield info");
return it->second;
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index daebabd..4b9ec66 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -37,17 +37,7 @@ public:
llvm::SmallVector<LLVMFieldInfo, 16> LLVMFields;
/// LLVMBitFieldInfo - Holds location and size information about a bit field.
- struct LLVMBitFieldInfo {
- LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
- unsigned Size)
- : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
-
- const FieldDecl *FD;
-
- unsigned FieldNo;
- unsigned Start;
- unsigned Size;
- };
+ typedef std::pair<const FieldDecl *, CGBitFieldInfo> LLVMBitFieldInfo;
llvm::SmallVector<LLVMBitFieldInfo, 16> LLVMBitFields;
/// ContainsPointerToDataMember - Whether one of the fields in this record
@@ -188,9 +178,11 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8;
- LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset / TypeSizeInBits,
- FieldOffset % TypeSizeInBits,
- FieldSize));
+ bool IsSigned = D->getType()->isSignedIntegerType();
+ LLVMBitFields.push_back(LLVMBitFieldInfo(
+ D, CGBitFieldInfo(FieldOffset / TypeSizeInBits,
+ FieldOffset % TypeSizeInBits,
+ FieldSize, IsSigned)));
AppendBytes(NumBytesToAppend);
@@ -288,7 +280,10 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
continue;
// Add the bit field info.
- LLVMBitFields.push_back(LLVMBitFieldInfo(*Field, 0, 0, FieldSize));
+ bool IsSigned = Field->getType()->isSignedIntegerType();
+ LLVMBitFields.push_back(LLVMBitFieldInfo(
+ *Field, CGBitFieldInfo(0, 0, FieldSize,
+ IsSigned)));
} else {
LLVMFields.push_back(LLVMFieldInfo(*Field, 0));
}
@@ -494,21 +489,12 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
new CGRecordLayout(Ty, Builder.ContainsPointerToDataMember);
// Add all the field numbers.
- for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i) {
- const FieldDecl *FD = Builder.LLVMFields[i].first;
- unsigned FieldNo = Builder.LLVMFields[i].second;
-
- RL->FieldInfo.insert(std::make_pair(FD, FieldNo));
- }
+ for (unsigned i = 0, e = Builder.LLVMFields.size(); i != e; ++i)
+ RL->FieldInfo.insert(Builder.LLVMFields[i]);
// Add bitfield info.
- for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) {
- const CGRecordLayoutBuilder::LLVMBitFieldInfo &Info =
- Builder.LLVMBitFields[i];
-
- CGRecordLayout::BitFieldInfo BFI(Info.FieldNo, Info.Start, Info.Size);
- RL->BitFields.insert(std::make_pair(Info.FD, BFI));
- }
+ for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i)
+ RL->BitFields.insert(Builder.LLVMBitFields[i]);
return RL;
}
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index fa77471..91fb714 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -27,6 +27,7 @@ namespace clang {
class ObjCImplicitSetterGetterRefExpr;
namespace CodeGen {
+ class CGBitFieldInfo;
/// RValue - This trivial value class is used to represent the result of an
/// expression that is evaluated. It can be one of three things: either a
@@ -128,14 +129,11 @@ class LValue {
llvm::Constant *VectorElts;
// BitField start bit and size
- struct {
- unsigned short StartBit;
- unsigned short Size;
- bool IsSigned;
- } BitfieldData;
+ const CGBitFieldInfo *BitFieldInfo;
// Obj-C property reference expression
const ObjCPropertyRefExpr *PropertyRefExpr;
+
// ObjC 'implicit' property reference expression
const ObjCImplicitSetterGetterRefExpr *KVCRefExpr;
};
@@ -170,7 +168,7 @@ private:
public:
bool isSimple() const { return LVType == Simple; }
bool isVectorElt() const { return LVType == VectorElt; }
- bool isBitfield() const { return LVType == BitField; }
+ bool isBitField() const { return LVType == BitField; }
bool isExtVectorElt() const { return LVType == ExtVectorElt; }
bool isPropertyRef() const { return LVType == PropertyRef; }
bool isKVCRef() const { return LVType == KVCRef; }
@@ -209,29 +207,28 @@ public:
// simple lvalue
llvm::Value *getAddress() const { assert(isSimple()); return V; }
+
// vector elt lvalue
llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
+
// extended vector elements.
llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
llvm::Constant *getExtVectorElts() const {
assert(isExtVectorElt());
return VectorElts;
}
+
// bitfield lvalue
- llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; }
- unsigned short getBitfieldStartBit() const {
- assert(isBitfield());
- return BitfieldData.StartBit;
- }
- unsigned short getBitfieldSize() const {
- assert(isBitfield());
- return BitfieldData.Size;
+ llvm::Value *getBitFieldAddr() const {
+ assert(isBitField());
+ return V;
}
- bool isBitfieldSigned() const {
- assert(isBitfield());
- return BitfieldData.IsSigned;
+ const CGBitFieldInfo &getBitFieldInfo() const {
+ assert(isBitField());
+ return *BitFieldInfo;
}
+
// property ref lvalue
const ObjCPropertyRefExpr *getPropertyRefExpr() const {
assert(isPropertyRef());
@@ -272,15 +269,12 @@ public:
return R;
}
- static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit,
- unsigned short Size, bool IsSigned,
+ static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info,
unsigned CVR) {
LValue R;
R.LVType = BitField;
R.V = V;
- R.BitfieldData.StartBit = StartBit;
- R.BitfieldData.Size = Size;
- R.BitfieldData.IsSigned = IsSigned;
+ R.BitFieldInfo = &Info;
R.SetQualifiers(Qualifiers::fromCVRMask(CVR));
return R;
}
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index b863aff..f38d8a1 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -495,12 +495,14 @@ void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
const llvm::Type *IntPtr = llvm::IntegerType::get(VMContext,
LLVMPointerWidth);
- Builder.CreateCall4(CGM.getMemSetFn(), DestPtr,
+ Builder.CreateCall5(CGM.getMemSetFn(BP, IntPtr), DestPtr,
llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext)),
// TypeInfo.first describes size in bits.
llvm::ConstantInt::get(IntPtr, TypeInfo.first/8),
llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
- TypeInfo.second/8));
+ TypeInfo.second/8),
+ llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
+ 0));
}
llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 3c872c8..a2ad31e 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -47,8 +47,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()),
- MangleCtx(C), VTables(*this), Runtime(0),
- MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0),
+ MangleCtx(C), VTables(*this), Runtime(0), CFConstantStringClassRef(0),
VMContext(M.getContext()) {
if (!Features.ObjC1)
@@ -1414,22 +1413,25 @@ llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys,
(llvm::Intrinsic::ID)IID, Tys, NumTys);
}
-llvm::Function *CodeGenModule::getMemCpyFn() {
- if (MemCpyFn) return MemCpyFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
- return MemCpyFn = getIntrinsic(llvm::Intrinsic::memcpy, &IntPtr, 1);
+
+llvm::Function *CodeGenModule::getMemCpyFn(const llvm::Type *DestType,
+ const llvm::Type *SrcType,
+ const llvm::Type *SizeType) {
+ const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
+ return getIntrinsic(llvm::Intrinsic::memcpy, ArgTypes, 3);
}
-llvm::Function *CodeGenModule::getMemMoveFn() {
- if (MemMoveFn) return MemMoveFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
- return MemMoveFn = getIntrinsic(llvm::Intrinsic::memmove, &IntPtr, 1);
+llvm::Function *CodeGenModule::getMemMoveFn(const llvm::Type *DestType,
+ const llvm::Type *SrcType,
+ const llvm::Type *SizeType) {
+ const llvm::Type *ArgTypes[3] = {DestType, SrcType, SizeType };
+ return getIntrinsic(llvm::Intrinsic::memmove, ArgTypes, 3);
}
-llvm::Function *CodeGenModule::getMemSetFn() {
- if (MemSetFn) return MemSetFn;
- const llvm::Type *IntPtr = TheTargetData.getIntPtrType(VMContext);
- return MemSetFn = getIntrinsic(llvm::Intrinsic::memset, &IntPtr, 1);
+llvm::Function *CodeGenModule::getMemSetFn(const llvm::Type *DestType,
+ const llvm::Type *SizeType) {
+ const llvm::Type *ArgTypes[2] = { DestType, SizeType };
+ return getIntrinsic(llvm::Intrinsic::memset, ArgTypes, 2);
}
static llvm::StringMapEntry<llvm::Constant*> &
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 3c57c0b..e9f78bc 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -97,10 +97,6 @@ class CodeGenModule : public BlockModule {
CGObjCRuntime* Runtime;
CGDebugInfo* DebugInfo;
-
- llvm::Function *MemCpyFn;
- llvm::Function *MemMoveFn;
- llvm::Function *MemSetFn;
// WeakRefReferences - A set of references that have only been seen via
// a weakref so far. This is used to remove the weak of the reference if we ever
@@ -290,9 +286,17 @@ public:
llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
unsigned BuiltinID);
- llvm::Function *getMemCpyFn();
- llvm::Function *getMemMoveFn();
- llvm::Function *getMemSetFn();
+ llvm::Function *getMemCpyFn(const llvm::Type *DestType,
+ const llvm::Type *SrcType,
+ const llvm::Type *SizeType);
+
+ llvm::Function *getMemMoveFn(const llvm::Type *DestType,
+ const llvm::Type *SrcType,
+ const llvm::Type *SizeType);
+
+ llvm::Function *getMemSetFn(const llvm::Type *DestType,
+ const llvm::Type *SizeType);
+
llvm::Function *getIntrinsic(unsigned IID, const llvm::Type **Tys = 0,
unsigned NumTys = 0);
OpenPOWER on IntegriCloud