Merge remote-tracking branch 'origin/master' into merge-2.064

Conflicts:
	gen/arrays.cpp
This commit is contained in:
Kai Nacke 2013-12-19 21:27:53 +01:00
commit c231ae0ad0
5 changed files with 76 additions and 69 deletions

View file

@ -7,6 +7,9 @@ if(MSVC)
set(LIBCONFIG_DLL OFF CACHE BOOL "Use libconfig++ DLL instead of static library") set(LIBCONFIG_DLL OFF CACHE BOOL "Use libconfig++ DLL instead of static library")
endif() endif()
include(CheckIncludeFile)
include(CheckLibraryExists)
# #
# Locate LLVM. # Locate LLVM.
# #
@ -350,6 +353,35 @@ else()
add_definitions(-D__LITTLE_ENDIAN__) add_definitions(-D__LITTLE_ENDIAN__)
endif() endif()
#
# Check if libpthread is available.
# FIXME: Guard with LLVM_ENABLE_THREADS
#
if( NOT WIN32 OR CYGWIN )
check_include_file(pthread.h HAVE_PTHREAD_H)
check_library_exists(pthread pthread_create "" HAVE_LIBPTHREAD)
if(HAVE_LIBPTHREAD)
set(PTHREAD_LIBS -lpthread)
endif()
endif()
#
# Check if terminfo is available.
# FIXME: Guard with LLVM_ENABLE_TERMINFO
#
if( NOT WIN32 OR CYGWIN )
set(HAVE_TERMINFO 0)
foreach(library tinfo terminfo curses ncurses ncursesw)
string(TOUPPER ${library} library_suffix)
check_library_exists(${library} setupterm "" HAVE_TERMINFO_${library_suffix})
if(HAVE_TERMINFO_${library_suffix})
set(HAVE_TERMINFO 1)
set(TERMINFO_LIBS "${library}")
break()
endif()
endforeach()
endif()
# #
# Set up the main ldc/ldc2 target. # Set up the main ldc/ldc2 target.
# #
@ -374,7 +406,7 @@ set_target_properties(
) )
# LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems # LDFLAGS should actually be in target property LINK_FLAGS, but this works, and gets around linking problems
target_link_libraries(${LDC_LIB} ${LLVM_LIBRARIES} "${LLVM_LDFLAGS}") target_link_libraries(${LDC_LIB} ${LLVM_LIBRARIES} ${PTHREAD_LIBS} ${TERMINFO_LIBS} "${LLVM_LDFLAGS}")
if(WIN32) if(WIN32)
target_link_libraries(${LDC_LIB} imagehlp psapi) target_link_libraries(${LDC_LIB} imagehlp psapi)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -394,7 +426,7 @@ set_target_properties(
COMPILE_FLAGS "${LLVM_CXXFLAGS} ${EXTRA_CXXFLAGS}" COMPILE_FLAGS "${LLVM_CXXFLAGS} ${EXTRA_CXXFLAGS}"
LINK_FLAGS "${SANITIZE_LDFLAGS}" LINK_FLAGS "${SANITIZE_LDFLAGS}"
) )
target_link_libraries(${LDC_EXE} ${LDC_LIB} ${LIBCONFIG++_LIBRARY}) target_link_libraries(${LDC_EXE} ${LDC_LIB} ${LIBCONFIG++_LIBRARY} ${PTHREAD_LIBS} ${CMAKE_DL_LIBS} ${TERMINFO_LIBS})
if(MSVC) if(MSVC)
# Add a post build event in Visual Studio to copy the config file into Debug/Release folder # Add a post build event in Visual Studio to copy the config file into Debug/Release folder
add_custom_command(TARGET ${LDC_EXE} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}.conf $<TARGET_FILE_DIR:${LDC_EXE}> COMMENT "Copy config file ${LDC_EXE}.conf") add_custom_command(TARGET ${LDC_EXE} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/bin/${LDC_EXE}.conf $<TARGET_FILE_DIR:${LDC_EXE}> COMMENT "Copy config file ${LDC_EXE}.conf")
@ -432,7 +464,7 @@ set_target_properties(
COMPILE_FLAGS "${TABLEGEN_CXXFLAGS} ${LDC_CXXFLAGS}" COMPILE_FLAGS "${TABLEGEN_CXXFLAGS} ${LDC_CXXFLAGS}"
LINK_FLAGS "${SANITIZE_LDFLAGS}" LINK_FLAGS "${SANITIZE_LDFLAGS}"
) )
target_link_libraries(gen_gccbuiltins ${LLVM_LIBRARIES} "${LLVM_LDFLAGS}") target_link_libraries(gen_gccbuiltins ${LLVM_LIBRARIES} ${PTHREAD_LIBS} ${TERMINFO_LIBS} ${CMAKE_DL_LIBS} "${LLVM_LDFLAGS}")
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries(gen_gccbuiltins dl) target_link_libraries(gen_gccbuiltins dl)
endif() endif()
@ -463,7 +495,7 @@ set_target_properties(${LDMD_EXE} PROPERTIES
# use symbols from libdl, ..., so LLVM_LDFLAGS must come _after_ them in the # use symbols from libdl, ..., so LLVM_LDFLAGS must come _after_ them in the
# command line. Maybe this could be improved using library groups, at least with # command line. Maybe this could be improved using library groups, at least with
# GNU ld. # GNU ld.
target_link_libraries(${LDMD_EXE} ${LLVM_LIBRARIES} "${LLVM_LDFLAGS}") target_link_libraries(${LDMD_EXE} ${LLVM_LIBRARIES} ${PTHREAD_LIBS} ${TERMINFO_LIBS} ${CMAKE_DL_LIBS} "${LLVM_LDFLAGS}")
# #
# Test and runtime targets. Note that enable_testing() is order-sensitive! # Test and runtime targets. Note that enable_testing() is order-sensitive!

View file

@ -52,6 +52,9 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
assert(f->next && "Encountered function type with invalid return type; " assert(f->next && "Encountered function type with invalid return type; "
"trying to codegen function ignored by the frontend?"); "trying to codegen function ignored by the frontend?");
// Return cached type if available
if (irFty.funcType) return irFty.funcType;
TargetABI* abi = (f->linkage == LINKintrinsic ? TargetABI::getIntrinsic() : gABI); TargetABI* abi = (f->linkage == LINKintrinsic ? TargetABI::getIntrinsic() : gABI);
// Tell the ABI we're resolving a new function type // Tell the ABI we're resolving a new function type
abi->newFunctionType(f); abi->newFunctionType(f);
@ -285,11 +288,11 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
std::reverse(argtypes.begin() + beg, argtypes.end()); std::reverse(argtypes.begin() + beg, argtypes.end());
} }
LLFunctionType* functype = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg); irFty.funcType = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);
Logger::cout() << "Final function type: " << *functype << "\n"; Logger::cout() << "Final function type: " << *irFty.funcType << "\n";
return functype; return irFty.funcType;
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////

