00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "CommaRT.h"
00010 #include "DependencySet.h"
00011 #include "DomainInfo.h"
00012 #include "DomainInstance.h"
00013 #include "comma/ast/SignatureSet.h"
00014 #include "comma/codegen/Mangle.h"
00015
00016 #include "llvm/ADT/IndexedMap.h"
00017 #include "llvm/Support/Casting.h"
00018 #include "llvm/DerivedTypes.h"
00019
00020 using namespace comma;
00021
00022 using llvm::dyn_cast;
00023 using llvm::cast;
00024 using llvm::isa;
00025
00026 DomainInfo::DomainInfo(CommaRT &CRT)
00027 : CRT(CRT),
00028 CG(CRT.getCodeGen()),
00029 TD(CG.getTargetData()),
00030 theType(CG.getOpaqueTy()) { }
00031
00032 void DomainInfo::init()
00033 {
00034 std::vector<const llvm::Type*> members;
00035
00036 members.push_back(CG.getInt32Ty());
00037 members.push_back(CG.getPointerType(CG.getInt8Ty()));
00038 members.push_back(CRT.getType<CommaRT::CRT_DomainCtor>());
00039 members.push_back(CRT.getType<CommaRT::CRT_ITable>());
00040
00041 llvm::StructType *InfoTy = CG.getStructTy(members);
00042 cast<llvm::OpaqueType>(theType.get())->refineAbstractTypeTo(InfoTy);
00043 }
00044
00045 const std::string DomainInfo::theTypeName("comma_domain_info_t");
00046
00047 const llvm::StructType *DomainInfo::getType() const
00048 {
00049 return cast<llvm::StructType>(theType.get());
00050 }
00051
00052 const llvm::PointerType *DomainInfo::getPointerTypeTo() const
00053 {
00054 return llvm::PointerType::getUnqual(theType.get());
00055 }
00056
00057 const llvm::PointerType *DomainInfo::getCtorPtrType() const
00058 {
00059 std::vector<const llvm::Type*> args;
00060 const llvm::Type *ctorTy;
00061
00062 args.push_back(CRT.getType<CommaRT::CRT_DomainInstance>());
00063
00064 ctorTy = llvm::FunctionType::get(CG.getVoidTy(), args, false);
00065 return CG.getPointerType(ctorTy);
00066 }
00067
00068 llvm::GlobalVariable *DomainInfo::emit(const Domoid *domoid)
00069 {
00070 std::vector<llvm::Constant *> elts;
00071
00072 elts.push_back(genArity(domoid));
00073 elts.push_back(genName(domoid));
00074 elts.push_back(genConstructor(domoid));
00075 elts.push_back(genITable(domoid));
00076
00077 llvm::Constant *theInfo = llvm::ConstantStruct::get(getType(), elts);
00078 return CG.makeExternGlobal(theInfo, false, mangle::getLinkName(domoid));
00079 }
00080
00081 std::string DomainInfo::getLinkName(const Domoid *domoid)
00082 {
00083 return mangle::getLinkName(domoid) + "__0domain_info";
00084 }
00085
00086 std::string DomainInfo::getCtorName(const Domoid *domoid)
00087 {
00088 return mangle::getLinkName(domoid) + "__0ctor";
00089 }
00090
00092 llvm::Constant *DomainInfo::genName(const Domoid *domoid)
00093 {
00094 const llvm::PointerType *NameTy = getFieldType<Name>();
00095
00096 llvm::Constant *capsuleName = CG.emitInternString(domoid->getString());
00097 return CG.getPointerCast(capsuleName, NameTy);
00098 }
00099
00101 llvm::Constant *DomainInfo::genArity(const Domoid *domoid)
00102 {
00103 const llvm::IntegerType *ArityTy = getFieldType<Arity>();
00104
00105 if (const FunctorDecl *functor = dyn_cast<FunctorDecl>(domoid))
00106 return llvm::ConstantInt::get(ArityTy, functor->getArity());
00107 else
00108 return llvm::ConstantInt::get(ArityTy, 0);
00109 }
00110
00112 llvm::Constant *DomainInfo::genConstructor(const Domoid *domoid)
00113 {
00114 const DependencySet &DS = CG.getDependencySet(domoid);
00115
00116
00117
00118
00119 if (DS.size() == 0)
00120 return CG.getNullPointer(getFieldType<Ctor>());
00121
00122 std::string ctorName = getCtorName(domoid);
00123 const llvm::FunctionType *ctorTy;
00124 llvm::Function *ctor;
00125
00126 ctorTy = cast<llvm::FunctionType>(
00127 CRT.getType<CommaRT::CRT_DomainCtor>()->getElementType());
00128 ctor = CG.makeInternFunction(ctorTy, ctorName);
00129
00130 CG.insertGlobal(ctorName, ctor);
00131
00132
00133
00134
00135
00136 llvm::BasicBlock *constructBB = CG.makeBasicBlock("construct", ctor);
00137 llvm::IRBuilder<> builder(CG.getLLVMContext());
00138 builder.SetInsertPoint(constructBB);
00139
00140
00141 llvm::Value *instance = &(ctor->getArgumentList().front());
00142
00143
00144 llvm::Value *capsules =
00145 CRT.getDomainInstance()->loadLocalVec(builder, instance);
00146
00147
00148
00149 typedef DependencySet::iterator iterator;
00150 iterator E = DS.end();
00151 for (iterator I = DS.begin(); I != E; ++I) {
00152 unsigned ID = DS.getDependentID(I);
00153 genInstanceRequirement(builder, DS, ID, capsules, instance);
00154 }
00155
00156
00157
00158 llvm::BasicBlock *initBB = CG.makeBasicBlock("init", ctor, constructBB);
00159 builder.SetInsertPoint(initBB);
00160
00161 llvm::Value *size = llvm::ConstantInt::get(CG.getInt32Ty(), DS.size());
00162 capsules = builder.CreateMalloc(CRT.getType<CommaRT::CRT_DomainInstance>(), size);
00163 CRT.getDomainInstance()->setLocalVec(builder, instance, capsules);
00164 builder.CreateBr(constructBB);
00165
00166
00167 builder.SetInsertPoint(constructBB);
00168 builder.CreateRetVoid();
00169
00170 return ctor;
00171 }
00172
00180 void DomainInfo::genInstanceRequirement(llvm::IRBuilder<> &builder,
00181 const DependencySet &DS,
00182 unsigned ID,
00183 llvm::Value *destVector,
00184 llvm::Value *percent)
00185 {
00186 const DomainInstanceDecl *instance = DS.getDependent(ID);
00187 const Domoid *domoid = instance->getDefinition();
00188
00189 if (isa<DomainDecl>(domoid))
00190 genDomainRequirement(builder, DS, ID, destVector);
00191 else
00192 genFunctorRequirement(builder, DS, ID, destVector, percent);
00193 }
00194
00199 void DomainInfo::genDomainRequirement(llvm::IRBuilder<> &builder,
00200 const DependencySet &DS,
00201 unsigned ID,
00202 llvm::Value *destVector)
00203 {
00204 const DomainInstanceDecl *instance = DS.getDependent(ID);
00205 const DomainDecl *domain = instance->getDefiningDomain();
00206 assert(domain && "Cannot gen requirement for this type of instance!");
00207
00208 llvm::GlobalValue *info = CG.lookupCapsuleInfo(domain);
00209 assert(info && "Could not resolve capsule info!");
00210
00211 llvm::Value *ptr = CRT.getDomain(builder, info);
00212 llvm::Value *slotIndex = llvm::ConstantInt::get(CG.getInt32Ty(), ID);
00213 builder.CreateStore(ptr, builder.CreateGEP(destVector, slotIndex));
00214 }
00215
00220 void DomainInfo::genFunctorRequirement(llvm::IRBuilder<> &builder,
00221 const DependencySet &DS,
00222 unsigned ID,
00223 llvm::Value *destVector,
00224 llvm::Value *percent)
00225 {
00226 const DomainInstanceDecl *instance = DS.getDependent(ID);
00227 const FunctorDecl *functor = instance->getDefiningFunctor();
00228 assert(functor && "Cannot gen requirement for this type of instance!");
00229
00230 const DomainInstance *DInstance = CRT.getDomainInstance();
00231
00232 llvm::Value *info = CG.lookupCapsuleInfo(functor);
00233 if (!info) {
00234
00235
00236
00237
00238 assert(functor == cast<FunctorDecl>(DS.getCapsule()) &&
00239 "Could not resolve capsule info!");
00240 info = DInstance->loadInfo(builder, percent);
00241 }
00242
00243 std::vector<llvm::Value *> arguments;
00244 arguments.push_back(info);
00245
00246 for (unsigned i = 0; i < instance->getArity(); ++i) {
00247 const DomainType *argTy = cast<DomainType>(instance->getActualParamType(i));
00248
00249 if (const PercentDecl *pdecl = argTy->getPercentDecl()) {
00250 assert(pdecl->getDefinition() == DS.getCapsule() &&
00251 "Percent node does not represent the current domain!");
00252 ((void*)pdecl);
00253
00254
00255
00256 arguments.push_back(percent);
00257 }
00258 else if (const DomainInstanceDecl *arg = argTy->getInstanceDecl()) {
00259 DependencySet::iterator argPos = DS.find(arg);
00260 assert(argPos != DS.end() && "Dependency lookup failed!");
00261 unsigned argIndex = DS.getDependentID(argPos);
00262
00263
00264
00265 llvm::Value *instanceSlot =
00266 llvm::ConstantInt::get(CG.getInt32Ty(), argIndex);
00267 llvm::Value *argInstance =
00268 builder.CreateLoad(builder.CreateGEP(destVector, instanceSlot));
00269 arguments.push_back(argInstance);
00270 }
00271 else {
00272 const AbstractDomainDecl *arg = argTy->getAbstractDecl();
00273 unsigned paramIdx = DS.getCapsule()->getFormalIndex(arg);
00274
00275
00276
00277 llvm::Value *param = DInstance->loadParam(builder, percent, paramIdx);
00278 arguments.push_back(param);
00279 }
00280 }
00281
00282 llvm::Value *theInstance = CRT.getDomain(builder, arguments);
00283 llvm::Value *slotIndex = llvm::ConstantInt::get(CG.getInt32Ty(), ID);
00284 builder.CreateStore(theInstance, builder.CreateGEP(destVector, slotIndex));
00285 }
00286
00287
00289 llvm::Constant *DomainInfo::genITable(const Domoid *domoid)
00290 {
00291
00292
00293 return CG.getNullPointer(getFieldType<ITable>());
00294 }
00295