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