00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/ast/Decl.h"
00010 #include "comma/ast/Expr.h"
00011 #include "comma/ast/Stmt.h"
00012 #include "comma/codegen/CodeGenCapsule.h"
00013 #include "comma/codegen/CodeGenRoutine.h"
00014 #include "comma/codegen/CodeGenTypes.h"
00015 #include "comma/codegen/CommaRT.h"
00016
00017 using namespace comma;
00018
00019 using llvm::dyn_cast;
00020 using llvm::cast;
00021 using llvm::isa;
00022
00023
00024 llvm::Value *CodeGenRoutine::emitExpr(Expr *expr)
00025 {
00026 llvm::Value *val = 0;
00027
00028 switch (expr->getKind()) {
00029 default:
00030 assert(false && "Cannot codegen expression!");
00031 val = 0;
00032 break;
00033
00034 case Ast::AST_DeclRefExpr:
00035 val = emitDeclRefExpr(cast<DeclRefExpr>(expr));
00036 break;
00037
00038 case Ast::AST_FunctionCallExpr:
00039 val = emitFunctionCall(cast<FunctionCallExpr>(expr));
00040 break;
00041
00042 case Ast::AST_InjExpr:
00043 val = emitInjExpr(cast<InjExpr>(expr));
00044 break;
00045
00046 case Ast::AST_PrjExpr:
00047 val = emitPrjExpr(cast<PrjExpr>(expr));
00048 break;
00049
00050 case Ast::AST_IntegerLiteral:
00051 val = emitIntegerLiteral(cast<IntegerLiteral>(expr));
00052 break;
00053 }
00054
00055 return val;
00056 }
00057
00058 llvm::Value *CodeGenRoutine::emitDeclRefExpr(DeclRefExpr *expr)
00059 {
00060 llvm::Value *val = lookupDecl(expr->getDeclaration());
00061 assert(val && "DeclRef lookup failed!");
00062 return val;
00063 }
00064
00065 llvm::Value *CodeGenRoutine::emitFunctionCall(FunctionCallExpr *expr)
00066 {
00067 FunctionDecl *fdecl = cast<FunctionDecl>(expr->getConnective());
00068 std::vector<llvm::Value *> args;
00069
00070 for (unsigned i = 0; i < expr->getNumArgs(); ++i) {
00071 Expr *arg = expr->getArg(i);
00072 args.push_back(emitCallArgument(fdecl, arg, i));
00073 }
00074
00075 if (fdecl->isPrimitive())
00076 return emitPrimitiveCall(expr, args);
00077 else if (isLocalCall(expr))
00078 return emitLocalCall(fdecl, args);
00079 else if (isDirectCall(expr))
00080 return emitDirectCall(fdecl, args);
00081 else
00082
00083 return CRT.genAbstractCall(Builder, percent, fdecl, args);
00084 }
00085
00086 llvm::Value *CodeGenRoutine::emitCallArgument(SubroutineDecl *srDecl, Expr *arg,
00087 unsigned argPosition)
00088 {
00089 PM::ParameterMode mode = srDecl->getParamMode(argPosition);
00090
00091 if (mode == PM::MODE_OUT or mode == PM::MODE_IN_OUT)
00092 return emitVariableReference(arg);
00093 else
00094 return emitValue(arg);
00095 }
00096
00097 llvm::Value *CodeGenRoutine::emitLocalCall(SubroutineDecl *srDecl,
00098 std::vector<llvm::Value *> &args)
00099 {
00100
00101
00102 args.insert(args.begin(), percent);
00103
00104 llvm::Value *func = CG.lookupGlobal(CodeGen::getLinkName(srDecl));
00105 assert(func && "function lookup failed!");
00106 return Builder.CreateCall(func, args.begin(), args.end());
00107 }
00108
00109 llvm::Value *CodeGenRoutine::emitDirectCall(SubroutineDecl *srDecl,
00110 std::vector<llvm::Value *> &args)
00111 {
00112 DomainInstanceDecl *instance;
00113 Domoid *target;
00114
00115
00116 instance = cast<DomainInstanceDecl>(srDecl->getDeclRegion());
00117 target = instance->getDefiningDecl();
00118 llvm::GlobalValue *capsuleInfo = CG.lookupCapsuleInfo(target);
00119 assert(capsuleInfo && "Could not resolve info for direct call!");
00120
00121
00122
00123
00124 unsigned instanceID = CGC.addCapsuleDependency(instance);
00125 args.insert(args.begin(), CRT.getLocalCapsule(Builder, percent, instanceID));
00126
00127 llvm::Value *func = CG.lookupGlobal(CodeGen::getLinkName(srDecl));
00128 assert(func && "function lookup failed!");
00129
00130 return Builder.CreateCall(func, args.begin(), args.end());
00131 }
00132
00133 llvm::Value *CodeGenRoutine::emitPrimitiveCall(FunctionCallExpr *expr,
00134 std::vector<llvm::Value *> &args)
00135 {
00136 FunctionDecl *decl = cast<FunctionDecl>(expr->getConnective());
00137
00138 switch (decl->getPrimitiveID()) {
00139
00140 default:
00141 assert(false && "Cannot codegen primitive!");
00142 return 0;
00143
00144 case PO::Equality:
00145 assert(args.size() == 2 && "Bad arity for primitive!");
00146 return Builder.CreateICmpEQ(args[0], args[1]);
00147
00148 case PO::Plus:
00149 assert(args.size() == 2 && "Bad arity for primitive!");
00150 return Builder.CreateAdd(args[0], args[1]);
00151
00152 case PO::Minus:
00153 assert(args.size() == 2 && "Bad arity for primitive!");
00154 return Builder.CreateSub(args[0], args[1]);
00155
00156 case PO::LessThan:
00157 assert(args.size() == 2 && "Bad arity for primitive!");
00158 return Builder.CreateICmpSLT(args[0], args[1]);
00159
00160 case PO::GreaterThan:
00161 assert(args.size() == 2 && "Bad arity for primitive!");
00162 return Builder.CreateICmpSGT(args[0], args[1]);
00163
00164 case PO::LessThanOrEqual:
00165 assert(args.size() == 2 && "Bad arity for primitive!");
00166 return Builder.CreateICmpSLE(args[0], args[1]);
00167
00168 case PO::GreaterThanOrEqual:
00169 assert(args.size() == 2 && "Bad arity for primitive!");
00170 return Builder.CreateICmpSGE(args[0], args[1]);
00171
00172 case PO::EnumFunction: {
00173 EnumLiteral *lit = cast<EnumLiteral>(decl);
00174 unsigned idx = lit->getIndex();
00175 const llvm::Type *ty = CGTypes.lowerType(lit->getReturnType());
00176 return llvm::ConstantInt::get(ty, idx);
00177 }
00178 };
00179 }
00180
00181 llvm::Value *CodeGenRoutine::emitInjExpr(InjExpr *expr)
00182 {
00183 llvm::Value *op = emitValue(expr->getOperand());
00184
00185
00186
00187 if (expr->getType()->isScalarType()) {
00188 const llvm::Type *loweredTy = CGTypes.lowerType(expr->getType());
00189 return Builder.CreatePtrToInt(op, loweredTy);
00190 }
00191
00192 assert(false && "Cannot codegen inj expression yet!");
00193 return 0;
00194 }
00195
00196 llvm::Value *CodeGenRoutine::emitPrjExpr(PrjExpr *expr)
00197 {
00198 Expr *operand = expr->getOperand();
00199 llvm::Value *val = emitValue(operand);
00200
00201
00202
00203 if (operand->getType()->isScalarType()) {
00204 const llvm::Type *loweredTy = CGTypes.lowerType(expr->getType());
00205 return Builder.CreateIntToPtr(val, loweredTy);
00206 }
00207
00208 assert(false && "Cannot codegen prj expression yet!");
00209 return 0;
00210 }
00211
00212 llvm::Value *CodeGenRoutine::emitIntegerLiteral(IntegerLiteral *expr)
00213 {
00214 assert(expr->hasType() && "Unresolve literal type!");
00215
00216 const llvm::IntegerType *ty =
00217 cast<llvm::IntegerType>(CGTypes.lowerType(expr->getType()));
00218 llvm::APInt val(expr->getValue());
00219
00220
00221
00222 unsigned valWidth = val.getBitWidth();
00223 unsigned tyWidth = ty->getBitWidth();
00224 assert(valWidth <= tyWidth && "Value/Type width mismatch!");
00225
00226 if (valWidth < tyWidth)
00227 val.sext(tyWidth);
00228
00229 return llvm::ConstantInt::get(val);
00230 }