fixes #434 :: add llvm 2.8 support

This commit is contained in:
Moritz Warning 2010-10-23 13:38:26 +02:00
parent 233299e5c8
commit c151d37365
9 changed files with 111 additions and 68 deletions

View file

@ -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)

View file

@ -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");

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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.
//

View file

@ -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);
}

View file

@ -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), "");
}
//////////////////////////////////////////////////////////////////////////////////////////

View file

@ -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.