comparison gen/statements.cpp @ 213:7816aafeea3c trunk

[svn r229] Updated the object.d implementation to the latest Tango. Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array. Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 . Cleaned up some type code. Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant. Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
author lindquist
date Fri, 30 May 2008 19:32:04 +0200
parents cd2c9f4010e4
children 0806379a5eca
comparison
equal deleted inserted replaced
212:4c2689d57ba4 213:7816aafeea3c
102 102
103 } 103 }
104 else { 104 else {
105 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum); 105 if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
106 DValue* e = exp->toElem(p); 106 DValue* e = exp->toElem(p);
107 llvm::Value* v = e->getRVal(); 107 LLValue* v = e->getRVal();
108 delete e; 108 delete e;
109 Logger::cout() << "return value is '" <<*v << "'\n"; 109 Logger::cout() << "return value is '" <<*v << "'\n";
110 110
111 // can happen for classes 111 // can happen for classes
112 if (v->getType() != p->topfunc()->getReturnType()) 112 if (v->getType() != p->topfunc()->getReturnType())
175 Logger::println("IfStatement::toIR(): %s", loc.toChars()); 175 Logger::println("IfStatement::toIR(): %s", loc.toChars());
176 LOG_SCOPE; 176 LOG_SCOPE;
177 177
178 if (match) 178 if (match)
179 { 179 {
180 llvm::Value* allocainst = new llvm::AllocaInst(DtoType(match->type), "._tmp_if_var", p->topallocapoint()); 180 LLValue* allocainst = new llvm::AllocaInst(DtoType(match->type), "._tmp_if_var", p->topallocapoint());
181 match->ir.irLocal = new IrLocal(match); 181 match->ir.irLocal = new IrLocal(match);
182 match->ir.irLocal->value = allocainst; 182 match->ir.irLocal->value = allocainst;
183 } 183 }
184 184
185 DValue* cond_e = condition->toElem(p); 185 DValue* cond_e = condition->toElem(p);
186 llvm::Value* cond_val = cond_e->getRVal(); 186 LLValue* cond_val = cond_e->getRVal();
187 delete cond_e; 187 delete cond_e;
188 188
189 llvm::BasicBlock* oldend = gIR->scopeend(); 189 llvm::BasicBlock* oldend = gIR->scopeend();
190 190
191 llvm::BasicBlock* ifbb = llvm::BasicBlock::Create("if", gIR->topfunc(), oldend); 191 llvm::BasicBlock* ifbb = llvm::BasicBlock::Create("if", gIR->topfunc(), oldend);
194 194
195 if (cond_val->getType() != llvm::Type::Int1Ty) { 195 if (cond_val->getType() != llvm::Type::Int1Ty) {
196 Logger::cout() << "if conditional: " << *cond_val << '\n'; 196 Logger::cout() << "if conditional: " << *cond_val << '\n';
197 cond_val = DtoBoolean(cond_val); 197 cond_val = DtoBoolean(cond_val);
198 } 198 }
199 llvm::Value* ifgoback = llvm::BranchInst::Create(ifbb, elsebb, cond_val, gIR->scopebb()); 199 LLValue* ifgoback = llvm::BranchInst::Create(ifbb, elsebb, cond_val, gIR->scopebb());
200 200
201 // replace current scope 201 // replace current scope
202 gIR->scope() = IRScope(ifbb,elsebb); 202 gIR->scope() = IRScope(ifbb,elsebb);
203 203
204 // do scoped statements 204 // do scoped statements
272 // replace current scope 272 // replace current scope
273 gIR->scope() = IRScope(whilebb,endbb); 273 gIR->scope() = IRScope(whilebb,endbb);
274 274
275 // create the condition 275 // create the condition
276 DValue* cond_e = condition->toElem(p); 276 DValue* cond_e = condition->toElem(p);
277 llvm::Value* cond_val = DtoBoolean(cond_e->getRVal()); 277 LLValue* cond_val = DtoBoolean(cond_e->getRVal());
278 delete cond_e; 278 delete cond_e;
279 279
280 // conditional branch 280 // conditional branch
281 llvm::Value* ifbreak = llvm::BranchInst::Create(whilebodybb, endbb, cond_val, p->scopebb()); 281 LLValue* ifbreak = llvm::BranchInst::Create(whilebodybb, endbb, cond_val, p->scopebb());
282 282
283 // rewrite scope 283 // rewrite scope
284 gIR->scope() = IRScope(whilebodybb,endbb); 284 gIR->scope() = IRScope(whilebodybb,endbb);
285 285
286 // while body code 286 // while body code
320 body->toIR(p); 320 body->toIR(p);
321 p->loopbbs.pop_back(); 321 p->loopbbs.pop_back();
322 322
323 // create the condition 323 // create the condition
324 DValue* cond_e = condition->toElem(p); 324 DValue* cond_e = condition->toElem(p);
325 llvm::Value* cond_val = DtoBoolean(cond_e->getRVal()); 325 LLValue* cond_val = DtoBoolean(cond_e->getRVal());
326 delete cond_e; 326 delete cond_e;
327 327
328 // conditional branch 328 // conditional branch
329 llvm::Value* ifbreak = llvm::BranchInst::Create(dowhilebb, endbb, cond_val, gIR->scopebb()); 329 LLValue* ifbreak = llvm::BranchInst::Create(dowhilebb, endbb, cond_val, gIR->scopebb());
330 330
331 // rewrite the scope 331 // rewrite the scope
332 gIR->scope() = IRScope(endbb,oldend); 332 gIR->scope() = IRScope(endbb,oldend);
333 } 333 }
334 334
359 // replace current scope 359 // replace current scope
360 gIR->scope() = IRScope(forbb,forbodybb); 360 gIR->scope() = IRScope(forbb,forbodybb);
361 361
362 // create the condition 362 // create the condition
363 DValue* cond_e = condition->toElem(p); 363 DValue* cond_e = condition->toElem(p);
364 llvm::Value* cond_val = DtoBoolean(cond_e->getRVal()); 364 LLValue* cond_val = DtoBoolean(cond_e->getRVal());
365 delete cond_e; 365 delete cond_e;
366 366
367 // conditional branch 367 // conditional branch
368 assert(!gIR->scopereturned()); 368 assert(!gIR->scopereturned());
369 llvm::BranchInst::Create(forbodybb, endbb, cond_val, gIR->scopebb()); 369 llvm::BranchInst::Create(forbodybb, endbb, cond_val, gIR->scopebb());
569 569
570 assert(exp); 570 assert(exp);
571 DValue* e = exp->toElem(p); 571 DValue* e = exp->toElem(p);
572 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception"); 572 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_throw_exception");
573 //Logger::cout() << "calling: " << *fn << '\n'; 573 //Logger::cout() << "calling: " << *fn << '\n';
574 llvm::Value* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0)); 574 LLValue* arg = DtoBitCast(e->getRVal(), fn->getFunctionType()->getParamType(0));
575 //Logger::cout() << "arg: " << *arg << '\n'; 575 //Logger::cout() << "arg: " << *arg << '\n';
576 gIR->ir->CreateCall(fn, arg, ""); 576 gIR->ir->CreateCall(fn, arg, "");
577 gIR->ir->CreateUnreachable(); 577 gIR->ir->CreateUnreachable();
578 } 578 }
579 579
594 Case* c2 = (Case*)obj; 594 Case* c2 = (Case*)obj;
595 return str->compare(c2->str); 595 return str->compare(c2->str);
596 } 596 }
597 }; 597 };
598 598
599 static llvm::Value* call_string_switch_runtime(llvm::GlobalVariable* table, Expression* e) 599 static LLValue* call_string_switch_runtime(llvm::GlobalVariable* table, Expression* e)
600 { 600 {
601 Type* dt = DtoDType(e->type); 601 Type* dt = DtoDType(e->type);
602 Type* dtnext = DtoDType(dt->next); 602 Type* dtnext = DtoDType(dt->next);
603 TY ty = dtnext->ty; 603 TY ty = dtnext->ty;
604 const char* fname; 604 const char* fname;
614 else { 614 else {
615 assert(0 && "not char/wchar/dchar"); 615 assert(0 && "not char/wchar/dchar");
616 } 616 }
617 617
618 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname); 618 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname);
619 std::vector<llvm::Value*> args; 619 std::vector<LLValue*> args;
620 Logger::cout() << *table->getType() << '\n'; 620 Logger::cout() << *table->getType() << '\n';
621 Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n'; 621 Logger::cout() << *fn->getFunctionType()->getParamType(0) << '\n';
622 assert(table->getType() == fn->getFunctionType()->getParamType(0)); 622 assert(table->getType() == fn->getFunctionType()->getParamType(0));
623 args.push_back(table); 623 args.push_back(table);
624 624
625 DValue* val = e->toElem(gIR); 625 DValue* val = e->toElem(gIR);
626 llvm::Value* llval; 626 LLValue* llval;
627 if (DSliceValue* sval = val->isSlice()) 627 if (DSliceValue* sval = val->isSlice())
628 { 628 {
629 // give storage 629 // give storage
630 llval = new llvm::AllocaInst(DtoType(e->type), "tmp", gIR->topallocapoint()); 630 llval = new llvm::AllocaInst(DtoType(e->type), "tmp", gIR->topallocapoint());
631 DVarValue* vv = new DVarValue(e->type, llval, true); 631 DVarValue* vv = new DVarValue(e->type, llval, true);
665 CaseStatement* last; 665 CaseStatement* last;
666 bool first = true; 666 bool first = true;
667 do { 667 do {
668 // integral case 668 // integral case
669 if (cs->exp->type->isintegral()) { 669 if (cs->exp->type->isintegral()) {
670 llvm::Constant* c = cs->exp->toConstElem(p); 670 LLConstant* c = cs->exp->toConstElem(p);
671 tmp.push_back(isaConstantInt(c)); 671 tmp.push_back(isaConstantInt(c));
672 } 672 }
673 // string case 673 // string case
674 else { 674 else {
675 assert(cs->exp->op == TOKstring); 675 assert(cs->exp->op == TOKstring);
692 if (!condition->type->isintegral()) 692 if (!condition->type->isintegral())
693 { 693 {
694 // first sort it 694 // first sort it
695 caseArray.sort(); 695 caseArray.sort();
696 // iterate and add indices to cases 696 // iterate and add indices to cases
697 std::vector<llvm::Constant*> inits; 697 std::vector<LLConstant*> inits;
698 for (size_t i=0; i<caseArray.dim; ++i) 698 for (size_t i=0; i<caseArray.dim; ++i)
699 { 699 {
700 Case* c = (Case*)caseArray.data[i]; 700 Case* c = (Case*)caseArray.data[i];
701 vcases[c->index].second.push_back(DtoConstUint(i)); 701 vcases[c->index].second.push_back(DtoConstUint(i));
702 inits.push_back(c->str->toConstElem(p)); 702 inits.push_back(c->str->toConstElem(p));
703 } 703 }
704 // build static array for ptr or final array 704 // build static array for ptr or final array
705 const llvm::Type* elemTy = DtoType(condition->type); 705 const LLType* elemTy = DtoType(condition->type);
706 const llvm::ArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size()); 706 const llvm::ArrayType* arrTy = llvm::ArrayType::get(elemTy, inits.size());
707 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, inits); 707 LLConstant* arrInit = llvm::ConstantArray::get(arrTy, inits);
708 llvm::GlobalVariable* arr = new llvm::GlobalVariable(arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, "string_switch_table_data", gIR->module); 708 llvm::GlobalVariable* arr = new llvm::GlobalVariable(arrTy, true, llvm::GlobalValue::InternalLinkage, arrInit, "string_switch_table_data", gIR->module);
709 709
710 const llvm::Type* elemPtrTy = getPtrToType(elemTy); 710 const LLType* elemPtrTy = getPtrToType(elemTy);
711 llvm::Constant* arrPtr = llvm::ConstantExpr::getBitCast(arr, elemPtrTy); 711 LLConstant* arrPtr = llvm::ConstantExpr::getBitCast(arr, elemPtrTy);
712 712
713 // build the static table 713 // build the static table
714 std::vector<const llvm::Type*> types; 714 std::vector<const LLType*> types;
715 types.push_back(DtoSize_t()); 715 types.push_back(DtoSize_t());
716 types.push_back(elemPtrTy); 716 types.push_back(elemPtrTy);
717 const llvm::StructType* sTy = llvm::StructType::get(types); 717 const llvm::StructType* sTy = llvm::StructType::get(types);
718 std::vector<llvm::Constant*> sinits; 718 std::vector<LLConstant*> sinits;
719 sinits.push_back(DtoConstSize_t(inits.size())); 719 sinits.push_back(DtoConstSize_t(inits.size()));
720 sinits.push_back(arrPtr); 720 sinits.push_back(arrPtr);
721 llvm::Constant* sInit = llvm::ConstantStruct::get(sTy, sinits); 721 LLConstant* sInit = llvm::ConstantStruct::get(sTy, sinits);
722 722
723 switchTable = new llvm::GlobalVariable(sTy, true, llvm::GlobalValue::InternalLinkage, sInit, "string_switch_table", gIR->module); 723 switchTable = new llvm::GlobalVariable(sTy, true, llvm::GlobalValue::InternalLinkage, sInit, "string_switch_table", gIR->module);
724 } 724 }
725 725
726 // default 726 // default
732 732
733 // end (break point) 733 // end (break point)
734 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("switchend", p->topfunc(), oldend); 734 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("switchend", p->topfunc(), oldend);
735 735
736 // condition var 736 // condition var
737 llvm::Value* condVal; 737 LLValue* condVal;
738 // integral switch 738 // integral switch
739 if (condition->type->isintegral()) { 739 if (condition->type->isintegral()) {
740 DValue* cond = condition->toElem(p); 740 DValue* cond = condition->toElem(p);
741 condVal = cond->getRVal(); 741 condVal = cond->getRVal();
742 } 742 }
843 //Logger::println("Argument is %s", arg->toChars()); 843 //Logger::println("Argument is %s", arg->toChars());
844 844
845 Logger::println("aggr = %s", aggr->toChars()); 845 Logger::println("aggr = %s", aggr->toChars());
846 846
847 // key 847 // key
848 const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t(); 848 const LLType* keytype = key ? DtoType(key->type) : DtoSize_t();
849 llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); 849 LLValue* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
850 if (key) 850 if (key)
851 { 851 {
852 //key->llvmValue = keyvar; 852 //key->llvmValue = keyvar;
853 assert(!key->ir.irLocal); 853 assert(!key->ir.irLocal);
854 key->ir.irLocal = new IrLocal(key); 854 key->ir.irLocal = new IrLocal(key);
855 key->ir.irLocal->value = keyvar; 855 key->ir.irLocal->value = keyvar;
856 } 856 }
857 llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false); 857 LLValue* zerokey = llvm::ConstantInt::get(keytype,0,false);
858 858
859 // value 859 // value
860 Logger::println("value = %s", value->toPrettyChars()); 860 Logger::println("value = %s", value->toPrettyChars());
861 const llvm::Type* valtype = DtoType(value->type); 861 const LLType* valtype = DtoType(value->type);
862 llvm::Value* valvar = NULL; 862 LLValue* valvar = NULL;
863 if (!value->isRef() && !value->isOut()) 863 if (!value->isRef() && !value->isOut())
864 valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()); 864 valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
865 if (!value->ir.irLocal) 865 if (!value->ir.irLocal)
866 value->ir.irLocal = new IrLocal(value); 866 value->ir.irLocal = new IrLocal(value);
867 867
868 // what to iterate 868 // what to iterate
869 DValue* aggrval = aggr->toElem(p); 869 DValue* aggrval = aggr->toElem(p);
870 Type* aggrtype = DtoDType(aggr->type); 870 Type* aggrtype = DtoDType(aggr->type);
871 871
872 // get length and pointer 872 // get length and pointer
873 llvm::Value* val = 0; 873 LLValue* val = 0;
874 llvm::Value* niters = 0; 874 LLValue* niters = 0;
875 875
876 // static array 876 // static array
877 if (aggrtype->ty == Tsarray) 877 if (aggrtype->ty == Tsarray)
878 { 878 {
879 Logger::println("foreach over static array"); 879 Logger::println("foreach over static array");
920 niters = gIR->ir->CreateTrunc(niters, keytype, "foreachtrunckey"); 920 niters = gIR->ir->CreateTrunc(niters, keytype, "foreachtrunckey");
921 else 921 else
922 niters = gIR->ir->CreateBitCast(niters, keytype, "foreachtrunckey"); 922 niters = gIR->ir->CreateBitCast(niters, keytype, "foreachtrunckey");
923 } 923 }
924 924
925 llvm::Constant* delta = 0; 925 LLConstant* delta = 0;
926 if (op == TOKforeach) { 926 if (op == TOKforeach) {
927 new llvm::StoreInst(zerokey, keyvar, p->scopebb()); 927 new llvm::StoreInst(zerokey, keyvar, p->scopebb());
928 } 928 }
929 else { 929 else {
930 new llvm::StoreInst(niters, keyvar, p->scopebb()); 930 new llvm::StoreInst(niters, keyvar, p->scopebb());
939 llvm::BranchInst::Create(condbb, p->scopebb()); 939 llvm::BranchInst::Create(condbb, p->scopebb());
940 940
941 // condition 941 // condition
942 p->scope() = IRScope(condbb,bodybb); 942 p->scope() = IRScope(condbb,bodybb);
943 943
944 llvm::Value* done = 0; 944 LLValue* done = 0;
945 llvm::Value* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb()); 945 LLValue* load = new llvm::LoadInst(keyvar, "tmp", p->scopebb());
946 if (op == TOKforeach) { 946 if (op == TOKforeach) {
947 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb()); 947 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_ULT, load, niters, "tmp", p->scopebb());
948 } 948 }
949 else if (op == TOKforeach_reverse) { 949 else if (op == TOKforeach_reverse) {
950 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, zerokey, "tmp", p->scopebb()); 950 done = new llvm::ICmpInst(llvm::ICmpInst::ICMP_UGT, load, zerokey, "tmp", p->scopebb());
955 955
956 // init body 956 // init body
957 p->scope() = IRScope(bodybb,nextbb); 957 p->scope() = IRScope(bodybb,nextbb);
958 958
959 // get value for this iteration 959 // get value for this iteration
960 llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); 960 LLConstant* zero = llvm::ConstantInt::get(keytype,0,false);
961 llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); 961 LLValue* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
962 if (aggrtype->ty == Tsarray) 962 if (aggrtype->ty == Tsarray)
963 value->ir.irLocal->value = DtoGEP(val,zero,loadedKey,"tmp"); 963 value->ir.irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
964 else if (aggrtype->ty == Tarray) 964 else if (aggrtype->ty == Tarray)
965 value->ir.irLocal->value = llvm::GetElementPtrInst::Create(val,loadedKey,"tmp",p->scopebb()); 965 value->ir.irLocal->value = llvm::GetElementPtrInst::Create(val,loadedKey,"tmp",p->scopebb());
966 966
980 llvm::BranchInst::Create(nextbb, p->scopebb()); 980 llvm::BranchInst::Create(nextbb, p->scopebb());
981 981
982 // next 982 // next
983 p->scope() = IRScope(nextbb,endbb); 983 p->scope() = IRScope(nextbb,endbb);
984 if (op == TOKforeach) { 984 if (op == TOKforeach) {
985 llvm::Value* load = DtoLoad(keyvar); 985 LLValue* load = DtoLoad(keyvar);
986 load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp"); 986 load = p->ir->CreateAdd(load, llvm::ConstantInt::get(keytype, 1, false), "tmp");
987 DtoStore(load, keyvar); 987 DtoStore(load, keyvar);
988 } 988 }
989 llvm::BranchInst::Create(condbb, p->scopebb()); 989 llvm::BranchInst::Create(condbb, p->scopebb());
990 990
1139 } while (t = t->next); 1139 } while (t = t->next);
1140 1140
1141 Logger::println("asm expr = '%s'", asmstr.c_str()); 1141 Logger::println("asm expr = '%s'", asmstr.c_str());
1142 1142
1143 // create function type 1143 // create function type
1144 std::vector<const llvm::Type*> args; 1144 std::vector<const LLType*> args;
1145 const llvm::FunctionType* fty = llvm::FunctionType::get(DtoSize_t(), args, false); 1145 const llvm::FunctionType* fty = llvm::FunctionType::get(DtoSize_t(), args, false);
1146 1146
1147 // create inline asm callee 1147 // create inline asm callee
1148 llvm::InlineAsm* inasm = llvm::InlineAsm::get(fty, asmstr, "r,r", false); 1148 llvm::InlineAsm* inasm = llvm::InlineAsm::get(fty, asmstr, "r,r", false);
1149 1149