00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BoundsEmitter.h"
00010 #include "CGContext.h"
00011 #include "CodeGenRoutine.h"
00012 #include "CodeGenTypes.h"
00013 #include "CommaRT.h"
00014 #include "DependencySet.h"
00015 #include "SRInfo.h"
00016 #include "comma/ast/AstRewriter.h"
00017 #include "comma/ast/AttribDecl.h"
00018 #include "comma/ast/Expr.h"
00019 #include "comma/ast/Stmt.h"
00020
00021 using namespace comma;
00022
00023 using llvm::dyn_cast;
00024 using llvm::dyn_cast_or_null;
00025 using llvm::cast;
00026 using llvm::isa;
00027
00028 namespace {
00029
00030 class CallEmitter {
00031
00032 public:
00033 CallEmitter(CodeGenRoutine &CGR, llvm::IRBuilder<> &Builder)
00034 : CGR(CGR),
00035 CG(CGR.getCodeGen()),
00036 CGC(CGR.getCGC()),
00037 CGT(CGC.getCGT()),
00038 Builder(Builder) { }
00039
00040 CValue emitSimpleCall(SubroutineCall *call);
00041
00051 CValue emitCompositeCall(FunctionCallExpr *call, llvm::Value *dst);
00052
00053 CValue emitVStackCall(FunctionCallExpr *call);
00054
00055 void emitProcedureCall(ProcedureCallStmt *call);
00056
00057 private:
00059 CodeGenRoutine &CGR;
00060 CodeGen &CG;
00061 CGContext &CGC;
00062 CodeGenTypes &CGT;
00063
00065 llvm::IRBuilder<> &Builder;
00066
00068 SubroutineCall *SRCall;
00069
00071 std::vector<llvm::Value*> arguments;
00072
00077 void emitCallArguments();
00078
00092 void emitArgument(Expr *expr, PM::ParameterMode mode, Type *type);
00093
00099 void emitCompositeArgument(Expr *expr, PM::ParameterMode mode,
00100 CompositeType *type);
00101
00107 void emitArrayArgument(Expr *expr, PM::ParameterMode mode, ArrayType *type);
00108
00111 llvm::Value *emitPrimitiveCall();
00112
00114 llvm::Value *emitAttributeCall();
00115
00117
00118
00120 llvm::Value *emitExponential(llvm::Value *x, llvm::Value *n);
00121
00123 llvm::Value *emitMod(llvm::Value *lhs, llvm::Value *rhs);
00124
00126 llvm::Value *emitRem(llvm::Value *lhs, llvm::Value *rhs);
00127
00129 llvm::Value *emitEQ(Type *argTy, llvm::Value *lhs, llvm::Value *rhs);
00130
00132 llvm::Value *emitNE(Type *argTy, llvm::Value *lhs, llvm::Value *rhs);
00134
00136
00137 llvm::Value *emitAttribute(PosAD *attrib);
00138 llvm::Value *emitAttribute(ValAD *attrib);
00140
00143 SRInfo *prepareCall();
00144
00147 SRInfo *prepareLocalCall();
00148
00150 SRInfo *prepareForeignCall();
00151
00154 SRInfo *prepareDirectCall();
00155
00158 SRInfo *prepareAbstractCall();
00159
00166 SubroutineDecl *
00167 resolveAbstractSubroutine(DomainInstanceDecl *instance,
00168 AbstractDomainDecl *abstract,
00169 SubroutineDecl *target);
00170
00174 llvm::Value *emitCall(llvm::Function *fn);
00175
00177 SRFrame *frame() { return CGR.getSRFrame(); }
00178 };
00179
00180 llvm::Value *CallEmitter::emitCall(llvm::Function *fn)
00181 {
00182 llvm::Value *result;
00183
00184 if (frame()->hasLandingPad()) {
00185 llvm::BasicBlock *mergeBB = frame()->makeBasicBlock();
00186 result = Builder.CreateInvoke(fn, mergeBB, frame()->getLandingPad(),
00187 arguments.begin(), arguments.end());
00188 Builder.SetInsertPoint(mergeBB);
00189 }
00190 else
00191 result = Builder.CreateCall(fn, arguments.begin(), arguments.end());
00192 return result;
00193 }
00194
00195 CValue CallEmitter::emitSimpleCall(SubroutineCall *call)
00196 {
00197 SRCall = call;
00198
00199
00200 if (SRCall->isPrimitive())
00201 return CValue::get(emitPrimitiveCall());
00202
00203
00204 if (SRCall->isAttributeCall())
00205 return CValue::get(emitAttributeCall());
00206
00207
00208
00209 SRInfo *callInfo = prepareCall();
00210 assert(!callInfo->hasSRet() && "Not a simple call!");
00211
00212
00213 emitCallArguments();
00214
00215
00216 return CValue::get(emitCall(callInfo->getLLVMFunction()));
00217 }
00218
00219 CValue CallEmitter::emitCompositeCall(FunctionCallExpr *call, llvm::Value *dst)
00220 {
00221 SRCall = call;
00222 const Type *callTy = CGT.resolveType(call->getType());
00223
00224
00225 if (dst == 0) {
00226 const llvm::Type *retTy = CGT.lowerType(callTy);
00227 dst = frame()->createTemp(retTy);
00228 }
00229
00230
00231
00232 arguments.push_back(dst);
00233
00234
00235
00236 SRInfo *callInfo = prepareCall();
00237 assert(callInfo->hasSRet() && "Not a composite call!");
00238
00239
00240 emitCallArguments();
00241
00242
00243 emitCall(callInfo->getLLVMFunction());
00244
00245 if (callTy->isFatAccessType())
00246 return CValue::getFat(dst);
00247 else
00248 return CValue::get(dst);
00249 }
00250
00251 CValue CallEmitter::emitVStackCall(FunctionCallExpr *call)
00252 {
00253 const CommaRT &CRT = CG.getRuntime();
00254 SRCall = call;
00255
00256
00257
00258 SRInfo *callInfo = prepareCall();
00259
00260
00261 emitCallArguments();
00262
00263
00264 emitCall(callInfo->getLLVMFunction());
00265
00266
00267 ArrayType *arrTy = cast<ArrayType>(CGR.resolveType(call->getType()));
00268 const llvm::Type *boundsTy = CGT.lowerArrayBounds(arrTy);
00269 const llvm::Type *boundsPtrTy = CG.getPointerType(boundsTy);
00270 llvm::Value *boundsSlot = frame()->createTemp(boundsTy);
00271 llvm::Value *dataSlot;
00272 llvm::Value *vstack;
00273 llvm::Value *bounds;
00274
00275
00276
00277 vstack = CRT.vstack(Builder, boundsPtrTy);
00278 bounds = Builder.CreateLoad(vstack);
00279 Builder.CreateStore(bounds, boundsSlot);
00280 CRT.vstack_pop(Builder);
00281
00282
00283
00284 BoundsEmitter emitter(CGR);
00285 frame()->stacksave();
00286 const llvm::Type *componentTy = CGT.lowerType(arrTy->getComponentType());
00287 llvm::Value *length = emitter.computeTotalBoundLength(Builder, bounds);
00288 dataSlot = Builder.CreateAlloca(componentTy, length);
00289
00290
00291 vstack = CRT.vstack(Builder, CG.getInt8PtrTy());
00292 CGR.emitArrayCopy(vstack, dataSlot, length, componentTy);
00293 CRT.vstack_pop(Builder);
00294
00295
00296 const llvm::Type *dataTy = CG.getPointerType(CG.getVLArrayTy(componentTy));
00297 dataSlot = Builder.CreatePointerCast(dataSlot, dataTy);
00298
00299
00300 return CValue::getArray(dataSlot, boundsSlot);
00301 }
00302
00303 void CallEmitter::emitProcedureCall(ProcedureCallStmt *call)
00304 {
00305 SRCall = call;
00306
00307
00308
00309 SRInfo *callInfo = prepareCall();
00310 assert(!callInfo->hasSRet() && "Not a simple call!");
00311
00312
00313 emitCallArguments();
00314
00315
00316 emitCall(callInfo->getLLVMFunction());
00317 }
00318
00319 void CallEmitter::emitCallArguments()
00320 {
00321 SubroutineDecl *SRDecl = SRCall->getConnective();
00322
00323 typedef SubroutineCall::arg_iterator iterator;
00324 iterator Iter = SRCall->begin_arguments();
00325 iterator E = SRCall->end_arguments();
00326 for (unsigned i = 0; Iter != E; ++Iter, ++i) {
00327 Expr *arg = *Iter;
00328 PM::ParameterMode mode = SRDecl->getParamMode(i);
00329 Type *type = SRDecl->getParamType(i);
00330 emitArgument(arg, mode, type);
00331 }
00332 }
00333
00334 void CallEmitter::emitArgument(Expr *param, PM::ParameterMode mode, Type *targetTy)
00335 {
00336 targetTy = CGR.resolveType(targetTy);
00337
00338 if (CompositeType *compTy = dyn_cast<CompositeType>(targetTy))
00339 emitCompositeArgument(param, mode, compTy);
00340 else if (mode == PM::MODE_OUT || mode == PM::MODE_IN_OUT)
00341 arguments.push_back(CGR.emitReference(param).first());
00342 else
00343 arguments.push_back(CGR.emitValue(param).first());
00344 }
00345
00346 void CallEmitter::emitCompositeArgument(Expr *param, PM::ParameterMode mode,
00347 CompositeType *targetTy)
00348 {
00349 if (ArrayType *arrTy = dyn_cast<ArrayType>(targetTy))
00350 emitArrayArgument(param, mode, arrTy);
00351 else {
00352
00353
00354 arguments.push_back(CGR.emitCompositeExpr(param, 0, false).first());
00355 }
00356 }
00357
00358 void CallEmitter::emitArrayArgument(Expr *param, PM::ParameterMode mode,
00359 ArrayType *targetTy)
00360 {
00361 if (FunctionCallExpr *call = dyn_cast<FunctionCallExpr>(param)) {
00362
00363 ArrayType *paramTy = cast<ArrayType>(CGR.resolveType(param->getType()));
00364
00365 if (paramTy->isStaticallyConstrained()) {
00366
00367
00368 arguments.push_back(CGR.emitCompositeCall(call, 0).first());
00369
00370
00371
00372
00373 if (!targetTy->isConstrained()) {
00374 BoundsEmitter emitter(CGR);
00375 llvm::Value *bounds;
00376 bounds = emitter.synthStaticArrayBounds(Builder, paramTy);
00377 arguments.push_back(bounds);
00378 }
00379 }
00380 else {
00381
00382 assert(!paramTy->isConstrained());
00383
00384
00385
00386 CValue arrValue = CGR.emitVStackCall(call);
00387 arguments.push_back(arrValue.first());
00388 if (!targetTy->isConstrained())
00389 arguments.push_back(arrValue.second());
00390 }
00391 return;
00392 }
00393
00394
00395 CValue arrValue = CGR.emitArrayExpr(param, 0, false);
00396 llvm::Value *components = arrValue.first();
00397
00398 if (targetTy->isStaticallyConstrained()) {
00399
00400
00401 arguments.push_back(components);
00402 }
00403 else {
00404
00405
00406
00407
00408
00409 const llvm::Type *contextTy;
00410 contextTy = CGT.lowerArrayType(targetTy);
00411 contextTy = CG.getPointerType(contextTy);
00412
00413 if (contextTy != components->getType())
00414 components = Builder.CreatePointerCast(components, contextTy);
00415
00416
00417 llvm::Value *bounds = arrValue.second();
00418 const llvm::Type *boundsTy = bounds->getType();
00419 if (boundsTy->isAggregateType()) {
00420 llvm::Value *slot = frame()->createTemp(boundsTy);
00421 Builder.CreateStore(bounds, slot);
00422 bounds = slot;
00423 }
00424 arguments.push_back(components);
00425 arguments.push_back(bounds);
00426 }
00427 }
00428
00429 llvm::Value *CallEmitter::emitPrimitiveCall()
00430 {
00431 SubroutineDecl *srDecl = SRCall->getConnective();
00432 PO::PrimitiveID ID = srDecl->getPrimitiveID();
00433 assert(ID != PO::NotPrimitive && "Not a primitive call!");
00434
00435
00436
00437
00438 emitCallArguments();
00439
00440
00441 llvm::Value *result = 0;
00442 if (PO::denotesUnaryOp(ID)) {
00443 assert(arguments.size() == 1 && "Arity mismatch!");
00444 llvm::Value *arg = arguments[0];
00445
00446 switch (ID) {
00447 default:
00448 assert(false && "Cannot codegen primitive!");
00449 break;
00450
00451 case PO::POS_op:
00452 result = arg;
00453 break;
00454
00455 case PO::NEG_op:
00456 result = Builder.CreateNeg(arg);
00457 break;
00458
00459 case PO::LNOT_op:
00460 result = Builder.CreateNot(arg);
00461 break;
00462 }
00463 }
00464 else if (PO::denotesBinaryOp(ID)) {
00465 assert(arguments.size() == 2 && "Arity mismatch!");
00466
00467 Type *argTy = srDecl->getParamType(0);
00468 llvm::Value *lhs = arguments[0];
00469 llvm::Value *rhs = arguments[1];
00470
00471 switch (ID) {
00472 default:
00473 assert(false && "Cannot codegen primitive!");
00474 break;
00475
00476 case PO::EQ_op:
00477 result = emitEQ(argTy, lhs, rhs);
00478 break;
00479
00480 case PO::NE_op:
00481 result = emitNE(argTy, lhs, rhs);
00482 break;
00483
00484 case PO::ADD_op:
00485 result = Builder.CreateAdd(lhs, rhs);
00486 break;
00487
00488 case PO::SUB_op:
00489 result = Builder.CreateSub(lhs, rhs);
00490 break;
00491
00492 case PO::MUL_op:
00493 result = Builder.CreateMul(lhs, rhs);
00494 break;
00495
00496 case PO::DIV_op:
00497
00498 result = Builder.CreateSDiv(lhs, rhs);
00499 break;
00500
00501 case PO::MOD_op:
00502 result = emitMod(lhs, rhs);
00503 break;
00504
00505 case PO::REM_op:
00506 result = emitRem(lhs, rhs);
00507 break;
00508
00509 case PO::POW_op:
00510 result = emitExponential(lhs, rhs);
00511 break;
00512
00513 case PO::LT_op:
00514 result = Builder.CreateICmpSLT(lhs, rhs);
00515 break;
00516
00517 case PO::GT_op:
00518 result = Builder.CreateICmpSGT(lhs, rhs);
00519 break;
00520
00521 case PO::LE_op:
00522 result = Builder.CreateICmpSLE(lhs, rhs);
00523 break;
00524
00525 case PO::GE_op:
00526 result = Builder.CreateICmpSGE(lhs, rhs);
00527 break;
00528
00529 case PO::LOR_op:
00530 result = Builder.CreateOr(lhs, rhs);
00531 break;
00532
00533 case PO::LAND_op:
00534 result = Builder.CreateAnd(lhs, rhs);
00535 break;
00536
00537 case PO::LXOR_op:
00538 result = Builder.CreateXor(lhs, rhs);
00539 break;
00540 }
00541 }
00542 else {
00543
00544 assert(ID == PO::ENUM_op && "Cannot codegen primitive!");
00545 assert(arguments.size() == 0 && "Arity mismatch!");
00546
00547 EnumLiteral *lit = cast<EnumLiteral>(srDecl);
00548 unsigned idx = lit->getIndex();
00549 const llvm::Type *ty = CGT.lowerType(lit->getReturnType());
00550 result = llvm::ConstantInt::get(ty, idx);
00551 }
00552 return result;
00553 }
00554
00555 llvm::Value *CallEmitter::emitAttributeCall()
00556 {
00557 FunctionAttribDecl *attrib = cast<FunctionAttribDecl>(SRCall->getConnective());
00558 llvm::Value *result;
00559
00560 switch (attrib->getKind()) {
00561 default:
00562 assert(false && "Unexpected attribute kind!");
00563 result = 0;
00564 break;
00565
00566 case Ast::AST_PosAD:
00567 result = emitAttribute(cast<PosAD>(attrib));
00568 break;
00569
00570 case Ast::AST_ValAD:
00571 result = emitAttribute(cast<ValAD>(attrib));
00572 break;
00573
00574 };
00575
00576 return result;
00577 }
00578
00579 llvm::Value *CallEmitter::emitAttribute(PosAD *attrib)
00580 {
00581 BoundsEmitter emitter(CGR);
00582
00583
00584
00585
00586 UniversalType *retTy;
00587 const llvm::IntegerType *targetTy;
00588 retTy = cast<UniversalType>(attrib->getReturnType());
00589 targetTy = cast<llvm::IntegerType>(CGT.lowerUniversalType(retTy));
00590
00591 Expr *argExpr = *SRCall->begin_arguments();
00592 DiscreteType *argTy = cast<DiscreteType>(argExpr->getType());
00593 llvm::Value *arg = CGR.emitValue(argExpr).first();
00594 const llvm::Type *sourceTy = cast<llvm::IntegerType>(arg->getType());
00595
00596
00597 llvm::Value *lower = emitter.getLowerBound(Builder, argTy);
00598
00599
00600 if (sourceTy != targetTy) {
00601 if (argTy->isSigned()) {
00602 arg = Builder.CreateSExt(arg, targetTy);
00603 lower = Builder.CreateSExt(lower, targetTy);
00604 }
00605 else {
00606 arg = Builder.CreateZExt(arg, targetTy);
00607 lower = Builder.CreateZExt(lower, targetTy);
00608 }
00609 }
00610
00611
00612 return Builder.CreateSub(arg, lower);
00613 }
00614
00615 llvm::Value *CallEmitter::emitAttribute(ValAD *attrib)
00616 {
00617 BoundsEmitter emitter(CGR);
00618
00619
00620
00621
00622 Expr *argExpr = *SRCall->begin_arguments();
00623 llvm::Value *arg = CGR.emitValue(argExpr).first();
00624
00625 DiscreteType *returnTy = cast<DiscreteType>(attrib->getReturnType());
00626 const llvm::Type *targetTy = CGT.lowerType(returnTy);
00627
00628
00629 if (arg->getType() != targetTy)
00630 arg = Builder.CreateTrunc(arg, targetTy);
00631
00632
00633 llvm::Value *lower = emitter.getLowerBound(Builder, returnTy);
00634 return Builder.CreateAdd(arg, lower);
00635 }
00636
00637 llvm::Value *CallEmitter::emitExponential(llvm::Value *x, llvm::Value *n)
00638 {
00639 CommaRT &CRT = CG.getRuntime();
00640
00641
00642
00643 const llvm::IntegerType *type = cast<llvm::IntegerType>(x->getType());
00644 const llvm::IntegerType *i32Ty = CG.getInt32Ty();
00645 const llvm::IntegerType *i64Ty = CG.getInt64Ty();
00646 unsigned width = type->getBitWidth();
00647 llvm::Value *result;
00648
00649 assert(cast<llvm::IntegerType>(n->getType()) == i32Ty &&
00650 "Unexpected type for rhs of exponential!");
00651
00652
00653
00654 if (width < 32) {
00655 x = Builder.CreateSExt(x, i32Ty);
00656 result = CRT.pow_i32_i32(Builder, x, n);
00657 result = Builder.CreateTrunc(result, type);
00658 }
00659 else if (width == 32)
00660 result = CRT.pow_i32_i32(Builder, x, n);
00661 else if (width < 64) {
00662 x = Builder.CreateSExt(x, i64Ty);
00663 result = CRT.pow_i64_i32(Builder, x, n);
00664 result = Builder.CreateTrunc(result, type);
00665 }
00666 else {
00667 assert(width == 64 && "Integer type too wide!");
00668 result = CRT.pow_i64_i32(Builder, x, n);
00669 }
00670
00671 return result;
00672 }
00673
00674 llvm::Value *CallEmitter::emitMod(llvm::Value *lhs, llvm::Value *rhs)
00675 {
00676
00677 const llvm::Type *doubleTy = Builder.getDoubleTy();
00678 llvm::Constant *doubleZero = llvm::ConstantFP::get(doubleTy, 0.0);
00679 llvm::Constant *doubleOne = llvm::ConstantFP::get(doubleTy, 1.0);
00680
00681
00682 llvm::Value *Flhs = Builder.CreateSIToFP(lhs, doubleTy);
00683 llvm::Value *Frhs = Builder.CreateSIToFP(rhs, doubleTy);
00684
00685
00686 llvm::Value *floor;
00687 floor = Builder.CreateFDiv(Flhs, Frhs);
00688
00689
00690
00691 llvm::Value *isNeg;
00692 llvm::Value *bias;
00693 isNeg = Builder.CreateFCmpOLT(floor, doubleZero);
00694 bias = Builder.CreateSelect(isNeg, doubleOne, doubleZero);
00695 floor = Builder.CreateFSub(floor, bias);
00696 floor = Builder.CreateFPToSI(floor, lhs->getType());
00697
00698
00699 return Builder.CreateSub(lhs, Builder.CreateMul(rhs, floor));
00700 }
00701
00702 llvm::Value *CallEmitter::emitRem(llvm::Value *lhs, llvm::Value *rhs)
00703 {
00704
00705 return Builder.CreateSRem(lhs, rhs);
00706 }
00707
00708 llvm::Value *CallEmitter::emitEQ(Type *argTy,
00709 llvm::Value *lhs, llvm::Value *rhs)
00710 {
00711 if (argTy->isFatAccessType()) {
00712
00713 lhs = Builder.CreateLoad(Builder.CreateStructGEP(lhs, 0));
00714 rhs = Builder.CreateLoad(Builder.CreateStructGEP(rhs, 0));
00715 lhs = Builder.CreatePtrToInt(lhs, CG.getIntPtrTy());
00716 rhs = Builder.CreatePtrToInt(rhs, CG.getIntPtrTy());
00717 }
00718 else if (argTy->isThinAccessType()) {
00719
00720 lhs = Builder.CreatePtrToInt(lhs, CG.getIntPtrTy());
00721 rhs = Builder.CreatePtrToInt(rhs, CG.getIntPtrTy());
00722 }
00723
00724 return Builder.CreateICmpEQ(lhs, rhs);
00725 }
00726
00727 llvm::Value *CallEmitter::emitNE(Type *argTy, llvm::Value *lhs, llvm::Value *rhs)
00728 {
00729 if (argTy->isFatAccessType()) {
00730
00731 lhs = Builder.CreateLoad(Builder.CreateStructGEP(lhs, 0));
00732 rhs = Builder.CreateLoad(Builder.CreateStructGEP(rhs, 0));
00733 lhs = Builder.CreatePtrToInt(lhs, CG.getIntPtrTy());
00734 rhs = Builder.CreatePtrToInt(rhs, CG.getIntPtrTy());
00735 }
00736 else if (argTy->isThinAccessType()) {
00737
00738 lhs = Builder.CreatePtrToInt(lhs, CG.getIntPtrTy());
00739 rhs = Builder.CreatePtrToInt(rhs, CG.getIntPtrTy());
00740 }
00741
00742 return Builder.CreateICmpNE(lhs, rhs);
00743 }
00744
00745 SRInfo *CallEmitter::prepareCall()
00746 {
00747 if (SRCall->isForeignCall())
00748 return prepareForeignCall();
00749 else if (SRCall->isLocalCall())
00750 return prepareLocalCall();
00751 else if (SRCall->isDirectCall())
00752 return prepareDirectCall();
00753 else if (SRCall->isAbstractCall())
00754 return prepareAbstractCall();
00755 else {
00756 assert(false && "Unsupported call type!");
00757 return 0;
00758 }
00759 }
00760
00761 SRInfo *CallEmitter::prepareLocalCall()
00762 {
00763
00764
00765
00766 arguments.push_back(CGR.getImplicitContext());
00767
00768
00769 SubroutineDecl *srDecl = SRCall->getConnective();
00770 InstanceInfo *IInfo = CGC.getInstanceInfo();
00771 DomainInstanceDecl *instance = IInfo->getInstanceDecl();
00772 return CGR.getCodeGen().getSRInfo(instance, srDecl);
00773 }
00774
00775 SRInfo *CallEmitter::prepareForeignCall()
00776 {
00777
00778 SubroutineDecl *srDecl = SRCall->getConnective();
00779 DeclRegion *region = srDecl->getDeclRegion();
00780 DomainInstanceDecl *instance = dyn_cast<DomainInstanceDecl>(region);
00781
00782 if (!instance)
00783 instance = CGC.getInstanceInfo()->getInstanceDecl();
00784
00785 return CG.getSRInfo(instance, srDecl);
00786 }
00787
00788 SRInfo *CallEmitter::prepareDirectCall()
00789 {
00790 SubroutineDecl *srDecl = SRCall->getConnective();
00791 const CommaRT &CRT = CG.getRuntime();
00792 InstanceInfo *IInfo = CGC.getInstanceInfo();
00793
00794
00795
00796
00797
00798
00799 DomainInstanceDecl *definingDecl
00800 = cast<DomainInstanceDecl>(srDecl->getDeclRegion());
00801 const DependencySet &DSet = CG.getDependencySet(IInfo->getDefinition());
00802 DependencySet::iterator IDPos = DSet.find(definingDecl);
00803 assert(IDPos != DSet.end() && "Failed to resolve dependency!");
00804 unsigned instanceID = DSet.getDependentID(IDPos);
00805
00806
00807
00808 llvm::Value *implicitCtx;
00809 implicitCtx = CGR.getImplicitContext();
00810 implicitCtx = CRT.getLocalCapsule(Builder, implicitCtx, instanceID);
00811 arguments.push_back(implicitCtx);
00812
00813
00814
00815
00816 DomainInstanceDecl *targetInstance;
00817 SubroutineDecl *targetRoutine;
00818 if (definingDecl->isDependent()) {
00819 AstRewriter rewriter(CG.getAstResource());
00820
00821
00822 rewriter.addTypeRewrite(IInfo->getDefinition()->getPercentType(),
00823 IInfo->getInstanceDecl()->getType());
00824
00825
00826 const CGContext::ParameterMap ¶mMap = CGC.getParameterMap();
00827 rewriter.addTypeRewrites(paramMap.begin(), paramMap.end());
00828
00829
00830
00831 DomainType *targetTy = rewriter.rewriteType(definingDecl->getType());
00832 targetInstance = targetTy->getInstanceDecl();
00833
00834
00835
00836
00837
00838
00839 rewriter.addTypeRewrite(definingDecl->getType(), targetTy);
00840 SubroutineType *srTy = rewriter.rewriteType(srDecl->getType());
00841 Decl *resolvedDecl = targetInstance->findDecl(srDecl->getIdInfo(), srTy);
00842 targetRoutine = cast<SubroutineDecl>(resolvedDecl);
00843 }
00844 else {
00845 targetInstance = definingDecl;
00846 targetRoutine = srDecl;
00847 }
00848
00849
00850
00851
00852 CG.extendWorklist(targetInstance);
00853
00854
00855 return CG.getSRInfo(targetInstance, targetRoutine);
00856 }
00857
00858 SRInfo *CallEmitter::prepareAbstractCall()
00859 {
00860 const CommaRT &CRT = CG.getRuntime();
00861
00862
00863 SubroutineDecl *srDecl = SRCall->getConnective();
00864 AbstractDomainDecl *abstract =
00865 cast<AbstractDomainDecl>(srDecl->getDeclRegion());
00866
00867
00868
00869 DomainInstanceDecl *instance = CGC.rewriteAbstractDecl(abstract);
00870 assert(instance && "Failed to resolve abstract domain!");
00871
00872
00873
00874
00875 CG.extendWorklist(instance);
00876
00877
00878 SubroutineDecl *resolvedRoutine;
00879 resolvedRoutine = resolveAbstractSubroutine(instance, abstract, srDecl);
00880
00881
00882
00883 InstanceInfo *IInfo = CGC.getInstanceInfo();
00884 const FunctorDecl *functor = cast<FunctorDecl>(IInfo->getDefinition());
00885 unsigned index = functor->getFormalIndex(abstract);
00886 llvm::Value *context = CGR.getImplicitContext();
00887 arguments.push_back(CRT.getCapsuleParameter(Builder, context, index));
00888
00889
00890 return CG.getSRInfo(instance, resolvedRoutine);
00891 }
00892
00893 SubroutineDecl *
00894 CallEmitter::resolveAbstractSubroutine(DomainInstanceDecl *instance,
00895 AbstractDomainDecl *abstract,
00896 SubroutineDecl *target)
00897 {
00898 DomainType *abstractTy = abstract->getType();
00899
00900
00901
00902
00903
00904 AstRewriter rewriter(CGR.getCodeGen().getAstResource());
00905 rewriter.addTypeRewrite(abstractTy, instance->getType());
00906 SubroutineType *targetTy = rewriter.rewriteType(target->getType());
00907
00908
00909 Decl *resolvedDecl = instance->findDecl(target->getIdInfo(), targetTy);
00910 return cast<SubroutineDecl>(resolvedDecl);
00911 }
00912
00913 }
00914
00915 CValue CodeGenRoutine::emitFunctionCall(FunctionCallExpr *expr)
00916 {
00917 CallEmitter emitter(*this, Builder);
00918
00919 if (resolveType(expr)->isFatAccessType())
00920 return emitter.emitCompositeCall(expr, 0);
00921 else
00922 return emitter.emitSimpleCall(expr);
00923 }
00924
00925 CValue CodeGenRoutine::emitSimpleCall(FunctionCallExpr *expr)
00926 {
00927 CallEmitter emitter(*this, Builder);
00928 return emitter.emitSimpleCall(expr);
00929 }
00930
00931 CValue CodeGenRoutine::emitCompositeCall(FunctionCallExpr *expr,
00932 llvm::Value *dst)
00933 {
00934 CallEmitter emitter(*this, Builder);
00935 return emitter.emitCompositeCall(expr, dst);
00936 }
00937
00938 CValue CodeGenRoutine::emitVStackCall(FunctionCallExpr *expr)
00939 {
00940 CallEmitter emitter(*this, Builder);
00941 return emitter.emitVStackCall(expr);
00942 }
00943
00944 void CodeGenRoutine::emitProcedureCallStmt(ProcedureCallStmt *stmt)
00945 {
00946 CallEmitter emitter(*this, Builder);
00947 emitter.emitProcedureCall(stmt);
00948 }