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 }