slang_backend.cpp revision 352e62d65caa48251d9c69cc8b5a82ddfea6b014
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
25e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines * Copyright 2010-2012, The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_backend.h"
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string>
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <vector>
213a6750f246eed4168351786074691e8eeee5b175David Gross#include <iostream>
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h"
2465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross#include "clang/AST/Attr.h"
259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h"
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h"
273a6750f246eed4168351786074691e8eeee5b175David Gross#include "clang/AST/RecordLayout.h"
28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/Diagnostic.h"
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TargetOptions.h"
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/CodeGen/ModuleBuilder.h"
34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h"
37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/Twine.h"
398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/StringExtras.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/RegAllocRegistry.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/SchedulerRegistry.h"
45e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constant.h"
478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constants.h"
488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DataLayout.h"
498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DebugLoc.h"
508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DerivedTypes.h"
518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Function.h"
528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRBuilder.h"
538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRPrintingPasses.h"
5423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
5523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h"
568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Module.h"
57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h"
59fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetMachine.h"
61e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetOptions.h"
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetRegistry.h"
6377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao
6477703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao#include "llvm/MC/SubtargetFeature.h"
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h"
68dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala#include "slang_bitcode_gen.h"
698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h"
708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_foreach.h"
718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_func.h"
72c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h"
738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h"
748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_var.h"
758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_metadata.h"
768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
772770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#include "rs_cc_options.h"
782770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
79552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines#include "strip_unknown_attributes.h"
806315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
81e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateFunctionPasses() {
843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerFunctionPasses) {
85c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
87fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
88fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
89fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateModulePasses() {
943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerModulePasses) {
95c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerModulePasses = new llvm::legacy::PassManager();
963a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
97fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
98fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
99fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
100b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar    PMBuilder.DisableUnitAtATime = 0; // TODO Pirama confirm if this is right
101fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
102fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnrollLoops) {
103fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 0;
104fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
105fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 1;
106fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
107fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
108fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateModulePassManager(*mPerModulePasses);
109552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    // Add a pass to strip off unknown/unsupported attributes.
110552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    mPerModulePasses->add(createStripUnknownAttributesPass());
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() {
1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now we add passes for code emitting
1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mCodeGenPasses) {
120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
122c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create the TargetMachine for generating code.
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Triple = mpModule->getTargetTriple();
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const llvm::Target* TargetInfo =
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      llvm::TargetRegistry::lookupTarget(Triple, Error);
1315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (TargetInfo == nullptr) {
1329207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
136ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Target Machine Options
137ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  llvm::TargetOptions Options;
138ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien
139167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // Use soft-float ABI for ARM (which is the target used by Slang during code
140167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // generation).  Codegen still uses hardware FPU by default.  To use software
141167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // floating point, add 'soft-float' feature to FeaturesStr below.
142167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  Options.FloatABIType = llvm::FloatABI::Soft;
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // BCC needs all unknown symbols resolved at compilation time. So we don't
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // need any relocation model.
146ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  llvm::Reloc::Model RM = llvm::Reloc::Static;
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
14841ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // This is set for the linker (specify how large of the virtual addresses we
14941ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // can access for all unknown symbols.)
1509207a2e495c8363606861e4f034504ec5c153dabLogan Chien  llvm::CodeModel::Model CM;
1510b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines  if (mpModule->getDataLayout().getPointerSize() == 4) {
1529207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Small;
1539207a2e495c8363606861e4f034504ec5c153dabLogan Chien  } else {
15441ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // The target may have pointer size greater than 32 (e.g. x86_64
15541ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // architecture) may need large data address model
1569207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Medium;
1579207a2e495c8363606861e4f034504ec5c153dabLogan Chien  }
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Setup feature string
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string FeaturesStr;
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SubtargetFeatures Features;
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (std::vector<std::string>::const_iterator
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Features.AddFeature(*I);
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    FeaturesStr = Features.getString();
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1729207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine *TM =
1749207a2e495c8363606861e4f034504ec5c153dabLogan Chien    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
175ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien                                    Options, RM, CM);
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register allocation policy:
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //  createFastRegisterAllocator: fast but bad quality
1792c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien  //  createGreedyRegisterAllocator: not so fast but good quality
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::createFastRegisterAllocator :
1822c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien                                     llvm::createGreedyRegisterAllocator);
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
18577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mCodeGenOpts.OptimizationLevel == 0) {
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::None;
18777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  } else if (mCodeGenOpts.OptimizationLevel == 3) {
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::Aggressive;
18977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine::CodeGenFileType CGFT =
1926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      llvm::TargetMachine::CGFT_AssemblyFile;
19377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mOT == Slang::OT_Object) {
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
19577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
19621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              CGFT, OptLevel)) {
1989207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletBackend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
2068f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const RSCCOptions &Opts,
2078f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::HeaderSearchOptions &HeaderSearchOpts,
2088f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::PreprocessorOptions &PreprocessorOpts,
2098f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::CodeGenOptions &CodeGenOpts,
2108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
2118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 llvm::raw_ostream *OS, Slang::OutputType OT,
2128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
2138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 bool IsFilterscript)
2148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
2158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
21621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
21721cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mBufferOutStream(*mpOS), mContext(Context),
2182770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
2198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
2208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
221dbf5b61ea24012f883e238fd17bdca0758f181d6David Gross      mExportForEachSignatureMetadata(nullptr),
2228ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      mExportReduceMetadata(nullptr),
223c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
224c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mRefCount(mContext->getASTContext()),
2258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
226fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mForEachHandler(Context),
227b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar      mLLVMContext(slang::getGlobalLLVMContext()), mDiagEngine(*DiagEngine),
2288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
2298f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts,
2308f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mCodeGenOpts, mLLVMContext);
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) {
2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->Initialize(Ctx);
235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mpModule = mGen->GetModule();
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
24068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPre(Ctx);
24168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang
2422770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if (mASTPrint)
2432770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    Ctx.getTranslationUnitDecl()->dump();
2442770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTranslationUnit(Ctx);
246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here, we complete a translation unit (whole translation unit is now in LLVM
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // IR). Now, interact with LLVM backend to generate actual machine code (asm
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // or machine code, whatever.)
250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Silently ignore if we weren't initialized for some reason.
25241ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  if (!mpModule)
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::Module *M = mGen->ReleaseModule();
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!M) {
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The module has been released by IR gen on failures, do not double free.
2585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    mpModule = nullptr;
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(mpModule == M &&
2636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Unexpected module change during LLVM IR generation");
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Insert #pragma information into metadata section of module
2663fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  if (!mPragmas->empty()) {
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::NamedMDNode *PragmaMetadata =
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
2693fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
272c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Name goes first
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // And then value
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
27783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Create MDNode and insert into PragmaMetadata
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PragmaMetadata->addOperand(
28018c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines          llvm::MDNode::get(mLLVMContext, Pragma));
281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
28468fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPost(mpModule);
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create passes for optimization and code emission
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run per-function passes
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateFunctionPasses();
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerFunctionPasses) {
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doInitialization();
292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!I->isDeclaration())
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mPerFunctionPasses->run(*I);
298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doFinalization();
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run module passes
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateModulePasses();
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerModulePasses)
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerModulePasses->run(*mpModule);
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
3083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Assembly:
3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Object: {
3106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!CreateCodeGenPasses())
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doInitialization();
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I != E;
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I++)
3186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        if (!I->isDeclaration())
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mCodeGenPasses->run(*I);
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doFinalization();
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3243a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_LLVMAssembly: {
325c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
32621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      LLEmitPM->run(*mpModule);
3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3303a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Bitcode: {
331dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
332b130e157d3a5c2256e7aa0005d7134f3ac060c56Stephen McGroarty                   mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3353a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Nothing: {
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      return;
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
3396e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown output type");
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
343462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3443a6750f246eed4168351786074691e8eeee5b175David Gross// Insert explicit padding fields into struct to follow the current layout.
3453a6750f246eed4168351786074691e8eeee5b175David Gross//
3463a6750f246eed4168351786074691e8eeee5b175David Gross// A similar algorithm is present in PadHelperFunctionStruct().
3473a6750f246eed4168351786074691e8eeee5b175David Grossvoid Backend::PadStruct(clang::RecordDecl* RD) {
3483a6750f246eed4168351786074691e8eeee5b175David Gross  // Example of padding:
3493a6750f246eed4168351786074691e8eeee5b175David Gross  //
3503a6750f246eed4168351786074691e8eeee5b175David Gross  //   // ORIGINAL CODE                   // TRANSFORMED CODE
3513a6750f246eed4168351786074691e8eeee5b175David Gross  //   struct foo {                       struct foo {
3523a6750f246eed4168351786074691e8eeee5b175David Gross  //     int a;                             int a;
3533a6750f246eed4168351786074691e8eeee5b175David Gross  //     // 4 bytes of padding              char <RS_PADDING_FIELD_NAME>[4];
3543a6750f246eed4168351786074691e8eeee5b175David Gross  //     long b;                            long b;
3553a6750f246eed4168351786074691e8eeee5b175David Gross  //     int c;                             int c;
3563a6750f246eed4168351786074691e8eeee5b175David Gross  //     // 4 bytes of (tail) padding       char <RS_PADDING_FIELD_NAME>[4];
3573a6750f246eed4168351786074691e8eeee5b175David Gross  //   };                                 };
3583a6750f246eed4168351786074691e8eeee5b175David Gross
3593a6750f246eed4168351786074691e8eeee5b175David Gross  // We collect all of RD's fields in a vector FieldsInfo.  We
3603a6750f246eed4168351786074691e8eeee5b175David Gross  // represent tail padding as an entry in the FieldsInfo vector with a
3613a6750f246eed4168351786074691e8eeee5b175David Gross  // null FieldDecl.
3623a6750f246eed4168351786074691e8eeee5b175David Gross  typedef std::pair<size_t, clang::FieldDecl*> FieldInfoType;  // (pre-field padding bytes, field)
3633a6750f246eed4168351786074691e8eeee5b175David Gross  std::vector<FieldInfoType> FieldsInfo;
3643a6750f246eed4168351786074691e8eeee5b175David Gross
3653a6750f246eed4168351786074691e8eeee5b175David Gross  // RenderScript is C99-based, so we only expect to see fields.  We
3663a6750f246eed4168351786074691e8eeee5b175David Gross  // could iterate over fields, but instead let's iterate over
3673a6750f246eed4168351786074691e8eeee5b175David Gross  // everything, to verify that there are only fields.
3683a6750f246eed4168351786074691e8eeee5b175David Gross  for (clang::Decl* D : RD->decls()) {
3693a6750f246eed4168351786074691e8eeee5b175David Gross    clang::FieldDecl* FD = clang::dyn_cast<clang::FieldDecl>(D);
3703a6750f246eed4168351786074691e8eeee5b175David Gross    slangAssert(FD && "found a non field declaration within a struct");
3713a6750f246eed4168351786074691e8eeee5b175David Gross    FieldsInfo.push_back(std::make_pair(size_t(0), FD));
3723a6750f246eed4168351786074691e8eeee5b175David Gross  }
3733a6750f246eed4168351786074691e8eeee5b175David Gross
3743a6750f246eed4168351786074691e8eeee5b175David Gross  clang::ASTContext& ASTC = mContext->getASTContext();
3753a6750f246eed4168351786074691e8eeee5b175David Gross
3763a6750f246eed4168351786074691e8eeee5b175David Gross  // ASTContext caches record layout.  We may transform the record in a way
3773a6750f246eed4168351786074691e8eeee5b175David Gross  // that would render this cached information incorrect.  clang does
3783a6750f246eed4168351786074691e8eeee5b175David Gross  // not provide any way to invalidate this cached information.  We
3793a6750f246eed4168351786074691e8eeee5b175David Gross  // take the following approach:
3803a6750f246eed4168351786074691e8eeee5b175David Gross  //
3813a6750f246eed4168351786074691e8eeee5b175David Gross  // 1. ASSUME that record layout has not yet been computed for RD.
3823a6750f246eed4168351786074691e8eeee5b175David Gross  //
3833a6750f246eed4168351786074691e8eeee5b175David Gross  // 2. Create a temporary clone of RD, and compute its layout.
3843a6750f246eed4168351786074691e8eeee5b175David Gross  //    ASSUME that we know how to clone RD in a way that copies all the
3853a6750f246eed4168351786074691e8eeee5b175David Gross  //    properties that are relevant to its layout.
3863a6750f246eed4168351786074691e8eeee5b175David Gross  //
3873a6750f246eed4168351786074691e8eeee5b175David Gross  // 3. Use the layout information from the temporary clone to
3883a6750f246eed4168351786074691e8eeee5b175David Gross  //    transform RD.
3893a6750f246eed4168351786074691e8eeee5b175David Gross  //
3903a6750f246eed4168351786074691e8eeee5b175David Gross  // NOTE: ASTContext also caches TypeInfo (see
3913a6750f246eed4168351786074691e8eeee5b175David Gross  //       ASTContext::getTypeInfo()).  ASSUME that inserting padding
3923a6750f246eed4168351786074691e8eeee5b175David Gross  //       fields doesn't change the type in any way that affects
3933a6750f246eed4168351786074691e8eeee5b175David Gross  //       TypeInfo.
3943a6750f246eed4168351786074691e8eeee5b175David Gross  //
3953a6750f246eed4168351786074691e8eeee5b175David Gross  // NOTE: A RecordType knows its associated RecordDecl -- so even
3963a6750f246eed4168351786074691e8eeee5b175David Gross  //       while we're manipulating RD, the associated RecordType
3973a6750f246eed4168351786074691e8eeee5b175David Gross  //       still recognizes RD as its RecordDecl.  ASSUME that we
3983a6750f246eed4168351786074691e8eeee5b175David Gross  //       don't do anything during our manipulation that would cause
3993a6750f246eed4168351786074691e8eeee5b175David Gross  //       the RecordType to be followed to RD while RD is in a
4003a6750f246eed4168351786074691e8eeee5b175David Gross  //       partially transformed state.
4013a6750f246eed4168351786074691e8eeee5b175David Gross
4023a6750f246eed4168351786074691e8eeee5b175David Gross  // The assumptions above may be brittle, and if they are incorrect,
4033a6750f246eed4168351786074691e8eeee5b175David Gross  // we may get mysterious failures.
4043a6750f246eed4168351786074691e8eeee5b175David Gross
4053a6750f246eed4168351786074691e8eeee5b175David Gross  // create a temporary clone
4063a6750f246eed4168351786074691e8eeee5b175David Gross  clang::RecordDecl* RDForLayout =
4073a6750f246eed4168351786074691e8eeee5b175David Gross      clang::RecordDecl::Create(ASTC, clang::TTK_Struct, RD->getDeclContext(),
4083a6750f246eed4168351786074691e8eeee5b175David Gross                                clang::SourceLocation(), clang::SourceLocation(),
4093a6750f246eed4168351786074691e8eeee5b175David Gross                                nullptr /* IdentifierInfo */);
4103a6750f246eed4168351786074691e8eeee5b175David Gross  RDForLayout->startDefinition();
4113a6750f246eed4168351786074691e8eeee5b175David Gross  RDForLayout->setTypeForDecl(RD->getTypeForDecl());
412352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung  if (RD->hasAttrs())
413352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung    RDForLayout->setAttrs(RD->getAttrs());
4143a6750f246eed4168351786074691e8eeee5b175David Gross  RDForLayout->completeDefinition();
4153a6750f246eed4168351786074691e8eeee5b175David Gross
4163a6750f246eed4168351786074691e8eeee5b175David Gross  // move all fields from RD to RDForLayout
4173a6750f246eed4168351786074691e8eeee5b175David Gross  for (const auto &info : FieldsInfo) {
4183a6750f246eed4168351786074691e8eeee5b175David Gross    RD->removeDecl(info.second);
419352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung    info.second->setLexicalDeclContext(RDForLayout);
4203a6750f246eed4168351786074691e8eeee5b175David Gross    RDForLayout->addDecl(info.second);
4213a6750f246eed4168351786074691e8eeee5b175David Gross  }
4223a6750f246eed4168351786074691e8eeee5b175David Gross
4233a6750f246eed4168351786074691e8eeee5b175David Gross  const clang::ASTRecordLayout& RL = ASTC.getASTRecordLayout(RDForLayout);
4243a6750f246eed4168351786074691e8eeee5b175David Gross
4253a6750f246eed4168351786074691e8eeee5b175David Gross  // An exportable type cannot contain a bitfield.  However, it's
4263a6750f246eed4168351786074691e8eeee5b175David Gross  // possible that this current type might have a bitfield and yet
4273a6750f246eed4168351786074691e8eeee5b175David Gross  // share a common initial sequence with an exportable type, so even
4283a6750f246eed4168351786074691e8eeee5b175David Gross  // if the current type has a bitfield, the current type still
4293a6750f246eed4168351786074691e8eeee5b175David Gross  // needs to have explicit padding inserted (in case the two types
4303a6750f246eed4168351786074691e8eeee5b175David Gross  // under discussion are members of a union).  We don't need to
4313a6750f246eed4168351786074691e8eeee5b175David Gross  // insert any padding after the bitfield, however, because that
4323a6750f246eed4168351786074691e8eeee5b175David Gross  // would be beyond the common initial sequence.
4333a6750f246eed4168351786074691e8eeee5b175David Gross  bool foundBitField = false;
4343a6750f246eed4168351786074691e8eeee5b175David Gross
4353a6750f246eed4168351786074691e8eeee5b175David Gross  // Is there any padding in this struct?
4363a6750f246eed4168351786074691e8eeee5b175David Gross  bool foundPadding = false;
4373a6750f246eed4168351786074691e8eeee5b175David Gross
4383a6750f246eed4168351786074691e8eeee5b175David Gross  unsigned fieldNo = 0;
4393a6750f246eed4168351786074691e8eeee5b175David Gross  uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
4403a6750f246eed4168351786074691e8eeee5b175David Gross  for (auto &info : FieldsInfo) {
4413a6750f246eed4168351786074691e8eeee5b175David Gross    const clang::FieldDecl* FD = info.second;
4423a6750f246eed4168351786074691e8eeee5b175David Gross
4433a6750f246eed4168351786074691e8eeee5b175David Gross    if ((foundBitField = FD->isBitField()))
4443a6750f246eed4168351786074691e8eeee5b175David Gross      break;
4453a6750f246eed4168351786074691e8eeee5b175David Gross
4463a6750f246eed4168351786074691e8eeee5b175David Gross    const uint64_t fieldOffset = RL.getFieldOffset(fieldNo) >> 3;
4473a6750f246eed4168351786074691e8eeee5b175David Gross    const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
4483a6750f246eed4168351786074691e8eeee5b175David Gross    foundPadding |= (prePadding != 0);
4493a6750f246eed4168351786074691e8eeee5b175David Gross    info.first = prePadding;
4503a6750f246eed4168351786074691e8eeee5b175David Gross
4513a6750f246eed4168351786074691e8eeee5b175David Gross    // get ready for the next field
4523a6750f246eed4168351786074691e8eeee5b175David Gross    //
4533a6750f246eed4168351786074691e8eeee5b175David Gross    //   assumes that getTypeSize() is the storage size of the Type -- for example,
4543a6750f246eed4168351786074691e8eeee5b175David Gross    //   that it includes a struct's tail padding (if any)
4553a6750f246eed4168351786074691e8eeee5b175David Gross    //
4563a6750f246eed4168351786074691e8eeee5b175David Gross    fieldPrePaddingOffset = fieldOffset + (ASTC.getTypeSize(FD->getType()) >> 3);
4573a6750f246eed4168351786074691e8eeee5b175David Gross    ++fieldNo;
4583a6750f246eed4168351786074691e8eeee5b175David Gross  }
4593a6750f246eed4168351786074691e8eeee5b175David Gross
4603a6750f246eed4168351786074691e8eeee5b175David Gross  if (!foundBitField) {
4613a6750f246eed4168351786074691e8eeee5b175David Gross    // In order to ensure that the front end (including reflected
4623a6750f246eed4168351786074691e8eeee5b175David Gross    // code) and back end agree on struct size (not just field
4633a6750f246eed4168351786074691e8eeee5b175David Gross    // offsets) we may need to add explicit tail padding, just as we'e
4643a6750f246eed4168351786074691e8eeee5b175David Gross    // added explicit padding between fields.
4653a6750f246eed4168351786074691e8eeee5b175David Gross    slangAssert(RL.getSize().getQuantity() >= fieldPrePaddingOffset);
4663a6750f246eed4168351786074691e8eeee5b175David Gross    if (const size_t tailPadding = RL.getSize().getQuantity() - fieldPrePaddingOffset) {
4673a6750f246eed4168351786074691e8eeee5b175David Gross      foundPadding = true;
4683a6750f246eed4168351786074691e8eeee5b175David Gross      FieldsInfo.push_back(std::make_pair(tailPadding, nullptr));
4693a6750f246eed4168351786074691e8eeee5b175David Gross    }
4703a6750f246eed4168351786074691e8eeee5b175David Gross  }
4713a6750f246eed4168351786074691e8eeee5b175David Gross
4723a6750f246eed4168351786074691e8eeee5b175David Gross  if (false /* change to "true" for extra debugging output */) {
4733a6750f246eed4168351786074691e8eeee5b175David Gross   if (foundPadding) {
4743a6750f246eed4168351786074691e8eeee5b175David Gross     std::cout << "PadStruct(" << RD->getNameAsString() << "):" << std::endl;
4753a6750f246eed4168351786074691e8eeee5b175David Gross     for (const auto &info : FieldsInfo)
4763a6750f246eed4168351786074691e8eeee5b175David Gross       std::cout << "  " << info.first << ", " << (info.second ? info.second->getNameAsString() : "<tail>") << std::endl;
4773a6750f246eed4168351786074691e8eeee5b175David Gross   }
4783a6750f246eed4168351786074691e8eeee5b175David Gross  }
4793a6750f246eed4168351786074691e8eeee5b175David Gross
4803a6750f246eed4168351786074691e8eeee5b175David Gross  if (foundPadding && Slang::IsLocInRSHeaderFile(RD->getLocation(), mSourceMgr)) {
4813a6750f246eed4168351786074691e8eeee5b175David Gross    mContext->ReportError(RD->getLocation(), "system structure contains padding: '%0'")
4823a6750f246eed4168351786074691e8eeee5b175David Gross        << RD->getName();
4833a6750f246eed4168351786074691e8eeee5b175David Gross  }
4843a6750f246eed4168351786074691e8eeee5b175David Gross
4853a6750f246eed4168351786074691e8eeee5b175David Gross  // now move fields from RDForLayout to RD, and add any necessary
4863a6750f246eed4168351786074691e8eeee5b175David Gross  // padding fields
4873a6750f246eed4168351786074691e8eeee5b175David Gross  const clang::QualType byteType = ASTC.getIntTypeForBitwidth(8, false /* not signed */);
4883a6750f246eed4168351786074691e8eeee5b175David Gross  clang::IdentifierInfo* const paddingIdentifierInfo = &ASTC.Idents.get(RS_PADDING_FIELD_NAME);
4893a6750f246eed4168351786074691e8eeee5b175David Gross  for (const auto &info : FieldsInfo) {
4903a6750f246eed4168351786074691e8eeee5b175David Gross    if (info.first != 0) {
4913a6750f246eed4168351786074691e8eeee5b175David Gross      // Create a padding field: "char <RS_PADDING_FIELD_NAME>[<info.first>];"
4923a6750f246eed4168351786074691e8eeee5b175David Gross
4933a6750f246eed4168351786074691e8eeee5b175David Gross      // TODO: Do we need to do anything else to keep this field from being shown in debugger?
4943a6750f246eed4168351786074691e8eeee5b175David Gross      //       There's no source location, and the field is marked as implicit.
4953a6750f246eed4168351786074691e8eeee5b175David Gross      const clang::QualType paddingType =
4963a6750f246eed4168351786074691e8eeee5b175David Gross          ASTC.getConstantArrayType(byteType,
4973a6750f246eed4168351786074691e8eeee5b175David Gross                                    llvm::APInt(sizeof(info.first) << 3, info.first),
4983a6750f246eed4168351786074691e8eeee5b175David Gross                                    clang::ArrayType::Normal, 0 /* IndexTypeQuals */);
4993a6750f246eed4168351786074691e8eeee5b175David Gross      clang::FieldDecl* const FD =
5003a6750f246eed4168351786074691e8eeee5b175David Gross          clang::FieldDecl::Create(ASTC, RD, clang::SourceLocation(), clang::SourceLocation(),
5013a6750f246eed4168351786074691e8eeee5b175David Gross                                   paddingIdentifierInfo,
5023a6750f246eed4168351786074691e8eeee5b175David Gross                                   paddingType,
5033a6750f246eed4168351786074691e8eeee5b175David Gross                                   nullptr,  // TypeSourceInfo*
5043a6750f246eed4168351786074691e8eeee5b175David Gross                                   nullptr,  // BW (bitwidth)
5053a6750f246eed4168351786074691e8eeee5b175David Gross                                   false,    // Mutable = false
5063a6750f246eed4168351786074691e8eeee5b175David Gross                                   clang::ICIS_NoInit);
5073a6750f246eed4168351786074691e8eeee5b175David Gross      FD->setImplicit(true);
5083a6750f246eed4168351786074691e8eeee5b175David Gross      RD->addDecl(FD);
5093a6750f246eed4168351786074691e8eeee5b175David Gross    }
5103a6750f246eed4168351786074691e8eeee5b175David Gross    if (info.second != nullptr) {
5113a6750f246eed4168351786074691e8eeee5b175David Gross      RDForLayout->removeDecl(info.second);
512352e62d65caa48251d9c69cc8b5a82ddfea6b014I-Jui (Ray) Sung      info.second->setLexicalDeclContext(RD);
5133a6750f246eed4168351786074691e8eeee5b175David Gross      RD->addDecl(info.second);
5143a6750f246eed4168351786074691e8eeee5b175David Gross    }
5153a6750f246eed4168351786074691e8eeee5b175David Gross  }
5163a6750f246eed4168351786074691e8eeee5b175David Gross
5173a6750f246eed4168351786074691e8eeee5b175David Gross  // There does not appear to be any safe way to delete a RecordDecl
5183a6750f246eed4168351786074691e8eeee5b175David Gross  // -- for example, there is no RecordDecl destructor to invalidate
5193a6750f246eed4168351786074691e8eeee5b175David Gross  // cached record layout, and if we were to get unlucky, some future
5203a6750f246eed4168351786074691e8eeee5b175David Gross  // RecordDecl could be allocated in the same place as a deleted
5213a6750f246eed4168351786074691e8eeee5b175David Gross  // RDForLayout and "inherit" the cached record layout from
5223a6750f246eed4168351786074691e8eeee5b175David Gross  // RDForLayout.
5233a6750f246eed4168351786074691e8eeee5b175David Gross}
5243a6750f246eed4168351786074691e8eeee5b175David Gross
5259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
5263a6750f246eed4168351786074691e8eeee5b175David Gross  // we want to insert explicit padding fields into structs per http://b/29154200 and http://b/28070272
5273a6750f246eed4168351786074691e8eeee5b175David Gross  switch (D->getTagKind()) {
5283a6750f246eed4168351786074691e8eeee5b175David Gross    case clang::TTK_Struct:
5293a6750f246eed4168351786074691e8eeee5b175David Gross      PadStruct(llvm::cast<clang::RecordDecl>(D));
5303a6750f246eed4168351786074691e8eeee5b175David Gross      break;
5313a6750f246eed4168351786074691e8eeee5b175David Gross
5323a6750f246eed4168351786074691e8eeee5b175David Gross    case clang::TTK_Union:
5333a6750f246eed4168351786074691e8eeee5b175David Gross      // cannot be part of an exported type
5343a6750f246eed4168351786074691e8eeee5b175David Gross      break;
5353a6750f246eed4168351786074691e8eeee5b175David Gross
5363a6750f246eed4168351786074691e8eeee5b175David Gross    case clang::TTK_Enum:
5373a6750f246eed4168351786074691e8eeee5b175David Gross      // a scalar
5383a6750f246eed4168351786074691e8eeee5b175David Gross      break;
5393a6750f246eed4168351786074691e8eeee5b175David Gross
5403a6750f246eed4168351786074691e8eeee5b175David Gross    case clang::TTK_Class:
5413a6750f246eed4168351786074691e8eeee5b175David Gross    case clang::TTK_Interface:
5423a6750f246eed4168351786074691e8eeee5b175David Gross    default:
5433a6750f246eed4168351786074691e8eeee5b175David Gross      slangAssert(false && "Unexpected TagTypeKind");
5443a6750f246eed4168351786074691e8eeee5b175David Gross      break;
5453a6750f246eed4168351786074691e8eeee5b175David Gross  }
5469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTagDeclDefinition(D);
547462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
548462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
5499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
5509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->CompleteTentativeDefinition(D);
551462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
552462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
553462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() {
5549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mpModule;
5559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mGen;
5569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerFunctionPasses;
5579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerModulePasses;
5589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mCodeGenPasses;
559462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
560e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) {
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD &&
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      FD->hasBody() &&
565c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung      !FD->isImplicit() &&
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Init();
568283a6cf32b808c703b219862ac491df3c9fc8b4bYang Ni    mRefCount.SetDeclContext(FD);
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
5742615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  // Find and remember the types for rs_allocation and rs_script_call_t so
5752615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  // they can be used later for translating rsForEach() calls.
5762615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
5772615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni       (mContext->getAllocationType().isNull() ||
5782615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni        mContext->getScriptCallType().isNull()) &&
5792615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni       I != E; I++) {
5802615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni    if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) {
5812615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      clang::StringRef TypeName = TD->getName();
5822615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      if (TypeName.equals("rs_allocation")) {
58388f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni        mContext->setAllocationType(TD);
5842615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      } else if (TypeName.equals("rs_script_call_t")) {
5852615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni        mContext->setScriptCallType(TD);
58688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni      }
58788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni    }
58888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  }
58988f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
61065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    if (FD) {
6115e306b944425a952fe744f59d828538137a59375David Gross      // Handle forward reference from pragma (see
6125e306b944425a952fe744f59d828538137a59375David Gross      // RSReducePragmaHandler::HandlePragma for backward reference).
6135e306b944425a952fe744f59d828538137a59375David Gross      mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes);
61465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      if (FD->isGlobal()) {
61565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        // Check that we don't have any array parameters being misinterpreted as
61665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        // kernel pointers due to the C type system's array to pointer decay.
61765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        size_t numParams = FD->getNumParams();
61865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        for (size_t i = 0; i < numParams; i++) {
61965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
62065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          clang::QualType QT = PVD->getOriginalType();
62165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          if (QT->isArrayType()) {
62265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross            mContext->ReportError(
62365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                PVD->getTypeSpecStartLoc(),
62465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                "exported function parameters may not have array type: %0")
62565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                << QT;
62665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          }
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
62865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        AnnotateFunction(FD);
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
631fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
63240bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni    if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) {
633c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung      if (FD && FD->hasBody() && !FD->isImplicit() &&
6349319dfc974a82794d46e9f474f316590f480b976Yang Ni          !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
635b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar        if (FD->hasAttr<clang::RenderScriptKernelAttr>()) {
63640bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // Log functions with attribute "kernel" by their names, and assign
63740bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // them slot numbers. Any other function cannot be used in a
63840bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // rsForEach() or rsForEachWithOptions() call, including old-style
63940bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // kernel functions which are defined without the "kernel" attribute.
6409319dfc974a82794d46e9f474f316590f480b976Yang Ni          mContext->addForEach(FD);
6411946749cebf4a64341d8210890688fef7d958c22Yang Ni        }
6421946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Look for any kernel launch calls and translate them into using the
6431946749cebf4a64341d8210890688fef7d958c22Yang Ni        // internal API.
64440bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni        // Report a compiler error on kernel launches inside a kernel.
6459319dfc974a82794d46e9f474f316590f480b976Yang Ni        mForEachHandler.handleForEachCalls(FD, getTargetAPI());
646fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      }
647fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
649fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6565e306b944425a952fe744f59d828538137a59375David Gross  if (!mContext->processReducePragmas(this))
65765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    return;
65865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
740b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar              mLLVMContext, llvm::utostr(PT->getType())));
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
756b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar              mLLVMContext, llvm::utostr(
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
7798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
7808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
7818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
7838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
7848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
7858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
7888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
789b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar          llvm::MDString::get(mLLVMContext, llvm::utostr(slotCount))));
7908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
7938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7963a6750f246eed4168351786074691e8eeee5b175David Gross// A similar algorithm is present in Backend::PadStruct().
7973a6750f246eed4168351786074691e8eeee5b175David Grossstatic void PadHelperFunctionStruct(llvm::Module *M,
7983a6750f246eed4168351786074691e8eeee5b175David Gross                                    llvm::StructType **paddedStructType,
7993a6750f246eed4168351786074691e8eeee5b175David Gross                                    std::vector<unsigned> *origFieldNumToPaddedFieldNum,
8003a6750f246eed4168351786074691e8eeee5b175David Gross                                    llvm::StructType *origStructType) {
8013a6750f246eed4168351786074691e8eeee5b175David Gross  slangAssert(origFieldNumToPaddedFieldNum->empty());
8023a6750f246eed4168351786074691e8eeee5b175David Gross  origFieldNumToPaddedFieldNum->resize(2 * origStructType->getNumElements());
8033a6750f246eed4168351786074691e8eeee5b175David Gross
8043a6750f246eed4168351786074691e8eeee5b175David Gross  llvm::LLVMContext &llvmContext = M->getContext();
8053a6750f246eed4168351786074691e8eeee5b175David Gross
8063a6750f246eed4168351786074691e8eeee5b175David Gross  const llvm::DataLayout *DL = &M->getDataLayout();
8073a6750f246eed4168351786074691e8eeee5b175David Gross  const llvm::StructLayout *SL = DL->getStructLayout(origStructType);
8083a6750f246eed4168351786074691e8eeee5b175David Gross
8093a6750f246eed4168351786074691e8eeee5b175David Gross  // Field types -- including any padding fields we need to insert.
8103a6750f246eed4168351786074691e8eeee5b175David Gross  std::vector<llvm::Type *> paddedFieldTypes;
8113a6750f246eed4168351786074691e8eeee5b175David Gross  paddedFieldTypes.reserve(2 * origStructType->getNumElements());
8123a6750f246eed4168351786074691e8eeee5b175David Gross
8133a6750f246eed4168351786074691e8eeee5b175David Gross  // Is there any padding in this struct?
8143a6750f246eed4168351786074691e8eeee5b175David Gross  bool foundPadding = false;
8153a6750f246eed4168351786074691e8eeee5b175David Gross
8163a6750f246eed4168351786074691e8eeee5b175David Gross  llvm::Type *const byteType = llvm::Type::getInt8Ty(llvmContext);
8173a6750f246eed4168351786074691e8eeee5b175David Gross  unsigned origFieldNum = 0, paddedFieldNum = 0;
8183a6750f246eed4168351786074691e8eeee5b175David Gross  uint64_t fieldPrePaddingOffset = 0;  // byte offset of pre-field padding within struct
8193a6750f246eed4168351786074691e8eeee5b175David Gross  for (llvm::Type *fieldType : origStructType->elements()) {
8203a6750f246eed4168351786074691e8eeee5b175David Gross    const uint64_t fieldOffset = SL->getElementOffset(origFieldNum);
8213a6750f246eed4168351786074691e8eeee5b175David Gross    const size_t prePadding = fieldOffset - fieldPrePaddingOffset;
8223a6750f246eed4168351786074691e8eeee5b175David Gross    if (prePadding != 0) {
8233a6750f246eed4168351786074691e8eeee5b175David Gross      foundPadding = true;
8243a6750f246eed4168351786074691e8eeee5b175David Gross      paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, prePadding));
8253a6750f246eed4168351786074691e8eeee5b175David Gross      ++paddedFieldNum;
8263a6750f246eed4168351786074691e8eeee5b175David Gross    }
8273a6750f246eed4168351786074691e8eeee5b175David Gross    paddedFieldTypes.push_back(fieldType);
8283a6750f246eed4168351786074691e8eeee5b175David Gross    (*origFieldNumToPaddedFieldNum)[origFieldNum] = paddedFieldNum;
8293a6750f246eed4168351786074691e8eeee5b175David Gross
8303a6750f246eed4168351786074691e8eeee5b175David Gross    // get ready for the next field
8313a6750f246eed4168351786074691e8eeee5b175David Gross    fieldPrePaddingOffset = fieldOffset + DL->getTypeAllocSize(fieldType);
8323a6750f246eed4168351786074691e8eeee5b175David Gross    ++origFieldNum;
8333a6750f246eed4168351786074691e8eeee5b175David Gross    ++paddedFieldNum;
8343a6750f246eed4168351786074691e8eeee5b175David Gross  }
8353a6750f246eed4168351786074691e8eeee5b175David Gross
8363a6750f246eed4168351786074691e8eeee5b175David Gross  // In order to ensure that the front end (including reflected code)
8373a6750f246eed4168351786074691e8eeee5b175David Gross  // and back end agree on struct size (not just field offsets) we may
8383a6750f246eed4168351786074691e8eeee5b175David Gross  // need to add explicit tail padding, just as we'e added explicit
8393a6750f246eed4168351786074691e8eeee5b175David Gross  // padding between fields.
8403a6750f246eed4168351786074691e8eeee5b175David Gross  slangAssert(SL->getSizeInBytes() >= fieldPrePaddingOffset);
8413a6750f246eed4168351786074691e8eeee5b175David Gross  if (const size_t tailPadding = SL->getSizeInBytes() - fieldPrePaddingOffset) {
8423a6750f246eed4168351786074691e8eeee5b175David Gross    foundPadding = true;
8433a6750f246eed4168351786074691e8eeee5b175David Gross    paddedFieldTypes.push_back(llvm::ArrayType::get(byteType, tailPadding));
8443a6750f246eed4168351786074691e8eeee5b175David Gross  }
8453a6750f246eed4168351786074691e8eeee5b175David Gross
8463a6750f246eed4168351786074691e8eeee5b175David Gross  *paddedStructType = (foundPadding
8473a6750f246eed4168351786074691e8eeee5b175David Gross                       ? llvm::StructType::get(llvmContext, paddedFieldTypes)
8483a6750f246eed4168351786074691e8eeee5b175David Gross                       : origStructType);
8493a6750f246eed4168351786074691e8eeee5b175David Gross}
8503a6750f246eed4168351786074691e8eeee5b175David Gross
8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
8608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
8638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
8648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
8668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
8678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
8688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
8698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
8708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
8718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
8728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
8738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
8758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
8778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
8783a6750f246eed4168351786074691e8eeee5b175David Gross        llvm::StructType *OrigHelperFunctionParameterTy = nullptr;
8793a6750f246eed4168351786074691e8eeee5b175David Gross        llvm::StructType *PaddedHelperFunctionParameterTy = nullptr;
8803a6750f246eed4168351786074691e8eeee5b175David Gross
8813a6750f246eed4168351786074691e8eeee5b175David Gross        std::vector<unsigned> OrigFieldNumToPaddedFieldNum;
8828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
8838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
8858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
8868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
8878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
8888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
8898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
8908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
8918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
8928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
8938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
8948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
8958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
8963a6750f246eed4168351786074691e8eeee5b175David Gross          OrigHelperFunctionParameterTy =
8978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
8983a6750f246eed4168351786074691e8eeee5b175David Gross          PadHelperFunctionStruct(M,
8993a6750f246eed4168351786074691e8eeee5b175David Gross                                  &PaddedHelperFunctionParameterTy, &OrigFieldNumToPaddedFieldNum,
9003a6750f246eed4168351786074691e8eeee5b175David Gross                                  OrigHelperFunctionParameterTy);
9018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
9028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9033a6750f246eed4168351786074691e8eeee5b175David Gross        if (!EF->checkParameterPacketType(OrigHelperFunctionParameterTy)) {
9048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
9058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
9068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
9078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
9098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
9108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
9118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
9128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
9133a6750f246eed4168351786074691e8eeee5b175David Gross          if (OrigHelperFunctionParameterTy) {
9148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
9153a6750f246eed4168351786074691e8eeee5b175David Gross            OrigHelperFunctionParameterTy->dump();
9168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
9178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
9188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
9203a6750f246eed4168351786074691e8eeee5b175David Gross        if (PaddedHelperFunctionParameterTy) {
9218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
9223a6750f246eed4168351786074691e8eeee5b175David Gross              llvm::PointerType::getUnqual(PaddedHelperFunctionParameterTy);
9238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
9248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
9258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
9278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
9288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
9298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
9308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
9328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
9338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
9348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
9358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
9368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
9388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
9398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
9418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
9428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
9438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
9448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
9458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
9468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
9478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
9488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
9498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
9518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
9528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
9548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
9553a6750f246eed4168351786074691e8eeee5b175David Gross          for (size_t origFieldNum = 0; origFieldNum < EF->getNumParameters(); origFieldNum++) {
9568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
9578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
9583a6750f246eed4168351786074691e8eeee5b175David Gross              llvm::Type::getInt32Ty(mLLVMContext), OrigFieldNumToPaddedFieldNum[origFieldNum]);
9598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
9618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
9638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
9653a6750f246eed4168351786074691e8eeee5b175David Gross            if (isStructInput[origFieldNum]) {
9668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
9678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
9688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
9698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
9708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
9718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
9728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
9748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
9758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
9778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
978fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
9798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
980fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          } else {
9818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
982fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          }
9838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
9858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
9868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
9878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
9898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
9908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
9918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
9938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
9948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
9958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
9968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
9978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
9998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
10008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
10018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
10028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
10038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
10048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
10058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
10068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
10078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
10098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
10108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
10128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
10138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
10148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
10158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
10168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
10178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
10198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
10208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
10228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
10238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
10248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
10268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
1027b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar                            llvm::utostr(EFE->getSignatureMetadata())));
10288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
10308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
10318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
10328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
10338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
10348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10358ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Grossvoid Backend::dumpExportReduceInfo(llvm::Module *M) {
10368ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  if (!mExportReduceMetadata) {
10378ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    mExportReduceMetadata =
10388ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
103915e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
104015e44e66adc350adb4fe0533a442092c64333ab5David Gross
10418ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo;
10428ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  // Add operand to ExportReduceInfo, padding out missing operands with
104315e44e66adc350adb4fe0533a442092c64333ab5David Gross  // nullptr.
10448ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) {
10458ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    while (Idx > ExportReduceInfo.size())
10468ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      ExportReduceInfo.push_back(nullptr);
10478ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    ExportReduceInfo.push_back(N);
104815e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
10498ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  // Add string operand to ExportReduceInfo, padding out missing operands
105015e44e66adc350adb4fe0533a442092c64333ab5David Gross  // with nullptr.
105115e44e66adc350adb4fe0533a442092c64333ab5David Gross  // If string is empty, then do not add it unless Always is true.
105215e44e66adc350adb4fe0533a442092c64333ab5David Gross  auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
105315e44e66adc350adb4fe0533a442092c64333ab5David Gross                                       bool Always = true) {
105415e44e66adc350adb4fe0533a442092c64333ab5David Gross    if (Always || !S.empty())
105515e44e66adc350adb4fe0533a442092c64333ab5David Gross      addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
105615e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
105715e44e66adc350adb4fe0533a442092c64333ab5David Gross
105815e44e66adc350adb4fe0533a442092c64333ab5David Gross  // Add the description of the reduction kernels to the metadata node.
10598ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  for (auto I = mContext->export_reduce_begin(),
10608ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross            E = mContext->export_reduce_end();
106115e44e66adc350adb4fe0533a442092c64333ab5David Gross       I != E; ++I) {
10628ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    ExportReduceInfo.clear();
106315e44e66adc350adb4fe0533a442092c64333ab5David Gross
106465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    int Idx = 0;
106565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
106665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameReduce());
106765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
1068b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar    addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr((*I)->getAccumulatorTypeSize())));
106915e44e66adc350adb4fe0533a442092c64333ab5David Gross
107015e44e66adc350adb4fe0533a442092c64333ab5David Gross    llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
107115e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(
107215e44e66adc350adb4fe0533a442092c64333ab5David Gross      llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
107315e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(llvm::MDString::get(
107415e44e66adc350adb4fe0533a442092c64333ab5David Gross      mLLVMContext,
1075b6a143562bda2117824a0515c208504e9a2830f1Pirama Arumuga Nainar      llvm::utostr((*I)->getAccumulatorSignatureMetadata())));
107665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator));
107715e44e66adc350adb4fe0533a442092c64333ab5David Gross
107865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameInitializer(), false);
107965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameCombiner(), false);
108065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameOutConverter(), false);
108165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameHalter(), false);
108215e44e66adc350adb4fe0533a442092c64333ab5David Gross
10838ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    mExportReduceMetadata->addOperand(
10848ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      llvm::MDTuple::get(mLLVMContext, ExportReduceInfo));
108515e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
108615e44e66adc350adb4fe0533a442092c64333ab5David Gross}
108715e44e66adc350adb4fe0533a442092c64333ab5David Gross
10888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
10898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
10908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
10928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
10938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
10948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
10958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
10968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
10978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
10988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
10998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
11008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
11018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
11028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
11038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
11058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
11068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
11078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
11098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
11108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
11118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
11138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
11148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
11168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
11178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
11188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
11198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
11208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
11218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
11238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
11248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
11258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
11268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
11278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
11288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
11298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
11318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
11328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
11338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
11358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
11368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
11378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
11388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
11408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
11418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
11428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
11438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
11448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
11458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
11468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
11488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
11508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
11518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
11528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
115365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  if (!mContext->processExports())
11548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
11558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
11578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
11588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
11608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
11618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
11638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
11648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
11658ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  if (mContext->hasExportReduce())
11668ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    dumpExportReduceInfo(M);
116715e44e66adc350adb4fe0533a442092c64333ab5David Gross
11688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
11698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
11708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
11718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
1172e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
1173