slang_backend.cpp revision 8ee018bdb53fc5abdc430878e2bec0c0c0aa560f
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"
2365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross#include "clang/AST/Attr.h"
249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h"
259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h"
26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/Diagnostic.h"
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TargetOptions.h"
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/CodeGen/ModuleBuilder.h"
32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
333a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h"
35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/Twine.h"
378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/StringExtras.h"
38e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/RegAllocRegistry.h"
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/SchedulerRegistry.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constant.h"
458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constants.h"
468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DataLayout.h"
478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DebugLoc.h"
488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DerivedTypes.h"
498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Function.h"
508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRBuilder.h"
518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRPrintingPasses.h"
5223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
5323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h"
548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Module.h"
55e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
569207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h"
57fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
58e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetMachine.h"
59e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetOptions.h"
609207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetRegistry.h"
6177703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao
6277703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao#include "llvm/MC/SubtargetFeature.h"
63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h"
66dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala#include "slang_bitcode_gen.h"
678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_context.h"
688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_foreach.h"
698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_func.h"
70c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala#include "slang_rs_export_reduce.h"
718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_type.h"
728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_export_var.h"
738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang_rs_metadata.h"
748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
752770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross#include "rs_cc_options.h"
762770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
77552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines#include "strip_unknown_attributes.h"
786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
79e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateFunctionPasses() {
823a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerFunctionPasses) {
83c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
843a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
85fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
86fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
87fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
903a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateModulePasses() {
923a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerModulePasses) {
93c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerModulePasses = new llvm::legacy::PassManager();
943a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
95fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
96fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
97fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
98fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnitAtATime) {
99fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 0;
100fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
101fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 1;
102fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
103fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
104fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnrollLoops) {
105fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 0;
106fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
107fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 1;
108fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
109fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
110fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateModulePassManager(*mPerModulePasses);
111552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    // Add a pass to strip off unknown/unsupported attributes.
112552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    mPerModulePasses->add(createStripUnknownAttributesPass());
1133a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1153a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() {
1173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now we add passes for code emitting
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mCodeGenPasses) {
122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
124c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create the TargetMachine for generating code.
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Triple = mpModule->getTargetTriple();
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const llvm::Target* TargetInfo =
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      llvm::TargetRegistry::lookupTarget(Triple, Error);
1335abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (TargetInfo == nullptr) {
1349207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
138ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Target Machine Options
139ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  llvm::TargetOptions Options;
140ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien
141167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // Use soft-float ABI for ARM (which is the target used by Slang during code
142167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // generation).  Codegen still uses hardware FPU by default.  To use software
143167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // floating point, add 'soft-float' feature to FeaturesStr below.
144167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  Options.FloatABIType = llvm::FloatABI::Soft;
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // BCC needs all unknown symbols resolved at compilation time. So we don't
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // need any relocation model.
148ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  llvm::Reloc::Model RM = llvm::Reloc::Static;
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
15041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // This is set for the linker (specify how large of the virtual addresses we
15141ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // can access for all unknown symbols.)
1529207a2e495c8363606861e4f034504ec5c153dabLogan Chien  llvm::CodeModel::Model CM;
1530b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines  if (mpModule->getDataLayout().getPointerSize() == 4) {
1549207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Small;
1559207a2e495c8363606861e4f034504ec5c153dabLogan Chien  } else {
15641ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // The target may have pointer size greater than 32 (e.g. x86_64
15741ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // architecture) may need large data address model
1589207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Medium;
1599207a2e495c8363606861e4f034504ec5c153dabLogan Chien  }
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Setup feature string
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string FeaturesStr;
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SubtargetFeatures Features;
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (std::vector<std::string>::const_iterator
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Features.AddFeature(*I);
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    FeaturesStr = Features.getString();
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1749207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine *TM =
1769207a2e495c8363606861e4f034504ec5c153dabLogan Chien    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
177ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien                                    Options, RM, CM);
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register allocation policy:
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //  createFastRegisterAllocator: fast but bad quality
1812c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien  //  createGreedyRegisterAllocator: not so fast but good quality
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::createFastRegisterAllocator :
1842c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien                                     llvm::createGreedyRegisterAllocator);
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
18777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mCodeGenOpts.OptimizationLevel == 0) {
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::None;
18977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  } else if (mCodeGenOpts.OptimizationLevel == 3) {
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::Aggressive;
19177703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine::CodeGenFileType CGFT =
1946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      llvm::TargetMachine::CGFT_AssemblyFile;
19577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mOT == Slang::OT_Object) {
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
19777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
19821cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
1999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              CGFT, OptLevel)) {
2009207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
2019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletBackend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
2088f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const RSCCOptions &Opts,
2098f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::HeaderSearchOptions &HeaderSearchOpts,
2108f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::PreprocessorOptions &PreprocessorOpts,
2118f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar                 const clang::CodeGenOptions &CodeGenOpts,
2128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
2138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 llvm::raw_ostream *OS, Slang::OutputType OT,
2148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
2158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 bool IsFilterscript)
2168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
2178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
21821cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
21921cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mBufferOutStream(*mpOS), mContext(Context),
2202770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross      mSourceMgr(SourceMgr), mASTPrint(Opts.mASTPrint), mAllowRSPrefix(AllowRSPrefix),
2218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
2228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
223dbf5b61ea24012f883e238fd17bdca0758f181d6David Gross      mExportForEachSignatureMetadata(nullptr),
2248ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      mExportReduceMetadata(nullptr),
225c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
226c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mRefCount(mContext->getASTContext()),
2278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
228fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      mForEachHandler(Context),
2298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
2308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
2318f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar  mGen = CreateLLVMCodeGen(mDiagEngine, "", HeaderSearchOpts, PreprocessorOpts,
2328f093e05e28046b6fc74175b66a06152f72e0c66Pirama Arumuga Nainar      mCodeGenOpts, mLLVMContext);
233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) {
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->Initialize(Ctx);
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mpModule = mGen->GetModule();
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
24268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPre(Ctx);
24368fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang
2442770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross  if (mASTPrint)
2452770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross    Ctx.getTranslationUnitDecl()->dump();
2462770d0e31ef3b14cd51ca07273240ad0995dc5cdDavid Gross
2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTranslationUnit(Ctx);
248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here, we complete a translation unit (whole translation unit is now in LLVM
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // IR). Now, interact with LLVM backend to generate actual machine code (asm
2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // or machine code, whatever.)
252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Silently ignore if we weren't initialized for some reason.
25441ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  if (!mpModule)
2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::Module *M = mGen->ReleaseModule();
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!M) {
2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The module has been released by IR gen on failures, do not double free.
2605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    mpModule = nullptr;
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(mpModule == M &&
2656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Unexpected module change during LLVM IR generation");
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Insert #pragma information into metadata section of module
2683fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  if (!mPragmas->empty()) {
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::NamedMDNode *PragmaMetadata =
2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
2713fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
274c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Name goes first
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // And then value
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
27983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao
2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Create MDNode and insert into PragmaMetadata
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PragmaMetadata->addOperand(
28218c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines          llvm::MDNode::get(mLLVMContext, Pragma));
283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
28668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPost(mpModule);
287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create passes for optimization and code emission
289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run per-function passes
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateFunctionPasses();
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerFunctionPasses) {
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doInitialization();
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!I->isDeclaration())
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mPerFunctionPasses->run(*I);
300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doFinalization();
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run module passes
3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateModulePasses();
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerModulePasses)
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerModulePasses->run(*mpModule);
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3093a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
3103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Assembly:
3113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Object: {
3126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!CreateCodeGenPasses())
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doInitialization();
316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I != E;
3199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I++)
3206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        if (!I->isDeclaration())
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mCodeGenPasses->run(*I);
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doFinalization();
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_LLVMAssembly: {
327c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
32821cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      LLEmitPM->run(*mpModule);
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
331462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3323a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Bitcode: {
333dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
334b130e157d3a5c2256e7aa0005d7134f3ac060c56Stephen McGroarty                   mCodeGenOpts.OptimizationLevel, mCodeGenOpts.getDebugInfo());
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3373a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Nothing: {
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      return;
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
3416e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown output type");
3429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
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();
368283a6cf32b808c703b219862ac491df3c9fc8b4bYang Ni    mRefCount.SetDeclContext(FD);
3698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
3708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
3718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
3728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
3738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
3742615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  // Find and remember the types for rs_allocation and rs_script_call_t so
3752615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  // they can be used later for translating rsForEach() calls.
3762615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
3772615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni       (mContext->getAllocationType().isNull() ||
3782615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni        mContext->getScriptCallType().isNull()) &&
3792615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni       I != E; I++) {
3802615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni    if (clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(*I)) {
3812615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      clang::StringRef TypeName = TD->getName();
3822615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      if (TypeName.equals("rs_allocation")) {
38388f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni        mContext->setAllocationType(TD);
3842615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni      } else if (TypeName.equals("rs_script_call_t")) {
3852615f383dfc1542a05f19aee23b03a09bd018f4eYang Ni        mContext->setScriptCallType(TD);
38688f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni      }
38788f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni    }
38888f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni  }
38988f21e16250d2e52a75607b7f0c396e1c2a34201Yang Ni
3908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
3918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
3928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
3938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
3948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
3958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
3968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
3978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
3988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
3998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
4008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
4018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
4028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
4038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
4048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
4058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
4098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
41065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    if (FD) {
4115e306b944425a952fe744f59d828538137a59375David Gross      // Handle forward reference from pragma (see
4125e306b944425a952fe744f59d828538137a59375David Gross      // RSReducePragmaHandler::HandlePragma for backward reference).
4135e306b944425a952fe744f59d828538137a59375David Gross      mContext->markUsedByReducePragma(FD, RSContext::CheckNameYes);
41465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      if (FD->isGlobal()) {
41565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        // Check that we don't have any array parameters being misinterpreted as
41665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        // kernel pointers due to the C type system's array to pointer decay.
41765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        size_t numParams = FD->getNumParams();
41865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        for (size_t i = 0; i < numParams; i++) {
41965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
42065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          clang::QualType QT = PVD->getOriginalType();
42165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          if (QT->isArrayType()) {
42265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross            mContext->ReportError(
42365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                PVD->getTypeSpecStartLoc(),
42465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                "exported function parameters may not have array type: %0")
42565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross                << QT;
42665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross          }
4278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
42865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross        AnnotateFunction(FD);
4298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
431fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
43240bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni    if (getTargetAPI() >= SLANG_FEATURE_SINGLE_SOURCE_API) {
4331946749cebf4a64341d8210890688fef7d958c22Yang Ni      if (FD && FD->hasBody() &&
4349319dfc974a82794d46e9f474f316590f480b976Yang Ni          !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
43540bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni        if (FD->hasAttr<clang::KernelAttr>()) {
43640bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // Log functions with attribute "kernel" by their names, and assign
43740bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // them slot numbers. Any other function cannot be used in a
43840bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // rsForEach() or rsForEachWithOptions() call, including old-style
43940bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni          // kernel functions which are defined without the "kernel" attribute.
4409319dfc974a82794d46e9f474f316590f480b976Yang Ni          mContext->addForEach(FD);
4411946749cebf4a64341d8210890688fef7d958c22Yang Ni        }
4421946749cebf4a64341d8210890688fef7d958c22Yang Ni        // Look for any kernel launch calls and translate them into using the
4431946749cebf4a64341d8210890688fef7d958c22Yang Ni        // internal API.
44440bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfaYang Ni        // Report a compiler error on kernel launches inside a kernel.
4459319dfc974a82794d46e9f474f316590f480b976Yang Ni        mForEachHandler.handleForEachCalls(FD, getTargetAPI());
446fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni      }
447fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni    }
4488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
449fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4565e306b944425a952fe744f59d828538137a59375David Gross  if (!mContext->processReducePragmas(this))
45765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    return;
45865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(PT->getType())));
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::StructType *HelperFunctionParameterTy = nullptr;
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          HelperFunctionParameterTy =
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (HelperFunctionParameterTy) {
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            HelperFunctionParameterTy->dump();
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (HelperFunctionParameterTy) {
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (size_t i = 0; i < EF->getNumParameters(); i++) {
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::Type::getInt32Ty(mLLVMContext), i);
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            if (isStructInput[i]) {
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
717fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext)) {
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
719fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          } else {
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
721fb40ee2a90f37967bf4a40a18dec7f60e5c580d8Yang Ni          }
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            llvm::utostr_32(EFE->getSignatureMetadata())));
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7748ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Grossvoid Backend::dumpExportReduceInfo(llvm::Module *M) {
7758ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  if (!mExportReduceMetadata) {
7768ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    mExportReduceMetadata =
7778ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
77815e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
77915e44e66adc350adb4fe0533a442092c64333ab5David Gross
7808ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  llvm::SmallVector<llvm::Metadata *, 6> ExportReduceInfo;
7818ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  // Add operand to ExportReduceInfo, padding out missing operands with
78215e44e66adc350adb4fe0533a442092c64333ab5David Gross  // nullptr.
7838ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  auto addOperand = [&ExportReduceInfo](uint32_t Idx, llvm::Metadata *N) {
7848ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    while (Idx > ExportReduceInfo.size())
7858ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      ExportReduceInfo.push_back(nullptr);
7868ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    ExportReduceInfo.push_back(N);
78715e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
7888ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  // Add string operand to ExportReduceInfo, padding out missing operands
78915e44e66adc350adb4fe0533a442092c64333ab5David Gross  // with nullptr.
79015e44e66adc350adb4fe0533a442092c64333ab5David Gross  // If string is empty, then do not add it unless Always is true.
79115e44e66adc350adb4fe0533a442092c64333ab5David Gross  auto addString = [&addOperand, this](uint32_t Idx, const std::string &S,
79215e44e66adc350adb4fe0533a442092c64333ab5David Gross                                       bool Always = true) {
79315e44e66adc350adb4fe0533a442092c64333ab5David Gross    if (Always || !S.empty())
79415e44e66adc350adb4fe0533a442092c64333ab5David Gross      addOperand(Idx, llvm::MDString::get(mLLVMContext, S));
79515e44e66adc350adb4fe0533a442092c64333ab5David Gross  };
79615e44e66adc350adb4fe0533a442092c64333ab5David Gross
79715e44e66adc350adb4fe0533a442092c64333ab5David Gross  // Add the description of the reduction kernels to the metadata node.
7988ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  for (auto I = mContext->export_reduce_begin(),
7998ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross            E = mContext->export_reduce_end();
80015e44e66adc350adb4fe0533a442092c64333ab5David Gross       I != E; ++I) {
8018ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    ExportReduceInfo.clear();
80215e44e66adc350adb4fe0533a442092c64333ab5David Gross
80365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    int Idx = 0;
80465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
80565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameReduce());
80665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross
80765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addOperand(Idx++, llvm::MDString::get(mLLVMContext, llvm::utostr_32((*I)->getAccumulatorTypeSize())));
80815e44e66adc350adb4fe0533a442092c64333ab5David Gross
80915e44e66adc350adb4fe0533a442092c64333ab5David Gross    llvm::SmallVector<llvm::Metadata *, 2> Accumulator;
81015e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(
81115e44e66adc350adb4fe0533a442092c64333ab5David Gross      llvm::MDString::get(mLLVMContext, (*I)->getNameAccumulator()));
81215e44e66adc350adb4fe0533a442092c64333ab5David Gross    Accumulator.push_back(llvm::MDString::get(
81315e44e66adc350adb4fe0533a442092c64333ab5David Gross      mLLVMContext,
81465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross      llvm::utostr_32((*I)->getAccumulatorSignatureMetadata())));
81565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addOperand(Idx++, llvm::MDTuple::get(mLLVMContext, Accumulator));
81615e44e66adc350adb4fe0533a442092c64333ab5David Gross
81765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameInitializer(), false);
81865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameCombiner(), false);
81965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameOutConverter(), false);
82065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross    addString(Idx++, (*I)->getNameHalter(), false);
82115e44e66adc350adb4fe0533a442092c64333ab5David Gross
8228ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    mExportReduceMetadata->addOperand(
8238ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross      llvm::MDTuple::get(mLLVMContext, ExportReduceInfo));
82415e44e66adc350adb4fe0533a442092c64333ab5David Gross  }
82515e44e66adc350adb4fe0533a442092c64333ab5David Gross}
82615e44e66adc350adb4fe0533a442092c64333ab5David Gross
8278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
8288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
8298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
8318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
8328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
8338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
8348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
8358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
8368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
8378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
8398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
8408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
8418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
8428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
8448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
8458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
8468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
8488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
8498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
8508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
8608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
8638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
8648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
8658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
8668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
8678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
8688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
8708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
8718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
8728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
8748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
8758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
8768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
8778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
8798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
8808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
8818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
8828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
8838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
8878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
8898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
8908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
89265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross  if (!mContext->processExports())
8938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
8948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
8968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
8978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
8998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
9008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
9028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
9038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
9048ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross  if (mContext->hasExportReduce())
9058ee018bdb53fc5abdc430878e2bec0c0c0aa560fDavid Gross    dumpExportReduceInfo(M);
90615e44e66adc350adb4fe0533a442092c64333ab5David Gross
9078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
9088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
9098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
9108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
911e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
912