[cfe-commits] r120530 - /cfe/trunk/lib/CodeGen/CGDecl.cpp
Chris Lattner
sabre at nondot.org
Tue Nov 30 18:05:19 PST 2010
Author: lattner
Date: Tue Nov 30 20:05:19 2010
New Revision: 120530
URL: http://llvm.org/viewvc/llvm-project?rev=120530&view=rev
Log:
add some infrastructure that will let us codegen
http://llvm.org/bugs/show_bug.cgi?id=279#c3 better.
No functionality change yet.
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=120530&r1=120529&r2=120530&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Nov 30 20:05:19 2010
@@ -507,6 +507,54 @@
};
}
+
+/// canEmitInitWithFewStoresAfterMemset - Decide whether we can emit the
+/// non-zero parts of the specified initializer with equal or fewer than
+/// NumStores scalar stores.
+static bool canEmitInitWithFewStoresAfterMemset(llvm::Constant *Init,
+ unsigned &NumStores) {
+ // Zero never requires any extra stores.
+ if (isa<llvm::ConstantAggregateZero>(Init)) return true;
+
+ // Anything else is hard and scary.
+ return false;
+}
+
+/// emitStoresForInitAfterMemset - For inits that
+/// canEmitInitWithFewStoresAfterMemset returned true for, emit the scalar
+/// stores that would be required.
+static void emitStoresForInitAfterMemset(llvm::Constant *Init, llvm::Value *Loc,
+ CGBuilderTy &Builder) {
+ // Zero doesn't require any stores.
+ if (isa<llvm::ConstantAggregateZero>(Init)) return;
+
+
+ assert(0 && "Unknown value type!");
+}
+
+
+/// shouldUseMemSetPlusStoresToInitialize - Decide whether we should use memset
+/// plus some stores to initialize a local variable instead of using a memcpy
+/// from a constant global. It is beneficial to use memset if the global is all
+/// zeros, or mostly zeros and large.
+static bool shouldUseMemSetPlusStoresToInitialize(llvm::Constant *Init,
+ uint64_t GlobalSize) {
+ // If a global is all zeros, always use a memset.
+ if (isa<llvm::ConstantAggregateZero>(Init)) return true;
+
+
+ // If a non-zero global is <= 32 bytes, always use a memcpy. If it is large,
+ // do it if it will require 6 or fewer scalar stores.
+ // TODO: Should budget depends on the size? Avoiding a large global warrants
+ // plopping in more stores.
+ unsigned StoreBudget = 6;
+ uint64_t SizeLimit = 32;
+
+ return GlobalSize > SizeLimit &&
+ canEmitInitWithFewStoresAfterMemset(Init, StoreBudget);
+}
+
+
/// EmitLocalVarDecl - 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.
@@ -680,7 +728,7 @@
flag |= BLOCK_FIELD_IS_WEAK;
int isa = 0;
- if (flag&BLOCK_FIELD_IS_WEAK)
+ if (flag & BLOCK_FIELD_IS_WEAK)
isa = 1;
V = Builder.CreateIntToPtr(Builder.getInt32(isa), PtrToInt8Ty, "isa");
Builder.CreateStore(V, isa_field);
@@ -735,11 +783,20 @@
llvm::Value *NotVolatile = Builder.getFalse();
- // If the initializer is all zeros, codegen with memset.
- if (isa<llvm::ConstantAggregateZero>(Init)) {
- llvm::Value *Zero = Builder.getInt8(0);
- Builder.CreateCall5(CGM.getMemSetFn(Loc->getType(), SizeVal->getType()),
- Loc, Zero, SizeVal, AlignVal, NotVolatile);
+ // If the initializer is all or mostly zeros, codegen with memset then do
+ // a few stores afterward.
+ if (shouldUseMemSetPlusStoresToInitialize(Init,
+ CGM.getTargetData().getTypeAllocSize(Init->getType()))) {
+ const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+ llvm::Value *MemSetDest = Loc;
+ if (MemSetDest->getType() != BP)
+ MemSetDest = Builder.CreateBitCast(MemSetDest, BP, "tmp");
+
+ Builder.CreateCall5(CGM.getMemSetFn(BP, SizeVal->getType()),
+ MemSetDest, Builder.getInt8(0), SizeVal, AlignVal,
+ NotVolatile);
+ emitStoresForInitAfterMemset(Init, Loc, Builder);
+
} else {
// Otherwise, create a temporary global with the initializer then
// memcpy from the global to the alloca.
@@ -754,6 +811,10 @@
if (SrcPtr->getType() != BP)
SrcPtr = Builder.CreateBitCast(SrcPtr, BP, "tmp");
+ const llvm::Type *BP = llvm::Type::getInt8PtrTy(VMContext);
+ if (Loc->getType() != BP)
+ Loc = Builder.CreateBitCast(Loc, BP, "tmp");
+
Builder.CreateCall5(CGM.getMemCpyFn(Loc->getType(), SrcPtr->getType(),
SizeVal->getType()),
Loc, SrcPtr, SizeVal, AlignVal, NotVolatile);
More information about the cfe-commits
mailing list