Mercurial > projects > ldc
comparison gen/tollvm.cpp @ 205:9d44ec83acd1 trunk
[svn r221] Update: Switched to the 2.3 LLVM svn branch, http://llvm.org/svn/llvm-project/llvm/branches/release_23 .
Fixed: Implemented volatile statements. Uses the LLVM memory barrier intrinsic, closes #21 .
author | lindquist |
---|---|
date | Tue, 13 May 2008 17:58:11 +0200 |
parents | e881c9b1c738 |
children | e0b6040585b4 |
comparison
equal
deleted
inserted
replaced
204:11fe364b9a3e | 205:9d44ec83acd1 |
---|---|
270 gIR->llvm_DeclareMemCpy64 = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); | 270 gIR->llvm_DeclareMemCpy64 = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); |
271 } | 271 } |
272 return gIR->llvm_DeclareMemCpy64; | 272 return gIR->llvm_DeclareMemCpy64; |
273 } | 273 } |
274 | 274 |
275 // llvm.memory.barrier | |
276 static llvm::Function* LLVM_DeclareMemBarrier() | |
277 { | |
278 if (gIR->llvm_DeclareMemBarrier == 0) { | |
279 std::vector<const llvm::Type*> pvec; | |
280 pvec.push_back(llvm::Type::Int1Ty); | |
281 pvec.push_back(llvm::Type::Int1Ty); | |
282 pvec.push_back(llvm::Type::Int1Ty); | |
283 pvec.push_back(llvm::Type::Int1Ty); | |
284 pvec.push_back(llvm::Type::Int1Ty); | |
285 llvm::FunctionType* functype = llvm::FunctionType::get(llvm::Type::VoidTy, pvec, false); | |
286 gIR->llvm_DeclareMemBarrier = llvm::cast<llvm::Function>(gIR->module->getOrInsertFunction("llvm.memory.barrier", functype)); | |
287 assert(gIR->llvm_DeclareMemBarrier != NULL); | |
288 } | |
289 return gIR->llvm_DeclareMemBarrier; | |
290 } | |
291 | |
292 void DtoMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device) | |
293 { | |
294 llvm::Function* fn = LLVM_DeclareMemBarrier(); | |
295 assert(fn != NULL); | |
296 | |
297 llvm::SmallVector<llvm::Value*, 5> llargs; | |
298 llargs.push_back(DtoConstBool(ll)); | |
299 llargs.push_back(DtoConstBool(ls)); | |
300 llargs.push_back(DtoConstBool(sl)); | |
301 llargs.push_back(DtoConstBool(ss)); | |
302 llargs.push_back(DtoConstBool(device)); | |
303 | |
304 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
305 } | |
306 | |
275 ////////////////////////////////////////////////////////////////////////////////////////// | 307 ////////////////////////////////////////////////////////////////////////////////////////// |
276 | 308 |
277 llvm::Value* DtoDelegateToNull(llvm::Value* v) | 309 llvm::Value* DtoDelegateToNull(llvm::Value* v) |
278 { | 310 { |
279 assert(gIR); | 311 assert(gIR); |
289 llargs[0] = arr; | 321 llargs[0] = arr; |
290 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | 322 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); |
291 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 323 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
292 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 324 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
293 | 325 |
294 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 326 llvm::Value* ret = llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
295 | 327 |
296 return ret; | 328 return ret; |
297 } | 329 } |
298 | 330 |
299 ////////////////////////////////////////////////////////////////////////////////////////// | 331 ////////////////////////////////////////////////////////////////////////////////////////// |
316 llargs[0] = dstarr; | 348 llargs[0] = dstarr; |
317 llargs[1] = srcarr; | 349 llargs[1] = srcarr; |
318 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 350 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
319 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 351 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
320 | 352 |
321 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 353 return llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
322 } | 354 } |
323 | 355 |
324 ////////////////////////////////////////////////////////////////////////////////////////// | 356 ////////////////////////////////////////////////////////////////////////////////////////// |
325 | 357 |
326 llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs) | 358 llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs) |
614 { | 646 { |
615 std::vector<llvm::Value*> v(2); | 647 std::vector<llvm::Value*> v(2); |
616 v[0] = i0; | 648 v[0] = i0; |
617 v[1] = i1; | 649 v[1] = i1; |
618 Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; | 650 Logger::cout() << "DtoGEP: " << *ptr << ", " << *i0 << ", " << *i1 << '\n'; |
619 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 651 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
620 } | 652 } |
621 | 653 |
622 ////////////////////////////////////////////////////////////////////////////////////////// | 654 ////////////////////////////////////////////////////////////////////////////////////////// |
623 | 655 |
624 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) | 656 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
631 { | 663 { |
632 //ostr << ' ' << i; | 664 //ostr << ' ' << i; |
633 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); | 665 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); |
634 } | 666 } |
635 //ostr << '\n';*/ | 667 //ostr << '\n';*/ |
636 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); | 668 return llvm::GetElementPtrInst::Create(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); |
637 } | 669 } |
638 | 670 |
639 ////////////////////////////////////////////////////////////////////////////////////////// | 671 ////////////////////////////////////////////////////////////////////////////////////////// |
640 | 672 |
641 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) | 673 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) |
642 { | 674 { |
643 return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); | 675 return llvm::GetElementPtrInst::Create(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); |
644 } | 676 } |
645 | 677 |
646 ////////////////////////////////////////////////////////////////////////////////////////// | 678 ////////////////////////////////////////////////////////////////////////////////////////// |
647 | 679 |
648 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) | 680 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) |
649 { | 681 { |
650 std::vector<llvm::Value*> v(2); | 682 std::vector<llvm::Value*> v(2); |
651 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); | 683 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); |
652 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); | 684 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); |
653 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); | 685 return llvm::GetElementPtrInst::Create(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
654 } | 686 } |
655 | 687 |
656 ////////////////////////////////////////////////////////////////////////////////////////// | 688 ////////////////////////////////////////////////////////////////////////////////////////// |
657 | 689 |
658 llvm::Value* DtoNew(Type* newtype) | 690 llvm::Value* DtoNew(Type* newtype) |
702 c = DtoConstUint(loc->linnum); | 734 c = DtoConstUint(loc->linnum); |
703 args.push_back(c); | 735 args.push_back(c); |
704 | 736 |
705 // call | 737 // call |
706 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); | 738 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); |
707 llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb()); | 739 llvm::CallInst* call = llvm::CallInst::Create(fn, args.begin(), args.end(), "", gIR->scopebb()); |
708 } | 740 } |
709 | 741 |
710 ////////////////////////////////////////////////////////////////////////////////////////// | 742 ////////////////////////////////////////////////////////////////////////////////////////// |
711 | 743 |
712 static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc) | 744 static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc) |
1232 | 1264 |
1233 llvm::ConstantFP* DtoConstFP(Type* t, long double value) | 1265 llvm::ConstantFP* DtoConstFP(Type* t, long double value) |
1234 { | 1266 { |
1235 TY ty = DtoDType(t)->ty; | 1267 TY ty = DtoDType(t)->ty; |
1236 if (ty == Tfloat32 || ty == Timaginary32) | 1268 if (ty == Tfloat32 || ty == Timaginary32) |
1237 return llvm::ConstantFP::get(llvm::Type::FloatTy, llvm::APFloat(float(value))); | 1269 return llvm::ConstantFP::get(llvm::APFloat(float(value))); |
1238 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tfloat80 || ty == Timaginary80) | 1270 else if (ty == Tfloat64 || ty == Timaginary64 || ty == Tfloat80 || ty == Timaginary80) |
1239 return llvm::ConstantFP::get(llvm::Type::DoubleTy, llvm::APFloat(double(value))); | 1271 return llvm::ConstantFP::get(llvm::APFloat(double(value))); |
1240 } | 1272 } |
1241 | 1273 |
1242 | 1274 |
1243 ////////////////////////////////////////////////////////////////////////////////////////// | 1275 ////////////////////////////////////////////////////////////////////////////////////////// |
1244 | 1276 |
1286 llargs[0] = dstarr; | 1318 llargs[0] = dstarr; |
1287 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | 1319 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); |
1288 llargs[2] = nbytes; | 1320 llargs[2] = nbytes; |
1289 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1321 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1290 | 1322 |
1291 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 1323 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
1292 } | 1324 } |
1293 | 1325 |
1294 ////////////////////////////////////////////////////////////////////////////////////////// | 1326 ////////////////////////////////////////////////////////////////////////////////////////// |
1295 | 1327 |
1296 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) | 1328 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) |
1315 llargs[0] = dstarr; | 1347 llargs[0] = dstarr; |
1316 llargs[1] = srcarr; | 1348 llargs[1] = srcarr; |
1317 llargs[2] = nbytes; | 1349 llargs[2] = nbytes; |
1318 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1350 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1319 | 1351 |
1320 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 1352 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
1321 } | 1353 } |
1322 | 1354 |
1323 ////////////////////////////////////////////////////////////////////////////////////////// | 1355 ////////////////////////////////////////////////////////////////////////////////////////// |
1324 | 1356 |
1325 llvm::Value* DtoLoad(llvm::Value* src) | 1357 llvm::Value* DtoLoad(llvm::Value* src) |
1326 { | 1358 { |
1327 return gIR->ir->CreateLoad(src,"tmp"); | 1359 llvm::Value* ld = gIR->ir->CreateLoad(src,"tmp"); |
1360 //ld->setVolatile(gIR->func()->inVolatile); | |
1361 return ld; | |
1328 } | 1362 } |
1329 | 1363 |
1330 void DtoStore(llvm::Value* src, llvm::Value* dst) | 1364 void DtoStore(llvm::Value* src, llvm::Value* dst) |
1331 { | 1365 { |
1332 gIR->ir->CreateStore(src,dst); | 1366 llvm::Value* st = gIR->ir->CreateStore(src,dst); |
1367 //st->setVolatile(gIR->func()->inVolatile); | |
1333 } | 1368 } |
1334 | 1369 |
1335 bool DtoCanLoad(llvm::Value* ptr) | 1370 bool DtoCanLoad(llvm::Value* ptr) |
1336 { | 1371 { |
1337 if (isaPointer(ptr->getType())) { | 1372 if (isaPointer(ptr->getType())) { |
1458 gflagname.append("__initflag"); | 1493 gflagname.append("__initflag"); |
1459 llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module); | 1494 llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,gIR->module); |
1460 | 1495 |
1461 // check flag and do init if not already done | 1496 // check flag and do init if not already done |
1462 llvm::BasicBlock* oldend = gIR->scopeend(); | 1497 llvm::BasicBlock* oldend = gIR->scopeend(); |
1463 llvm::BasicBlock* initbb = new llvm::BasicBlock("ifnotinit",gIR->topfunc(),oldend); | 1498 llvm::BasicBlock* initbb = llvm::BasicBlock::Create("ifnotinit",gIR->topfunc(),oldend); |
1464 llvm::BasicBlock* endinitbb = new llvm::BasicBlock("ifnotinitend",gIR->topfunc(),oldend); | 1499 llvm::BasicBlock* endinitbb = llvm::BasicBlock::Create("ifnotinitend",gIR->topfunc(),oldend); |
1465 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); | 1500 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); |
1466 gIR->ir->CreateCondBr(cond, initbb, endinitbb); | 1501 gIR->ir->CreateCondBr(cond, initbb, endinitbb); |
1467 gIR->scope() = IRScope(initbb,endinitbb); | 1502 gIR->scope() = IRScope(initbb,endinitbb); |
1468 DValue* ie = DtoInitializer(init); | 1503 DValue* ie = DtoInitializer(init); |
1469 if (!ie->inPlace()) { | 1504 if (!ie->inPlace()) { |