slang_backend.cpp revision 15e44e66adc350adb4fe0533a442092c64333ab5
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>
21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h"
239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h"
249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h"
25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/Diagnostic.h"
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TargetOptions.h"
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/CodeGen/ModuleBuilder.h"
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h"
34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/Twine.h"
368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/StringExtras.h"
37e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/RegAllocRegistry.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/SchedulerRegistry.h"
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constant.h"
448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constants.h"
458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DataLayout.h"
468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DebugLoc.h"
478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DerivedTypes.h"
488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Function.h"
498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRBuilder.h"
508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRPrintingPasses.h"
5123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
5223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h"
538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Module.h"
54e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
559207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h"
56fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
57e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetMachine.h"
58e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetOptions.h"
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetRegistry.h"
6077703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao
6177703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao#include "llvm/MC/SubtargetFeature.h"
62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h"
65dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala#include "slang_bitcode_gen.h"
668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h"
678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_foreach.h"
688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_func.h"
69c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h"
708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h"
718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_var.h"
728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_metadata.h"
738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
742770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#include "rs_cc_options.h"
752770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
76552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines#include "strip_unknown_attributes.h"
776315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
78e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
803a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateFunctionPasses() {
813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerFunctionPasses) {
82c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
833a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
84fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
85fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
86fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateModulePasses() {
913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerModulePasses) {
92c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerModulePasses = new llvm::legacy::PassManager();
933a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
94fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
95fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
96fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
97fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnitAtATime) {
98fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 0;
99fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
100fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 1;
101fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
102fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
103fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnrollLoops) {
104fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 0;
105fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
106fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 1;
107fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
108fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
109fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateModulePassManager(*mPerModulePasses);
110552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    // Add a pass to strip off unknown/unsupported attributes.
111552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    mPerModulePasses->add(createStripUnknownAttributesPass());
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() {
1163a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now we add passes for code emitting
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mCodeGenPasses) {
121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
123c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create the TargetMachine for generating code.
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Triple = mpModule->getTargetTriple();
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const llvm::Target* TargetInfo =
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      llvm::TargetRegistry::lookupTarget(Triple, Error);
1325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (TargetInfo == nullptr) {
1339207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
137ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Target Machine Options
138ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  llvm::TargetOptions Options;
139ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien
140167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // Use soft-float ABI for ARM (which is the target used by Slang during code
141167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // generation).  Codegen still uses hardware FPU by default.  To use software
142167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // floating point, add 'soft-float' feature to FeaturesStr below.
143167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  Options.FloatABIType = llvm::FloatABI::Soft;
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // BCC needs all unknown symbols resolved at compilation time. So we don't
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // need any relocation model.
147ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  llvm::Reloc::Model RM = llvm::Reloc::Static;
1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
14941ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // This is set for the linker (specify how large of the virtual addresses we
15041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // can access for all unknown symbols.)
1519207a2e495c8363606861e4f034504ec5c153dabLogan Chien  llvm::CodeModel::Model CM;
1520b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines  if (mpModule->getDataLayout().getPointerSize() == 4) {
1539207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Small;
1549207a2e495c8363606861e4f034504ec5c153dabLogan Chien  } else {
15541ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // The target may have pointer size greater than 32 (e.g. x86_64
15641ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // architecture) may need large data address model
1579207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Medium;
1589207a2e495c8363606861e4f034504ec5c153dabLogan Chien  }
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Setup feature string
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string FeaturesStr;
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SubtargetFeatures Features;
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (std::vector<std::string>::const_iterator
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Features.AddFeature(*I);
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    FeaturesStr = Features.getString();
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1739207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine *TM =
1759207a2e495c8363606861e4f034504ec5c153dabLogan Chien    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
176ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien                                    Options, RM, CM);
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register scheduler
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register allocation policy:
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //  createFastRegisterAllocator: fast but bad quality
1832c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien  //  createGreedyRegisterAllocator: not so fast but good quality
1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::createFastRegisterAllocator :
1862c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien                                     llvm::createGreedyRegisterAllocator);
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
18977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mCodeGenOpts.OptimizationLevel == 0) {
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::None;
19177703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  } else if (mCodeGenOpts.OptimizationLevel == 3) {
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::Aggressive;
19377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine::CodeGenFileType CGFT =
1966315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      llvm::TargetMachine::CGFT_AssemblyFile;
19777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mOT == Slang::OT_Object) {
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
19977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
20021cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              CGFT, OptLevel)) {
2029207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletBackend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
2102770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross                 const RSCCOptions &Opts, const clang::CodeGenOptions &CodeGenOpts,
2118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
2128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 llvm::raw_ostream *OS, Slang::OutputType OT,
2138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
2148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 bool IsFilterscript)
2158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
2168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
21721cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
21821cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mBufferOutStream(*mpOS), mContext(Context),
2192770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
2208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
2218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
222c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportForEachSignatureMetadata(nullptr), mExportReduceMetadata(nullptr),
22315e44e66adc350adb4fe0533a442092c64333ab5David Gross      mExportReduceNewMetadata(nullptr),
224c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
225c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mRefCount(mContext->getASTContext()),
2268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
227fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mForEachHandler(Context),
2288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
2298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
230c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  mGen = CreateLLVMCodeGen(mDiagEngine, "", 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
34321cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream.flush();
344462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTagDeclDefinition(D);
348462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
349462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->CompleteTentativeDefinition(D);
352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
353462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
354462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() {
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mpModule;
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mGen;
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerFunctionPasses;
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerModulePasses;
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mCodeGenPasses;
360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
361e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
3628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types
3638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) {
3648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD &&
3658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      FD->hasBody() &&
3668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
3678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Init();
3688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
3698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
3708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
3718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
372fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nivoid Backend::LowerRSForEachCall(clang::FunctionDecl *FD) {
373fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  // Skip this AST walking for lower API levels.
374fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (getTargetAPI() < SLANG_DEVELOPMENT_TARGET_API) {
375fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return;
376fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
377fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
378fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (!FD || !FD->hasBody() ||
379fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
380fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return;
381fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
382fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
383fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  mForEachHandler.VisitStmt(FD->getBody());
384fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni}
385fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
3868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
3878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
3888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
3898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
3908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
3918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
3928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
3938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
3948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
3958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
3968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
3978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
3988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
3998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
4008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
4018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
4028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
4068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
407fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    // Process any non-static function declarations
4088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (FD && FD->isGlobal()) {
4098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Check that we don't have any array parameters being misintrepeted as
4108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // kernel pointers due to the C type system's array to pointer decay.
4118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      size_t numParams = FD->getNumParams();
4128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (size_t i = 0; i < numParams; i++) {
4138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
4148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        clang::QualType QT = PVD->getOriginalType();
4158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (QT->isArrayType()) {
4168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mContext->ReportError(
4178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              PVD->getTypeSpecStartLoc(),
4188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              "exported function parameters may not have array type: %0")
4198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              << QT;
4208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
4218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      AnnotateFunction(FD);
4238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
424fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
4251946749cebf4a64341d8210890688fef7d958c22Yang Ni    if (getTargetAPI() == SLANG_DEVELOPMENT_TARGET_API) {
4261946749cebf4a64341d8210890688fef7d958c22Yang Ni      if (FD && FD->hasBody() &&
4271946749cebf4a64341d8210890688fef7d958c22Yang Ni          RSExportForEach::isRSForEachFunc(getTargetAPI(), FD)) {
4281946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Log kernels by their names, and assign them slot numbers.
4291946749cebf4a64341d8210890688fef7d958c22Yang Ni        if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
4301946749cebf4a64341d8210890688fef7d958c22Yang Ni            mContext->addForEach(FD);
4311946749cebf4a64341d8210890688fef7d958c22Yang Ni        }
4321946749cebf4a64341d8210890688fef7d958c22Yang Ni      } else {
4331946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Look for any kernel launch calls and translate them into using the
4341946749cebf4a64341d8210890688fef7d958c22Yang Ni        // internal API.
4351946749cebf4a64341d8210890688fef7d958c22Yang Ni        // TODO: Simply ignores kernel launch inside a kernel for now.
4361946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Needs more rigorous and comprehensive checks.
4371946749cebf4a64341d8210890688fef7d958c22Yang Ni        LowerRSForEachCall(FD);
438fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      }
439fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
4408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
441fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
4428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
4438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
4468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
4478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
4498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(PT->getType())));
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::StructType *HelperFunctionParameterTy = nullptr;
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          HelperFunctionParameterTy =
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (HelperFunctionParameterTy) {
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            HelperFunctionParameterTy->dump();
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (HelperFunctionParameterTy) {
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (size_t i = 0; i < EF->getNumParameters(); i++) {
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::Type::getInt32Ty(mLLVMContext), i);
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            if (isStructInput[i]) {
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
706fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
708fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          } else {
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
710fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          }
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            llvm::utostr_32(EFE->getSignatureMetadata())));
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
763c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walavoid Backend::dumpExportReduceInfo(llvm::Module *M) {
764c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (!mExportReduceMetadata) {
765c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
766c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
767c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
768c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  llvm::SmallVector<llvm::Metadata *, 1> ExportReduceInfo;
769c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
770c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Add the names of the reduce-style kernel functions to the metadata node.
771c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  for (auto I = mContext->export_reduce_begin(),
772c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala            E = mContext->export_reduce_end(); I != E; ++I) {
773c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.clear();
774c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
775c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.push_back(
776c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDString::get(mLLVMContext, (*I)->getName().c_str()));
777c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
778c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata->addOperand(
779c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDNode::get(mLLVMContext, ExportReduceInfo));
780c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
781c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala}
782c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
78315e44e66adc350adb4fe0533a442092c64333ab5David Grossvoid Backend::dumpExportReduceNewInfo(llvm::Module *M) {
78415e44e66adc350adb4fe0533a442092c64333ab5David Gross  if (!mExportReduceNewMetadata) {
78515e44e66adc350adb4fe0533a442092c64333ab5David Gross    mExportReduceNewMetadata =
78615e44e66adc350adb4fe0533a442092c64333ab5David Gross      M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_NEW_MN);
78715e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
78815e44e66adc350adb4fe0533a442092c64333ab5David Gross
78915e44e66adc350adb4fe0533a442092c64333ab5David Gross  llvm::SmallVector<llvm::Metadata *, 6> ExportReduceNewInfo;
79015e44e66adc350adb4fe0533a442092c64333ab5David Gross  // Add operand to ExportReduceNewInfo, padding out missing operands with
79115e44e66adc350adb4fe0533a442092c64333ab5David Gross  // nullptr.
79215e44e66adc350adb4fe0533a442092c64333ab5David Gross  auto addOperand = [&ExportReduceNewInfo](uint32_t Idx, llvm::Metadata *N) {
79315e44e66adc350adb4fe0533a442092c64333ab5David Gross    while (Idx > ExportReduceNewInfo.size())
79415e44e66adc350adb4fe0533a442092c64333ab5David Gross      ExportReduceNewInfo.push_back(nullptr);
79515e44e66adc350adb4fe0533a442092c64333ab5David Gross    ExportReduceNewInfo.push_back(N);
79615e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
79715e44e66adc350adb4fe0533a442092c64333ab5David Gross  // Add string operand to ExportReduceNewInfo, padding out missing operands
79815e44e66adc350adb4fe0533a442092c64333ab5David Gross  // with nullptr.
79915e44e66adc350adb4fe0533a442092c64333ab5David Gross  // If string is empty, then do not add it unless Always is true.
80015e44e66adc350adb4fe0533a442092c64333ab5David Gross  auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
80115e44e66adc350adb4fe0533a442092c64333ab5David Gross                                       bool Always = true) {
80215e44e66adc350adb4fe0533a442092c64333ab5David Gross    if (Always || !S.empty())
80315e44e66adc350adb4fe0533a442092c64333ab5David Gross      addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
80415e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
80515e44e66adc350adb4fe0533a442092c64333ab5David Gross
80615e44e66adc350adb4fe0533a442092c64333ab5David Gross  // Add the description of the reduction kernels to the metadata node.
80715e44e66adc350adb4fe0533a442092c64333ab5David Gross  for (auto I = mContext->export_reduce_new_begin(),
80815e44e66adc350adb4fe0533a442092c64333ab5David Gross            E = mContext->export_reduce_new_end();
80915e44e66adc350adb4fe0533a442092c64333ab5David Gross       I != E; ++I) {
81015e44e66adc350adb4fe0533a442092c64333ab5David Gross    ExportReduceNewInfo.clear();
81115e44e66adc350adb4fe0533a442092c64333ab5David Gross
81215e44e66adc350adb4fe0533a442092c64333ab5David Gross    addString(0, (*I)->getNameReduce());
81315e44e66adc350adb4fe0533a442092c64333ab5David Gross    addString(1, (*I)->getNameInitializer());
81415e44e66adc350adb4fe0533a442092c64333ab5David Gross
81515e44e66adc350adb4fe0533a442092c64333ab5David Gross    llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
81615e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(
81715e44e66adc350adb4fe0533a442092c64333ab5David Gross      llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
81815e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(llvm::MDString::get(
81915e44e66adc350adb4fe0533a442092c64333ab5David Gross      mLLVMContext,
82015e44e66adc350adb4fe0533a442092c64333ab5David Gross      llvm::utostr_32(0))); // TODO: emit actual accumulator signature bits
82115e44e66adc350adb4fe0533a442092c64333ab5David Gross    addOperand(2, llvm::MDTuple::get(mLLVMContext, Accumulator));
82215e44e66adc350adb4fe0533a442092c64333ab5David Gross
82315e44e66adc350adb4fe0533a442092c64333ab5David Gross    addString(3, (*I)->getNameCombiner(), false);
82415e44e66adc350adb4fe0533a442092c64333ab5David Gross    addString(4, (*I)->getNameOutConverter(), false);
82515e44e66adc350adb4fe0533a442092c64333ab5David Gross    addString(5, (*I)->getNameHalter(), false);
82615e44e66adc350adb4fe0533a442092c64333ab5David Gross
82715e44e66adc350adb4fe0533a442092c64333ab5David Gross    mExportReduceNewMetadata->addOperand(
82815e44e66adc350adb4fe0533a442092c64333ab5David Gross      llvm::MDTuple::get(mLLVMContext, ExportReduceNewInfo));
82915e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
83015e44e66adc350adb4fe0533a442092c64333ab5David Gross}
83115e44e66adc350adb4fe0533a442092c64333ab5David Gross
8328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
8338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
8348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
8368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
8378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
8388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
8398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
8408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
8418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
8428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
8448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
8458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
8468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
8478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
8498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
8508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
8608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
8638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
8648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
8658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
8678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
8688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
8698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
8708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
8718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
8728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
8738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
8758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
8768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
8778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
8798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
8808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
8818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
8828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
8848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
8858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
8868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
8878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
8888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
8928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
8948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
8958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
897fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (!mContext->processExports()) {
8988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
8998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
9008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
9028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
9038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
9058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
9068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
9088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
9098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
910c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (mContext->hasExportReduce())
911c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    dumpExportReduceInfo(M);
912c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
91315e44e66adc350adb4fe0533a442092c64333ab5David Gross  if (mContext->hasExportReduceNew())
91415e44e66adc350adb4fe0533a442092c64333ab5David Gross    dumpExportReduceNewInfo(M);
91515e44e66adc350adb4fe0533a442092c64333ab5David Gross
9168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
9178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
9188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
9198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
920e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
921