View file

@ -56,6 +56,10 @@
using namespace llvm; using namespace llvm;
#if LDC_LLVM_VER < 302
typedef TargetData DataLayout;
#endif
STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas"); STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas"); STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas");
STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused"); STATISTIC(NumDeleted, "Number of GC calls deleted because the return value was unused");
@ -66,11 +70,7 @@ SizeLimit("dgc2stack-size-limit", cl::init(1024), cl::Hidden,
namespace { namespace {
struct Analysis { struct Analysis {
#if LDC_LLVM_VER >= 302 DataLayout& DL;
DataLayout& TD;
#else
TargetData& TD;
#endif
const Module& M; const Module& M;
CallGraph* CG; CallGraph* CG;
CallGraphNode* CGNode; CallGraphNode* CGNode;
@ -151,7 +151,7 @@ namespace {
APInt Mask = APInt::getLowBitsSet(Bits, BitsLimit); APInt Mask = APInt::getLowBitsSet(Bits, BitsLimit);
Mask.flipAllBits(); Mask.flipAllBits();
APInt KnownZero(Bits, 0), KnownOne(Bits, 0); APInt KnownZero(Bits, 0), KnownOne(Bits, 0);
ComputeMaskedBits(Val, KnownZero, KnownOne, &A.TD); ComputeMaskedBits(Val, KnownZero, KnownOne, &A.DL);
if ((KnownZero & Mask) != Mask) if ((KnownZero & Mask) != Mask)
return false; return false;
@ -171,7 +171,7 @@ namespace {
Value* TypeInfo = CS.getArgument(TypeInfoArgNr); Value* TypeInfo = CS.getArgument(TypeInfoArgNr);
Ty = A.getTypeFor(TypeInfo); Ty = A.getTypeFor(TypeInfo);
if (!Ty) return false; if (!Ty) return false;
return A.TD.getTypeAllocSize(Ty) < SizeLimit; return A.DL.getTypeAllocSize(Ty) < SizeLimit;
} }
}; };
@ -207,7 +207,7 @@ namespace {
// (set bits) inference algorithm is rather limited, this is // (set bits) inference algorithm is rather limited, this is
// useful for experimenting. // useful for experimenting.
if (SizeLimit > 0) { if (SizeLimit > 0) {
uint64_t ElemSize = A.TD.getTypeAllocSize(Ty); uint64_t ElemSize = A.DL.getTypeAllocSize(Ty);
if (!isKnownLessThan(arrSize, SizeLimit / ElemSize, A)) if (!isKnownLessThan(arrSize, SizeLimit / ElemSize, A))
return false; return false;
} }
@ -237,7 +237,7 @@ namespace {
if (Initialized) { if (Initialized) {
// For now, only zero-init is supported. // For now, only zero-init is supported.
uint64_t size = A.TD.getTypeStoreSize(Ty); uint64_t size = A.DL.getTypeStoreSize(Ty);
Value* TypeSize = ConstantInt::get(arrSize->getType(), size); Value* TypeSize = ConstantInt::get(arrSize->getType(), size);
// Use the original B to put initialization at the // Use the original B to put initialization at the
// allocation site. // allocation site.
@ -295,7 +295,7 @@ namespace {
return false; return false;
Ty =node->getOperand(CD_BodyType)->getType(); Ty =node->getOperand(CD_BodyType)->getType();
return A.TD.getTypeAllocSize(Ty) < SizeLimit; return A.DL.getTypeAllocSize(Ty) < SizeLimit;
} }
// The default promote() should be fine. // The default promote() should be fine.
@ -390,11 +390,7 @@ namespace {
bool runOnFunction(Function &F); bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
#if LDC_LLVM_VER >= 302
AU.addRequired<DataLayout>(); AU.addRequired<DataLayout>();
#else
AU.addRequired<TargetData>();
#endif
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
#if LDC_LLVM_VER >= 305 #if LDC_LLVM_VER >= 305
@ -458,11 +454,7 @@ static bool isSafeToStackAllocate(Instruction* Alloc, Value* V, DominatorTree& D
bool GarbageCollect2Stack::runOnFunction(Function &F) { bool GarbageCollect2Stack::runOnFunction(Function &F) {
DEBUG(errs() << "\nRunning -dgc2stack on function " << F.getName() << '\n'); DEBUG(errs() << "\nRunning -dgc2stack on function " << F.getName() << '\n');
#if LDC_LLVM_VER >= 302 DataLayout& DL = getAnalysis<DataLayout>();
DataLayout& TD = getAnalysis<DataLayout>();
#else
TargetData& TD = getAnalysis<TargetData>();
#endif
DominatorTree& DT = getAnalysis<DominatorTree>(); DominatorTree& DT = getAnalysis<DominatorTree>();
#if LDC_LLVM_VER >= 305 #if LDC_LLVM_VER >= 305
CallGraphWrapperPass* CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>(); CallGraphWrapperPass* CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>();
@ -472,7 +464,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
#endif #endif
CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL; CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL;
Analysis A = { TD, *M, CG, CGNode }; Analysis A = { DL, *M, CG, CGNode };
BasicBlock& Entry = F.getEntryBlock(); BasicBlock& Entry = F.getEntryBlock();

View file

@ -45,6 +45,10 @@
using namespace llvm; using namespace llvm;
#if LDC_LLVM_VER < 302
typedef TargetData DataLayout;
#endif
STATISTIC(NumSimplified, "Number of runtime calls simplified"); STATISTIC(NumSimplified, "Number of runtime calls simplified");
STATISTIC(NumDeleted, "Number of runtime calls deleted"); STATISTIC(NumDeleted, "Number of runtime calls deleted");
@ -59,11 +63,7 @@ namespace {
protected: protected:
Function *Caller; Function *Caller;
bool* Changed; bool* Changed;
#if LDC_LLVM_VER >= 302 const DataLayout *DL;
const DataLayout *TD;
#else
const TargetData *TD;
#endif
AliasAnalysis *AA; AliasAnalysis *AA;
LLVMContext *Context; LLVMContext *Context;
@ -85,16 +85,11 @@ namespace {
/// delete CI. /// delete CI.
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0; virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
#if LDC_LLVM_VER >= 302 Value *OptimizeCall(CallInst *CI, bool& Changed, const DataLayout &DL,
Value *OptimizeCall(CallInst *CI, bool& Changed, const DataLayout &TD,
AliasAnalysis& AA, IRBuilder<> &B) { AliasAnalysis& AA, IRBuilder<> &B) {
#else
Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
AliasAnalysis& AA, IRBuilder<> &B) {
#endif
Caller = CI->getParent()->getParent(); Caller = CI->getParent()->getParent();
this->Changed = &Changed; this->Changed = &Changed;
this->TD = &TD; this->DL = &DL;
this->AA = &AA; this->AA = &AA;
if (CI->getCalledFunction()) if (CI->getCalledFunction())
Context = &CI->getCalledFunction()->getContext(); Context = &CI->getCalledFunction()->getContext();
@ -112,14 +107,7 @@ Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
/// expects that the size has type 'intptr_t' and Dst/Src are pointers. /// expects that the size has type 'intptr_t' and Dst/Src are pointers.
Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
unsigned Align, IRBuilder<> &B) { unsigned Align, IRBuilder<> &B) {
Module *M = Caller->getParent(); return B.CreateMemCpy(CastToCStr(Dst, B), CastToCStr(Src, B), Len, Align, false);
Type* intTy = Len->getType();
Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty());
Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy};
Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, llvm::makeArrayRef(Tys, 3));
return B.CreateCall5(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
ConstantInt::get(B.getInt32Ty(), Align), B.getFalse());
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -312,18 +300,10 @@ namespace {
void InitOptimizations(); void InitOptimizations();
bool runOnFunction(Function &F); bool runOnFunction(Function &F);
#if LDC_LLVM_VER >= 302
bool runOnce(Function &F, const DataLayout& DL, AliasAnalysis& AA); bool runOnce(Function &F, const DataLayout& DL, AliasAnalysis& AA);
#else
bool runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA);
#endif
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
#if LDC_LLVM_VER >= 302
AU.addRequired<DataLayout>(); AU.addRequired<DataLayout>();
#else
AU.addRequired<TargetData>();
#endif
AU.addRequired<AliasAnalysis>(); AU.addRequired<AliasAnalysis>();
} }
}; };
@ -373,11 +353,7 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
if (Optimizations.empty()) if (Optimizations.empty())
InitOptimizations(); InitOptimizations();
#if LDC_LLVM_VER >= 302 const DataLayout &DL = getAnalysis<DataLayout>();
const DataLayout &TD = getAnalysis<DataLayout>();
#else
const TargetData &TD = getAnalysis<TargetData>();
#endif
AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
// Iterate to catch opportunities opened up by other optimizations, // Iterate to catch opportunities opened up by other optimizations,
@ -388,18 +364,14 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
bool EverChanged = false; bool EverChanged = false;
bool Changed; bool Changed;
do { do {
Changed = runOnce(F, TD, AA); Changed = runOnce(F, DL, AA);
EverChanged |= Changed; EverChanged |= Changed;
} while (Changed); } while (Changed);
return EverChanged; return EverChanged;
} }
#if LDC_LLVM_VER >= 302 bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout& DL, AliasAnalysis& AA) {
bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout& TD, AliasAnalysis& AA) {
#else
bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
#endif
IRBuilder<> Builder(F.getContext()); IRBuilder<> Builder(F.getContext());
bool Changed = false; bool Changed = false;
@ -426,7 +398,7 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnal
Builder.SetInsertPoint(BB, I); Builder.SetInsertPoint(BB, I);
// Try to optimize this call. // Try to optimize this call.
Value *Result = OMI->second->OptimizeCall(CI, Changed, TD, AA, Builder); Value *Result = OMI->second->OptimizeCall(CI, Changed, DL, AA, Builder);
if (Result == 0) continue; if (Result == 0) continue;
DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI; DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI;

View file

@ -33,6 +33,7 @@ namespace llvm {
class Value; class Value;
class Instruction; class Instruction;
class Function; class Function;
class FunctionType;
} }
// represents a function type argument // represents a function type argument
@ -87,6 +88,9 @@ struct IrFuncTyArg
// represents a function type // represents a function type
struct IrFuncTy struct IrFuncTy
{ {
// The final LLVM type
llvm::FunctionType* funcType;
// return value // return value
IrFuncTyArg* ret; IrFuncTyArg* ret;
@ -111,7 +115,8 @@ struct IrFuncTy
bool reverseParams; bool reverseParams;
IrFuncTy() IrFuncTy()
: ret(NULL), : funcType(0),
ret(NULL),
arg_sret(NULL), arg_sret(NULL),
arg_this(NULL), arg_this(NULL),
arg_nest(NULL), arg_nest(NULL),
@ -126,7 +131,8 @@ struct IrFuncTy
// Copy constructor and operator= seems to be required for MSC // Copy constructor and operator= seems to be required for MSC
IrFuncTy(const IrFuncTy& rhs) IrFuncTy(const IrFuncTy& rhs)
: ret(rhs.ret), : funcType(ths.funcType),
ret(rhs.ret),
args(IrFuncTy::ArgList(rhs.args)), args(IrFuncTy::ArgList(rhs.args)),
arg_sret(rhs.arg_sret), arg_sret(rhs.arg_sret),
arg_this(rhs.arg_this), arg_this(rhs.arg_this),
@ -139,6 +145,7 @@ struct IrFuncTy
IrFuncTy& operator=(const IrFuncTy& rhs) IrFuncTy& operator=(const IrFuncTy& rhs)
{ {
funcType = rhs.funcType;
ret = rhs.ret; ret = rhs.ret;
args = IrFuncTy::ArgList(rhs.args); args = IrFuncTy::ArgList(rhs.args);
arg_sret = rhs.arg_sret; arg_sret = rhs.arg_sret;
@ -153,6 +160,7 @@ struct IrFuncTy
#endif #endif
void reset() { void reset() {
funcType = 0;
ret = NULL; ret = NULL;
arg_sret = arg_this = arg_nest = arg_arguments = arg_argptr = NULL; arg_sret = arg_this = arg_nest = arg_arguments = arg_argptr = NULL;
#if defined(_MSC_VER) #if defined(_MSC_VER)