summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGDecl.cpp
diff options
context:
space:
mode:
authorJF Bastien <jfbastien@apple.com>2018-08-07 21:55:13 +0000
committerJF Bastien <jfbastien@apple.com>2018-08-07 21:55:13 +0000
commitb9cc1fcf6bf2c8fdade9d8b304e049cedc56741d (patch)
tree58cd027eb88d75487dfd5c768421b76283718da2 /clang/lib/CodeGen/CGDecl.cpp
parent7b2c98ab5991385b1259176cb1939e52fd2d7d55 (diff)
downloadbcm5719-llvm-b9cc1fcf6bf2c8fdade9d8b304e049cedc56741d.tar.gz
bcm5719-llvm-b9cc1fcf6bf2c8fdade9d8b304e049cedc56741d.zip
[NFC] CGDecl factor out constant emission
The code is cleaner this way, and with some changes I'm playing with it makes sense to split it out so we can reuse it. llvm-svn: 339191
Diffstat (limited to 'clang/lib/CodeGen/CGDecl.cpp')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp103
1 files changed, 56 insertions, 47 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 57b2fbadbee..3a5bc0e4694 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -1055,6 +1055,61 @@ static BytePattern shouldUseMemSetToInitialize(llvm::Constant *Init,
return constantIsRepeatedBytePattern(Init);
}
+static void emitStoresForConstant(CodeGenModule &CGM, const VarDecl &D,
+ Address Loc, bool isVolatile,
+ CGBuilderTy &Builder,
+ llvm::Constant *constant) {
+ auto *Int8Ty = llvm::IntegerType::getInt8Ty(CGM.getLLVMContext());
+ auto *IntPtrTy = CGM.getDataLayout().getIntPtrType(CGM.getLLVMContext());
+
+ // If the initializer is all or mostly the same, codegen with bzero / memset
+ // then do a few stores afterward.
+ uint64_t ConstantSize =
+ CGM.getDataLayout().getTypeAllocSize(constant->getType());
+ auto *SizeVal = llvm::ConstantInt::get(IntPtrTy, ConstantSize);
+ if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
+ Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
+ isVolatile);
+
+ bool valueAlreadyCorrect =
+ constant->isNullValue() || isa<llvm::UndefValue>(constant);
+ if (!valueAlreadyCorrect) {
+ Loc = Builder.CreateBitCast(
+ Loc, constant->getType()->getPointerTo(Loc.getAddressSpace()));
+ emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder);
+ }
+ return;
+ }
+
+ BytePattern Pattern = shouldUseMemSetToInitialize(constant, ConstantSize);
+ if (!Pattern.isNone()) {
+ uint8_t Value = Pattern.isAny() ? 0x00 : Pattern.getValue();
+ Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, Value), SizeVal,
+ isVolatile);
+ return;
+ }
+
+ // Otherwise, create a temporary global with the initializer then memcpy from
+ // the global to the alloca.
+ std::string Name = getStaticDeclName(CGM, D);
+ unsigned AS = CGM.getContext().getTargetAddressSpace(
+ CGM.getStringLiteralAddressSpace());
+ llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(), AS);
+
+ llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+ CGM.getModule(), constant->getType(), true,
+ llvm::GlobalValue::PrivateLinkage, constant, Name, nullptr,
+ llvm::GlobalValue::NotThreadLocal, AS);
+ GV->setAlignment(Loc.getAlignment().getQuantity());
+ GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+
+ Address SrcPtr = Address(GV, Loc.getAlignment());
+ if (SrcPtr.getType() != BP)
+ SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
+
+ Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, isVolatile);
+}
+
/// EmitAutoVarDecl - Emit code and set up an entry in LocalDeclMap for a
/// variable declaration with auto, register, or no storage class specifier.
/// These turn into simple stack objects, or GlobalValues depending on target.
@@ -1500,57 +1555,11 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
// in various ways.
bool isVolatile = type.isVolatileQualified();
- llvm::Value *SizeVal =
- llvm::ConstantInt::get(IntPtrTy,
- getContext().getTypeSizeInChars(type).getQuantity());
-
llvm::Type *BP = CGM.Int8Ty->getPointerTo(Loc.getAddressSpace());
if (Loc.getType() != BP)
Loc = Builder.CreateBitCast(Loc, BP);
- // If the initializer is all or mostly the same, codegen with bzero / memset
- // then do a few stores afterward.
- uint64_t ConstantSize =
- CGM.getDataLayout().getTypeAllocSize(constant->getType());
- if (shouldUseBZeroPlusStoresToInitialize(constant, ConstantSize)) {
- Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, 0), SizeVal,
- isVolatile);
- // Zero and undef don't require a stores.
- if (!constant->isNullValue() && !isa<llvm::UndefValue>(constant)) {
- Loc = Builder.CreateBitCast(Loc,
- constant->getType()->getPointerTo(Loc.getAddressSpace()));
- emitStoresForInitAfterBZero(CGM, constant, Loc, isVolatile, Builder);
- }
- return;
- }
-
- BytePattern Pattern = shouldUseMemSetToInitialize(constant, ConstantSize);
- if (!Pattern.isNone()) {
- uint8_t Value = Pattern.isAny() ? 0x00 : Pattern.getValue();
- Builder.CreateMemSet(Loc, llvm::ConstantInt::get(Int8Ty, Value), SizeVal,
- isVolatile);
- return;
- }
-
- // Otherwise, create a temporary global with the initializer then
- // memcpy from the global to the alloca.
- std::string Name = getStaticDeclName(CGM, D);
- unsigned AS = CGM.getContext().getTargetAddressSpace(
- CGM.getStringLiteralAddressSpace());
- BP = llvm::PointerType::getInt8PtrTy(getLLVMContext(), AS);
-
- llvm::GlobalVariable *GV = new llvm::GlobalVariable(
- CGM.getModule(), constant->getType(), true,
- llvm::GlobalValue::PrivateLinkage, constant, Name, nullptr,
- llvm::GlobalValue::NotThreadLocal, AS);
- GV->setAlignment(Loc.getAlignment().getQuantity());
- GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-
- Address SrcPtr = Address(GV, Loc.getAlignment());
- if (SrcPtr.getType() != BP)
- SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
-
- Builder.CreateMemCpy(Loc, SrcPtr, SizeVal, isVolatile);
+ emitStoresForConstant(CGM, D, Loc, isVolatile, Builder, constant);
}
/// Emit an expression as an initializer for an object (variable, field, etc.)
OpenPOWER on IntegriCloud