mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
fixes #434 :: add llvm 2.8 support
This commit is contained in:
parent
233299e5c8
commit
c151d37365
9 changed files with 111 additions and 68 deletions
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<FunctionInfo*> KnownFunctions;
|
||||
Module* M;
|
||||
|
||||
|
|
|
@ -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<LibCallOptimization*> 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);
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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();
|
||||
|
||||
if (type->isintegral())
|
||||
val = gIR->ir->CreateNeg(val,"negval");
|
||||
else
|
||||
val = gIR->ir->CreateFNeg(val,"negval");
|
||||
|
||||
return new DImValue(type, val);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
llvm::Intrinsic::memset, Tys, 2);
|
||||
|
||||
gIR->ir->CreateCall4(fn, dst, val, nbytes, DtoConstUint(0), "");
|
||||
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);
|
||||
llvm::Intrinsic::memcpy, Tys, 3);
|
||||
|
||||
gIR->ir->CreateCall4(fn, dst, src, nbytes, DtoConstUint(align), "");
|
||||
gIR->ir->CreateCall5(fn, dst, src, nbytes, DtoConstUint(align), DtoConstBool(false), "");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue