diff options
author | Stephen Hines <srhines@google.com> | 2013-07-29 22:19:24 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-07-29 22:19:24 +0000 |
commit | b40d1003f71a3fb8f45654994a276bb6a67e225b (patch) | |
tree | 3e3a9cccfd204bca0c3e1ac5f2a92a5582606932 | |
parent | dde98533fad4c6534af537ae583aa4db35a1c699 (diff) | |
parent | d460f623328e2b4ebd05bb93910edb471e6e91d6 (diff) | |
download | slang-b40d1003f71a3fb8f45654994a276bb6a67e225b.tar.gz |
Merge "Split HandleTranslationUnitPost in subfunctions"
-rw-r--r-- | slang_rs_backend.cpp | 578 | ||||
-rw-r--r-- | slang_rs_backend.h | 5 |
2 files changed, 298 insertions, 285 deletions
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp index 3fb9f1a..8dcd213 100644 --- a/slang_rs_backend.cpp +++ b/slang_rs_backend.cpp @@ -187,322 +187,330 @@ void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) { } /////////////////////////////////////////////////////////////////////////////// -void RSBackend::HandleTranslationUnitPost(llvm::Module *M) { - if (!mContext->processExport()) { - return; - } - - // Write optimization level - llvm::SmallVector<llvm::Value*, 1> OptimizationOption; - OptimizationOption.push_back(llvm::ConstantInt::get( - mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel))); - - // Dump export variable info - if (mContext->hasExportVar()) { - int slotCount = 0; - if (mExportVarMetadata == NULL) - mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); - - llvm::SmallVector<llvm::Value*, 2> ExportVarInfo; - - // We emit slot information (#rs_object_slots) for any reference counted - // RS type or pointer (which can also be bound). - - for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), - E = mContext->export_vars_end(); - I != E; - I++) { - const RSExportVar *EV = *I; - const RSExportType *ET = EV->getType(); - bool countsAsRSObject = false; - - // Variable name - ExportVarInfo.push_back( - llvm::MDString::get(mLLVMContext, EV->getName().c_str())); - - // Type name - switch (ET->getClass()) { - case RSExportType::ExportClassPrimitive: { - const RSExportPrimitiveType *PT = - static_cast<const RSExportPrimitiveType*>(ET); - ExportVarInfo.push_back( - llvm::MDString::get( - mLLVMContext, llvm::utostr_32(PT->getType()))); - if (PT->isRSObjectType()) { - countsAsRSObject = true; - } - break; - } - case RSExportType::ExportClassPointer: { - ExportVarInfo.push_back( - llvm::MDString::get( - mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) - ->getPointeeType()->getName()).c_str())); - break; - } - case RSExportType::ExportClassMatrix: { - ExportVarInfo.push_back( - llvm::MDString::get( - mLLVMContext, llvm::utostr_32( - RSExportPrimitiveType::DataTypeRSMatrix2x2 + - static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); - break; - } - case RSExportType::ExportClassVector: - case RSExportType::ExportClassConstantArray: - case RSExportType::ExportClassRecord: { - ExportVarInfo.push_back( - llvm::MDString::get(mLLVMContext, - EV->getType()->getName().c_str())); - break; +void RSBackend::dumpExportVarInfo(llvm::Module *M) { + int slotCount = 0; + if (mExportVarMetadata == NULL) + mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN); + + llvm::SmallVector<llvm::Value*, 2> ExportVarInfo; + + // We emit slot information (#rs_object_slots) for any reference counted + // RS type or pointer (which can also be bound). + + for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(), + E = mContext->export_vars_end(); + I != E; + I++) { + const RSExportVar *EV = *I; + const RSExportType *ET = EV->getType(); + bool countsAsRSObject = false; + + // Variable name + ExportVarInfo.push_back( + llvm::MDString::get(mLLVMContext, EV->getName().c_str())); + + // Type name + switch (ET->getClass()) { + case RSExportType::ExportClassPrimitive: { + const RSExportPrimitiveType *PT = + static_cast<const RSExportPrimitiveType*>(ET); + ExportVarInfo.push_back( + llvm::MDString::get( + mLLVMContext, llvm::utostr_32(PT->getType()))); + if (PT->isRSObjectType()) { + countsAsRSObject = true; } + break; } - - mExportVarMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, ExportVarInfo)); - ExportVarInfo.clear(); - - if (mRSObjectSlotsMetadata == NULL) { - mRSObjectSlotsMetadata = - M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); + case RSExportType::ExportClassPointer: { + ExportVarInfo.push_back( + llvm::MDString::get( + mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET) + ->getPointeeType()->getName()).c_str())); + break; } - - if (countsAsRSObject) { - mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext, - llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)))); + case RSExportType::ExportClassMatrix: { + ExportVarInfo.push_back( + llvm::MDString::get( + mLLVMContext, llvm::utostr_32( + RSExportPrimitiveType::DataTypeRSMatrix2x2 + + static_cast<const RSExportMatrixType*>(ET)->getDim() - 2))); + break; } + case RSExportType::ExportClassVector: + case RSExportType::ExportClassConstantArray: + case RSExportType::ExportClassRecord: { + ExportVarInfo.push_back( + llvm::MDString::get(mLLVMContext, + EV->getType()->getName().c_str())); + break; + } + } + + mExportVarMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, ExportVarInfo)); + ExportVarInfo.clear(); - slotCount++; + if (mRSObjectSlotsMetadata == NULL) { + mRSObjectSlotsMetadata = + M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN); } - } - // Dump export function info - if (mContext->hasExportFunc()) { - if (mExportFuncMetadata == NULL) - mExportFuncMetadata = - M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); - - llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo; - - for (RSContext::const_export_func_iterator - I = mContext->export_funcs_begin(), - E = mContext->export_funcs_end(); - I != E; - I++) { - const RSExportFunc *EF = *I; - - // Function name - if (!EF->hasParam()) { - ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, - EF->getName().c_str())); - } else { - llvm::Function *F = M->getFunction(EF->getName()); - llvm::Function *HelperFunction; - const std::string HelperFunctionName(".helper_" + EF->getName()); - - slangAssert(F && "Function marked as exported disappeared in Bitcode"); - - // Create helper function - { - llvm::StructType *HelperFunctionParameterTy = NULL; + if (countsAsRSObject) { + mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext, + llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount)))); + } - if (!F->getArgumentList().empty()) { - std::vector<llvm::Type*> HelperFunctionParameterTys; - for (llvm::Function::arg_iterator AI = F->arg_begin(), - AE = F->arg_end(); AI != AE; AI++) - HelperFunctionParameterTys.push_back(AI->getType()); + slotCount++; + } +} - HelperFunctionParameterTy = - llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); - } +void RSBackend::dumpExportFunctionInfo(llvm::Module *M) { + if (mExportFuncMetadata == NULL) + mExportFuncMetadata = + M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN); + + llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo; + + for (RSContext::const_export_func_iterator + I = mContext->export_funcs_begin(), + E = mContext->export_funcs_end(); + I != E; + I++) { + const RSExportFunc *EF = *I; + + // Function name + if (!EF->hasParam()) { + ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext, + EF->getName().c_str())); + } else { + llvm::Function *F = M->getFunction(EF->getName()); + llvm::Function *HelperFunction; + const std::string HelperFunctionName(".helper_" + EF->getName()); + + slangAssert(F && "Function marked as exported disappeared in Bitcode"); + + // Create helper function + { + llvm::StructType *HelperFunctionParameterTy = NULL; + + if (!F->getArgumentList().empty()) { + std::vector<llvm::Type*> HelperFunctionParameterTys; + for (llvm::Function::arg_iterator AI = F->arg_begin(), + AE = F->arg_end(); AI != AE; AI++) + HelperFunctionParameterTys.push_back(AI->getType()); + + HelperFunctionParameterTy = + llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys); + } - if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) { - fprintf(stderr, "Failed to export function %s: parameter type " - "mismatch during creation of helper function.\n", - EF->getName().c_str()); - - const RSExportRecordType *Expected = EF->getParamPacketType(); - if (Expected) { - fprintf(stderr, "Expected:\n"); - Expected->getLLVMType()->dump(); - } - if (HelperFunctionParameterTy) { - fprintf(stderr, "Got:\n"); - HelperFunctionParameterTy->dump(); - } - } + if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) { + fprintf(stderr, "Failed to export function %s: parameter type " + "mismatch during creation of helper function.\n", + EF->getName().c_str()); - std::vector<llvm::Type*> Params; + const RSExportRecordType *Expected = EF->getParamPacketType(); + if (Expected) { + fprintf(stderr, "Expected:\n"); + Expected->getLLVMType()->dump(); + } if (HelperFunctionParameterTy) { - llvm::PointerType *HelperFunctionParameterTyP = - llvm::PointerType::getUnqual(HelperFunctionParameterTy); - Params.push_back(HelperFunctionParameterTyP); + fprintf(stderr, "Got:\n"); + HelperFunctionParameterTy->dump(); } + } - llvm::FunctionType * HelperFunctionType = - llvm::FunctionType::get(F->getReturnType(), - Params, - /* IsVarArgs = */false); - - HelperFunction = - llvm::Function::Create(HelperFunctionType, - llvm::GlobalValue::ExternalLinkage, - HelperFunctionName, - M); - - HelperFunction->addFnAttr(llvm::Attribute::NoInline); - HelperFunction->setCallingConv(F->getCallingConv()); - - // Create helper function body - { - llvm::Argument *HelperFunctionParameter = - &(*HelperFunction->arg_begin()); - llvm::BasicBlock *BB = - llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); - llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); - llvm::SmallVector<llvm::Value*, 6> Params; - llvm::Value *Idx[2]; - - Idx[0] = - llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); - - // getelementptr and load instruction for all elements in - // parameter .p - for (size_t i = 0; i < EF->getNumParameters(); i++) { - // getelementptr - Idx[1] = llvm::ConstantInt::get( - llvm::Type::getInt32Ty(mLLVMContext), i); - - llvm::Value *Ptr = - IB->CreateInBoundsGEP(HelperFunctionParameter, Idx); - - // load - llvm::Value *V = IB->CreateLoad(Ptr); - Params.push_back(V); - } - - // Call and pass the all elements as parameter to F - llvm::CallInst *CI = IB->CreateCall(F, Params); - - CI->setCallingConv(F->getCallingConv()); - - if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) - IB->CreateRetVoid(); - else - IB->CreateRet(CI); - - delete IB; - } + std::vector<llvm::Type*> Params; + if (HelperFunctionParameterTy) { + llvm::PointerType *HelperFunctionParameterTyP = + llvm::PointerType::getUnqual(HelperFunctionParameterTy); + Params.push_back(HelperFunctionParameterTyP); } - ExportFuncInfo.push_back( - llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); + llvm::FunctionType * HelperFunctionType = + llvm::FunctionType::get(F->getReturnType(), + Params, + /* IsVarArgs = */false); + + HelperFunction = + llvm::Function::Create(HelperFunctionType, + llvm::GlobalValue::ExternalLinkage, + HelperFunctionName, + M); + + HelperFunction->addFnAttr(llvm::Attribute::NoInline); + HelperFunction->setCallingConv(F->getCallingConv()); + + // Create helper function body + { + llvm::Argument *HelperFunctionParameter = + &(*HelperFunction->arg_begin()); + llvm::BasicBlock *BB = + llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction); + llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB); + llvm::SmallVector<llvm::Value*, 6> Params; + llvm::Value *Idx[2]; + + Idx[0] = + llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0); + + // getelementptr and load instruction for all elements in + // parameter .p + for (size_t i = 0; i < EF->getNumParameters(); i++) { + // getelementptr + Idx[1] = llvm::ConstantInt::get( + llvm::Type::getInt32Ty(mLLVMContext), i); + + llvm::Value *Ptr = + IB->CreateInBoundsGEP(HelperFunctionParameter, Idx); + + // load + llvm::Value *V = IB->CreateLoad(Ptr); + Params.push_back(V); + } + + // Call and pass the all elements as parameter to F + llvm::CallInst *CI = IB->CreateCall(F, Params); + + CI->setCallingConv(F->getCallingConv()); + + if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) + IB->CreateRetVoid(); + else + IB->CreateRet(CI); + + delete IB; + } } - mExportFuncMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, ExportFuncInfo)); - ExportFuncInfo.clear(); + ExportFuncInfo.push_back( + llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str())); } + + mExportFuncMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, ExportFuncInfo)); + ExportFuncInfo.clear(); } +} - // Dump export function info - if (mContext->hasExportForEach()) { - if (mExportForEachNameMetadata == NULL) { - mExportForEachNameMetadata = - M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN); - } - if (mExportForEachSignatureMetadata == NULL) { - mExportForEachSignatureMetadata = - M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN); - } +void RSBackend::dumpExportForEachInfo(llvm::Module *M) { + if (mExportForEachNameMetadata == NULL) { + mExportForEachNameMetadata = + M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN); + } + if (mExportForEachSignatureMetadata == NULL) { + mExportForEachSignatureMetadata = + M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN); + } - llvm::SmallVector<llvm::Value*, 1> ExportForEachName; - llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo; + llvm::SmallVector<llvm::Value*, 1> ExportForEachName; + llvm::SmallVector<llvm::Value*, 1> ExportForEachInfo; - for (RSContext::const_export_foreach_iterator - I = mContext->export_foreach_begin(), - E = mContext->export_foreach_end(); - I != E; - I++) { - const RSExportForEach *EFE = *I; + for (RSContext::const_export_foreach_iterator + I = mContext->export_foreach_begin(), + E = mContext->export_foreach_end(); + I != E; + I++) { + const RSExportForEach *EFE = *I; - ExportForEachName.push_back( - llvm::MDString::get(mLLVMContext, EFE->getName().c_str())); + ExportForEachName.push_back( + llvm::MDString::get(mLLVMContext, EFE->getName().c_str())); - mExportForEachNameMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, ExportForEachName)); - ExportForEachName.clear(); + mExportForEachNameMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, ExportForEachName)); + ExportForEachName.clear(); - ExportForEachInfo.push_back( - llvm::MDString::get(mLLVMContext, - llvm::utostr_32(EFE->getSignatureMetadata()))); + ExportForEachInfo.push_back( + llvm::MDString::get(mLLVMContext, + llvm::utostr_32(EFE->getSignatureMetadata()))); - mExportForEachSignatureMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, ExportForEachInfo)); - ExportForEachInfo.clear(); - } + mExportForEachSignatureMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, ExportForEachInfo)); + ExportForEachInfo.clear(); } +} - // Dump export type info - if (mContext->hasExportType()) { - llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo; - - for (RSContext::const_export_type_iterator - I = mContext->export_types_begin(), - E = mContext->export_types_end(); - I != E; - I++) { - // First, dump type name list to export - const RSExportType *ET = I->getValue(); - - ExportTypeInfo.clear(); - // Type name - ExportTypeInfo.push_back( - llvm::MDString::get(mLLVMContext, ET->getName().c_str())); - - if (ET->getClass() == RSExportType::ExportClassRecord) { - const RSExportRecordType *ERT = - static_cast<const RSExportRecordType*>(ET); - - if (mExportTypeMetadata == NULL) - mExportTypeMetadata = - M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); - - mExportTypeMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, ExportTypeInfo)); - - // Now, export struct field information to %[struct name] - std::string StructInfoMetadataName("%"); - StructInfoMetadataName.append(ET->getName()); - llvm::NamedMDNode *StructInfoMetadata = - M->getOrInsertNamedMetadata(StructInfoMetadataName); - llvm::SmallVector<llvm::Value*, 3> FieldInfo; - - slangAssert(StructInfoMetadata->getNumOperands() == 0 && - "Metadata with same name was created before"); - for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), - FE = ERT->fields_end(); - FI != FE; - FI++) { - const RSExportRecordType::Field *F = *FI; - - // 1. field name - FieldInfo.push_back(llvm::MDString::get(mLLVMContext, - F->getName().c_str())); - - // 2. field type name - FieldInfo.push_back( - llvm::MDString::get(mLLVMContext, - F->getType()->getName().c_str())); - - StructInfoMetadata->addOperand( - llvm::MDNode::get(mLLVMContext, FieldInfo)); - FieldInfo.clear(); - } - } // ET->getClass() == RSExportType::ExportClassRecord - } +void RSBackend::dumpExportTypeInfo(llvm::Module *M) { + llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo; + + for (RSContext::const_export_type_iterator + I = mContext->export_types_begin(), + E = mContext->export_types_end(); + I != E; + I++) { + // First, dump type name list to export + const RSExportType *ET = I->getValue(); + + ExportTypeInfo.clear(); + // Type name + ExportTypeInfo.push_back( + llvm::MDString::get(mLLVMContext, ET->getName().c_str())); + + if (ET->getClass() == RSExportType::ExportClassRecord) { + const RSExportRecordType *ERT = + static_cast<const RSExportRecordType*>(ET); + + if (mExportTypeMetadata == NULL) + mExportTypeMetadata = + M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN); + + mExportTypeMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, ExportTypeInfo)); + + // Now, export struct field information to %[struct name] + std::string StructInfoMetadataName("%"); + StructInfoMetadataName.append(ET->getName()); + llvm::NamedMDNode *StructInfoMetadata = + M->getOrInsertNamedMetadata(StructInfoMetadataName); + llvm::SmallVector<llvm::Value*, 3> FieldInfo; + + slangAssert(StructInfoMetadata->getNumOperands() == 0 && + "Metadata with same name was created before"); + for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), + FE = ERT->fields_end(); + FI != FE; + FI++) { + const RSExportRecordType::Field *F = *FI; + + // 1. field name + FieldInfo.push_back(llvm::MDString::get(mLLVMContext, + F->getName().c_str())); + + // 2. field type name + FieldInfo.push_back( + llvm::MDString::get(mLLVMContext, + F->getType()->getName().c_str())); + + StructInfoMetadata->addOperand( + llvm::MDNode::get(mLLVMContext, FieldInfo)); + FieldInfo.clear(); + } + } // ET->getClass() == RSExportType::ExportClassRecord + } +} + +void RSBackend::HandleTranslationUnitPost(llvm::Module *M) { + if (!mContext->processExport()) { + return; } + // Write optimization level + llvm::SmallVector<llvm::Value*, 1> OptimizationOption; + OptimizationOption.push_back(llvm::ConstantInt::get( + mLLVMContext, llvm::APInt(32, mCodeGenOpts.OptimizationLevel))); + + if (mContext->hasExportVar()) + dumpExportVarInfo(M); + + if (mContext->hasExportFunc()) + dumpExportFunctionInfo(M); + + if (mContext->hasExportForEach()) + dumpExportForEachInfo(M); + + if (mContext->hasExportType()) + dumpExportTypeInfo(M); + return; } diff --git a/slang_rs_backend.h b/slang_rs_backend.h index 80c643d..2d6ab72 100644 --- a/slang_rs_backend.h +++ b/slang_rs_backend.h @@ -64,6 +64,11 @@ class RSBackend : public Backend { void AnnotateFunction(clang::FunctionDecl *FD); + void dumpExportVarInfo(llvm::Module *M); + void dumpExportFunctionInfo(llvm::Module *M); + void dumpExportForEachInfo(llvm::Module *M); + void dumpExportTypeInfo(llvm::Module *M); + protected: virtual unsigned int getTargetAPI() const { return mContext->getTargetAPI(); |