Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010-2012, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "slang_backend.h"
     18 
     19 #include <string>
     20 #include <vector>
     21 #include <iostream>
     22 
     23 #include "clang/AST/ASTContext.h"
     24 #include "clang/AST/Attr.h"
     25 #include "clang/AST/Decl.h"
     26 #include "clang/AST/DeclGroup.h"
     27 #include "clang/AST/RecordLayout.h"
     28 
     29 #include "clang/Basic/Diagnostic.h"
     30 #include "clang/Basic/TargetInfo.h"
     31 #include "clang/Basic/TargetOptions.h"
     32 
     33 #include "clang/CodeGen/ModuleBuilder.h"
     34 
     35 #include "clang/Frontend/CodeGenOptions.h"
     36 #include "clang/Frontend/FrontendDiagnostic.h"
     37 
     38 #include "llvm/ADT/Twine.h"
     39 #include "llvm/ADT/StringExtras.h"
     40 
     41 #include "llvm/Bitcode/ReaderWriter.h"
     42 
     43 #include "llvm/CodeGen/RegAllocRegistry.h"
     44 #include "llvm/CodeGen/SchedulerRegistry.h"
     45 
     46 #include "llvm/IR/Constant.h"
     47 #include "llvm/IR/Constants.h"
     48 #include "llvm/IR/DataLayout.h"
     49 #include "llvm/IR/DebugLoc.h"
     50 #include "llvm/IR/DerivedTypes.h"
     51 #include "llvm/IR/Function.h"
     52 #include "llvm/IR/IRBuilder.h"
     53 #include "llvm/IR/IRPrintingPasses.h"
     54 #include "llvm/IR/LLVMContext.h"
     55 #include "llvm/IR/Metadata.h"
     56 #include "llvm/IR/Module.h"
     57 
     58 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
     59 
     60 #include "llvm/Target/TargetMachine.h"
     61 #include "llvm/Target/TargetOptions.h"
     62 #include "llvm/Support/TargetRegistry.h"
     63 
     64 #include "llvm/MC/SubtargetFeature.h"
     65 
     66 #include "slang_assert.h"
     67 #include "slang.h"
     68 #include "slang_bitcode_gen.h"
     69 #include "slang_rs_context.h"
     70 #include "slang_rs_export_foreach.h"
     71 #include "slang_rs_export_func.h"
     72 #include "slang_rs_export_reduce.h"
     73 #include "slang_rs_export_type.h"
     74 #include "slang_rs_export_var.h"
     75 #include "slang_rs_metadata.h"
     76 
     77 #include "rs_cc_options.h"
     78 
     79 #include "StripUnkAttr/strip_unknown_attributes_pass.h"
     80 
     81 namespace {
     82 class VersionInfoPass : public llvm::ModulePass {
     83   const clang::CodeGenOptions &mCodeGenOpts;
     84 
     85   const char *getSlangLLVMVersion() const {
     86     if (mCodeGenOpts.getDebugInfo() != clang::codegenoptions::NoDebugInfo)
     87       return LLVM_VERSION_STRING;
     88     return nullptr;
     89   }
     90 
     91 public:
     92   static char ID;
     93   VersionInfoPass(const clang::CodeGenOptions &codegenOpts)
     94       : ModulePass(ID), mCodeGenOpts(codegenOpts) {}
     95   virtual bool runOnModule(llvm::Module &M) override {
     96     const char *versionString = getSlangLLVMVersion();
     97     if (!versionString)
     98       return false;
     99     auto &ctx = M.getContext();
    100     auto md = M.getOrInsertNamedMetadata("slang.llvm.version");
    101     auto ver = llvm::MDString::get(ctx, versionString);
    102     md->addOperand(
    103         llvm::MDNode::get(ctx, llvm::ArrayRef<llvm::Metadata *>(ver)));
    104     return true;
    105   }
    106 };
    107 
    108 char VersionInfoPass::ID = 0;
    109 
    110 llvm::ModulePass *createVersionInfoPass(const clang::CodeGenOptions &cgo) {
    111   return new VersionInfoPass(cgo);
    112 }
    113 }
    114 
    115 namespace slang {
    116 
    117 void Backend::CreateFunctionPasses() {
    118   if (!mPerFunctionPasses) {
    119     mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
    120 
    121     llvm::PassManagerBuilder PMBuilder;
    122     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
    123     PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
    124   }
    125 }
    126 
    127 void Backend::CreateModulePasses() {
    128   if (!mPerModulePasses) {
    129     mPerModulePasses = new llvm::legacy::PassManager();
    130 
    131     llvm::PassManagerBuilder PMBuilder;
    132     PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
    133     PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
    134     PMBuilder.DisableUnitAtATime = 0; // TODO Pirama confirm if this is right
    135 
    136     if (mCodeGenOpts.UnrollLoops) {
    137       PMBuilder.DisableUnrollLoops = 0;
    138     } else {
    139       PMBuilder.DisableUnrollLoops = 1;
    140     }
    141 
    142     PMBuilder.populateModulePassManager(*mPerModulePasses);
    143     // Add a pass to strip off unknown/unsupported attributes.
    144     mPerModulePasses->add(createStripUnknownAttributesPass());
    145     if (!mContext->isCompatLib()) {
    146       // The version info pass is used to ensure that debugging
    147       // is matched between slang and bcc.
    148       mPerModulePasses->add(createVersionInfoPass(mCodeGenOpts));
    149     }
    150   }
    151 }
    152 
    153 bool Backend::CreateCodeGenPasses() {
    154   if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
    155     return true;
    156 
    157   // Now we add passes for code emitting
    158   if (mCodeGenPasses) {
    159     return true;
    160   } else {
    161     mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
    162   }
    163 
    164   // Create the TargetMachine for generating code.
    165   std::string Triple = mpModule->getTargetTriple();
    166 
    167   std::string Error;
    168   const llvm::Target* TargetInfo =
    169       llvm::TargetRegistry::lookupTarget(Triple, Error);
    170   if (TargetInfo == nullptr) {
    171     mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
    172     return false;
    173   }
    174 
    175   // Target Machine Options
    176   llvm::TargetOptions Options;
    177 
    178   // Use soft-float ABI for ARM (which is the target used by Slang during code
    179   // generation).  Codegen still uses hardware FPU by default.  To use software
    180   // floating point, add 'soft-float' feature to FeaturesStr below.
    181   Options.FloatABIType = llvm::FloatABI::Soft;
    182 
    183   // BCC needs all unknown symbols resolved at compilation time. So we don't
    184   // need any relocation model.
    185   llvm::Reloc::Model RM = llvm::Reloc::Static;
    186 
    187   // This is set for the linker (specify how large of the virtual addresses we
    188   // can access for all unknown symbols.)
    189   llvm::CodeModel::Model CM;
    190   if (mpModule->getDataLayout().getPointerSize() == 4) {
    191     CM = llvm::CodeModel::Small;
    192   } else {
    193     // The target may have pointer size greater than 32 (e.g. x86_64
    194     // architecture) may need large data address model
    195     CM = llvm::CodeModel::Medium;
    196   }
    197 
    198   // Setup feature string
    199   std::string FeaturesStr;
    200   if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
    201     llvm::SubtargetFeatures Features;
    202 
    203     for (std::vector<std::string>::const_iterator
    204              I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
    205          I != E;
    206          I++)
    207       Features.AddFeature(*I);
    208 
    209     FeaturesStr = Features.getString();
    210   }
    211 
    212   llvm::TargetMachine *TM =
    213     TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
    214                                     Options, RM, CM);
    215 
    216   // Register allocation policy:
    217   //  createFastRegisterAllocator: fast but bad quality
    218   //  createGreedyRegisterAllocator: not so fast but good quality
    219   llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
    220                                      llvm::createFastRegisterAllocator :
    221                                      llvm::createGreedyRegisterAllocator);
    222 
    223   llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
    224   if (mCodeGenOpts.OptimizationLevel == 0) {
    225     OptLevel = llvm::CodeGenOpt::None;
    226   } else if (mCodeGenOpts.OptimizationLevel == 3) {
    227     OptLevel = llvm::CodeGenOpt::Aggressive;
    228   }
    229 
    230   llvm::TargetMachine::CodeGenFileType CGFT =
    231       llvm::TargetMachine::CGFT_AssemblyFile;
    232   if (mOT == Slang::OT_Object) {
    233     CGFT = llvm::TargetMachine::CGFT_ObjectFile;
    234   }
    235   if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
    236                               CGFT, OptLevel)) {
    237     mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
    238     return false;
    239   }
    240 
    241   return true;
    242 }
    243 
    244 Backend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
    245                  const RSCCOptions &Opts,
    246                  const clang::HeaderSearchOptions &HeaderSearchOpts,
    247                  const clang::PreprocessorOptions &PreprocessorOpts,
    248                  const clang::CodeGenOptions &CodeGenOpts,
    249                  const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
    250                  llvm::raw_ostream *OS, Slang::OutputType OT,
    251                  clang::SourceManager &SourceMgr, bool AllowRSPrefix,
    252                  bool IsFilterscript)
    253     : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
    254       mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
    255       mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
    256       mBufferOutStream(*mpOS), mContext(Context),
    257       mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
    258       mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
    259       mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
    260       mExportForEachSignatureMetadata(nullptr),
    261       mExportReduceMetadata(nullptr),
    262       mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
    263       mRefCount(mContext->getASTContext()),
    264       mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
    265       mForEachHandler(Context),
    266       mLLVMContext(slang::getGlobalLLVMContext()), mDiagEngine(*DiagEngine),
    267       mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
    268   mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts,
    269       mCodeGenOpts, mLLVMContext);
    270 }
    271 
    272 void Backend::Initialize(clang::ASTContext &Ctx) {
    273   mGen->Initialize(Ctx);
    274 
    275   mpModule = mGen->GetModule();
    276 }
    277 
    278 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
    279   HandleTranslationUnitPre(Ctx);
    280 
    281   if (mASTPrint)
    282     Ctx.getTranslationUnitDecl()->dump();
    283 
    284   mGen->HandleTranslationUnit(Ctx);
    285 
    286   // Here, we complete a translation unit (whole translation unit is now in LLVM
    287   // IR). Now, interact with LLVM backend to generate actual machine code (asm
    288   // or machine code, whatever.)
    289 
    290   // Silently ignore if we weren't initialized for some reason.
    291   if (!mpModule)
    292     return;
    293 
    294   llvm::Module *M = mGen->ReleaseModule();
    295   if (!M) {
    296     // The module has been released by IR gen on failures, do not double free.
    297     mpModule = nullptr;
    298     return;
    299   }
    300 
    301   slangAssert(mpModule == M &&
    302               "Unexpected module change during LLVM IR generation");
    303 
    304   // Insert #pragma information into metadata section of module
    305   if (!mPragmas->empty()) {
    306     llvm::NamedMDNode *PragmaMetadata =
    307         mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
    308     for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
    309          I != E;
    310          I++) {
    311       llvm::SmallVector<llvm::Metadata*, 2> Pragma;
    312       // Name goes first
    313       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
    314       // And then value
    315       Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
    316 
    317       // Create MDNode and insert into PragmaMetadata
    318       PragmaMetadata->addOperand(
    319           llvm::MDNode::get(mLLVMContext, Pragma));
    320     }
    321   }
    322 
    323   HandleTranslationUnitPost(mpModule);
    324 
    325   // Create passes for optimization and code emission
    326 
    327   // Create and run per-function passes
    328   CreateFunctionPasses();
    329   if (mPerFunctionPasses) {
    330     mPerFunctionPasses->doInitialization();
    331 
    332     for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    333          I != E;
    334          I++)
    335       if (!I->isDeclaration())
    336         mPerFunctionPasses->run(*I);
    337 
    338     mPerFunctionPasses->doFinalization();
    339   }
    340 
    341   // Create and run module passes
    342   CreateModulePasses();
    343   if (mPerModulePasses)
    344     mPerModulePasses->run(*mpModule);
    345 
    346   switch (mOT) {
    347     case Slang::OT_Assembly:
    348     case Slang::OT_Object: {
    349       if (!CreateCodeGenPasses())
    350         return;
    351 
    352       mCodeGenPasses->doInitialization();
    353 
    354       for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
    355           I != E;
    356           I++)
    357         if (!I->isDeclaration())
    358           mCodeGenPasses->run(*I);
    359 
    360       mCodeGenPasses->doFinalization();
    361       break;
    362     }
    363     case Slang::OT_LLVMAssembly: {
    364       llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
    365       LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
    366       LLEmitPM->run(*mpModule);
    367       break;
    368     }
    369     case Slang::OT_Bitcode: {
    370       writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
    371                    mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
    372       break;
    373     }
    374     case Slang::OT_Nothing: {
    375       return;
    376     }
    377     default: {
    378       slangAssert(false && "Unknown output type");
    379     }
    380   }
    381 }
    382 
    383 // Insert explicit padding fields into struct to follow the current layout.
    384 //
    385 // A similar algorithm is present in PadHelperFunctionStruct().
    386 void Backend::PadStruct(clang::RecordDecl* RD) {
    387   // Example of padding:
    388   //
    389   //   // ORIGINAL CODE                   // TRANSFORMED CODE
    390   //   struct foo {                       struct foo {
    391   //     int a;                             int a;
    392   //     // 4 bytes of padding              char <RS_PADDING_FIELD_NAME>[4];
    393   //     long b;                            long b;
    394   //     int c;                             int c;
    395   //     // 4 bytes of (tail) padding       char <RS_PADDING_FIELD_NAME>[4];
    396   //   };                                 };
    397 
    398   // We collect all of RD's fields in a vector FieldsInfo.  We
    399   // represent tail padding as an entry in the FieldsInfo vector with a
    400   // null FieldDecl.
    401   typedef std::pair<size_t, clang::FieldDecl*> FieldInfoType;  // (pre-field padding bytes, field)
    402   std::vector<FieldInfoType> FieldsInfo;
    403 
    404   // RenderScript is C99-based, so we only expect to see fields.  We
    405   // could iterate over fields, but instead let's iterate over
    406   // everything, to verify that there are only fields.
    407   for (clang::Decl* D : RD->decls()) {
    408     clang::FieldDecl* FD = clang::dyn_cast<clang::FieldDecl>(D);
    409     slangAssert(FD && "found a non field declaration within a struct");
    410     FieldsInfo.push_back(std::make_pair(size_t(0), FD));
    411   }
    412 
    413   clang::ASTContext& ASTC = mContext->getASTContext();
    414 
    415   // ASTContext caches record layout.  We may transform the record in a way
    416   // that would render this cached information incorrect.  clang does
    417   // not provide any way to invalidate this cached information.  We
    418   // take the following approach:
    419   //
    420   // 1. ASSUME that record layout has not yet been computed for RD.
    421   //
    422   // 2. Create a temporary clone of RD, and compute its layout.
    423   //    ASSUME that we know how to clone RD in a way that copies all the
    424   //    properties that are relevant to its layout.
    425   //
    426   // 3. Use the layout information from the temporary clone to
    427   //    transform RD.
    428   //
    429   // NOTE: ASTContext also caches TypeInfo (see
    430   //       ASTContext::getTypeInfo()).  ASSUME that inserting padding
    431   //       fields doesn't change the type in any way that affects
    432   //       TypeInfo.
    433   //
    434   // NOTE: A RecordType knows its associated RecordDecl -- so even
    435   //       while we're manipulating RD, the associated RecordType
    436   //       still recognizes RD as its RecordDecl.  ASSUME that we
    437   //       don't do anything during our manipulation that would cause
    438   //       the RecordType to be followed to RD while RD is in a
    439   //       partially transformed state.
    440 
    441   // The assumptions above may be brittle, and if they are incorrect,
    442   // we may get mysterious failures.
    443 
    444   // create a temporary clone
    445   clang::RecordDecl* RDForLayout =
    446       clang::RecordDecl::Create(ASTC, clang::TTK_Struct, RD->getDeclContext(),
    447                                 clang::SourceLocation(), clang::SourceLocation(),
    448                                 nullptr /* IdentifierInfo */);
    449   RDForLayout->startDefinition();
    450   RDForLayout->setTypeForDecl(RD->getTypeForDecl());
    451   if (RD->hasAttrs())
    452     RDForLayout->setAttrs(RD->getAttrs());
    453   RDForLayout->completeDefinition();
    454 
    455   // move all fields from RD to RDForLayout
    456   for (const auto &info : FieldsInfo) {
    457     RD->removeDecl(info.second);
    458     info.second->setLexicalDeclContext(RDForLayout);
    459     RDForLayout->addDecl(info.second);
    460   }
    461 
    462   const clang::ASTRecordLayout& RL = ASTC.getASTRecordLayout(RDForLayout);
    463 
    464   // An exportable type cannot contain a bitfield.  However, it's
    465   // possible that this current type might have a bitfield and yet
    466   // share a common initial sequence with an exportable type, so even
    467   // if the current type has a bitfield, the current type still
    468   // needs to have explicit padding inserted (in case the two types
    469   // under discussion are members of a union).  We don't need to
    470   // insert any padding after the bitfield, however, because that
    471   // would be beyond the common initial sequence.
    472   bool foundBitField = false;
    473 
    474   // Is there any padding in this struct?
    475   bool foundPadding = false;
    476 
    477   unsigned fieldNo = 0;
    478   uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
    479   for (auto &info : FieldsInfo) {
    480     const clang::FieldDecl* FD = info.second;
    481 
    482     if ((foundBitField = FD->isBitField()))
    483       break;
    484 
    485     const uint64_t fieldOffset = RL.getFieldOffset(fieldNo) >> 3;
    486     const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
    487     foundPadding |= (prePadding != 0);
    488     info.first = prePadding;
    489 
    490     // get ready for the next field
    491     //
    492     //   assumes that getTypeSize() is the storage size of the Type -- for example,
    493     //   that it includes a struct's tail padding (if any)
    494     //
    495     fieldPrePaddingOffset = fieldOffset + (ASTC.getTypeSize(FD->getType()) >> 3);
    496     ++fieldNo;
    497   }
    498 
    499   if (!foundBitField) {
    500     // In order to ensure that the front end (including reflected
    501     // code) and back end agree on struct size (not just field
    502     // offsets) we may need to add explicit tail padding, just as we'e
    503     // added explicit padding between fields.
    504     slangAssert(RL.getSize().getQuantity() >= fieldPrePaddingOffset);
    505     if (const size_t tailPadding = RL.getSize().getQuantity() - fieldPrePaddingOffset) {
    506       foundPadding = true;
    507       FieldsInfo.push_back(std::make_pair(tailPadding, nullptr));
    508     }
    509   }
    510 
    511   if (false /* change to "true" for extra debugging output */) {
    512    if (foundPadding) {
    513      std::cout << "PadStruct(" << RD->getNameAsString() << "):" << std::endl;
    514      for (const auto &info : FieldsInfo)
    515        std::cout << "  " << info.first << ", " << (info.second ? info.second->getNameAsString() : "<tail>") << std::endl;
    516    }
    517   }
    518 
    519   if (foundPadding && Slang::IsLocInRSHeaderFile(RD->getLocation(), mSourceMgr)) {
    520     mContext->ReportError(RD->getLocation(), "system structure contains padding: '%0'")
    521         << RD->getName();
    522   }
    523 
    524   // now move fields from RDForLayout to RD, and add any necessary
    525   // padding fields
    526   const clang::QualType byteType = ASTC.getIntTypeForBitwidth(8, false /* not signed */);
    527   clang::IdentifierInfo* const paddingIdentifierInfo = &ASTC.Idents.get(RS_PADDING_FIELD_NAME);
    528   for (const auto &info : FieldsInfo) {
    529     if (info.first != 0) {
    530       // Create a padding field: "char <RS_PADDING_FIELD_NAME>[<info.first>];"
    531 
    532       // TODO: Do we need to do anything else to keep this field from being shown in debugger?
    533       //       There's no source location, and the field is marked as implicit.
    534       const clang::QualType paddingType =
    535           ASTC.getConstantArrayType(byteType,
    536                                     llvm::APInt(sizeof(info.first) << 3, info.first),
    537                                     clang::ArrayType::Normal, 0 /* IndexTypeQuals */);
    538       clang::FieldDecl* const FD =
    539           clang::FieldDecl::Create(ASTC, RD, clang::SourceLocation(), clang::SourceLocation(),
    540                                    paddingIdentifierInfo,
    541                                    paddingType,
    542                                    nullptr,  // TypeSourceInfo*
    543                                    nullptr,  // BW (bitwidth)
    544                                    false,    // Mutable = false
    545                                    clang::ICIS_NoInit);
    546       FD->setImplicit(true);
    547       RD->addDecl(FD);
    548     }
    549     if (info.second != nullptr) {
    550       RDForLayout->removeDecl(info.second);
    551       info.second->setLexicalDeclContext(RD);
    552       RD->addDecl(info.second);
    553     }
    554   }
    555 
    556   // There does not appear to be any safe way to delete a RecordDecl
    557   // -- for example, there is no RecordDecl destructor to invalidate
    558   // cached record layout, and if we were to get unlucky, some future
    559   // RecordDecl could be allocated in the same place as a deleted
    560   // RDForLayout and "inherit" the cached record layout from
    561   // RDForLayout.
    562 }
    563 
    564 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
    565   // we want to insert explicit padding fields into structs per http://b/29154200 and http://b/28070272
    566   switch (D->getTagKind()) {
    567     case clang::TTK_Struct:
    568       PadStruct(llvm::cast<clang::RecordDecl>(D));
    569       break;
    570 
    571     case clang::TTK_Union:
    572       // cannot be part of an exported type
    573       break;
    574 
    575     case clang::TTK_Enum:
    576       // a scalar
    577       break;
    578 
    579     case clang::TTK_Class:
    580     case clang::TTK_Interface:
    581     default:
    582       slangAssert(false && "Unexpected TagTypeKind");
    583       break;
    584   }
    585   mGen->HandleTagDeclDefinition(D);
    586 }
    587 
    588 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
    589   mGen->CompleteTentativeDefinition(D);
    590 }
    591 
    592 Backend::~Backend() {
    593   delete mpModule;
    594   delete mGen;
    595   delete mPerFunctionPasses;
    596   delete mPerModulePasses;
    597   delete mCodeGenPasses;
    598 }
    599 
    600 // 1) Add zero initialization of local RS object types
    601 void Backend::AnnotateFunction(clang::FunctionDecl *FD) {
    602   if (FD &&
    603       FD->hasBody() &&
    604       !FD->isImplicit() &&
    605       !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
    606     mRefCount.Init();
    607     mRefCount.SetDeclContext(FD);
    608     mRefCount.HandleParamsAndLocals(FD);
    609   }
    610 }
    611 
    612 bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
    613   // Find and remember the types for rs_allocation and rs_script_call_t so
    614   // they can be used later for translating rsForEach() calls.
    615   for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
    616        (mContext->getAllocationType().isNull() ||
    617         mContext->getScriptCallType().isNull()) &&
    618        I != E; I++) {
    619     if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) {
    620       clang::StringRef TypeName = TD->getName();
    621       if (TypeName.equals("rs_allocation")) {
    622         mContext->setAllocationType(TD);
    623       } else if (TypeName.equals("rs_script_call_t")) {
    624         mContext->setScriptCallType(TD);
    625       }
    626     }
    627   }
    628 
    629   // Disallow user-defined functions with prefix "rs"
    630   if (!mAllowRSPrefix) {
    631     // Iterate all function declarations in the program.
    632     for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
    633          I != E; I++) {
    634       clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
    635       if (FD == nullptr)
    636         continue;
    637       if (!FD->getName().startswith("rs"))  // Check prefix
    638         continue;
    639       if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
    640         mContext->ReportError(FD->getLocation(),
    641                               "invalid function name prefix, "
    642                               "\"rs\" is reserved: '%0'")
    643             << FD->getName();
    644     }
    645   }
    646 
    647   for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
    648     clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
    649     if (FD) {
    650       // Handle forward reference from pragma (see
    651       // RSReducePragmaHandler::HandlePragma for backward reference).
    652       mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes);
    653       if (FD->isGlobal()) {
    654         // Check that we don't have any array parameters being misinterpreted as
    655         // kernel pointers due to the C type system's array to pointer decay.
    656         size_t numParams = FD->getNumParams();
    657         for (size_t i = 0; i < numParams; i++) {
    658           const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
    659           clang::QualType QT = PVD->getOriginalType();
    660           if (QT->isArrayType()) {
    661             mContext->ReportError(
    662                 PVD->getTypeSpecStartLoc(),
    663                 "exported function parameters may not have array type: %0")
    664                 << QT;
    665           }
    666         }
    667         AnnotateFunction(FD);
    668       }
    669     }
    670 
    671     if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) {
    672       if (FD && FD->hasBody() && !FD->isImplicit() &&
    673           !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
    674         if (FD->hasAttr<clang::RenderScriptKernelAttr>()) {
    675           // Log functions with attribute "kernel" by their names, and assign
    676           // them slot numbers. Any other function cannot be used in a
    677           // rsForEach() or rsForEachWithOptions() call, including old-style
    678           // kernel functions which are defined without the "kernel" attribute.
    679           mContext->addForEach(FD);
    680         }
    681         // Look for any kernel launch calls and translate them into using the
    682         // internal API.
    683         // Report a compiler error on kernel launches inside a kernel.
    684         mForEachHandler.handleForEachCalls(FD, getTargetAPI());
    685       }
    686     }
    687   }
    688 
    689   return mGen->HandleTopLevelDecl(D);
    690 }
    691 
    692 void Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
    693   clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
    694 
    695   if (!mContext->processReducePragmas(this))
    696     return;
    697 
    698   // If we have an invalid RS/FS AST, don't check further.
    699   if (!mASTChecker.Validate()) {
    700     return;
    701   }
    702 
    703   if (mIsFilterscript) {
    704     mContext->addPragma("rs_fp_relaxed", "");
    705   }
    706 
    707   int version = mContext->getVersion();
    708   if (version == 0) {
    709     // Not setting a version is an error
    710     mDiagEngine.Report(
    711         mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
    712         mDiagEngine.getCustomDiagID(
    713             clang::DiagnosticsEngine::Error,
    714             "missing pragma for version in source file"));
    715   } else {
    716     slangAssert(version == 1);
    717   }
    718 
    719   if (mContext->getReflectJavaPackageName().empty()) {
    720     mDiagEngine.Report(
    721         mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
    722         mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
    723                                     "missing \"#pragma rs "
    724                                     "java_package_name(com.foo.bar)\" "
    725                                     "in source file"));
    726     return;
    727   }
    728 
    729   // Create a static global destructor if necessary (to handle RS object
    730   // runtime cleanup).
    731   clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
    732   if (FD) {
    733     HandleTopLevelDecl(clang::DeclGroupRef(FD));
    734   }
    735 
    736   // Process any static function declarations
    737   for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
    738           E = TUDecl->decls_end(); I != E; I++) {
    739     if ((I->getKind() >= clang::Decl::firstFunction) &&
    740         (I->getKind() <= clang::Decl::lastFunction)) {
    741       clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
    742       if (FD && !FD->isGlobal()) {
    743         AnnotateFunction(FD);
    744       }
    745     }
    746   }
    747 }
    748 
    749 ///////////////////////////////////////////////////////////////////////////////
    750 void Backend::dumpExportVarInfo(llvm::Module *M) {
    751   int slotCount = 0;
    752   if (mExportVarMetadata == nullptr)
    753     mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
    754 
    755   llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
    756 
    757   // We emit slot information (#rs_object_slots) for any reference counted
    758   // RS type or pointer (which can also be bound).
    759 
    760   for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
    761           E = mContext->export_vars_end();
    762        I != E;
    763        I++) {
    764     const RSExportVar *EV = *I;
    765     const RSExportType *ET = EV->getType();
    766     bool countsAsRSObject = false;
    767 
    768     // Variable name
    769     ExportVarInfo.push_back(
    770         llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
    771 
    772     // Type name
    773     switch (ET->getClass()) {
    774       case RSExportType::ExportClassPrimitive: {
    775         const RSExportPrimitiveType *PT =
    776             static_cast<const RSExportPrimitiveType*>(ET);
    777         ExportVarInfo.push_back(
    778             llvm::MDString::get(
    779               mLLVMContext, llvm::utostr(PT->getType())));
    780         if (PT->isRSObjectType()) {
    781           countsAsRSObject = true;
    782         }
    783         break;
    784       }
    785       case RSExportType::ExportClassPointer: {
    786         ExportVarInfo.push_back(
    787             llvm::MDString::get(
    788               mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
    789                 ->getPointeeType()->getName()).c_str()));
    790         break;
    791       }
    792       case RSExportType::ExportClassMatrix: {
    793         ExportVarInfo.push_back(
    794             llvm::MDString::get(
    795               mLLVMContext, llvm::utostr(
    796                   /* TODO Strange value.  This pushes just a number, quite
    797                    * different than the other cases.  What is this used for?
    798                    * These are the metadata values that some partner drivers
    799                    * want to reference (for TBAA, etc.). We may want to look
    800                    * at whether these provide any reasonable value (or have
    801                    * distinct enough values to actually depend on).
    802                    */
    803                 DataTypeRSMatrix2x2 +
    804                 static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
    805         break;
    806       }
    807       case RSExportType::ExportClassVector:
    808       case RSExportType::ExportClassConstantArray:
    809       case RSExportType::ExportClassRecord: {
    810         ExportVarInfo.push_back(
    811             llvm::MDString::get(mLLVMContext,
    812               EV->getType()->getName().c_str()));
    813         break;
    814       }
    815     }
    816 
    817     mExportVarMetadata->addOperand(
    818         llvm::MDNode::get(mLLVMContext, ExportVarInfo));
    819     ExportVarInfo.clear();
    820 
    821     if (mRSObjectSlotsMetadata == nullptr) {
    822       mRSObjectSlotsMetadata =
    823           M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
    824     }
    825 
    826     if (countsAsRSObject) {
    827       mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
    828           llvm::MDString::get(mLLVMContext, llvm::utostr(slotCount))));
    829     }
    830 
    831     slotCount++;
    832   }
    833 }
    834 
    835 // A similar algorithm is present in Backend::PadStruct().
    836 static void PadHelperFunctionStruct(llvm::Module *M,
    837                                     llvm::StructType **paddedStructType,
    838                                     std::vector<unsigned> *origFieldNumToPaddedFieldNum,
    839                                     llvm::StructType *origStructType) {
    840   slangAssert(origFieldNumToPaddedFieldNum->empty());
    841   origFieldNumToPaddedFieldNum->resize(2 * origStructType->getNumElements());
    842 
    843   llvm::LLVMContext &llvmContext = M->getContext();
    844 
    845   const llvm::DataLayout *DL = &M->getDataLayout();
    846   const llvm::StructLayout *SL = DL->getStructLayout(origStructType);
    847 
    848   // Field types -- including any padding fields we need to insert.
    849   std::vector<llvm::Type *> paddedFieldTypes;
    850   paddedFieldTypes.reserve(2 * origStructType->getNumElements());
    851 
    852   // Is there any padding in this struct?
    853   bool foundPadding = false;
    854 
    855   llvm::Type *const byteType = llvm::Type::getInt8Ty(llvmContext);
    856   unsigned origFieldNum = 0, paddedFieldNum = 0;
    857   uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
    858   for (llvm::Type *fieldType : origStructType->elements()) {
    859     const uint64_t fieldOffset = SL->getElementOffset(origFieldNum);
    860     const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
    861     if (prePadding != 0) {
    862       foundPadding = true;
    863       paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, prePadding));
    864       ++paddedFieldNum;
    865     }
    866     paddedFieldTypes.push_back(fieldType);
    867     (*origFieldNumToPaddedFieldNum)[origFieldNum] = paddedFieldNum;
    868 
    869     // get ready for the next field
    870     fieldPrePaddingOffset = fieldOffset + DL->getTypeAllocSize(fieldType);
    871     ++origFieldNum;
    872     ++paddedFieldNum;
    873   }
    874 
    875   // In order to ensure that the front end (including reflected code)
    876   // and back end agree on struct size (not just field offsets) we may
    877   // need to add explicit tail padding, just as we'e added explicit
    878   // padding between fields.
    879   slangAssert(SL->getSizeInBytes() >= fieldPrePaddingOffset);
    880   if (const size_t tailPadding = SL->getSizeInBytes() - fieldPrePaddingOffset) {
    881     foundPadding = true;
    882     paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, tailPadding));
    883   }
    884 
    885   *paddedStructType = (foundPadding
    886                        ? llvm::StructType::get(llvmContext, paddedFieldTypes)
    887                        : origStructType);
    888 }
    889 
    890 void Backend::dumpExportFunctionInfo(llvm::Module *M) {
    891   if (mExportFuncMetadata == nullptr)
    892     mExportFuncMetadata =
    893         M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
    894 
    895   llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
    896 
    897   for (RSContext::const_export_func_iterator
    898           I = mContext->export_funcs_begin(),
    899           E = mContext->export_funcs_end();
    900        I != E;
    901        I++) {
    902     const RSExportFunc *EF = *I;
    903 
    904     // Function name
    905     if (!EF->hasParam()) {
    906       ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
    907                                                    EF->getName().c_str()));
    908     } else {
    909       llvm::Function *F = M->getFunction(EF->getName());
    910       llvm::Function *HelperFunction;
    911       const std::string HelperFunctionName(".helper_" + EF->getName());
    912 
    913       slangAssert(F && "Function marked as exported disappeared in Bitcode");
    914 
    915       // Create helper function
    916       {
    917         llvm::StructType *OrigHelperFunctionParameterTy = nullptr;
    918         llvm::StructType *PaddedHelperFunctionParameterTy = nullptr;
    919 
    920         std::vector<unsigned> OrigFieldNumToPaddedFieldNum;
    921         std::vector<bool> isPassedViaPtr;
    922 
    923         if (!F->getArgumentList().empty()) {
    924           std::vector<llvm::Type*> HelperFunctionParameterTys;
    925           for (llvm::Function::arg_iterator AI = F->arg_begin(),
    926                                             AE = F->arg_end();
    927                AI != AE; AI++) {
    928             if (AI->getType()->isPointerTy() &&
    929                 AI->getType()->getPointerElementType()->isStructTy()) {
    930               HelperFunctionParameterTys.push_back(
    931                   AI->getType()->getPointerElementType());
    932               isPassedViaPtr.push_back(true);
    933             } else {
    934               // on 64-bit architecture(s), a vector type could be too big
    935               // to be passed in a register and instead passed
    936               // via a pointer to a temporary copy
    937               llvm::Type *Ty = AI->getType();
    938               bool viaPtr = false;
    939               if (Ty->isPointerTy() && Ty->getPointerElementType()) {
    940                 Ty = Ty->getPointerElementType();
    941                 viaPtr = true;
    942               }
    943               HelperFunctionParameterTys.push_back(Ty);
    944               isPassedViaPtr.push_back(viaPtr);
    945             }
    946           }
    947           OrigHelperFunctionParameterTy =
    948               llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
    949           PadHelperFunctionStruct(M,
    950                                   &PaddedHelperFunctionParameterTy, &OrigFieldNumToPaddedFieldNum,
    951                                   OrigHelperFunctionParameterTy);
    952         }
    953 
    954         if (!EF->checkParameterPacketType(OrigHelperFunctionParameterTy)) {
    955           fprintf(stderr, "Failed to export function %s: parameter type "
    956                           "mismatch during creation of helper function.\n",
    957                   EF->getName().c_str());
    958 
    959           const RSExportRecordType *Expected = EF->getParamPacketType();
    960           if (Expected) {
    961             fprintf(stderr, "Expected:\n");
    962             Expected->getLLVMType()->dump();
    963           }
    964           if (OrigHelperFunctionParameterTy) {
    965             fprintf(stderr, "Got:\n");
    966             OrigHelperFunctionParameterTy->dump();
    967           }
    968           abort();
    969         }
    970 
    971         std::vector<llvm::Type*> Params;
    972         if (PaddedHelperFunctionParameterTy) {
    973           llvm::PointerType *HelperFunctionParameterTyP =
    974               llvm::PointerType::getUnqual(PaddedHelperFunctionParameterTy);
    975           Params.push_back(HelperFunctionParameterTyP);
    976         }
    977 
    978         llvm::FunctionType * HelperFunctionType =
    979             llvm::FunctionType::get(F->getReturnType(),
    980                                     Params,
    981                                     /* IsVarArgs = */false);
    982 
    983         HelperFunction =
    984             llvm::Function::Create(HelperFunctionType,
    985                                    llvm::GlobalValue::ExternalLinkage,
    986                                    HelperFunctionName,
    987                                    M);
    988 
    989         HelperFunction->addFnAttr(llvm::Attribute::NoInline);
    990         HelperFunction->setCallingConv(F->getCallingConv());
    991 
    992         // Create helper function body
    993         {
    994           llvm::Argument *HelperFunctionParameter =
    995               &(*HelperFunction->arg_begin());
    996           llvm::BasicBlock *BB =
    997               llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
    998           llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
    999           llvm::SmallVector<llvm::Value*, 6> Params;
   1000           llvm::Value *Idx[2];
   1001 
   1002           Idx[0] =
   1003               llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
   1004 
   1005           // getelementptr and load instruction for all elements in
   1006           // parameter .p
   1007           for (size_t origFieldNum = 0; origFieldNum < EF->getNumParameters(); origFieldNum++) {
   1008             // getelementptr
   1009             Idx[1] = llvm::ConstantInt::get(
   1010               llvm::Type::getInt32Ty(mLLVMContext), OrigFieldNumToPaddedFieldNum[origFieldNum]);
   1011 
   1012             llvm::Value *Ptr = NULL;
   1013 
   1014             Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
   1015 
   1016             // Load is only required for non-struct ptrs
   1017             if (isPassedViaPtr[origFieldNum]) {
   1018                 Params.push_back(Ptr);
   1019             } else {
   1020                 llvm::Value *V = IB->CreateLoad(Ptr);
   1021                 Params.push_back(V);
   1022             }
   1023           }
   1024 
   1025           // Call and pass the all elements as parameter to F
   1026           llvm::CallInst *CI = IB->CreateCall(F, Params);
   1027 
   1028           CI->setCallingConv(F->getCallingConv());
   1029 
   1030           if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
   1031             IB->CreateRetVoid();
   1032           } else {
   1033             IB->CreateRet(CI);
   1034           }
   1035 
   1036           delete IB;
   1037         }
   1038       }
   1039 
   1040       ExportFuncInfo.push_back(
   1041           llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
   1042     }
   1043 
   1044     mExportFuncMetadata->addOperand(
   1045         llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
   1046     ExportFuncInfo.clear();
   1047   }
   1048 }
   1049 
   1050 void Backend::dumpExportForEachInfo(llvm::Module *M) {
   1051   if (mExportForEachNameMetadata == nullptr) {
   1052     mExportForEachNameMetadata =
   1053         M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
   1054   }
   1055   if (mExportForEachSignatureMetadata == nullptr) {
   1056     mExportForEachSignatureMetadata =
   1057         M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
   1058   }
   1059 
   1060   llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
   1061   llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
   1062 
   1063   for (RSContext::const_export_foreach_iterator
   1064           I = mContext->export_foreach_begin(),
   1065           E = mContext->export_foreach_end();
   1066        I != E;
   1067        I++) {
   1068     const RSExportForEach *EFE = *I;
   1069 
   1070     ExportForEachName.push_back(
   1071         llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
   1072 
   1073     mExportForEachNameMetadata->addOperand(
   1074         llvm::MDNode::get(mLLVMContext, ExportForEachName));
   1075     ExportForEachName.clear();
   1076 
   1077     ExportForEachInfo.push_back(
   1078         llvm::MDString::get(mLLVMContext,
   1079                             llvm::utostr(EFE->getSignatureMetadata())));
   1080 
   1081     mExportForEachSignatureMetadata->addOperand(
   1082         llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
   1083     ExportForEachInfo.clear();
   1084   }
   1085 }
   1086 
   1087 void Backend::dumpExportReduceInfo(llvm::Module *M) {
   1088   if (!mExportReduceMetadata) {
   1089     mExportReduceMetadata =
   1090       M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
   1091   }
   1092 
   1093   llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo;
   1094   // Add operand to ExportReduceInfo, padding out missing operands with
   1095   // nullptr.
   1096   auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) {
   1097     while (Idx > ExportReduceInfo.size())
   1098       ExportReduceInfo.push_back(nullptr);
   1099     ExportReduceInfo.push_back(N);
   1100   };
   1101   // Add string operand to ExportReduceInfo, padding out missing operands
   1102   // with nullptr.
   1103   // If string is empty, then do not add it unless Always is true.
   1104   auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
   1105                                        bool Always = true) {
   1106     if (Always || !S.empty())
   1107       addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
   1108   };
   1109 
   1110   // Add the description of the reduction kernels to the metadata node.
   1111   for (auto I = mContext->export_reduce_begin(),
   1112             E = mContext->export_reduce_end();
   1113        I != E; ++I) {
   1114     ExportReduceInfo.clear();
   1115 
   1116     int Idx = 0;
   1117 
   1118     addString(Idx++, (*I)->getNameReduce());
   1119 
   1120     addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr((*I)->getAccumulatorTypeSize())));
   1121 
   1122     llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
   1123     Accumulator.push_back(
   1124       llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
   1125     Accumulator.push_back(llvm::MDString::get(
   1126       mLLVMContext,
   1127       llvm::utostr((*I)->getAccumulatorSignatureMetadata())));
   1128     addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator));
   1129 
   1130     addString(Idx++, (*I)->getNameInitializer(), false);
   1131     addString(Idx++, (*I)->getNameCombiner(), false);
   1132     addString(Idx++, (*I)->getNameOutConverter(), false);
   1133     addString(Idx++, (*I)->getNameHalter(), false);
   1134 
   1135     mExportReduceMetadata->addOperand(
   1136       llvm::MDTuple::get(mLLVMContext, ExportReduceInfo));
   1137   }
   1138 }
   1139 
   1140 void Backend::dumpExportTypeInfo(llvm::Module *M) {
   1141   llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
   1142 
   1143   for (RSContext::const_export_type_iterator
   1144           I = mContext->export_types_begin(),
   1145           E = mContext->export_types_end();
   1146        I != E;
   1147        I++) {
   1148     // First, dump type name list to export
   1149     const RSExportType *ET = I->getValue();
   1150 
   1151     ExportTypeInfo.clear();
   1152     // Type name
   1153     ExportTypeInfo.push_back(
   1154         llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
   1155 
   1156     if (ET->getClass() == RSExportType::ExportClassRecord) {
   1157       const RSExportRecordType *ERT =
   1158           static_cast<const RSExportRecordType*>(ET);
   1159 
   1160       if (mExportTypeMetadata == nullptr)
   1161         mExportTypeMetadata =
   1162             M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
   1163 
   1164       mExportTypeMetadata->addOperand(
   1165           llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
   1166 
   1167       // Now, export struct field information to %[struct name]
   1168       std::string StructInfoMetadataName("%");
   1169       StructInfoMetadataName.append(ET->getName());
   1170       llvm::NamedMDNode *StructInfoMetadata =
   1171           M->getOrInsertNamedMetadata(StructInfoMetadataName);
   1172       llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
   1173 
   1174       slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
   1175                   "Metadata with same name was created before");
   1176       for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
   1177               FE = ERT->fields_end();
   1178            FI != FE;
   1179            FI++) {
   1180         const RSExportRecordType::Field *F = *FI;
   1181 
   1182         // 1. field name
   1183         FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
   1184                                                 F->getName().c_str()));
   1185 
   1186         // 2. field type name
   1187         FieldInfo.push_back(
   1188             llvm::MDString::get(mLLVMContext,
   1189                                 F->getType()->getName().c_str()));
   1190 
   1191         StructInfoMetadata->addOperand(
   1192             llvm::MDNode::get(mLLVMContext, FieldInfo));
   1193         FieldInfo.clear();
   1194       }
   1195     }   // ET->getClass() == RSExportType::ExportClassRecord
   1196   }
   1197 }
   1198 
   1199 void Backend::HandleTranslationUnitPost(llvm::Module *M) {
   1200 
   1201   if (!mContext->is64Bit()) {
   1202     M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
   1203   }
   1204 
   1205   if (!mContext->processExports())
   1206     return;
   1207 
   1208   if (mContext->hasExportVar())
   1209     dumpExportVarInfo(M);
   1210 
   1211   if (mContext->hasExportFunc())
   1212     dumpExportFunctionInfo(M);
   1213 
   1214   if (mContext->hasExportForEach())
   1215     dumpExportForEachInfo(M);
   1216 
   1217   if (mContext->hasExportReduce())
   1218     dumpExportReduceInfo(M);
   1219 
   1220   if (mContext->hasExportType())
   1221     dumpExportTypeInfo(M);
   1222 }
   1223 
   1224 }  // namespace slang
   1225