mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 15:40:55 +03:00
Merge remote-tracking branch 'origin/master' into merge-2.064
Conflicts: gen/arrays.cpp
This commit is contained in:
commit
c231ae0ad0
5 changed files with 76 additions and 69 deletions
|
@ -7,6 +7,9 @@ if(MSVC)
|
|||
set(LIBCONFIG_DLL OFF CACHE BOOL "Use libconfig++ DLL instead of static library")
|
||||
endif()
|
||||
|
||||
include(CheckIncludeFile)
|
||||
include(CheckLibraryExists)
|
||||
|
||||
#
|
||||
# Locate LLVM.
|
||||
#
|
||||
|
@ -350,6 +353,35 @@ else()
|
|||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
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.
|
||||
#
|
||||
|
@ -374,7 +406,7 @@ set_target_properties(
|
|||
)
|
||||
|
||||
# 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)
|
||||
target_link_libraries(${LDC_LIB} imagehlp psapi)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
@ -394,7 +426,7 @@ set_target_properties(
|
|||
COMPILE_FLAGS "${LLVM_CXXFLAGS} ${EXTRA_CXXFLAGS}"
|
||||
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)
|
||||
# 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")
|
||||
|
@ -432,7 +464,7 @@ set_target_properties(
|
|||
COMPILE_FLAGS "${TABLEGEN_CXXFLAGS} ${LDC_CXXFLAGS}"
|
||||
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")
|
||||
target_link_libraries(gen_gccbuiltins dl)
|
||||
endif()
|
||||
|
@ -463,7 +495,7 @@ set_target_properties(${LDMD_EXE} PROPERTIES
|
|||
# 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
|
||||
# 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!
|
||||
|
|
|
@ -52,6 +52,9 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
|||
assert(f->next && "Encountered function type with invalid return type; "
|
||||
"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);
|
||||
// Tell the ABI we're resolving a new function type
|
||||
abi->newFunctionType(f);
|
||||
|
@ -285,11 +288,11 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
|
|||
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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -56,6 +56,10 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
#if LDC_LLVM_VER < 302
|
||||
typedef TargetData DataLayout;
|
||||
#endif
|
||||
|
||||
STATISTIC(NumGcToStack, "Number of calls promoted to constant-size allocas");
|
||||
STATISTIC(NumToDynSize, "Number of calls promoted to dynamically-sized allocas");
|
||||
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 {
|
||||
struct Analysis {
|
||||
#if LDC_LLVM_VER >= 302
|
||||
DataLayout& TD;
|
||||
#else
|
||||
TargetData& TD;
|
||||
#endif
|
||||
DataLayout& DL;
|
||||
const Module& M;
|
||||
CallGraph* CG;
|
||||
CallGraphNode* CGNode;
|
||||
|
@ -151,7 +151,7 @@ namespace {
|
|||
APInt Mask = APInt::getLowBitsSet(Bits, BitsLimit);
|
||||
Mask.flipAllBits();
|
||||
APInt KnownZero(Bits, 0), KnownOne(Bits, 0);
|
||||
ComputeMaskedBits(Val, KnownZero, KnownOne, &A.TD);
|
||||
ComputeMaskedBits(Val, KnownZero, KnownOne, &A.DL);
|
||||
|
||||
if ((KnownZero & Mask) != Mask)
|
||||
return false;
|
||||
|
@ -171,7 +171,7 @@ namespace {
|
|||
Value* TypeInfo = CS.getArgument(TypeInfoArgNr);
|
||||
Ty = A.getTypeFor(TypeInfo);
|
||||
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
|
||||
// useful for experimenting.
|
||||
if (SizeLimit > 0) {
|
||||
uint64_t ElemSize = A.TD.getTypeAllocSize(Ty);
|
||||
uint64_t ElemSize = A.DL.getTypeAllocSize(Ty);
|
||||
if (!isKnownLessThan(arrSize, SizeLimit / ElemSize, A))
|
||||
return false;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ namespace {
|
|||
|
||||
if (Initialized) {
|
||||
// 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);
|
||||
// Use the original B to put initialization at the
|
||||
// allocation site.
|
||||
|
@ -295,7 +295,7 @@ namespace {
|
|||
return false;
|
||||
|
||||
Ty =node->getOperand(CD_BodyType)->getType();
|
||||
return A.TD.getTypeAllocSize(Ty) < SizeLimit;
|
||||
return A.DL.getTypeAllocSize(Ty) < SizeLimit;
|
||||
}
|
||||
|
||||
// The default promote() should be fine.
|
||||
|
@ -390,11 +390,7 @@ namespace {
|
|||
bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
#if LDC_LLVM_VER >= 302
|
||||
AU.addRequired<DataLayout>();
|
||||
#else
|
||||
AU.addRequired<TargetData>();
|
||||
#endif
|
||||
AU.addRequired<DominatorTree>();
|
||||
|
||||
#if LDC_LLVM_VER >= 305
|
||||
|
@ -458,11 +454,7 @@ static bool isSafeToStackAllocate(Instruction* Alloc, Value* V, DominatorTree& D
|
|||
bool GarbageCollect2Stack::runOnFunction(Function &F) {
|
||||
DEBUG(errs() << "\nRunning -dgc2stack on function " << F.getName() << '\n');
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
DataLayout& TD = getAnalysis<DataLayout>();
|
||||
#else
|
||||
TargetData& TD = getAnalysis<TargetData>();
|
||||
#endif
|
||||
DataLayout& DL = getAnalysis<DataLayout>();
|
||||
DominatorTree& DT = getAnalysis<DominatorTree>();
|
||||
#if LDC_LLVM_VER >= 305
|
||||
CallGraphWrapperPass* CGPass = getAnalysisIfAvailable<CallGraphWrapperPass>();
|
||||
|
@ -472,7 +464,7 @@ bool GarbageCollect2Stack::runOnFunction(Function &F) {
|
|||
#endif
|
||||
CallGraphNode* CGNode = CG ? (*CG)[&F] : NULL;
|
||||
|
||||
Analysis A = { TD, *M, CG, CGNode };
|
||||
Analysis A = { DL, *M, CG, CGNode };
|
||||
|
||||
BasicBlock& Entry = F.getEntryBlock();
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
#if LDC_LLVM_VER < 302
|
||||
typedef TargetData DataLayout;
|
||||
#endif
|
||||
|
||||
STATISTIC(NumSimplified, "Number of runtime calls simplified");
|
||||
STATISTIC(NumDeleted, "Number of runtime calls deleted");
|
||||
|
||||
|
@ -59,11 +63,7 @@ namespace {
|
|||
protected:
|
||||
Function *Caller;
|
||||
bool* Changed;
|
||||
#if LDC_LLVM_VER >= 302
|
||||
const DataLayout *TD;
|
||||
#else
|
||||
const TargetData *TD;
|
||||
#endif
|
||||
const DataLayout *DL;
|
||||
AliasAnalysis *AA;
|
||||
LLVMContext *Context;
|
||||
|
||||
|
@ -85,16 +85,11 @@ namespace {
|
|||
/// delete CI.
|
||||
virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)=0;
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
Value *OptimizeCall(CallInst *CI, bool& Changed, const DataLayout &TD,
|
||||
Value *OptimizeCall(CallInst *CI, bool& Changed, const DataLayout &DL,
|
||||
AliasAnalysis& AA, IRBuilder<> &B) {
|
||||
#else
|
||||
Value *OptimizeCall(CallInst *CI, bool& Changed, const TargetData &TD,
|
||||
AliasAnalysis& AA, IRBuilder<> &B) {
|
||||
#endif
|
||||
Caller = CI->getParent()->getParent();
|
||||
this->Changed = &Changed;
|
||||
this->TD = &TD;
|
||||
this->DL = &DL;
|
||||
this->AA = &AA;
|
||||
if (CI->getCalledFunction())
|
||||
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.
|
||||
Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
|
||||
unsigned Align, IRBuilder<> &B) {
|
||||
Module *M = Caller->getParent();
|
||||
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());
|
||||
return B.CreateMemCpy(CastToCStr(Dst, B), CastToCStr(Src, B), Len, Align, false);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -312,18 +300,10 @@ namespace {
|
|||
void InitOptimizations();
|
||||
bool runOnFunction(Function &F);
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
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 {
|
||||
#if LDC_LLVM_VER >= 302
|
||||
AU.addRequired<DataLayout>();
|
||||
#else
|
||||
AU.addRequired<TargetData>();
|
||||
#endif
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
}
|
||||
};
|
||||
|
@ -373,11 +353,7 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
|
|||
if (Optimizations.empty())
|
||||
InitOptimizations();
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
const DataLayout &TD = getAnalysis<DataLayout>();
|
||||
#else
|
||||
const TargetData &TD = getAnalysis<TargetData>();
|
||||
#endif
|
||||
const DataLayout &DL = getAnalysis<DataLayout>();
|
||||
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
||||
|
||||
// Iterate to catch opportunities opened up by other optimizations,
|
||||
|
@ -388,18 +364,14 @@ bool SimplifyDRuntimeCalls::runOnFunction(Function &F) {
|
|||
bool EverChanged = false;
|
||||
bool Changed;
|
||||
do {
|
||||
Changed = runOnce(F, TD, AA);
|
||||
Changed = runOnce(F, DL, AA);
|
||||
EverChanged |= Changed;
|
||||
} while (Changed);
|
||||
|
||||
return EverChanged;
|
||||
}
|
||||
|
||||
#if LDC_LLVM_VER >= 302
|
||||
bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout& TD, AliasAnalysis& AA) {
|
||||
#else
|
||||
bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnalysis& AA) {
|
||||
#endif
|
||||
bool SimplifyDRuntimeCalls::runOnce(Function &F, const DataLayout& DL, AliasAnalysis& AA) {
|
||||
IRBuilder<> Builder(F.getContext());
|
||||
|
||||
bool Changed = false;
|
||||
|
@ -426,7 +398,7 @@ bool SimplifyDRuntimeCalls::runOnce(Function &F, const TargetData& TD, AliasAnal
|
|||
Builder.SetInsertPoint(BB, I);
|
||||
|
||||
// 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;
|
||||
|
||||
DEBUG(errs() << "SimplifyDRuntimeCalls simplified: " << *CI;
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace llvm {
|
|||
class Value;
|
||||
class Instruction;
|
||||
class Function;
|
||||
class FunctionType;
|
||||
}
|
||||
|
||||
// represents a function type argument
|
||||
|
@ -87,6 +88,9 @@ struct IrFuncTyArg
|
|||
// represents a function type
|
||||
struct IrFuncTy
|
||||
{
|
||||
// The final LLVM type
|
||||
llvm::FunctionType* funcType;
|
||||
|
||||
// return value
|
||||
IrFuncTyArg* ret;
|
||||
|
||||
|
@ -111,7 +115,8 @@ struct IrFuncTy
|
|||
bool reverseParams;
|
||||
|
||||
IrFuncTy()
|
||||
: ret(NULL),
|
||||
: funcType(0),
|
||||
ret(NULL),
|
||||
arg_sret(NULL),
|
||||
arg_this(NULL),
|
||||
arg_nest(NULL),
|
||||
|
@ -126,7 +131,8 @@ struct IrFuncTy
|
|||
// Copy constructor and operator= seems to be required for MSC
|
||||
|
||||
IrFuncTy(const IrFuncTy& rhs)
|
||||
: ret(rhs.ret),
|
||||
: funcType(ths.funcType),
|
||||
ret(rhs.ret),
|
||||
args(IrFuncTy::ArgList(rhs.args)),
|
||||
arg_sret(rhs.arg_sret),
|
||||
arg_this(rhs.arg_this),
|
||||
|
@ -139,6 +145,7 @@ struct IrFuncTy
|
|||
|
||||
IrFuncTy& operator=(const IrFuncTy& rhs)
|
||||
{
|
||||
funcType = rhs.funcType;
|
||||
ret = rhs.ret;
|
||||
args = IrFuncTy::ArgList(rhs.args);
|
||||
arg_sret = rhs.arg_sret;
|
||||
|
@ -153,6 +160,7 @@ struct IrFuncTy
|
|||
#endif
|
||||
|
||||
void reset() {
|
||||
funcType = 0;
|
||||
ret = NULL;
|
||||
arg_sret = arg_this = arg_nest = arg_arguments = arg_argptr = NULL;
|
||||
#if defined(_MSC_VER)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue