slang_backend.cpp revision c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9
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
74552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines#include "strip_unknown_attributes.h"
756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
76e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
783a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateFunctionPasses() {
793a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerFunctionPasses) {
80c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerFunctionPasses = new llvm::legacy::FunctionPassManager(mpModule);
813a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
82fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
83fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
84fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
863a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
873a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
883a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Changvoid Backend::CreateModulePasses() {
893a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if (!mPerModulePasses) {
90c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mPerModulePasses = new llvm::legacy::PassManager();
913a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
92fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    llvm::PassManagerBuilder PMBuilder;
93fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
94fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
95fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnitAtATime) {
96fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 0;
97fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
98fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnitAtATime = 1;
99fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
100fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
101fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    if (mCodeGenOpts.UnrollLoops) {
102fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 0;
103fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    } else {
104fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao      PMBuilder.DisableUnrollLoops = 1;
105fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    }
106fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
107fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao    PMBuilder.populateModulePassManager(*mPerModulePasses);
108552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    // Add a pass to strip off unknown/unsupported attributes.
109552d872e5cdc883d9f8e76d8c67d3a82e3ece488Stephen Hines    mPerModulePasses->add(createStripUnknownAttributesPass());
1103a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  }
1113a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang}
1123a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang
113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() {
1143a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return true;
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Now we add passes for code emitting
1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mCodeGenPasses) {
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return true;
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
121c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines    mCodeGenPasses = new llvm::legacy::FunctionPassManager(mpModule);
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create the TargetMachine for generating code.
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Triple = mpModule->getTargetTriple();
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string Error;
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const llvm::Target* TargetInfo =
1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      llvm::TargetRegistry::lookupTarget(Triple, Error);
1305abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes  if (TargetInfo == nullptr) {
1319207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
135ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Target Machine Options
136ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  llvm::TargetOptions Options;
137ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien
138167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // Use soft-float ABI for ARM (which is the target used by Slang during code
139167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // generation).  Codegen still uses hardware FPU by default.  To use software
140167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  // floating point, add 'soft-float' feature to FeaturesStr below.
141167bd79e95d496474346fcb9b2905d42ab55d750Pirama Arumuga Nainar  Options.FloatABIType = llvm::FloatABI::Soft;
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // BCC needs all unknown symbols resolved at compilation time. So we don't
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // need any relocation model.
145ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  llvm::Reloc::Model RM = llvm::Reloc::Static;
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
14741ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // This is set for the linker (specify how large of the virtual addresses we
14841ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // can access for all unknown symbols.)
1499207a2e495c8363606861e4f034504ec5c153dabLogan Chien  llvm::CodeModel::Model CM;
1500b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines  if (mpModule->getDataLayout().getPointerSize() == 4) {
1519207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Small;
1529207a2e495c8363606861e4f034504ec5c153dabLogan Chien  } else {
15341ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // The target may have pointer size greater than 32 (e.g. x86_64
15441ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // architecture) may need large data address model
1559207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Medium;
1569207a2e495c8363606861e4f034504ec5c153dabLogan Chien  }
1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Setup feature string
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string FeaturesStr;
1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SubtargetFeatures Features;
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (std::vector<std::string>::const_iterator
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Features.AddFeature(*I);
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    FeaturesStr = Features.getString();
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1719207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine *TM =
1739207a2e495c8363606861e4f034504ec5c153dabLogan Chien    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
174ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien                                    Options, RM, CM);
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register scheduler
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
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,
2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                 const clang::CodeGenOptions &CodeGenOpts,
2098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
2108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 llvm::raw_ostream *OS, Slang::OutputType OT,
2118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
2128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 bool IsFilterscript)
2138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
2148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
21521cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
21621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mBufferOutStream(*mpOS), mContext(Context),
2178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mSourceMgr(SourceMgr), mAllowRSPrefix(AllowRSPrefix),
2188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
2198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
220c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportForEachSignatureMetadata(nullptr), mExportReduceMetadata(nullptr),
221c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mExportTypeMetadata(nullptr), mRSObjectSlotsMetadata(nullptr),
222c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      mRefCount(mContext->getASTContext()),
2238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
2248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
2258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
226c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) {
2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->Initialize(Ctx);
231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mpModule = mGen->GetModule();
233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
23668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPre(Ctx);
23768fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTranslationUnit(Ctx);
239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here, we complete a translation unit (whole translation unit is now in LLVM
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // IR). Now, interact with LLVM backend to generate actual machine code (asm
2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // or machine code, whatever.)
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Silently ignore if we weren't initialized for some reason.
24541ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  if (!mpModule)
2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::Module *M = mGen->ReleaseModule();
2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!M) {
2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The module has been released by IR gen on failures, do not double free.
2515abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    mpModule = nullptr;
2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2556e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(mpModule == M &&
2566e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Unexpected module change during LLVM IR generation");
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Insert #pragma information into metadata section of module
2593fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  if (!mPragmas->empty()) {
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::NamedMDNode *PragmaMetadata =
2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
2623fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
265c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Name goes first
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // And then value
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
27083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Create MDNode and insert into PragmaMetadata
2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PragmaMetadata->addOperand(
27318c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines          llvm::MDNode::get(mLLVMContext, Pragma));
274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
27768fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPost(mpModule);
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create passes for optimization and code emission
280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run per-function passes
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateFunctionPasses();
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerFunctionPasses) {
2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doInitialization();
285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!I->isDeclaration())
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mPerFunctionPasses->run(*I);
291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doFinalization();
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run module passes
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateModulePasses();
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerModulePasses)
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerModulePasses->run(*mpModule);
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3003a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
3013a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Assembly:
3023a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Object: {
3036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!CreateCodeGenPasses())
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doInitialization();
307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I != E;
3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I++)
3116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        if (!I->isDeclaration())
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mCodeGenPasses->run(*I);
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doFinalization();
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3173a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_LLVMAssembly: {
318c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
31921cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      LLEmitPM->run(*mpModule);
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3233a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Bitcode: {
324dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala      writeBitcode(mBufferOutStream, *mpModule, getTargetAPI(),
325dabd246c169fe8bc7d80a31779311bfc583b2ea0Matt Wala                   mCodeGenOpts.OptimizationLevel);
3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3283a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Nothing: {
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      return;
3309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
3326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown output type");
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
33621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream.flush();
337462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTagDeclDefinition(D);
341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->CompleteTentativeDefinition(D);
345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
346462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() {
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mpModule;
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mGen;
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerFunctionPasses;
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerModulePasses;
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mCodeGenPasses;
353462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
354e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
3558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types
3568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) {
3578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD &&
3588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      FD->hasBody() &&
3598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
3608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Init();
3618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
3628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
3638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
3648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
3658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
3668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
3678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
3688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
3698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
3708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
3718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
3728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
3738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
3748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
3758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
3768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
3778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
3788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
3798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
3808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
3818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
3828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
3838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
3848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any non-static function declarations
3858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
3868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
3878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (FD && FD->isGlobal()) {
3888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Check that we don't have any array parameters being misintrepeted as
3898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // kernel pointers due to the C type system's array to pointer decay.
3908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      size_t numParams = FD->getNumParams();
3918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (size_t i = 0; i < numParams; i++) {
3928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
3938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        clang::QualType QT = PVD->getOriginalType();
3948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (QT->isArrayType()) {
3958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mContext->ReportError(
3968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              PVD->getTypeSpecStartLoc(),
3978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              "exported function parameters may not have array type: %0")
3988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              << QT;
3998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
4008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      AnnotateFunction(FD);
4028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
4058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
4088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
4098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
4118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
4128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
4168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
4178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
4208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
4218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
4228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
4258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
4268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
4278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
4298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
4328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
4358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
4368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
4378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
4388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
4428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
4438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
4448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
4458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
4468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
4498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(PT->getType())));
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::StructType *HelperFunctionParameterTy = nullptr;
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          HelperFunctionParameterTy =
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (HelperFunctionParameterTy) {
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            HelperFunctionParameterTy->dump();
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (HelperFunctionParameterTy) {
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (size_t i = 0; i < EF->getNumParameters(); i++) {
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::Type::getInt32Ty(mLLVMContext), i);
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            if (isStructInput[i]) {
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          else
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            llvm::utostr_32(EFE->getSignatureMetadata())));
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
724c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Walavoid Backend::dumpExportReduceInfo(llvm::Module *M) {
725c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (!mExportReduceMetadata) {
726c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_REDUCE_MN);
727c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
728c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
729c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  llvm::SmallVector<llvm::Metadata *, 1> ExportReduceInfo;
730c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
731c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  // Add the names of the reduce-style kernel functions to the metadata node.
732c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  for (auto I = mContext->export_reduce_begin(),
733c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala            E = mContext->export_reduce_end(); I != E; ++I) {
734c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.clear();
735c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
736c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    ExportReduceInfo.push_back(
737c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDString::get(mLLVMContext, (*I)->getName().c_str()));
738c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
739c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    mExportReduceMetadata->addOperand(
740c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala      llvm::MDNode::get(mLLVMContext, ExportReduceInfo));
741c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  }
742c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala}
743c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
7798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
7808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
7818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
7828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
7838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
7848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
7858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
7878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
7888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
7898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
7918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
7928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
7938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
7948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
7968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
7978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
7988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
8008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
8048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
8068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
8078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->processExport()) {
8108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
8118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
8148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
8158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
8178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
8188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
8208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
8218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
822c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala  if (mContext->hasExportReduce())
823c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala    dumpExportReduceInfo(M);
824c0c5dd85f2d2df2bcf0cb284001f544d6c42eff9Matt Wala
8258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
8268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
8278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
829e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
830