comparison gen/toir.cpp @ 96:ce7ed8f59b99 trunk

[svn r100] Moved test/ray.d to demos/ray.d. Cleanups.
author lindquist
date Mon, 12 Nov 2007 07:58:44 +0100
parents 61615fa85940
children c4e161556a21
comparison
equal deleted inserted replaced
95:71b8fecdae38 96:ce7ed8f59b99
14 14
15 #include "gen/llvm.h" 15 #include "gen/llvm.h"
16 16
17 #include "total.h" 17 #include "total.h"
18 #include "init.h" 18 #include "init.h"
19 #include "symbol.h"
20 #include "mtype.h" 19 #include "mtype.h"
21 #include "hdrgen.h" 20 #include "hdrgen.h"
22 #include "port.h" 21 #include "port.h"
23 22
24 #include "gen/irstate.h" 23 #include "gen/irstate.h"
25 #include "gen/elem.h"
26 #include "gen/logger.h" 24 #include "gen/logger.h"
27 #include "gen/tollvm.h" 25 #include "gen/tollvm.h"
28 #include "gen/runtime.h" 26 #include "gen/runtime.h"
29 #include "gen/arrays.h" 27 #include "gen/arrays.h"
30 #include "gen/structs.h" 28 #include "gen/structs.h"
247 llvm::Constant* IntegerExp::toConstElem(IRState* p) 245 llvm::Constant* IntegerExp::toConstElem(IRState* p)
248 { 246 {
249 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); 247 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars());
250 LOG_SCOPE; 248 LOG_SCOPE;
251 const llvm::Type* t = DtoType(type); 249 const llvm::Type* t = DtoType(type);
252 if (llvm::isa<llvm::PointerType>(t)) { 250 if (isaPointer(t)) {
253 Logger::println("pointer"); 251 Logger::println("pointer");
254 llvm::Constant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); 252 llvm::Constant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false);
255 return llvm::ConstantExpr::getIntToPtr(i, t); 253 return llvm::ConstantExpr::getIntToPtr(i, t);
256 } 254 }
257 assert(llvm::isa<llvm::IntegerType>(t)); 255 assert(llvm::isa<llvm::IntegerType>(t));
303 { 301 {
304 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); 302 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars());
305 LOG_SCOPE; 303 LOG_SCOPE;
306 const llvm::Type* t = DtoType(type); 304 const llvm::Type* t = DtoType(type);
307 if (type->ty == Tarray) { 305 if (type->ty == Tarray) {
308 assert(llvm::isa<llvm::StructType>(t)); 306 assert(isaStruct(t));
309 return llvm::ConstantAggregateZero::get(t); 307 return llvm::ConstantAggregateZero::get(t);
310 } 308 }
311 else { 309 else {
312 return llvm::Constant::getNullValue(t); 310 return llvm::Constant::getNullValue(t);
313 } 311 }
750 return DtoBinSub(l,r); 748 return DtoBinSub(l,r);
751 } 749 }
752 750
753 /* 751 /*
754 llvm::Value* left = l->getValue(); 752 llvm::Value* left = l->getValue();
755 if (llvm::isa<llvm::PointerType>(left->getType())) 753 if (isaPointer(left->getType()))
756 left = new llvm::PtrToIntInst(left,DtoSize_t(),"tmp",p->scopebb()); 754 left = new llvm::PtrToIntInst(left,DtoSize_t(),"tmp",p->scopebb());
757 755
758 llvm::Value* right = r->getValue(); 756 llvm::Value* right = r->getValue();
759 if (llvm::isa<llvm::PointerType>(right->getType())) 757 if (isaPointer(right->getType()))
760 right = new llvm::PtrToIntInst(right,DtoSize_t(),"tmp",p->scopebb()); 758 right = new llvm::PtrToIntInst(right,DtoSize_t(),"tmp",p->scopebb());
761 759
762 e->val = llvm::BinaryOperator::createSub(left,right,"tmp",p->scopebb()); 760 e->val = llvm::BinaryOperator::createSub(left,right,"tmp",p->scopebb());
763 e->type = DValue::VAL; 761 e->type = DValue::VAL;
764 762
765 const llvm::Type* totype = DtoType(type); 763 const llvm::Type* totype = DtoType(type);
766 if (e->val->getType() != totype) { 764 if (e->val->getType() != totype) {
767 assert(0); 765 assert(0);
768 assert(llvm::isa<llvm::PointerType>(e->val->getType())); 766 assert(isaPointer(e->val->getType()));
769 assert(llvm::isa<llvm::IntegerType>(totype)); 767 assert(llvm::isa<llvm::IntegerType>(totype));
770 e->val = new llvm::IntToPtrInst(e->val,totype,"tmp",p->scopebb()); 768 e->val = new llvm::IntToPtrInst(e->val,totype,"tmp",p->scopebb());
771 } 769 }
772 770
773 delete l; 771 delete l;
1102 DValue* expelem = exp->toElem(p); 1100 DValue* expelem = exp->toElem(p);
1103 Type* t = DtoDType(type); 1101 Type* t = DtoDType(type);
1104 const llvm::Type* llt = DtoType(type); 1102 const llvm::Type* llt = DtoType(type);
1105 if (DtoIsPassedByRef(t)) 1103 if (DtoIsPassedByRef(t))
1106 llt = llvm::PointerType::get(llt); 1104 llt = llvm::PointerType::get(llt);
1105 // TODO
1106 if (strcmp(global.params.llvmArch, "x86") != 0) {
1107 warning("va_arg for C variadic functions is broken for anything but x86");
1108 }
1107 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp")); 1109 return new DImValue(type, p->ir->CreateVAArg(expelem->getLVal(),llt,"tmp"));
1108 } 1110 }
1109 else if (fndecl->llvmInternal == LLVMalloca) { 1111 else if (fndecl->llvmInternal == LLVMalloca) {
1110 //Argument* fnarg = Argument::getNth(tf->parameters, 0); 1112 //Argument* fnarg = Argument::getNth(tf->parameters, 0);
1111 Expression* exp = (Expression*)arguments->data[0]; 1113 Expression* exp = (Expression*)arguments->data[0];
1134 // normal function call 1136 // normal function call
1135 if (llvm::isa<llvm::FunctionType>(funcval->getType())) { 1137 if (llvm::isa<llvm::FunctionType>(funcval->getType())) {
1136 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()); 1138 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType());
1137 } 1139 }
1138 // pointer to something 1140 // pointer to something
1139 else if (llvm::isa<llvm::PointerType>(funcval->getType())) { 1141 else if (isaPointer(funcval->getType())) {
1140 // pointer to function pointer - I think this not really supposed to happen, but does :/ 1142 // pointer to function pointer - I think this not really supposed to happen, but does :/
1141 // seems like sometimes we get a func* other times a func** 1143 // seems like sometimes we get a func* other times a func**
1142 if (llvm::isa<llvm::PointerType>(funcval->getType()->getContainedType(0))) { 1144 if (isaPointer(funcval->getType()->getContainedType(0))) {
1143 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); 1145 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
1144 } 1146 }
1145 // function pointer 1147 // function pointer
1146 if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) { 1148 if (llvm::isa<llvm::FunctionType>(funcval->getType()->getContainedType(0))) {
1147 //Logger::cout() << "function pointer type:\n" << *funcval << '\n'; 1149 //Logger::cout() << "function pointer type:\n" << *funcval << '\n';
1148 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0)); 1150 llfnty = llvm::cast<llvm::FunctionType>(funcval->getType()->getContainedType(0));
1149 } 1151 }
1150 // struct pointer - delegate 1152 // struct pointer - delegate
1151 else if (llvm::isa<llvm::StructType>(funcval->getType()->getContainedType(0))) { 1153 else if (isaStruct(funcval->getType()->getContainedType(0))) {
1152 funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb()); 1154 funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb());
1153 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); 1155 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
1154 const llvm::Type* ty = funcval->getType()->getContainedType(0); 1156 const llvm::Type* ty = funcval->getType()->getContainedType(0);
1155 llfnty = llvm::cast<llvm::FunctionType>(ty); 1157 llfnty = llvm::cast<llvm::FunctionType>(ty);
1156 } 1158 }
1176 // hidden struct return arguments 1178 // hidden struct return arguments
1177 if (retinptr) { 1179 if (retinptr) {
1178 if (topexp && topexp->e2 == this) { 1180 if (topexp && topexp->e2 == this) {
1179 assert(topexp->v); 1181 assert(topexp->v);
1180 llvm::Value* tlv = topexp->v->getLVal(); 1182 llvm::Value* tlv = topexp->v->getLVal();
1181 assert(llvm::isa<llvm::StructType>(tlv->getType()->getContainedType(0))); 1183 assert(isaStruct(tlv->getType()->getContainedType(0)));
1182 llargs[j] = tlv; 1184 llargs[j] = tlv;
1183 if (DtoIsPassedByRef(tf->next)) { 1185 if (DtoIsPassedByRef(tf->next)) {
1184 isInPlace = true; 1186 isInPlace = true;
1185 } 1187 }
1186 else 1188 else
1260 const llvm::StructType* vtype = llvm::StructType::get(vtypes); 1262 const llvm::StructType* vtype = llvm::StructType::get(vtypes);
1261 llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); 1263 llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint());
1262 for (unsigned i=0; i<vtype->getNumElements(); ++i) 1264 for (unsigned i=0; i<vtype->getNumElements(); ++i)
1263 p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp")); 1265 p->ir->CreateStore(vvalues[i], DtoGEPi(mem,0,i,"tmp"));
1264 1266
1265 //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(llfnty->getParamType(j))); 1267 //llvm::Constant* typeinfoparam = llvm::ConstantPointerNull::get(isaPointer(llfnty->getParamType(j)));
1266 assert(Type::typeinfo->llvmInitZ); 1268 assert(Type::typeinfo->llvmInitZ);
1267 const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmInitZ->getType()); 1269 const llvm::Type* typeinfotype = llvm::PointerType::get(Type::typeinfo->llvmInitZ->getType());
1268 Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; 1270 Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n';
1269 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); 1271 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements());
1270 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); 1272 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint());
1446 } 1448 }
1447 else { 1449 else {
1448 llvm::Value* uval = u->getRVal(); 1450 llvm::Value* uval = u->getRVal();
1449 if (fromtype->ty == Tsarray) { 1451 if (fromtype->ty == Tsarray) {
1450 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; 1452 Logger::cout() << "uvalTy = " << *uval->getType() << '\n';
1451 assert(llvm::isa<llvm::PointerType>(uval->getType())); 1453 assert(isaPointer(uval->getType()));
1452 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(uval->getType()->getContainedType(0)); 1454 const llvm::ArrayType* arrty = isaArray(uval->getType()->getContainedType(0));
1453 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false); 1455 rval2 = llvm::ConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
1454 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0)); 1456 rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
1455 rval = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb()); 1457 rval = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb());
1456 } 1458 }
1457 else { 1459 else {
2477 eval = DtoDynArrayIs(op,l,r); 2479 eval = DtoDynArrayIs(op,l,r);
2478 } 2480 }
2479 else { 2481 else {
2480 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; 2482 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
2481 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { 2483 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) {
2482 r = llvm::ConstantPointerNull::get(llvm::cast<llvm::PointerType>(l->getType())); 2484 r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
2483 } 2485 }
2484 Logger::cout() << "l = " << *l << " r = " << *r << '\n'; 2486 Logger::cout() << "l = " << *l << " r = " << *r << '\n';
2485 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb()); 2487 eval = new llvm::ICmpInst(pred, l, r, "tmp", p->scopebb());
2486 } 2488 }
2487 return new DImValue(type, eval); 2489 return new DImValue(type, eval);
2658 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); 2660 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint());
2659 temp = true; 2661 temp = true;
2660 } 2662 }
2661 2663
2662 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); 2664 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
2663 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(context->getType()->getContainedType(0)); 2665 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
2664 llvm::Value* llvmNested = p->func().decl->llvmNested; 2666 llvm::Value* llvmNested = p->func().decl->llvmNested;
2665 if (llvmNested == NULL) { 2667 if (llvmNested == NULL) {
2666 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); 2668 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty);
2667 p->ir->CreateStore(nullcontext, context); 2669 p->ir->CreateStore(nullcontext, context);
2668 } 2670 }
2707 } 2709 }
2708 else { 2710 else {
2709 mem = p->topexp()->v->getLVal(); 2711 mem = p->topexp()->v->getLVal();
2710 } 2712 }
2711 assert(mem); 2713 assert(mem);
2712 if (!llvm::isa<llvm::PointerType>(mem->getType()) || 2714 if (!isaPointer(mem->getType()) ||
2713 !llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0))) 2715 !isaArray(mem->getType()->getContainedType(0)))
2714 { 2716 {
2715 assert(ty->ty == Tarray); 2717 assert(ty->ty == Tarray);
2716 // we need to give this array literal storage 2718 // we need to give this array literal storage
2717 const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim); 2719 const llvm::ArrayType* arrty = llvm::ArrayType::get(DtoType(ty->next), elements->dim);
2718 mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint()); 2720 mem = new llvm::AllocaInst(arrty, "arrayliteral", p->topallocapoint());
2746 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); 2748 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars());
2747 LOG_SCOPE; 2749 LOG_SCOPE;
2748 2750
2749 const llvm::Type* t = DtoType(type); 2751 const llvm::Type* t = DtoType(type);
2750 Logger::cout() << "array literal has llvm type: " << *t << '\n'; 2752 Logger::cout() << "array literal has llvm type: " << *t << '\n';
2751 assert(llvm::isa<llvm::ArrayType>(t)); 2753 assert(isaArray(t));
2752 const llvm::ArrayType* arrtype = llvm::cast<llvm::ArrayType>(t); 2754 const llvm::ArrayType* arrtype = isaArray(t);
2753 2755
2754 assert(arrtype->getNumElements() == elements->dim); 2756 assert(arrtype->getNumElements() == elements->dim);
2755 std::vector<llvm::Constant*> vals(elements->dim, NULL); 2757 std::vector<llvm::Constant*> vals(elements->dim, NULL);
2756 for (unsigned i=0; i<elements->dim; ++i) 2758 for (unsigned i=0; i<elements->dim; ++i)
2757 { 2759 {
2849 vals[i] = vx->toConstElem(p); 2851 vals[i] = vx->toConstElem(p);
2850 } 2852 }
2851 2853
2852 assert(DtoDType(type)->ty == Tstruct); 2854 assert(DtoDType(type)->ty == Tstruct);
2853 const llvm::Type* t = DtoType(type); 2855 const llvm::Type* t = DtoType(type);
2854 const llvm::StructType* st = llvm::cast<llvm::StructType>(t); 2856 const llvm::StructType* st = isaStruct(t);
2855 return llvm::ConstantStruct::get(st,vals); 2857 return llvm::ConstantStruct::get(st,vals);
2856 } 2858 }
2857 2859
2858 ////////////////////////////////////////////////////////////////////////////////////////// 2860 //////////////////////////////////////////////////////////////////////////////////////////
2859 2861
3128 } 3130 }
3129 3131
3130 int AsmStatement::comeFrom() 3132 int AsmStatement::comeFrom()
3131 { 3133 {
3132 assert(0); 3134 assert(0);
3133 return FALSE; 3135 return 0;
3134 } 3136 }
3135 3137
3136 void 3138 void
3137 backend_init() 3139 backend_init()
3138 { 3140 {