00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #ifndef COMMA_CODEGEN_CODEGEN_HDR_GUARD
00010 #define COMMA_CODEGEN_CODEGEN_HDR_GUARD
00011 
00012 #include "comma/ast/AstBase.h"
00013 #include "comma/codegen/Generator.h"
00014 
00015 #include "llvm/DerivedTypes.h"
00016 #include "llvm/GlobalValue.h"
00017 #include "llvm/Intrinsics.h"
00018 #include "llvm/Constants.h"
00019 #include "llvm/ADT/DenseMap.h"
00020 #include "llvm/ADT/StringMap.h"
00021 
00022 namespace comma {
00023 
00024 class CodeGenTypes;
00025 class CommaRT;
00026 class DependencySet;
00027 class InstanceInfo;
00028 class SRInfo;
00029 
00030 class CodeGen : public Generator {
00031 
00032 public:
00033     ~CodeGen();
00034 
00036     CommaRT &getRuntime() const { return *CRT; }
00037 
00039     llvm::Module *getModule() { return M; }
00040 
00042     llvm::Constant *getModuleName();
00043 
00045     const llvm::TargetData &getTargetData() const { return TD; }
00046 
00048     AstResource &getAstResource() const { return Resource; }
00049 
00051     llvm::LLVMContext &getLLVMContext() const {
00052         return llvm::getGlobalContext();
00053     }
00054 
00069     bool extendWorklist(DomainInstanceDecl *instace);
00070 
00071     InstanceInfo *lookupInstanceInfo(const DomainInstanceDecl *instance) const {
00072         return instanceTable.lookup(instance);
00073     }
00074 
00075     InstanceInfo *getInstanceInfo(const DomainInstanceDecl *instance) const {
00076         InstanceInfo *info = lookupInstanceInfo(instance);
00077         assert(info && "Instance lookup failed!");
00078         return info;
00079     }
00080 
00085     SRInfo *getSRInfo(DomainInstanceDecl *instance, SubroutineDecl *srDecl);
00086 
00088     const DependencySet &getDependencySet(const Domoid *domoid);
00089 
00095     bool insertGlobal(const std::string &linkName, llvm::GlobalValue *GV);
00096 
00099     llvm::GlobalValue *lookupGlobal(const std::string &linkName) const;
00100 
00104     llvm::GlobalValue *lookupCapsuleInfo(const Domoid *domoid) const;
00105 
00109     llvm::GlobalVariable *emitInternString(const llvm::StringRef &elems,
00110                                            bool addNull = true,
00111                                            bool isConstant = true,
00112                                            const std::string &name = "");
00113 
00115     llvm::BasicBlock *makeBasicBlock(const std::string &name = "",
00116                                      llvm::Function *parent = 0,
00117                                      llvm::BasicBlock *insertBefore = 0) const;
00118 
00128     llvm::GlobalVariable *makeExternGlobal(llvm::Constant *init,
00129                                            bool isConstant = false,
00130                                            const std::string &name = "");
00131 
00141     llvm::GlobalVariable *makeInternGlobal(llvm::Constant *init,
00142                                            bool isConstant = false,
00143                                            const std::string &name = "");
00144 
00147     llvm::Function *makeFunction(const llvm::FunctionType *Ty,
00148                                  const std::string &name = "");
00149 
00152     llvm::Function *makeFunction(const DomainInstanceDecl *instance,
00153                                  const SubroutineDecl *srDecl,
00154                                  CodeGenTypes &CGT);
00155 
00158     llvm::Function *makeInternFunction(const llvm::FunctionType *Ty,
00159                                        const std::string &name = "");
00160 
00165     llvm::Function *getLLVMIntrinsic(llvm::Intrinsic::ID id) const {
00166         assert(!llvm::Intrinsic::isOverloaded(id) &&
00167                "Cannot retrieve overloaded intrinsics!");
00168         return llvm::Intrinsic::getDeclaration(M, id);
00169     }
00170 
00172     llvm::Function *getMemcpy64() const;
00173 
00175     llvm::Function *getMemcpy32() const;
00176 
00178     llvm::Function *getMemset32() const;
00179 
00181 
00182     llvm::Function *getEHExceptionIntrinsic() const;
00183     llvm::Function *getEHSelectorIntrinsic() const;
00184     llvm::Function *getEHTypeidIntrinsic() const;
00186 
00188     const llvm::OpaqueType *getOpaqueTy() const {
00189         return llvm::OpaqueType::get(getLLVMContext());
00190     }
00191 
00193     const llvm::PointerType *getInt8PtrTy() const {
00194         return getPointerType(getInt8Ty());
00195     }
00196 
00198     const llvm::Type *getVoidTy() const {
00199         return llvm::Type::getVoidTy(getLLVMContext());
00200     }
00201 
00203     const llvm::IntegerType *getInt1Ty() const {
00204         return llvm::Type::getInt1Ty(getLLVMContext());
00205     }
00206 
00208     const llvm::IntegerType *getInt8Ty() const {
00209         return llvm::Type::getInt8Ty(getLLVMContext());
00210     }
00211 
00213     const llvm::IntegerType *getInt16Ty() const {
00214         return llvm::Type::getInt16Ty(getLLVMContext());
00215     }
00216 
00218     const llvm::IntegerType *getInt32Ty() const {
00219         return llvm::Type::getInt32Ty(getLLVMContext());
00220     }
00221 
00223     const llvm::IntegerType *getInt64Ty() const {
00224         return llvm::Type::getInt64Ty(getLLVMContext());
00225     }
00226 
00228     const llvm::IntegerType *getIntPtrTy() const {
00229         unsigned width = TD.getPointerSizeInBits();
00230         return llvm::IntegerType::get(getLLVMContext(), width);
00231     }
00232 
00234     llvm::Constant *getNullPointer(const llvm::PointerType *Ty) const {
00235         return llvm::ConstantPointerNull::get(Ty);
00236     }
00237 
00239     llvm::PointerType *getPointerType(const llvm::Type *Ty) const {
00240         return llvm::PointerType::getUnqual(Ty);
00241     }
00242 
00244     llvm::ConstantInt *getConstantInt(const llvm::IntegerType *type,
00245                                       uint64_t value) const {
00246         return llvm::ConstantInt::get(type, value);
00247     }
00248 
00257     llvm::ConstantInt *getConstantInt(const llvm::IntegerType *type,
00258                                       const llvm::APInt &value) const;
00259 
00262     llvm::Constant *
00263     getConstantArray(const llvm::Type *elementType,
00264                      std::vector<llvm::Constant*> &elems) const {
00265         llvm::ArrayType *arrayTy;
00266         arrayTy = llvm::ArrayType::get(elementType, elems.size());
00267         return llvm::ConstantArray::get(arrayTy, elems);
00268 
00269     }
00270 
00272     llvm::Constant *getPointerCast(llvm::Constant *constant,
00273                                    const llvm::PointerType *Ty) const {
00274         return llvm::ConstantExpr::getPointerCast(constant, Ty);
00275     }
00276 
00278     llvm::StructType *getStructTy(const std::vector<const llvm::Type*> &elts,
00279                                   bool isPacked = false) const {
00280         return llvm::StructType::get(getLLVMContext(), elts, isPacked);
00281     }
00282 
00284     llvm::ArrayType *getVLArrayTy(const llvm::Type *componentTy) const {
00285         return llvm::ArrayType::get(componentTy, 0);
00286     }
00287 
00293 
00294 
00297     SourceLocation getSourceLocation(Location loc);
00298 
00300     llvm::ConstantInt *getSourceLine(Location loc) {
00301         return llvm::ConstantInt::get(getInt32Ty(),
00302                                       getSourceLocation(loc).getLine());
00303     }
00304 
00306     llvm::ConstantInt *getSourceColumn(Location loc) {
00307         return llvm::ConstantInt::get(getInt32Ty(),
00308                                       getSourceLocation(loc).getColumn());
00309     }
00311 
00312 private:
00314     llvm::Module *M;
00315 
00317     const llvm::TargetData &TD;
00318 
00320     AstResource &Resource;
00321 
00323     CommaRT *CRT;
00324 
00326     typedef llvm::StringMap<llvm::GlobalValue *> StringGlobalMap;
00327 
00329     StringGlobalMap capsuleInfoTable;
00330 
00332     StringGlobalMap globalTable;
00333 
00336     typedef llvm::DenseMap<const DomainInstanceDecl*, InstanceInfo*> InstanceMap;
00337     InstanceMap instanceTable;
00338 
00341     typedef llvm::DenseMap<const Domoid*, DependencySet*> DependenceMap;
00342     DependenceMap dependenceTable;
00343 
00348     llvm::Constant *moduleName;
00349 
00354     InstanceInfo *createInstanceInfo(DomainInstanceDecl *instance);
00355 
00358     bool instancesPending() const;
00359 
00362     void emitNextInstance();
00363 
00365     void emitCapsule(InstanceInfo *info);
00366 
00367     
00368     
00369 
00370     friend class Generator;
00371 
00373     CodeGen(llvm::Module *M, const llvm::TargetData &data,
00374             AstResource &resource);
00375 
00376     void emitToplevelDecl(Decl *decl);
00377     void emitEntry(ProcedureDecl *decl);
00378 };
00379 
00380 } 
00381 
00382 #endif