aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/ABIInfo.h2
-rw-r--r--lib/CodeGen/BackendUtil.cpp23
-rw-r--r--lib/CodeGen/CGAtomic.cpp11
-rw-r--r--lib/CodeGen/CGBlocks.cpp93
-rw-r--r--lib/CodeGen/CGBuiltin.cpp45
-rw-r--r--lib/CodeGen/CGCXXABI.cpp33
-rw-r--r--lib/CodeGen/CGCXXABI.h57
-rw-r--r--lib/CodeGen/CGCall.cpp214
-rw-r--r--lib/CodeGen/CGCall.h19
-rw-r--r--lib/CodeGen/CGClass.cpp28
-rw-r--r--lib/CodeGen/CGCleanup.cpp12
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp184
-rw-r--r--lib/CodeGen/CGDebugInfo.h18
-rw-r--r--lib/CodeGen/CGDecl.cpp261
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp89
-rw-r--r--lib/CodeGen/CGException.cpp12
-rw-r--r--lib/CodeGen/CGExpr.cpp374
-rw-r--r--lib/CodeGen/CGExprAgg.cpp11
-rw-r--r--lib/CodeGen/CGExprCXX.cpp2
-rw-r--r--lib/CodeGen/CGExprComplex.cpp4
-rw-r--r--lib/CodeGen/CGExprConstant.cpp9
-rw-r--r--lib/CodeGen/CGExprScalar.cpp105
-rw-r--r--lib/CodeGen/CGObjC.cpp90
-rw-r--r--lib/CodeGen/CGObjCMac.cpp27
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp2
-rw-r--r--lib/CodeGen/CGRTTI.cpp6
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp8
-rw-r--r--lib/CodeGen/CGStmt.cpp86
-rw-r--r--lib/CodeGen/CGValue.h31
-rw-r--r--lib/CodeGen/CMakeLists.txt1
-rw-r--r--lib/CodeGen/CodeGenAction.cpp2
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp171
-rw-r--r--lib/CodeGen/CodeGenFunction.h153
-rw-r--r--lib/CodeGen/CodeGenModule.cpp176
-rw-r--r--lib/CodeGen/CodeGenModule.h117
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp137
-rw-r--r--lib/CodeGen/CodeGenTBAA.h65
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp14
-rw-r--r--lib/CodeGen/CodeGenTypes.h13
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp220
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp505
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp14
-rw-r--r--lib/CodeGen/TargetInfo.cpp624
43 files changed, 3087 insertions, 981 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 35780f1556..df6dc7216a 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -22,6 +22,7 @@ namespace llvm {
namespace clang {
class ASTContext;
+ class TargetInfo;
namespace CodeGen {
class CGFunctionInfo;
@@ -196,6 +197,7 @@ namespace clang {
ASTContext &getContext() const;
llvm::LLVMContext &getVMContext() const;
const llvm::DataLayout &getDataLayout() const;
+ const TargetInfo &getTarget() const;
/// Return the calling convention to use for system runtime
/// functions.
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index ab65801ce5..45079c0989 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -302,14 +302,19 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {
// Set up the per-module pass manager.
PassManager *MPM = getPerModulePasses(TM);
- if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) {
- MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes,
- CodeGenOpts.EmitGcovArcs,
- CodeGenOpts.CoverageVersion,
- CodeGenOpts.CoverageExtraChecksum,
- CodeGenOpts.DisableRedZone,
- CodeGenOpts.CoverageFunctionNamesInData));
-
+ if (!CodeGenOpts.DisableGCov &&
+ (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
+ // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
+ // LLVM's -default-gcov-version flag is set to something invalid.
+ GCOVOptions Options;
+ Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
+ Options.EmitData = CodeGenOpts.EmitGcovArcs;
+ memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
+ Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
+ Options.NoRedZone = CodeGenOpts.DisableRedZone;
+ Options.FunctionNamesInData =
+ !CodeGenOpts.CoverageNoFunctionNamesInData;
+ MPM->add(createGCOVProfilerPass(Options));
if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
MPM->add(createStripSymbolsPass(true));
}
@@ -452,6 +457,7 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Options.TrapFuncName = CodeGenOpts.TrapFuncName;
Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
Options.SSPBufferSize = CodeGenOpts.SSPBufferSize;
+ Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks;
TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
FeaturesStr, Options,
@@ -522,6 +528,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
Action != Backend_EmitBC &&
Action != Backend_EmitLL);
TargetMachine *TM = CreateTargetMachine(UsesCodeGen);
+ if (UsesCodeGen && !TM) return;
CreatePasses(TM);
switch (Action) {
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 817d5c4cc6..0b48a5c664 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -327,7 +327,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy);
unsigned Align = alignChars.getQuantity();
unsigned MaxInlineWidthInBits =
- getContext().getTargetInfo().getMaxAtomicInlineWidth();
+ getTarget().getMaxAtomicInlineWidth();
bool UseLibcall = (Size != Align ||
getContext().toBits(sizeChars) > MaxInlineWidthInBits);
@@ -483,15 +483,6 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
getContext().VoidPtrTy);
break;
-#if 0
- // These are only defined for 1-16 byte integers. It is not clear what
- // their semantics would be on anything else...
- case AtomicExpr::Add: LibCallName = "__atomic_fetch_add_generic"; break;
- case AtomicExpr::Sub: LibCallName = "__atomic_fetch_sub_generic"; break;
- case AtomicExpr::And: LibCallName = "__atomic_fetch_and_generic"; break;
- case AtomicExpr::Or: LibCallName = "__atomic_fetch_or_generic"; break;
- case AtomicExpr::Xor: LibCallName = "__atomic_fetch_xor_generic"; break;
-#endif
default: return EmitUnsupportedRValue(E, "atomic library call");
}
// order is always the last parameter
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index b9f466117c..ded019e64a 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -695,8 +695,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
bool isLambdaConv = blockInfo.getBlockDecl()->isConversionFromLambda();
llvm::Constant *blockFn
= CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo,
- CurFuncDecl, LocalDeclMap,
- isLambdaConv);
+ LocalDeclMap,
+ isLambdaConv);
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
// If there is nothing to capture, we can emit this as a global block.
@@ -753,6 +753,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
if (capture.isConstant()) continue;
QualType type = variable->getType();
+ CharUnits align = getContext().getDeclAlign(variable);
// This will be a [[type]]*, except that a byref entry will just be
// an i8**.
@@ -796,21 +797,21 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
if (ci->isByRef()) {
// Get a void* that points to the byref struct.
if (ci->isNested())
- src = Builder.CreateLoad(src, "byref.capture");
+ src = Builder.CreateAlignedLoad(src, align.getQuantity(),
+ "byref.capture");
else
src = Builder.CreateBitCast(src, VoidPtrTy);
// Write that void* into the capture field.
- Builder.CreateStore(src, blockField);
+ Builder.CreateAlignedStore(src, blockField, align.getQuantity());
// If we have a copy constructor, evaluate that into the block field.
} else if (const Expr *copyExpr = ci->getCopyExpr()) {
if (blockDecl->isConversionFromLambda()) {
// If we have a lambda conversion, emit the expression
// directly into the block instead.
- CharUnits Align = getContext().getTypeAlignInChars(type);
AggValueSlot Slot =
- AggValueSlot::forAddr(blockField, Align, Qualifiers(),
+ AggValueSlot::forAddr(blockField, align, Qualifiers(),
AggValueSlot::IsDestructed,
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased);
@@ -821,7 +822,27 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// If it's a reference variable, copy the reference into the block field.
} else if (type->isReferenceType()) {
- Builder.CreateStore(Builder.CreateLoad(src, "ref.val"), blockField);
+ llvm::Value *ref =
+ Builder.CreateAlignedLoad(src, align.getQuantity(), "ref.val");
+ Builder.CreateAlignedStore(ref, blockField, align.getQuantity());
+
+ // If this is an ARC __strong block-pointer variable, don't do a
+ // block copy.
+ //
+ // TODO: this can be generalized into the normal initialization logic:
+ // we should never need to do a block-copy when initializing a local
+ // variable, because the local variable's lifetime should be strictly
+ // contained within the stack block's.
+ } else if (type.getObjCLifetime() == Qualifiers::OCL_Strong &&
+ type->isBlockPointerType()) {
+ // Load the block and do a simple retain.
+ LValue srcLV = MakeAddrLValue(src, type, align);
+ llvm::Value *value = EmitLoadOfScalar(srcLV);
+ value = EmitARCRetainNonBlock(value);
+
+ // Do a primitive store to the block field.
+ LValue destLV = MakeAddrLValue(blockField, type, align);
+ EmitStoreOfScalar(value, destLV, /*init*/ true);
// Otherwise, fake up a POD copy into the block field.
} else {
@@ -839,8 +860,7 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
&declRef, VK_RValue);
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
- MakeAddrLValue(blockField, type,
- getContext().getDeclAlign(variable)),
+ MakeAddrLValue(blockField, type, align),
/*captured by init*/ false);
}
@@ -1014,7 +1034,7 @@ CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *blockExpr,
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(),
blockInfo,
- 0, LocalDeclMap,
+ LocalDeclMap,
false);
}
blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
@@ -1068,7 +1088,6 @@ static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
llvm::Function *
CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
const CGBlockInfo &blockInfo,
- const Decl *outerFnDecl,
const DeclMapTy &ldm,
bool IsLambdaConversionToBlock) {
const BlockDecl *blockDecl = blockInfo.getBlockDecl();
@@ -1128,7 +1147,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
// Begin generating the function.
StartFunction(blockDecl, fnType->getResultType(), fn, fnInfo, args,
blockInfo.getBlockExpr()->getBody()->getLocStart());
- CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl
// Okay. Undo some of what StartFunction did.
@@ -1138,6 +1156,22 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
BlockPointer = Builder.CreateBitCast(blockAddr,
blockInfo.StructureType->getPointerTo(),
"block");
+ // At -O0 we generate an explicit alloca for the BlockPointer, so the RA
+ // won't delete the dbg.declare intrinsics for captured variables.
+ llvm::Value *BlockPointerDbgLoc = BlockPointer;
+ if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+ // Allocate a stack slot for it, so we can point the debugger to it
+ llvm::AllocaInst *Alloca = CreateTempAlloca(BlockPointer->getType(),
+ "block.addr");
+ unsigned Align = getContext().getDeclAlign(&selfDecl).getQuantity();
+ Alloca->setAlignment(Align);
+ // Set the DebugLocation to empty, so the store is recognized as a
+ // frame setup instruction by llvm::DwarfDebug::beginFunction().
+ Builder.DisableDebugLocations();
+ Builder.CreateAlignedStore(BlockPointer, Alloca, Align);
+ Builder.EnableDebugLocations();
+ BlockPointerDbgLoc = Alloca;
+ }
// If we have a C++ 'this' reference, go ahead and force it into
// existence now.
@@ -1148,22 +1182,6 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
CXXThisValue = Builder.CreateLoad(addr, "this");
}
- // LoadObjCSelf() expects there to be an entry for 'self' in LocalDeclMap;
- // appease it.
- if (const ObjCMethodDecl *method
- = dyn_cast_or_null<ObjCMethodDecl>(CurFuncDecl)) {
- const VarDecl *self = method->getSelfDecl();
-
- // There might not be a capture for 'self', but if there is...
- if (blockInfo.Captures.count(self)) {
- const CGBlockInfo::Capture &capture = blockInfo.getCapture(self);
- llvm::Value *selfAddr = Builder.CreateStructGEP(BlockPointer,
- capture.getIndex(),
- "block.captured-self");
- LocalDeclMap[self] = selfAddr;
- }
- }
-
// Also force all the constant captures.
for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
ce = blockDecl->capture_end(); ci != ce; ++ci) {
@@ -1177,7 +1195,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
CreateMemTemp(variable->getType(), "block.captured-const");
alloca->setAlignment(align);
- Builder.CreateStore(capture.getConstant(), alloca, align);
+ Builder.CreateAlignedStore(capture.getConstant(), alloca, align);
LocalDeclMap[variable] = alloca;
}
@@ -1216,13 +1234,13 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
continue;
}
- DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer,
+ DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointerDbgLoc,
Builder, blockInfo);
}
}
// Recover location if it was changed in the above loop.
DI->EmitLocation(Builder,
- cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
+ cast<CompoundStmt>(blockDecl->getBody())->getRBracLoc());
}
// And resume where we left off.
@@ -1297,7 +1315,6 @@ CodeGenFunction::GenerateCopyHelperFunction(const CGBlockInfo &blockInfo) {
SourceLocation(),
SourceLocation(), II, C.VoidTy, 0,
SC_Static,
- SC_None,
false,
false);
StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
@@ -1472,7 +1489,6 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
SourceLocation(),
SourceLocation(), II, C.VoidTy, 0,
SC_Static,
- SC_None,
false, false);
StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
@@ -1547,7 +1563,7 @@ CodeGenFunction::GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo) {
// Destroy strong objects with a call if requested.
} else if (useARCStrongDestroy) {
- EmitARCDestroyStrong(srcField, /*precise*/ false);
+ EmitARCDestroyStrong(srcField, ARCImpreciseLifetime);
// Otherwise we call _Block_object_dispose. It wouldn't be too
// hard to just emit this as a cleanup if we wanted to make sure
@@ -1656,7 +1672,7 @@ public:
}
void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
- CGF.EmitARCDestroyStrong(field, /*precise*/ false);
+ CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
}
void profileImpl(llvm::FoldingSetNodeID &id) const {
@@ -1686,7 +1702,7 @@ public:
}
void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
- CGF.EmitARCDestroyStrong(field, /*precise*/ false);
+ CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
}
void profileImpl(llvm::FoldingSetNodeID &id) const {
@@ -1763,7 +1779,6 @@ generateByrefCopyHelper(CodeGenFunction &CGF,
SourceLocation(),
SourceLocation(), II, R, 0,
SC_Static,
- SC_None,
false, false);
// Initialize debug info if necessary.
@@ -1838,7 +1853,6 @@ generateByrefDisposeHelper(CodeGenFunction &CGF,
SourceLocation(),
SourceLocation(), II, R, 0,
SC_Static,
- SC_None,
false, false);
// Initialize debug info if necessary.
CGF.maybeInitializeDebugInfo();
@@ -2047,7 +2061,8 @@ llvm::Type *CodeGenFunction::BuildByRefType(const VarDecl *D) {
bool Packed = false;
CharUnits Align = getContext().getDeclAlign(D);
- if (Align > getContext().toCharUnitsFromBits(Target.getPointerAlign(0))) {
+ if (Align >
+ getContext().toCharUnitsFromBits(getTarget().getPointerAlign(0))) {
// We have to insert padding.
// The struct above has 2 32-bit integers.
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index e9c1431d30..a655966d6e 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -296,7 +296,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
- Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef());
+ Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef);
if (Result->getType() != ResultType)
Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
@@ -313,7 +313,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
llvm::Type *ResultType = ConvertType(E->getType());
- Value *ZeroUndef = Builder.getInt1(Target.isCLZForZeroUndef());
+ Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
Value *Result = Builder.CreateCall2(F, ArgValue, ZeroUndef);
if (Result->getType() != ResultType)
Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
@@ -1434,7 +1434,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
if (const char *Prefix =
- llvm::Triple::getArchTypePrefix(Target.getTriple().getArch()))
+ llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()))
IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
if (IntrinsicID != Intrinsic::not_intrinsic) {
@@ -1505,7 +1505,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
- switch (Target.getTriple().getArch()) {
+ switch (getTarget().getTriple().getArch()) {
+ case llvm::Triple::aarch64:
+ return EmitAArch64BuiltinExpr(BuiltinID, E);
case llvm::Triple::arm:
case llvm::Triple::thumb:
return EmitARMBuiltinExpr(BuiltinID, E);
@@ -1625,6 +1627,25 @@ CodeGenFunction::EmitPointerWithAlignment(const Expr *Addr) {
return std::make_pair(EmitScalarExpr(Addr), Align);
}
+Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
+ const CallExpr *E) {
+ if (BuiltinID == AArch64::BI__clear_cache) {
+ assert(E->getNumArgs() == 2 &&
+ "Variadic __clear_cache slipped through on AArch64");
+
+ const FunctionDecl *FD = E->getDirectCallee();
+ SmallVector<Value *, 2> Ops;
+ for (unsigned i = 0; i < E->getNumArgs(); i++)
+ Ops.push_back(EmitScalarExpr(E->getArg(i)));
+ llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
+ llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
+ StringRef Name = FD->getName();
+ return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
+ }
+
+ return 0;
+}
+
Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
if (BuiltinID == ARM::BI__clear_cache) {
@@ -1856,7 +1877,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
// Generate target-independent intrinsic; also need to add second argument
// for whether or not clz of zero is undefined; on ARM it isn't.
Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty);
- Ops.push_back(Builder.getInt1(Target.isCLZForZeroUndef()));
+ Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
return EmitNeonCall(F, Ops, "vclz");
}
case ARM::BI__builtin_neon_vcnt_v:
@@ -2713,7 +2734,10 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
}
case X86::BI__builtin_ia32_rdrand16_step:
case X86::BI__builtin_ia32_rdrand32_step:
- case X86::BI__builtin_ia32_rdrand64_step: {
+ case X86::BI__builtin_ia32_rdrand64_step:
+ case X86::BI__builtin_ia32_rdseed16_step:
+ case X86::BI__builtin_ia32_rdseed32_step:
+ case X86::BI__builtin_ia32_rdseed64_step: {
Intrinsic::ID ID;
switch (BuiltinID) {
default: llvm_unreachable("Unsupported intrinsic!");
@@ -2726,6 +2750,15 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_rdrand64_step:
ID = Intrinsic::x86_rdrand_64;
break;
+ case X86::BI__builtin_ia32_rdseed16_step:
+ ID = Intrinsic::x86_rdseed_16;
+ break;
+ case X86::BI__builtin_ia32_rdseed32_step:
+ ID = Intrinsic::x86_rdseed_32;
+ break;
+ case X86::BI__builtin_ia32_rdseed64_step:
+ ID = Intrinsic::x86_rdseed_64;
+ break;
}
Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index f9fea57ea6..68fecb2d0c 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -19,8 +19,7 @@ using namespace CodeGen;
CGCXXABI::~CGCXXABI() { }
-static void ErrorUnsupportedABI(CodeGenFunction &CGF,
- StringRef S) {
+void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
DiagnosticsEngine &Diags = CGF.CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot yet compile %0 in this ABI");
@@ -29,8 +28,7 @@ static void ErrorUnsupportedABI(CodeGenFunction &CGF,
<< S;
}
-static llvm::Constant *GetBogusMemberPointer(CodeGenModule &CGM,
- QualType T) {
+llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
}
@@ -67,12 +65,12 @@ llvm::Value *CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
const CastExpr *E,
llvm::Value *Src) {
ErrorUnsupportedABI(CGF, "member function pointer conversions");
- return GetBogusMemberPointer(CGM, E->getType());
+ return GetBogusMemberPointer(E->getType());
}
llvm::Constant *CGCXXABI::EmitMemberPointerConversion(const CastExpr *E,
llvm::Constant *Src) {
- return GetBogusMemberPointer(CGM, E->getType());
+ return GetBogusMemberPointer(E->getType());
}
llvm::Value *
@@ -95,22 +93,22 @@ CGCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
llvm::Constant *
CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
- return GetBogusMemberPointer(CGM, QualType(MPT, 0));
+ return GetBogusMemberPointer(QualType(MPT, 0));
}
llvm::Constant *CGCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
- return GetBogusMemberPointer(CGM,
+ return GetBogusMemberPointer(
CGM.getContext().getMemberPointerType(MD->getType(),
MD->getParent()->getTypeForDecl()));
}
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
CharUnits offset) {
- return GetBogusMemberPointer(CGM, QualType(MPT, 0));
+ return GetBogusMemberPointer(QualType(MPT, 0));
}
llvm::Constant *CGCXXABI::EmitMemberPointer(const APValue &MP, QualType MPT) {
- return GetBogusMemberPointer(CGM, MPT);
+ return GetBogusMemberPointer(MPT);
}
bool CGCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
@@ -222,8 +220,12 @@ void CGCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
}
void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
+ const VarDecl &D,
llvm::Constant *dtor,
llvm::Constant *addr) {
+ if (D.getTLSKind())
+ CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
+
// The default behavior is to use atexit.
CGF.registerGlobalDtorWithAtExit(dtor, addr);
}
@@ -257,3 +259,14 @@ llvm::BasicBlock *CGCXXABI::EmitCtorCompleteObjectHandler(
ErrorUnsupportedABI(CGF, "complete object detection in ctor");
return 0;
}
+
+void CGCXXABI::EmitThreadLocalInitFuncs(
+ llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+ llvm::Function *InitFunc) {
+}
+
+LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
+ const DeclRefExpr *DRE) {
+ ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
+ return LValue();
+}
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index cdc87b70e5..1e4da631d6 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -54,6 +54,12 @@ protected:
return CGF.CXXABIThisValue;
}
+ /// Issue a diagnostic about unsupported features in the ABI.
+ void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S);
+
+ /// Get a null value for unsupported member pointers.
+ llvm::Constant *GetBogusMemberPointer(QualType T);
+
// FIXME: Every place that calls getVTT{Decl,Value} is something
// that needs to be abstracted properly.
ImplicitParamDecl *&getVTTDecl(CodeGenFunction &CGF) {
@@ -91,6 +97,31 @@ public:
return *MangleCtx;
}
+ /// Returns true if the given instance method is one of the
+ /// kinds that the ABI says returns 'this'.
+ virtual bool HasThisReturn(GlobalDecl GD) const { return false; }
+
+ /// Returns true if the given record type should be returned indirectly.
+ virtual bool isReturnTypeIndirect(const CXXRecordDecl *RD) const = 0;
+
+ /// Specify how one should pass an argument of a record type.
+ enum RecordArgABI {
+ /// Pass it using the normal C aggregate rules for the ABI, potentially
+ /// introducing extra copies and passing some or all of it in registers.
+ RAA_Default = 0,
+
+ /// Pass it on the stack using its defined layout. The argument must be
+ /// evaluated directly into the correct stack position in the arguments area,
+ /// and the call machinery must not move it or introduce extra copies.
+ RAA_DirectInMemory,
+
+ /// Pass it as a pointer to temporary memory.
+ RAA_Indirect
+ };
+
+ /// Returns how an argument of the given record type should be passed.
+ virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0;
+
/// Find the LLVM type used to represent the given member pointer
/// type.
virtual llvm::Type *
@@ -209,7 +240,8 @@ public: