slang_backend.cpp revision 88f21e16250d2e52a75607b7f0c396e1c2a34201
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),
223c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
224c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mRefCount(mContext->getASTContext()),
2258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
226fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mForEachHandler(Context),
2278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
2288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
229c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) {
2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->Initialize(Ctx);
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mpModule = mGen->GetModule();
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
23968fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPre(Ctx);
24068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang
2412770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if (mASTPrint)
2422770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    Ctx.getTranslationUnitDecl()->dump();
2432770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTranslationUnit(Ctx);
245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here, we complete a translation unit (whole translation unit is now in LLVM
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // IR). Now, interact with LLVM backend to generate actual machine code (asm
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // or machine code, whatever.)
249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Silently ignore if we weren't initialized for some reason.
25141ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  if (!mpModule)
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::Module *M = mGen->ReleaseModule();
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!M) {
2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The module has been released by IR gen on failures, do not double free.
2575abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    mpModule = nullptr;
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(mpModule == M &&
2626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Unexpected module change during LLVM IR generation");
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Insert #pragma information into metadata section of module
2653fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  if (!mPragmas->empty()) {
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::NamedMDNode *PragmaMetadata =
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
2683fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
271c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Name goes first
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // And then value
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
27683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Create MDNode and insert into PragmaMetadata
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PragmaMetadata->addOperand(
27918c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines          llvm::MDNode::get(mLLVMContext, Pragma));
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
28368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPost(mpModule);
284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create passes for optimization and code emission
286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run per-function passes
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateFunctionPasses();
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerFunctionPasses) {
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doInitialization();
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!I->isDeclaration())
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mPerFunctionPasses->run(*I);
297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doFinalization();
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run module passes
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateModulePasses();
3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerModulePasses)
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerModulePasses->run(*mpModule);
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3063a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
3073a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Assembly:
3083a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Object: {
3096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!CreateCodeGenPasses())
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
311462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doInitialization();
313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I != E;
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I++)
3176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        if (!I->isDeclaration())
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mCodeGenPasses->run(*I);
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doFinalization();
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_LLVMAssembly: {
324c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
32521cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      LLEmitPM->run(*mpModule);
3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3293a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Bitcode: {
330dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
331b130e157d3a5c2256e7aa0005d7134f3ac060c56Stephen McGroarty                   mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
3329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Nothing: {
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      return;
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
3386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown output type");
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
34221cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream.flush();
343462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
344462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTagDeclDefinition(D);
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
348462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->CompleteTentativeDefinition(D);
351462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
353462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() {
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mpModule;
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mGen;
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerFunctionPasses;
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerModulePasses;
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mCodeGenPasses;
359462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
360e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
3618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types
3628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) {
3638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD &&
3648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      FD->hasBody() &&
3658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
3668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Init();
3678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
3688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
3698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
3708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
371fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Nivoid Backend::LowerRSForEachCall(clang::FunctionDecl *FD) {
372fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  // Skip this AST walking for lower API levels.
373fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (getTargetAPI() < SLANG_DEVELOPMENT_TARGET_API) {
374fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return;
375fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
376fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
377fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (!FD || !FD->hasBody() ||
378fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
379fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    return;
380fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  }
381fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
382fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  mForEachHandler.VisitStmt(FD->getBody());
383fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni}
384fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
3858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
38688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  // Find and remember the TypeDecl for rs_allocation so we can use it
38788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  // later during the compilation
38888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  if (mContext->getAllocationType().isNull()) {
38988f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
39088f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni         I != E; I++) {
39188f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni      clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I);
39288f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni      if (TD && TD->getName().equals("rs_allocation")) {
39388f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni        mContext->setAllocationType(TD);
39488f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni        break;
39588f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni      }
39688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni    }
39788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  }
39888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni
3998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
4008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
4018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
4028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
4038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
4048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
4058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
4068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
4078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
4088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
4098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
4108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
4118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
4128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
4138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
4148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
4188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
419fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    // Process any non-static function declarations
4208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (FD && FD->isGlobal()) {
4218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Check that we don't have any array parameters being misintrepeted as
4228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // kernel pointers due to the C type system's array to pointer decay.
4238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      size_t numParams = FD->getNumParams();
4248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (size_t i = 0; i < numParams; i++) {
4258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
4268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        clang::QualType QT = PVD->getOriginalType();
4278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (QT->isArrayType()) {
4288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mContext->ReportError(
4298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              PVD->getTypeSpecStartLoc(),
4308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              "exported function parameters may not have array type: %0")
4318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              << QT;
4328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
4338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      AnnotateFunction(FD);
4358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
436fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
4371946749cebf4a64341d8210890688fef7d958c22Yang Ni    if (getTargetAPI() == SLANG_DEVELOPMENT_TARGET_API) {
4381946749cebf4a64341d8210890688fef7d958c22Yang Ni      if (FD && FD->hasBody() &&
4391946749cebf4a64341d8210890688fef7d958c22Yang Ni          RSExportForEach::isRSForEachFunc(getTargetAPI(), FD)) {
4401946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Log kernels by their names, and assign them slot numbers.
4411946749cebf4a64341d8210890688fef7d958c22Yang Ni        if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
4421946749cebf4a64341d8210890688fef7d958c22Yang Ni            mContext->addForEach(FD);
4431946749cebf4a64341d8210890688fef7d958c22Yang Ni        }
4441946749cebf4a64341d8210890688fef7d958c22Yang Ni      } else {
4451946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Look for any kernel launch calls and translate them into using the
4461946749cebf4a64341d8210890688fef7d958c22Yang Ni        // internal API.
4471946749cebf4a64341d8210890688fef7d958c22Yang Ni        // TODO: Simply ignores kernel launch inside a kernel for now.
4481946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Needs more rigorous and comprehensive checks.
4491946749cebf4a64341d8210890688fef7d958c22Yang Ni        LowerRSForEachCall(FD);
450fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      }
451fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
453fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(PT->getType())));
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::StructType *HelperFunctionParameterTy = nullptr;
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          HelperFunctionParameterTy =
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (HelperFunctionParameterTy) {
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            HelperFunctionParameterTy->dump();
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (HelperFunctionParameterTy) {
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (size_t i = 0; i < EF->getNumParameters(); i++) {
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::Type::getInt32Ty(mLLVMContext), i);
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            if (isStructInput[i]) {
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
718fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
720fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          } else {
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
722fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          }
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            llvm::utostr_32(EFE->getSignatureMetadata())));
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
775c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walavoid Backend::dumpExportReduceInfo(llvm::Module *M) {
776c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (!mExportReduceMetadata) {
777c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
778c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
779c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
780c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  llvm::SmallVector<llvm::Metadata *, 1> ExportReduceInfo;
781c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
782c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Add the names of the reduce-style kernel functions to the metadata node.
783c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  for (auto I = mContext->export_reduce_begin(),
784c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala            E = mContext->export_reduce_end(); I != E; ++I) {
785c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.clear();
786c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
787c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.push_back(
788c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDString::get(mLLVMContext, (*I)->getName().c_str()));
789c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
790c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata->addOperand(
791c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDNode::get(mLLVMContext, ExportReduceInfo));
792c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
793c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala}
794c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
7958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
7968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
7978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
7998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
8008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
8018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
8028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
8038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
8048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
8058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
8078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
8088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
8098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
8108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
8128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
8138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
8148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
8168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
8178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
8188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
8208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
8218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
8238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
8248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
8258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
8268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
8278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
8288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
8308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
8318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
8328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
8338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
8348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
8358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
8368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
8388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
8398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
8408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
8428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
8438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
8448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
8458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
8478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
8488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
8498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
8508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
860fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni  if (!mContext->processExports()) {
8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
8658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
8668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
8688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
8698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
8718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
8728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
873c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (mContext->hasExportReduce())
874c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    dumpExportReduceInfo(M);
875c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
8768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
8778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
8788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
880e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
881