Mercurial > projects > ldc
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 { |