diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c5eb198..fa2e0741 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,7 +149,7 @@ if(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") else(LLVM_CONFIG_FILE_PATH STREQUAL "LLVM_CONFIG_FILE_PATH-NOTFOUND") file(STRINGS ${LLVM_CONFIG_FILE_PATH}/config.h LLVM_NATIVE_ARCH REGEX "^#define LLVM_NATIVE_ARCH") if(LLVM_NATIVE_ARCH) - string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)Target$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) + string(REGEX REPLACE "^#define LLVM_NATIVE_ARCH (.*)(Target|)$" "\\1" LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH}) message(STATUS "Found native target ${LLVM_NATIVE_ARCH}") set(LLVM_MODULES_DEFINE "LLVM_TARGET(${LLVM_NATIVE_ARCH})") else(LLVM_NATIVE_ARCH) diff --git a/gen/binops.cpp b/gen/binops.cpp index 95781d17..340ffa5a 100644 --- a/gen/binops.cpp +++ b/gen/binops.cpp @@ -12,24 +12,56 @@ DValue* DtoBinAdd(DValue* lhs, DValue* rhs) { - LLValue* v = gIR->ir->CreateAdd(lhs->getRVal(), rhs->getRVal(), "tmp"); - return new DImValue( lhs->getType(), v ); + Type* t = lhs->getType(); + LLValue *l, *r; + l = lhs->getRVal(); + r = rhs->getRVal(); + assert(l->isintegral == r->isintegral); + + LLValue* res; + if (t->isfloating()) + res = gIR->ir->CreateFAdd(l, r, "tmp"); + else + res = gIR->ir->CreateAdd(l, r, "tmp"); + + return new DImValue( t, res ); } ////////////////////////////////////////////////////////////////////////////// DValue* DtoBinSub(DValue* lhs, DValue* rhs) { - LLValue* v = gIR->ir->CreateSub(lhs->getRVal(), rhs->getRVal(), "tmp"); - return new DImValue( lhs->getType(), v ); + Type* t = lhs->getType(); + LLValue *l, *r; + l = lhs->getRVal(); + r = rhs->getRVal(); + assert(l->isintegral == r->isintegral); + + LLValue* res; + if (t->isfloating()) + res = gIR->ir->CreateFSub(l, r, "tmp"); + else + res = gIR->ir->CreateSub(l, r, "tmp"); + + return new DImValue( t, res ); } ////////////////////////////////////////////////////////////////////////////// DValue* DtoBinMul(Type* targettype, DValue* lhs, DValue* rhs) { - LLValue* v = gIR->ir->CreateMul(lhs->getRVal(), rhs->getRVal(), "tmp"); - return new DImValue( targettype, v ); + Type* t = lhs->getType(); + LLValue *l, *r; + l = lhs->getRVal(); + r = rhs->getRVal(); + assert(l->isintegral == r->isintegral); + + LLValue* res; + if (t->isfloating()) + res = gIR->ir->CreateFMul(l, r, "tmp"); + else + res = gIR->ir->CreateMul(l, r, "tmp"); + return new DImValue( targettype, res ); } ////////////////////////////////////////////////////////////////////////////// @@ -40,6 +72,7 @@ DValue* DtoBinDiv(Type* targettype, DValue* lhs, DValue* rhs) LLValue *l, *r; l = lhs->getRVal(); r = rhs->getRVal(); + LLValue* res; if (t->isfloating()) res = gIR->ir->CreateFDiv(l, r, "tmp"); diff --git a/gen/complex.cpp b/gen/complex.cpp index 4fa98851..652a3992 100644 --- a/gen/complex.cpp +++ b/gen/complex.cpp @@ -191,14 +191,14 @@ DValue* DtoComplexAdd(Loc& loc, Type* type, DValue* lhs, DValue* rhs) // add up if(lhs_re && rhs_re) - res_re = gIR->ir->CreateAdd(lhs_re, rhs_re, "tmp"); + res_re = gIR->ir->CreateFAdd(lhs_re, rhs_re, "tmp"); else if(lhs_re) res_re = lhs_re; else // either rhs_re or no re at all (then use any) res_re = rhs_re; if(lhs_im && rhs_im) - res_im = gIR->ir->CreateAdd(lhs_im, rhs_im, "tmp"); + res_im = gIR->ir->CreateFAdd(lhs_im, rhs_im, "tmp"); else if(lhs_im) res_im = lhs_im; else // either rhs_im or no im at all (then use any) @@ -221,18 +221,18 @@ DValue* DtoComplexSub(Loc& loc, Type* type, DValue* lhs, DValue* rhs) // add up if(lhs_re && rhs_re) - res_re = gIR->ir->CreateSub(lhs_re, rhs_re, "tmp"); + res_re = gIR->ir->CreateFSub(lhs_re, rhs_re, "tmp"); else if(lhs_re) res_re = lhs_re; else // either rhs_re or no re at all (then use any) - res_re = gIR->ir->CreateNeg(rhs_re, "neg"); + res_re = gIR->ir->CreateFNeg(rhs_re, "neg"); if(lhs_im && rhs_im) - res_im = gIR->ir->CreateSub(lhs_im, rhs_im, "tmp"); + res_im = gIR->ir->CreateFSub(lhs_im, rhs_im, "tmp"); else if(lhs_im) res_im = lhs_im; else // either rhs_im or no im at all (then use any) - res_im = gIR->ir->CreateNeg(rhs_im, "neg"); + res_im = gIR->ir->CreateFNeg(rhs_im, "neg"); LLValue* res = DtoAggrPair(DtoType(type), res_re, res_im); return new DImValue(type, res); @@ -256,25 +256,25 @@ DValue* DtoComplexMul(Loc& loc, Type* type, DValue* lhs, DValue* rhs) llvm::Value *imim = NULL; if(lhs_re && rhs_re) - rere = gIR->ir->CreateMul(lhs_re, rhs_re, "rere_mul"); + rere = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere_mul"); if(lhs_re && rhs_im) - reim = gIR->ir->CreateMul(lhs_re, rhs_im, "reim_mul"); + reim = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim_mul"); if(lhs_im && rhs_re) - imre = gIR->ir->CreateMul(lhs_im, rhs_re, "imre_mul"); + imre = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre_mul"); if(lhs_im && rhs_im) - imim = gIR->ir->CreateMul(lhs_im, rhs_im, "imim_mul"); + imim = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim_mul"); if(rere && imim) - res_re = gIR->ir->CreateSub(rere, imim, "rere_imim_sub"); + res_re = gIR->ir->CreateFSub(rere, imim, "rere_imim_sub"); else if(rere) res_re = rere; else if(imim) - res_re = gIR->ir->CreateNeg(imim, "imim_neg"); + res_re = gIR->ir->CreateFNeg(imim, "imim_neg"); else res_re = lhs_re ? rhs_re : lhs_re; // null! if(reim && imre) - res_im = gIR->ir->CreateAdd(reim, imre, "reim_imre_add"); + res_im = gIR->ir->CreateFAdd(reim, imre, "reim_imre_add"); else if(reim) res_im = reim; else if(imre) @@ -311,7 +311,7 @@ DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) // if divisor is only imaginary, division is simple too else if(!rhs_re && rhs_im) { if(lhs_re) - res_im = gIR->ir->CreateNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg"); + res_im = gIR->ir->CreateFNeg(gIR->ir->CreateFDiv(lhs_re, rhs_im, "re_divby_im"), "neg"); else res_im = lhs_re; if(lhs_im) @@ -324,30 +324,30 @@ DValue* DtoComplexDiv(Loc& loc, Type* type, DValue* lhs, DValue* rhs) llvm::Value *tmp1, *tmp2, *denom; if(lhs_re && lhs_im) { - tmp1 = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); - tmp2 = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); - res_re = gIR->ir->CreateAdd(tmp1, tmp2, "rere_plus_imim"); + tmp1 = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere"); + tmp2 = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim"); + res_re = gIR->ir->CreateFAdd(tmp1, tmp2, "rere_plus_imim"); - tmp1 = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); - tmp2 = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); - res_im = gIR->ir->CreateSub(tmp2, tmp1, "imre_sub_reim"); + tmp1 = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim"); + tmp2 = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre"); + res_im = gIR->ir->CreateFSub(tmp2, tmp1, "imre_sub_reim"); } else if(lhs_re) { - res_re = gIR->ir->CreateMul(lhs_re, rhs_re, "rere"); + res_re = gIR->ir->CreateFMul(lhs_re, rhs_re, "rere"); - res_im = gIR->ir->CreateMul(lhs_re, rhs_im, "reim"); - res_im = gIR->ir->CreateNeg(res_im); + res_im = gIR->ir->CreateFMul(lhs_re, rhs_im, "reim"); + res_im = gIR->ir->CreateFNeg(res_im); } else if(lhs_im) { - res_re = gIR->ir->CreateMul(lhs_im, rhs_im, "imim"); - res_im = gIR->ir->CreateMul(lhs_im, rhs_re, "imre"); + res_re = gIR->ir->CreateFMul(lhs_im, rhs_im, "imim"); + res_im = gIR->ir->CreateFMul(lhs_im, rhs_re, "imre"); } else assert(0 && "lhs has neither real nor imaginary part"); - tmp1 = gIR->ir->CreateMul(rhs_re, rhs_re, "rhs_resq"); - tmp2 = gIR->ir->CreateMul(rhs_im, rhs_im, "rhs_imsq"); - denom = gIR->ir->CreateAdd(tmp1, tmp2, "denom"); + tmp1 = gIR->ir->CreateFMul(rhs_re, rhs_re, "rhs_resq"); + tmp2 = gIR->ir->CreateFMul(rhs_im, rhs_im, "rhs_imsq"); + denom = gIR->ir->CreateFAdd(tmp1, tmp2, "denom"); res_re = gIR->ir->CreateFDiv(res_re, denom, "res_re"); res_im = gIR->ir->CreateFDiv(res_im, denom, "res_im"); @@ -368,8 +368,8 @@ DValue* DtoComplexNeg(Loc& loc, Type* type, DValue* val) // neg up assert(a && b); - re = gIR->ir->CreateNeg(a, "tmp"); - im = gIR->ir->CreateNeg(b, "tmp"); + re = gIR->ir->CreateFNeg(a, "tmp"); + im = gIR->ir->CreateFNeg(b, "tmp"); LLValue* res = DtoAggrPair(DtoType(type), re, im); return new DImValue(type, res); diff --git a/gen/passes/GarbageCollect2Stack.cpp b/gen/passes/GarbageCollect2Stack.cpp index 206e760c..b6a91fe1 100644 --- a/gen/passes/GarbageCollect2Stack.cpp +++ b/gen/passes/GarbageCollect2Stack.cpp @@ -65,12 +65,13 @@ void EmitMemSet(IRBuilder<>& B, Value* Dst, Value* Val, Value* Len, Dst = B.CreateBitCast(Dst, PointerType::getUnqual(B.getInt8Ty())); Module *M = B.GetInsertBlock()->getParent()->getParent(); - const Type* Tys[1]; - Tys[0] = Len->getType(); - Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 1); + const Type* intTy = Len->getType(); + const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); + const Type *Tys[2] ={VoidPtrTy, intTy}; + Function *MemSet = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys, 2); Value *Align = ConstantInt::get(B.getInt32Ty(), 1); - CallSite CS = B.CreateCall4(MemSet, Dst, Val, Len, Align); + CallSite CS = B.CreateCall5(MemSet, Dst, Val, Len, Align, B.getFalse()); if (A.CGNode) A.CGNode->addCalledFunction(CS, A.CG->getOrInsertFunction(MemSet)); } @@ -247,7 +248,7 @@ namespace { namespace { /// This pass replaces GC calls with alloca's /// - class VISIBILITY_HIDDEN GarbageCollect2Stack : public FunctionPass { + class LLVM_LIBRARY_VISIBILITY GarbageCollect2Stack : public FunctionPass { StringMap KnownFunctions; Module* M; diff --git a/gen/passes/SimplifyDRuntimeCalls.cpp b/gen/passes/SimplifyDRuntimeCalls.cpp index 2706353f..6d690bb2 100644 --- a/gen/passes/SimplifyDRuntimeCalls.cpp +++ b/gen/passes/SimplifyDRuntimeCalls.cpp @@ -42,7 +42,7 @@ STATISTIC(NumDeleted, "Number of runtime calls deleted"); /// This class is the abstract base class for the set of optimizations that /// corresponds to one library call. namespace { - class VISIBILITY_HIDDEN LibCallOptimization { + class LLVM_LIBRARY_VISIBILITY LibCallOptimization { protected: Function *Caller; bool* Changed; @@ -91,12 +91,13 @@ Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) { Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len, unsigned Align, IRBuilder<> &B) { Module *M = Caller->getParent(); - Intrinsic::ID IID = Intrinsic::memcpy; - const Type *Tys[1]; - Tys[0] = Len->getType(); - Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1); - return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len, - ConstantInt::get(B.getInt32Ty(), Align)); + const Type* intTy = Len->getType(); + const Type *VoidPtrTy = PointerType::getUnqual(B.getInt8Ty()); + const Type *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; + Value *MemCpy = Intrinsic::getDeclaration(M, Intrinsic::memcpy, Tys, 3); + + return B.CreateCall5(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len, + ConstantInt::get(B.getInt32Ty(), Align), B.getFalse()); } //===----------------------------------------------------------------------===// @@ -108,7 +109,7 @@ namespace { // '_d_arraysetlengthT'/'_d_arraysetlengthiT' Optimizations /// ArraySetLengthOpt - remove libcall for arr.length = N if N <= arr.length -struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { +struct LLVM_LIBRARY_VISIBILITY ArraySetLengthOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify we have a reasonable prototype for _d_arraysetlength[i]T const FunctionType *FT = Callee->getFunctionType(); @@ -150,7 +151,7 @@ struct VISIBILITY_HIDDEN ArraySetLengthOpt : public LibCallOptimization { }; /// ArrayCastLenOpt - remove libcall for cast(T[]) arr if it's safe to do so. -struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { +struct LLVM_LIBRARY_VISIBILITY ArrayCastLenOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify we have a reasonable prototype for _d_array_cast_len const FunctionType *FT = Callee->getFunctionType(); @@ -189,7 +190,7 @@ struct VISIBILITY_HIDDEN ArrayCastLenOpt : public LibCallOptimization { }; /// AllocationOpt - Common optimizations for various GC allocations. -struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization { +struct LLVM_LIBRARY_VISIBILITY AllocationOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Allocations are never equal to constants, so remove any equality // comparisons to constants. (Most importantly comparisons to null at @@ -225,7 +226,7 @@ struct VISIBILITY_HIDDEN AllocationOpt : public LibCallOptimization { }; /// ArraySliceCopyOpt - Turn slice copies into llvm.memcpy when safe -struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization { +struct LLVM_LIBRARY_VISIBILITY ArraySliceCopyOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify we have a reasonable prototype for _d_array_slice_copy const FunctionType *FT = Callee->getFunctionType(); @@ -255,7 +256,7 @@ struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization { // Equal length and the pointers definitely don't alias, so it's safe to // replace the call with memcpy - return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 0, B); + return EmitMemCpy(CI->getOperand(1), CI->getOperand(3), Size, 1, B); } }; @@ -270,7 +271,7 @@ struct VISIBILITY_HIDDEN ArraySliceCopyOpt : public LibCallOptimization { namespace { /// This pass optimizes library functions from the D runtime as used by LDC. /// - class VISIBILITY_HIDDEN SimplifyDRuntimeCalls : public FunctionPass { + class LLVM_LIBRARY_VISIBILITY SimplifyDRuntimeCalls : public FunctionPass { StringMap Optimizations; // Array operations @@ -283,7 +284,7 @@ namespace { public: static char ID; // Pass identification - SimplifyDRuntimeCalls() : FunctionPass(&ID) {} + SimplifyDRuntimeCalls() : FunctionPass(ID) {} void InitOptimizations(); bool runOnFunction(Function &F); diff --git a/gen/passes/StripExternals.cpp b/gen/passes/StripExternals.cpp index f1325b29..d971fcf5 100644 --- a/gen/passes/StripExternals.cpp +++ b/gen/passes/StripExternals.cpp @@ -31,9 +31,9 @@ STATISTIC(NumFunctions, "Number of function bodies removed"); STATISTIC(NumVariables, "Number of global initializers removed"); namespace { - struct VISIBILITY_HIDDEN StripExternals : public ModulePass { + struct LLVM_LIBRARY_VISIBILITY StripExternals : public ModulePass { static char ID; // Pass identification, replacement for typeid - StripExternals() : ModulePass(&ID) {} + StripExternals() : ModulePass(ID) {} // run - Do the StripExternals pass on the specified module. // diff --git a/gen/toir.cpp b/gen/toir.cpp index cf547239..82bef8bc 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1571,10 +1571,10 @@ DValue* PostExp::toElem(IRState* p) assert(e2type->isfloating()); LLValue* one = DtoConstFP(e1type, 1.0); if (op == TOKplusplus) { - post = llvm::BinaryOperator::CreateAdd(val,one,"tmp",p->scopebb()); + post = llvm::BinaryOperator::CreateFAdd(val,one,"tmp",p->scopebb()); } else if (op == TOKminusminus) { - post = llvm::BinaryOperator::CreateSub(val,one,"tmp",p->scopebb()); + post = llvm::BinaryOperator::CreateFSub(val,one,"tmp",p->scopebb()); } } else @@ -2192,7 +2192,11 @@ DValue* NegExp::toElem(IRState* p) LLValue* val = l->getRVal(); - val = gIR->ir->CreateNeg(val,"negval"); + if (type->isintegral()) + val = gIR->ir->CreateNeg(val,"negval"); + else + val = gIR->ir->CreateFNeg(val,"negval"); + return new DImValue(type, val); } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 6e2b6982..c870e844 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -444,10 +444,12 @@ void DtoMemSet(LLValue* dst, LLValue* val, LLValue* nbytes) dst = DtoBitCast(dst,getVoidPtrType()); const LLType* intTy = DtoSize_t(); + const LLType *VoidPtrTy = getVoidPtrType(); + const LLType *Tys[2] ={VoidPtrTy, intTy}; llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module, - llvm::Intrinsic::memset, &intTy, 1); - - gIR->ir->CreateCall4(fn, dst, val, nbytes, DtoConstUint(0), ""); + llvm::Intrinsic::memset, Tys, 2); + + gIR->ir->CreateCall5(fn, dst, val, nbytes, DtoConstUint(1), DtoConstBool(false), ""); } ////////////////////////////////////////////////////////////////////////////////////////// @@ -465,10 +467,12 @@ void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes, unsigned align) src = DtoBitCast(src,getVoidPtrType()); const LLType* intTy = DtoSize_t(); + const LLType *VoidPtrTy = getVoidPtrType(); + const LLType *Tys[3] ={VoidPtrTy, VoidPtrTy, intTy}; llvm::Function* fn = llvm::Intrinsic::getDeclaration(gIR->module, - llvm::Intrinsic::memcpy, &intTy, 1); - - gIR->ir->CreateCall4(fn, dst, src, nbytes, DtoConstUint(align), ""); + llvm::Intrinsic::memcpy, Tys, 3); + + gIR->ir->CreateCall5(fn, dst, src, nbytes, DtoConstUint(align), DtoConstBool(false), ""); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/tollvm.h b/gen/tollvm.h index 2244e831..6a6fc538 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -131,7 +131,7 @@ void DtoMemSetZero(LLValue* dst, LLValue* nbytes); * @param nbytes Number of bytes to copy. * @param align The minimum alignment of the source and destination memory. */ -void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes, unsigned align = 0); +void DtoMemCpy(LLValue* dst, LLValue* src, LLValue* nbytes, unsigned align = 1); /** * Generates a call to C memcmp.