00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_CODEGEN_CODEGENROUTINE_HDR_GUARD
00010 #define COMMA_CODEGEN_CODEGENROUTINE_HDR_GUARD
00011 
00012 #include "CodeGen.h"
00013 #include "CValue.h"
00014 #include "Frame.h"
00015 #include "comma/ast/Expr.h"
00016 
00017 #include "llvm/DerivedTypes.h"
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/Support/IRBuilder.h"
00020 
00021 namespace llvm {
00022 
00023 class BasicBlock;
00024 class Function;
00025 
00026 } 
00027 
00028 namespace comma {
00029 
00030 class CGContext;
00031 
00032 
00033 class CodeGenRoutine {
00034 
00035     CodeGen       &CG;
00036     CGContext     &CGC;
00037     CodeGenTypes  &CGT;
00038     const CommaRT &CRT;
00039 
00040     
00041     SRInfo *SRI;
00042 
00043     
00044     llvm::IRBuilder<> Builder;
00045 
00046     
00047     SRFrame *SRF;
00048 
00049 public:
00050     CodeGenRoutine(CGContext &CGC, SRInfo *info);
00051 
00053     CodeGen &getCodeGen() { return CG; }
00054 
00056     CGContext &getCGC() { return CGC; }
00057 
00060     SRInfo *getSRInfo() { return SRI; }
00061 
00064     SRFrame *getSRFrame() { return SRF; }
00065 
00066     llvm::Value *getImplicitContext() const {
00067         return SRF->getImplicitContext();
00068     }
00069 
00070     void emit();
00071 
00072     CValue emitValue(Expr *expr);
00073     CValue emitReference(Expr *expr);
00074 
00075     CValue emitArrayExpr(Expr *expr, llvm::Value *dst, bool genTmp);
00076 
00077     CValue emitRecordExpr(Expr *expr, llvm::Value *dst, bool genTmp);
00078 
00079     CValue emitCompositeExpr(Expr *expr, llvm::Value *dst, bool genTmp);
00080 
00081     void emitStmt(Stmt *stmt);
00082 
00083     CValue emitSimpleCall(FunctionCallExpr *expr);
00084     CValue emitFunctionCall(FunctionCallExpr *expr);
00085 
00095     CValue emitCompositeCall(FunctionCallExpr *expr, llvm::Value *dst);
00096 
00097     CValue emitVStackCall(FunctionCallExpr *expr);
00098 
00099     void emitArrayCopy(llvm::Value *source, llvm::Value *destination,
00100                        ArrayType *arrTy);
00101 
00102     void emitArrayCopy(llvm::Value *source, llvm::Value *destination,
00103                        llvm::Value *length, const llvm::Type *componentTy);
00104 
00105     CValue emitIndexedArrayRef(IndexedArrayExpr *expr);
00106     CValue emitSelectedRef(SelectedExpr *expr);
00107 
00108     Type *resolveType(Type *type);
00109     Type *resolveType(Expr *expr) {
00110         return resolveType(expr->getType());
00111     }
00112 
00114     void emitNullAccessCheck(llvm::Value *pointer, Location loc);
00115 
00116 private:
00117     
00118     llvm::Function *getLLVMFunction() const;
00119 
00121     void emitSubroutineBody();
00122 
00123     void emitObjectDecl(ObjectDecl *objDecl);
00124     void emitRenamedObjectDecl(RenamedObjectDecl *objDecl);
00125 
00126     void emitIfStmt(IfStmt *ite);
00127     void emitReturnStmt(ReturnStmt *ret);
00128     void emitVStackReturn(Expr *expr, ArrayType *type);
00129     void emitStmtSequence(StmtSequence *seq);
00130     void emitProcedureCallStmt(ProcedureCallStmt *stmt);
00131     void emitAssignmentStmt(AssignmentStmt *stmt);
00132     void emitWhileStmt(WhileStmt *stmt);
00133     void emitForStmt(ForStmt *stmt);
00134     void emitLoopStmt(LoopStmt *stmt);
00135     void emitRaiseStmt(RaiseStmt *stmt);
00136     void emitPragmaStmt(PragmaStmt *stmt);
00137 
00145     llvm::BasicBlock *emitBlockStmt(BlockStmt *block,
00146                                     llvm::BasicBlock *predecessor = 0);
00147 
00148     CValue emitDeclRefExpr(DeclRefExpr *expr);
00149     CValue emitPrjExpr(PrjExpr *expr);
00150     CValue emitInjExpr(InjExpr *expr);
00151     CValue emitIntegerLiteral(IntegerLiteral *expr);
00152     CValue emitIndexedArrayValue(IndexedArrayExpr *expr);
00153     CValue emitConversionValue(ConversionExpr *expr);
00154     CValue emitAttribExpr(AttribExpr *expr);
00155     CValue emitSelectedValue(SelectedExpr *expr);
00156     CValue emitNullExpr(NullExpr *expr);
00157     CValue emitDereferencedValue(DereferenceExpr *expr);
00158     CValue emitDefaultValue(Type *type);
00159     CValue emitAllocatorValue(AllocatorExpr *expr);
00160     CValue emitCompositeAllocator(AllocatorExpr *expr);
00161 
00162     llvm::Value *emitScalarBoundAE(ScalarBoundAE *expr);
00163     llvm::Value *emitArrayBoundAE(ArrayBoundAE *expr);
00164 
00165     
00166     llvm::Value *emitDiscreteConversion(Expr *expr, DiscreteType *target);
00167 
00169     void emitDiscreteRangeCheck(llvm::Value *sourceVal, Location loc,
00170                                 Type *sourceTy, DiscreteType *targetTy);
00171 
00178     SubroutineDecl *resolveAbstractSubroutine(DomainInstanceDecl *instance,
00179                                               AbstractDomainDecl *abstract,
00180                                               SubroutineDecl *target);
00181 
00183     void emitPragmaAssert(PragmaAssert *pragma);
00184 
00185     void emitCompositeObjectDecl(ObjectDecl *objDecl);
00186 
00188     llvm::Value *emitExponential(llvm::Value *x, llvm::Value *n);
00189 
00191     std::pair<llvm::Value*, llvm::Value*> emitRangeAttrib(RangeAttrib *attrib);
00192 };
00193 
00194 } 
00195 
00196 #endif