The Mother-of-All code review:
1. Fix AllowRSPrefix bug
2. Remove member mRS*Pragma in class RSContext
3. No longer only support 2x2, 3x3, 4x4 arrays
4. Fix Export All code for victorhsieh
5. Improve readability and maintainability
6. size_t -> int in calculating padding
Change-Id: I772aebd1440af66a89e2d2e688b193e500f38d69
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp
index 0a53d11..09bb6b8 100644
--- a/slang_rs_backend.cpp
+++ b/slang_rs_backend.cpp
@@ -1,37 +1,36 @@
-#include <vector>
-#include <string>
-
#include "slang_rs_backend.hpp"
#include "slang_rs_context.hpp"
#include "slang_rs_export_var.hpp"
#include "slang_rs_export_func.hpp"
#include "slang_rs_export_type.hpp"
-#include "llvm/Metadata.h" /* for class llvm::NamedMDNode */
-#include "llvm/ADT/Twine.h" /* for class llvm::Twine */
+#include "llvm/Metadata.h"
-#include "clang/AST/DeclGroup.h" /* for class clang::DeclGroup */
-#include "llvm/ADT/StringExtras.h" /* for function llvm::utostr_32() and llvm::itostr() */
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/IRBuilder.h" /* for class llvm::IRBuilder */
-#include "llvm/Constant.h" /* for class llvm::Constant */
-#include "llvm/Constants.h" /* for class llvm::Constant* */
-#include "llvm/Module.h" /* for class llvm::Module */
-#include "llvm/Function.h" /* for class llvm::Function */
-#include "llvm/DerivedTypes.h" /* for class llvm::*Type */
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Constant.h"
+#include "llvm/Constants.h"
+#include "llvm/Module.h"
+#include "llvm/Function.h"
+#include "llvm/DerivedTypes.h"
-#define MAKE
+#include "clang/AST/DeclGroup.h"
-namespace slang {
+#include <vector>
+#include <string>
-RSBackend::RSBackend(RSContext* Context,
- Diagnostic &Diags,
- const CodeGenOptions& CodeGenOpts,
- const TargetOptions& TargetOpts,
- const PragmaList& Pragmas,
- llvm::raw_ostream* OS,
+using namespace slang;
+
+RSBackend::RSBackend(RSContext *Context,
+ clang::Diagnostic &Diags,
+ const clang::CodeGenOptions &CodeGenOpts,
+ const clang::TargetOptions &TargetOpts,
+ const PragmaList &Pragmas,
+ llvm::raw_ostream *OS,
SlangCompilerOutputTy OutputType,
- SourceManager& SourceMgr,
+ clang::SourceManager &SourceMgr,
bool AllowRSPrefix) :
Backend(Diags,
CodeGenOpts,
@@ -44,203 +43,258 @@
mContext(Context),
mExportVarMetadata(NULL),
mExportFuncMetadata(NULL),
- mExportTypeMetadata(NULL)
-{
- return;
+ mExportTypeMetadata(NULL) {
+ return;
}
-void RSBackend::HandleTopLevelDecl(DeclGroupRef D) {
- Backend::HandleTopLevelDecl(D);
- return;
+void RSBackend::HandleTopLevelDecl(clang::DeclGroupRef D) {
+ Backend::HandleTopLevelDecl(D);
+ return;
}
-void RSBackend::HandleTranslationUnitEx(ASTContext& Ctx) {
- assert((&Ctx == mContext->getASTContext()) && "Unexpected AST context change during LLVM IR generation");
- mContext->processExport();
+void RSBackend::HandleTranslationUnitEx(clang::ASTContext &Ctx) {
+ assert((&Ctx == mContext->getASTContext()) && "Unexpected AST context change"
+ " during LLVM IR generation");
+ mContext->processExport();
- /* Dump export variable info */
- if(mContext->hasExportVar()) {
- if(mExportVarMetadata == NULL)
- mExportVarMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_var");
+ // Dump export variable info
+ if (mContext->hasExportVar()) {
+ if (mExportVarMetadata == NULL)
+ mExportVarMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_var");
- llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
+ llvm::SmallVector<llvm::Value*, 2> ExportVarInfo;
- for(RSContext::const_export_var_iterator I = mContext->export_vars_begin();
- I != mContext->export_vars_end();
- I++)
- {
- const RSExportVar* EV = *I;
- const RSExportType* ET = EV->getType();
+ for (RSContext::const_export_var_iterator I = mContext->export_vars_begin();
+ I != mContext->export_vars_end();
+ I++)
+ {
+ const RSExportVar* EV = *I;
+ const RSExportType* ET = EV->getType();
- /* variable name */
- ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, EV->getName().c_str()) );
+ // Variable name
+ ExportVarInfo.push_back(
+ llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
- /* type name */
- if(ET->getClass() == RSExportType::ExportClassPrimitive)
- ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::utostr_32(static_cast<const RSExportPrimitiveType*>(ET)->getType())) );
- else if(ET->getClass() == RSExportType::ExportClassPointer)
- ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)->getPointeeType()->getName()).c_str()) );
- else
- ExportVarInfo.push_back( llvm::MDString::get(mLLVMContext, EV->getType()->getName().c_str()) );
+ // Type name
+ if (ET->getClass() == RSExportType::ExportClassPrimitive)
+ ExportVarInfo.push_back(
+ llvm::MDString::get(
+ mLLVMContext, llvm::utostr_32(
+ static_cast<const RSExportPrimitiveType*>(ET)->getType()
+ )));
+ else if (ET->getClass() == RSExportType::ExportClassPointer)
+ ExportVarInfo.push_back(
+ llvm::MDString::get(
+ mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
+ ->getPointeeType()->getName()
+ ).c_str()
+ ));
+ else
+ ExportVarInfo.push_back(
+ llvm::MDString::get(mLLVMContext,
+ EV->getType()->getName().c_str()));
- mExportVarMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportVarInfo.data(), ExportVarInfo.size()) );
+ mExportVarMetadata->addOperand(
+ llvm::MDNode::get(mLLVMContext,
+ ExportVarInfo.data(),
+ ExportVarInfo.size()) );
- ExportVarInfo.clear();
- }
+ ExportVarInfo.clear();
}
+ }
- /* Dump export function info */
- if(mContext->hasExportFunc()) {
- if(mExportFuncMetadata == NULL)
- mExportFuncMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_func");
+ // Dump export function info
+ if (mContext->hasExportFunc()) {
+ if (mExportFuncMetadata == NULL)
+ mExportFuncMetadata =
+ mpModule->getOrInsertNamedMetadata("#rs_export_func");
- llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
+ llvm::SmallVector<llvm::Value*, 1> ExportFuncInfo;
- for(RSContext::const_export_func_iterator I = mContext->export_funcs_begin();
- I != mContext->export_funcs_end();
- I++)
+ 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 = mpModule->getFunction(EF->getName());
+ llvm::Function *HelperFunction;
+ const std::string HelperFunctionName(".helper_" + EF->getName());
+
+ assert(F && "Function marked as exported disappeared in Bitcode");
+
+ // Create helper function
{
- const RSExportFunc* EF = *I;
+ llvm::PointerType *HelperFunctionParameterTypeP =
+ llvm::PointerType::getUnqual(
+ EF->getParamPacketType()->getLLVMType());
+ llvm::FunctionType *HelperFunctionType;
+ std::vector<const llvm::Type*> Params;
- /* function name */
+ Params.push_back(HelperFunctionParameterTypeP);
+ HelperFunctionType = llvm::FunctionType::get(F->getReturnType(),
+ Params,
+ false);
- if(!EF->hasParam())
- ExportFuncInfo.push_back( llvm::MDString::get(mLLVMContext, EF->getName().c_str()) );
- else {
- llvm::Function* F = mpModule->getFunction(EF->getName());
- llvm::Function* HelperFunction;
- const std::string HelperFunctionName(".helper_" + EF->getName());
+ HelperFunction =
+ llvm::Function::Create(HelperFunctionType,
+ llvm::GlobalValue::ExternalLinkage,
+ HelperFunctionName,
+ mpModule);
- assert(F && "Function marked as exported disappeared in Bitcode");
+ HelperFunction->addFnAttr(llvm::Attribute::NoInline);
+ HelperFunction->setCallingConv(F->getCallingConv());
- /* Create helper function */
- {
- llvm::PointerType* HelperFunctionParameterTypeP = llvm::PointerType::getUnqual(EF->getParamPacketType()->getLLVMType());
- llvm::FunctionType* HelperFunctionType;
- std::vector<const llvm::Type*> Params;
+ // 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];
- Params.push_back(HelperFunctionParameterTypeP);
- HelperFunctionType = llvm::FunctionType::get(F->getReturnType(), Params, false);
+ Idx[0] =
+ llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
- HelperFunction = llvm::Function::Create(HelperFunctionType, llvm::GlobalValue::ExternalLinkage, HelperFunctionName, mpModule);
+ // getelementptr and load instruction for all elements in
+ // parameter .p
+ for (int i = 0; i < EF->getNumParameters(); i++) {
+ // getelementptr
+ Idx[1] =
+ llvm::ConstantInt::get(
+ llvm::Type::getInt32Ty(mLLVMContext), i);
+ llvm::Value *Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter,
+ Idx,
+ Idx + 2);
- 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 */
- int i;
- for (i=0; i < EF->getNumParameters(); i++) {
-
- /* getelementptr */
- Idx[1] = llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), i);
- llvm::Value* Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx, Idx + 2);
-
- /* load */
- llvm::Value* V = IB->CreateLoad(Ptr);
- Params.push_back(V);
- }
-
- /* call and pass the all elements as paramter to F */
- llvm::CallInst* CI = IB->CreateCall(F, Params.data(), Params.data() + Params.size());
- CI->setCallingConv(F->getCallingConv());
-
- if(F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
- IB->CreateRetVoid();
- else
- IB->CreateRet(CI);
-
- delete IB;
- }
- }
-
- ExportFuncInfo.push_back( llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()) );
+ // load
+ llvm::Value *V = IB->CreateLoad(Ptr);
+ Params.push_back(V);
}
- mExportFuncMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportFuncInfo.data(), ExportFuncInfo.size()) );
+ // Call and pass the all elements as paramter to F
+ llvm::CallInst *CI = IB->CreateCall(F,
+ Params.data(),
+ Params.data() + Params.size());
- ExportFuncInfo.clear();
+ CI->setCallingConv(F->getCallingConv());
+
+ if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
+ IB->CreateRetVoid();
+ else
+ IB->CreateRet(CI);
+
+ delete IB;
+ }
}
+
+ ExportFuncInfo.push_back(
+ llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
+ }
+
+ mExportFuncMetadata->addOperand(
+ llvm::MDNode::get(mLLVMContext,
+ ExportFuncInfo.data(),
+ ExportFuncInfo.size()));
+
+ ExportFuncInfo.clear();
}
+ }
- /* Dump export type info */
- if(mContext->hasExportType()) {
- llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
+ // Dump export type info
+ if (mContext->hasExportType()) {
+ llvm::SmallVector<llvm::Value*, 1> ExportTypeInfo;
- for(RSContext::const_export_type_iterator I = mContext->export_types_begin();
- I != mContext->export_types_end();
- I++)
- {
- /* First, dump type name list to export */
- const RSExportType* ET = I->getValue();
+ 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()) );
+ 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 (ET->getClass() == RSExportType::ExportClassRecord) {
+ const RSExportRecordType *ERT =
+ static_cast<const RSExportRecordType*>(ET);
- if(mExportTypeMetadata == NULL)
- mExportTypeMetadata = mpModule->getOrInsertNamedMetadata("#rs_export_type");
+ if (mExportTypeMetadata == NULL)
+ mExportTypeMetadata =
+ mpModule->getOrInsertNamedMetadata("#rs_export_type");
- mExportTypeMetadata->addOperand( llvm::MDNode::get(mLLVMContext, ExportTypeInfo.data(), ExportTypeInfo.size()) );
+ mExportTypeMetadata->addOperand(
+ llvm::MDNode::get(mLLVMContext,
+ ExportTypeInfo.data(),
+ ExportTypeInfo.size()));
- /* Now, export struct field information to %[struct name] */
- std::string StructInfoMetadataName("%");
- StructInfoMetadataName.append(ET->getName());
- llvm::NamedMDNode* StructInfoMetadata = mpModule->getOrInsertNamedMetadata(StructInfoMetadataName);
- llvm::SmallVector<llvm::Value*, 3> FieldInfo;
+ // Now, export struct field information to %[struct name]
+ std::string StructInfoMetadataName("%");
+ StructInfoMetadataName.append(ET->getName());
+ llvm::NamedMDNode *StructInfoMetadata =
+ mpModule->getOrInsertNamedMetadata(StructInfoMetadataName);
+ llvm::SmallVector<llvm::Value*, 3> FieldInfo;
- assert(StructInfoMetadata->getNumOperands() == 0 && "Metadata with same name was created before");
- for(RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
- FI != ERT->fields_end();
- FI++)
- {
- const RSExportRecordType::Field* F = *FI;
+ assert(StructInfoMetadata->getNumOperands() == 0 &&
+ "Metadata with same name was created before");
+ for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin();
+ FI != ERT->fields_end();
+ 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()) );
+ // 1. field name
+ FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
+ F->getName().c_str()));
- /* 3. field kind */
- switch(F->getType()->getClass()) {
- case RSExportType::ExportClassPrimitive:
- case RSExportType::ExportClassVector:
- {
- const RSExportPrimitiveType* EPT = static_cast<const RSExportPrimitiveType*>(F->getType());
- FieldInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::itostr(EPT->getKind())) );
- }
- break;
+ // 2. field type name
+ FieldInfo.push_back(
+ llvm::MDString::get(mLLVMContext,
+ F->getType()->getName().c_str()));
- default:
- FieldInfo.push_back( llvm::MDString::get(mLLVMContext, llvm::itostr(RSExportPrimitiveType::DataKindUser)) );
- break;
- }
+ // 3. field kind
+ switch (F->getType()->getClass()) {
+ case RSExportType::ExportClassPrimitive:
+ case RSExportType::ExportClassVector: {
+ const RSExportPrimitiveType *EPT =
+ static_cast<const RSExportPrimitiveType*>(F->getType());
+ FieldInfo.push_back(
+ llvm::MDString::get(mLLVMContext,
+ llvm::itostr(EPT->getKind())));
+ break;
+ }
- StructInfoMetadata->addOperand( llvm::MDNode::get(mLLVMContext, FieldInfo.data(), FieldInfo.size()) );
+ default: {
+ FieldInfo.push_back(
+ llvm::MDString::get(mLLVMContext,
+ llvm::itostr(
+ RSExportPrimitiveType::DataKindUser
+ )));
+ break;
+ }
+ }
- FieldInfo.clear();
- }
- } /* ET->getClass() == RSExportType::ExportClassRecord */
+ StructInfoMetadata->addOperand( llvm::MDNode::get(mLLVMContext,
+ FieldInfo.data(),
+ FieldInfo.size()));
+
+ FieldInfo.clear();
}
+ } // ET->getClass() == RSExportType::ExportClassRecord
}
+ }
- return;
+ return;
}
RSBackend::~RSBackend() {
- return;
+ return;
}
-
-} /* namespace slang */