slang_backend.cpp revision 21cc01860b95cad7ae60c686e511e8f4ae034e39
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
225e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines#include "bcinfo/BitcodeWrapper.h"
235e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/ASTContext.h"
259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h"
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/DeclGroup.h"
27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/Diagnostic.h"
29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/TargetInfo.h"
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/TargetOptions.h"
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/CodeGen/ModuleBuilder.h"
33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
343a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang#include "clang/Frontend/CodeGenOptions.h"
359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h"
36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/Twine.h"
388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/ADT/StringExtras.h"
39e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Bitcode/ReaderWriter.h"
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/RegAllocRegistry.h"
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/CodeGen/SchedulerRegistry.h"
44e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constant.h"
468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Constants.h"
478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DataLayout.h"
488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DebugLoc.h"
498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/DerivedTypes.h"
508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Function.h"
518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRBuilder.h"
528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/IRPrintingPasses.h"
5323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/LLVMContext.h"
5423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Metadata.h"
558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "llvm/IR/Module.h"
56e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
579207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Transforms/IPO/PassManagerBuilder.h"
58fcc654a1f4034978f7534479f9c5c33a92ca8546Shih-wei Liao
59e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetMachine.h"
60e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Target/TargetOptions.h"
619207a2e495c8363606861e4f034504ec5c153dabLogan Chien#include "llvm/Support/TargetRegistry.h"
6277703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao
6377703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao#include "llvm/MC/SubtargetFeature.h"
64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h"
668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.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"
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"
754cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include "BitWriter_2_9/ReaderWriter_2_9.h"
769b044ec938fd56355012851890c63974c8042c9fStephen Hines#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
77d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines#include "BitWriter_3_2/ReaderWriter_3_2.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
141ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Use hardware FPU.
1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // FIXME: Need to detect the CPU capability and decide whether to use softfp.
1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // To use softfp, change following 2 lines to
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //
148ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Options.FloatABIType = llvm::FloatABI::Soft;
149ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  // Options.UseSoftFloat = true;
150ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  Options.FloatABIType = llvm::FloatABI::Hard;
151ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien  Options.UseSoftFloat = false;
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // BCC needs all unknown symbols resolved at compilation time. So we don't
1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // need any relocation model.
155ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  llvm::Reloc::Model RM = llvm::Reloc::Static;
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
15741ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // This is set for the linker (specify how large of the virtual addresses we
15841ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  // can access for all unknown symbols.)
1599207a2e495c8363606861e4f034504ec5c153dabLogan Chien  llvm::CodeModel::Model CM;
1600b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines  if (mpModule->getDataLayout().getPointerSize() == 4) {
1619207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Small;
1629207a2e495c8363606861e4f034504ec5c153dabLogan Chien  } else {
16341ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // The target may have pointer size greater than 32 (e.g. x86_64
16441ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang    // architecture) may need large data address model
1659207a2e495c8363606861e4f034504ec5c153dabLogan Chien    CM = llvm::CodeModel::Medium;
1669207a2e495c8363606861e4f034504ec5c153dabLogan Chien  }
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Setup feature string
1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  std::string FeaturesStr;
1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::SubtargetFeatures Features;
1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (std::vector<std::string>::const_iterator
1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Features.AddFeature(*I);
1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    FeaturesStr = Features.getString();
1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1819207a2e495c8363606861e4f034504ec5c153dabLogan Chien
1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine *TM =
1839207a2e495c8363606861e4f034504ec5c153dabLogan Chien    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
184ac4e18584b8768b3f68535fa5f16232e03974323Logan Chien                                    Options, RM, CM);
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register scheduler
1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Register allocation policy:
1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  //  createFastRegisterAllocator: fast but bad quality
1912c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien  //  createGreedyRegisterAllocator: not so fast but good quality
1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     llvm::createFastRegisterAllocator :
1942c6bad5038d8509466b9e0f9aa6a8ae533c0e029Logan Chien                                     llvm::createGreedyRegisterAllocator);
1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
19777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mCodeGenOpts.OptimizationLevel == 0) {
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::None;
19977703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  } else if (mCodeGenOpts.OptimizationLevel == 3) {
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    OptLevel = llvm::CodeGenOpt::Aggressive;
20177703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::TargetMachine::CodeGenFileType CGFT =
2046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      llvm::TargetMachine::CGFT_AssemblyFile;
20577703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  if (mOT == Slang::OT_Object) {
2069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
20777703262b9c2fecc22287ca236daa72b2cea7d27Shih-wei Liao  }
20821cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  if (TM->addPassesToEmitFile(*mCodeGenPasses, mBufferOutStream,
2099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              CGFT, OptLevel)) {
2109207a2e495c8363606861e4f034504ec5c153dabLogan Chien    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return false;
2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return true;
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc BrouilletBackend::Backend(RSContext *Context, clang::DiagnosticsEngine *DiagEngine,
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                 const clang::CodeGenOptions &CodeGenOpts,
2198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 const clang::TargetOptions &TargetOpts, PragmaList *Pragmas,
2208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 llvm::raw_ostream *OS, Slang::OutputType OT,
2218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 clang::SourceManager &SourceMgr, bool AllowRSPrefix,
2228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                 bool IsFilterscript)
2238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    : ASTConsumer(), mTargetOpts(TargetOpts), mpModule(nullptr), mpOS(OS),
2248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mOT(OT), mGen(nullptr), mPerFunctionPasses(nullptr),
22521cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mPerModulePasses(nullptr), mCodeGenPasses(nullptr),
22621cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      mBufferOutStream(*mpOS), mContext(Context),
2278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mSourceMgr(SourceMgr), mAllowRSPrefix(AllowRSPrefix),
2288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mIsFilterscript(IsFilterscript), mExportVarMetadata(nullptr),
2298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportFuncMetadata(nullptr), mExportForEachNameMetadata(nullptr),
2308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportForEachSignatureMetadata(nullptr), mExportTypeMetadata(nullptr),
2318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata(nullptr), mRefCount(mContext->getASTContext()),
2328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mASTChecker(Context, Context->getTargetAPI(), IsFilterscript),
2338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mLLVMContext(llvm::getGlobalContext()), mDiagEngine(*DiagEngine),
2348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mCodeGenOpts(CodeGenOpts), mPragmas(Pragmas) {
235c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines  mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::Initialize(clang::ASTContext &Ctx) {
2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->Initialize(Ctx);
240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mpModule = mGen->GetModule();
242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2445e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines// Encase the Bitcode in a wrapper containing RS version information.
2455e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hinesvoid Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
2465e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines  bcinfo::AndroidBitcodeWrapper wrapper;
2475e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines  size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
2485e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines      &wrapper, Bitcode.str().length(), getTargetAPI(),
2495e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines      SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
2505e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines
2515e3b677a3041c86a7f860238dd1f5ff9d111b507Stephen Hines  slangAssert(actualWrapperLen > 0);
2525e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines
2535e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines  // Write out the bitcode wrapper.
25421cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
2555e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines
2565e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines  // Write out the actual encoded bitcode.
25721cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream << Bitcode.str();
2585e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines}
2595e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
26168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPre(Ctx);
26268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTranslationUnit(Ctx);
264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Here, we complete a translation unit (whole translation unit is now in LLVM
2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // IR). Now, interact with LLVM backend to generate actual machine code (asm
2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // or machine code, whatever.)
268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Silently ignore if we weren't initialized for some reason.
27041ebf534161bb67f6207a070c1f6a895dc853408Zonr Chang  if (!mpModule)
2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  llvm::Module *M = mGen->ReleaseModule();
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!M) {
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // The module has been released by IR gen on failures, do not double free.
2765abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes    mpModule = nullptr;
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return;
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  slangAssert(mpModule == M &&
2816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines              "Unexpected module change during LLVM IR generation");
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Insert #pragma information into metadata section of module
2843fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines  if (!mPragmas->empty()) {
2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    llvm::NamedMDNode *PragmaMetadata =
2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
2873fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
2899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++) {
290c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::SmallVector<llvm::Metadata*, 2> Pragma;
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Name goes first
2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // And then value
2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
29583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao
2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Create MDNode and insert into PragmaMetadata
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      PragmaMetadata->addOperand(
29818c8829f2bd3cbe0d02471588c6643c0a8c6ca3cStephen Hines          llvm::MDNode::get(mLLVMContext, Pragma));
299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang  HandleTranslationUnitPost(mpModule);
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create passes for optimization and code emission
305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run per-function passes
3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateFunctionPasses();
3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerFunctionPasses) {
3099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doInitialization();
310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I != E;
3139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao         I++)
3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (!I->isDeclaration())
3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        mPerFunctionPasses->run(*I);
316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerFunctionPasses->doFinalization();
3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
319462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // Create and run module passes
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  CreateModulePasses();
3229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (mPerModulePasses)
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    mPerModulePasses->run(*mpModule);
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3253a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang  switch (mOT) {
3263a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Assembly:
3273a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Object: {
3286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      if (!CreateCodeGenPasses())
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
330462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doInitialization();
332462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
3349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I != E;
3359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          I++)
3366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        if (!I->isDeclaration())
3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mCodeGenPasses->run(*I);
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      mCodeGenPasses->doFinalization();
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3423a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_LLVMAssembly: {
343c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *LLEmitPM = new llvm::legacy::PassManager();
34421cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar      LLEmitPM->add(llvm::createPrintModulePass(mBufferOutStream));
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      LLEmitPM->run(*mpModule);
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
3483a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Bitcode: {
349c706907a8041faaa882f9bd87f1d1c1669023a62Stephen Hines      llvm::legacy::PassManager *BCEmitPM = new llvm::legacy::PassManager();
3505e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines      std::string BCStr;
3515e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines      llvm::raw_string_ostream Bitcode(BCStr);
352c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes      unsigned int TargetAPI = getTargetAPI();
3539b044ec938fd56355012851890c63974c8042c9fStephen Hines      switch (TargetAPI) {
3549b044ec938fd56355012851890c63974c8042c9fStephen Hines        case SLANG_HC_TARGET_API:
3559b044ec938fd56355012851890c63974c8042c9fStephen Hines        case SLANG_HC_MR1_TARGET_API:
3569b044ec938fd56355012851890c63974c8042c9fStephen Hines        case SLANG_HC_MR2_TARGET_API: {
3579b044ec938fd56355012851890c63974c8042c9fStephen Hines          // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
3589b044ec938fd56355012851890c63974c8042c9fStephen Hines          BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
3599b044ec938fd56355012851890c63974c8042c9fStephen Hines          break;
3609b044ec938fd56355012851890c63974c8042c9fStephen Hines        }
3619b044ec938fd56355012851890c63974c8042c9fStephen Hines        case SLANG_ICS_TARGET_API:
3629b044ec938fd56355012851890c63974c8042c9fStephen Hines        case SLANG_ICS_MR1_TARGET_API: {
3639b044ec938fd56355012851890c63974c8042c9fStephen Hines          // ICS targets must use the LLVM 2.9_func BitcodeWriter
3649b044ec938fd56355012851890c63974c8042c9fStephen Hines          BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
3659b044ec938fd56355012851890c63974c8042c9fStephen Hines          break;
3669b044ec938fd56355012851890c63974c8042c9fStephen Hines        }
3679b044ec938fd56355012851890c63974c8042c9fStephen Hines        default: {
3689e3aa07a4456aad52920e0a7464954fe67cdbe01Chris Wailes          if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
3699e3aa07a4456aad52920e0a7464954fe67cdbe01Chris Wailes              (TargetAPI < SLANG_MINIMUM_TARGET_API ||
3709e3aa07a4456aad52920e0a7464954fe67cdbe01Chris Wailes               TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
3719b044ec938fd56355012851890c63974c8042c9fStephen Hines            slangAssert(false && "Invalid target API value");
3729b044ec938fd56355012851890c63974c8042c9fStephen Hines          }
373d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines          // Switch to the 3.2 BitcodeWriter by default, and don't use
374d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines          // LLVM's included BitcodeWriter at all (for now).
375d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines          BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
376d711dec946b6408791ca59eb98e363ef04bbd4aaStephen Hines          //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
3779b044ec938fd56355012851890c63974c8042c9fStephen Hines          break;
3789b044ec938fd56355012851890c63974c8042c9fStephen Hines        }
3794cc499d6e5ec602309501873449c938af61170b2Stephen Hines      }
3805e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines
3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      BCEmitPM->run(*mpModule);
3825e6d0d5a911fff0b7b4bce216a213a4cf8a811f5Stephen Hines      WrapBitcode(Bitcode);
3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3853a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    case Slang::OT_Nothing: {
3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      return;
3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
3896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines      slangAssert(false && "Unknown output type");
3909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
392462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
39321cc01860b95cad7ae60c686e511e8f4ae034e39Pirama Arumuga Nainar  mBufferOutStream.flush();
394462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
395462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->HandleTagDeclDefinition(D);
398462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  mGen->CompleteTentativeDefinition(D);
402462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
403462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
404462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() {
4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mpModule;
4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mGen;
4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerFunctionPasses;
4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mPerModulePasses;
4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  delete mCodeGenPasses;
410462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
411e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
4128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet// 1) Add zero initialization of local RS object types
4138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::AnnotateFunction(clang::FunctionDecl *FD) {
4148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD &&
4158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      FD->hasBody() &&
4168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      !Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr)) {
4178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Init();
4188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mRefCount.Visit(FD->getBody());
4198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletbool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
4238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Disallow user-defined functions with prefix "rs"
4248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mAllowRSPrefix) {
4258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Iterate all function declarations in the program.
4268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end();
4278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet         I != E; I++) {
4288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
4298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD == nullptr)
4308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
4318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!FD->getName().startswith("rs"))  // Check prefix
4328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        continue;
4338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (!Slang::IsLocInRSHeaderFile(FD->getLocation(), mSourceMgr))
4348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mContext->ReportError(FD->getLocation(),
4358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "invalid function name prefix, "
4368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                              "\"rs\" is reserved: '%0'")
4378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            << FD->getName();
4388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any non-static function declarations
4428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; I++) {
4438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
4448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (FD && FD->isGlobal()) {
4458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Check that we don't have any array parameters being misintrepeted as
4468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // kernel pointers due to the C type system's array to pointer decay.
4478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      size_t numParams = FD->getNumParams();
4488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (size_t i = 0; i < numParams; i++) {
4498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
4508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        clang::QualType QT = PVD->getOriginalType();
4518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (QT->isArrayType()) {
4528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          mContext->ReportError(
4538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              PVD->getTypeSpecStartLoc(),
4548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              "exported function parameters may not have array type: %0")
4558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              << QT;
4568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
4578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
4588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      AnnotateFunction(FD);
4598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
4608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  return mGen->HandleTopLevelDecl(D);
4628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
4638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPre(clang::ASTContext &C) {
4658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
4668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // If we have an invalid RS/FS AST, don't check further.
4688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mASTChecker.Validate()) {
4698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mIsFilterscript) {
4738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mContext->addPragma("rs_fp_relaxed", "");
4748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int version = mContext->getVersion();
4778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (version == 0) {
4788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Not setting a version is an error
4798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(
4828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            clang::DiagnosticsEngine::Error,
4838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            "missing pragma for version in source file"));
4848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  } else {
4858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slangAssert(version == 1);
4868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->getReflectJavaPackageName().empty()) {
4898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mDiagEngine.Report(
4908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mSourceMgr.getLocForEndOfFile(mSourceMgr.getMainFileID()),
4918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mDiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error,
4928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "missing \"#pragma rs "
4938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "java_package_name(com.foo.bar)\" "
4948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    "in source file"));
4958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
4968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
4978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
4988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Create a static global destructor if necessary (to handle RS object
4998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // runtime cleanup).
5008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  clang::FunctionDecl *FD = mRefCount.CreateStaticGlobalDtor();
5018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (FD) {
5028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    HandleTopLevelDecl(clang::DeclGroupRef(FD));
5038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // Process any static function declarations
5068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
5078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = TUDecl->decls_end(); I != E; I++) {
5088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if ((I->getKind() >= clang::Decl::firstFunction) &&
5098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        (I->getKind() <= clang::Decl::lastFunction)) {
5108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      clang::FunctionDecl *FD = llvm::dyn_cast<clang::FunctionDecl>(*I);
5118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (FD && !FD->isGlobal()) {
5128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        AnnotateFunction(FD);
5138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
5168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
5178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet///////////////////////////////////////////////////////////////////////////////
5198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportVarInfo(llvm::Module *M) {
5208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  int slotCount = 0;
5218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportVarMetadata == nullptr)
5228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata = M->getOrInsertNamedMetadata(RS_EXPORT_VAR_MN);
5238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 2> ExportVarInfo;
5258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // We emit slot information (#rs_object_slots) for any reference counted
5278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  // RS type or pointer (which can also be bound).
5288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_var_iterator I = mContext->export_vars_begin(),
5308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_vars_end();
5318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
5328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
5338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportVar *EV = *I;
5348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = EV->getType();
5358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    bool countsAsRSObject = false;
5368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Variable name
5388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.push_back(
5398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EV->getName().c_str()));
5408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
5428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    switch (ET->getClass()) {
5438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPrimitive: {
5448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportPrimitiveType *PT =
5458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            static_cast<const RSExportPrimitiveType*>(ET);
5468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(PT->getType())));
5498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (PT->isRSObjectType()) {
5508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          countsAsRSObject = true;
5518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
5528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassPointer: {
5558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, ("*" + static_cast<const RSExportPointerType*>(ET)
5588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                ->getPointeeType()->getName()).c_str()));
5598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassMatrix: {
5628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(
5648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              mLLVMContext, llvm::utostr_32(
5658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  /* TODO Strange value.  This pushes just a number, quite
5668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * different than the other cases.  What is this used for?
5678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * These are the metadata values that some partner drivers
5688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * want to reference (for TBAA, etc.). We may want to look
5698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * at whether these provide any reasonable value (or have
5708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   * distinct enough values to actually depend on).
5718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   */
5728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                DataTypeRSMatrix2x2 +
5738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                static_cast<const RSExportMatrixType*>(ET)->getDim() - 2)));
5748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassVector:
5778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassConstantArray:
5788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      case RSExportType::ExportClassRecord: {
5798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        ExportVarInfo.push_back(
5808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
5818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              EV->getType()->getName().c_str()));
5828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        break;
5838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
5848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportVarMetadata->addOperand(
5878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportVarInfo));
5888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportVarInfo.clear();
5898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (mRSObjectSlotsMetadata == nullptr) {
5918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata =
5928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(RS_OBJECT_SLOTS_MN);
5938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
5958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (countsAsRSObject) {
5968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mRSObjectSlotsMetadata->addOperand(llvm::MDNode::get(mLLVMContext,
5978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, llvm::utostr_32(slotCount))));
5988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
5998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    slotCount++;
6018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
6028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
6038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportFunctionInfo(llvm::Module *M) {
6058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportFuncMetadata == nullptr)
6068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata =
6078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FUNC_MN);
6088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportFuncInfo;
6108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_func_iterator
6128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_funcs_begin(),
6138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_funcs_end();
6148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
6158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
6168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportFunc *EF = *I;
6178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Function name
6198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (!EF->hasParam()) {
6208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(llvm::MDString::get(mLLVMContext,
6218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                   EF->getName().c_str()));
6228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    } else {
6238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *F = M->getFunction(EF->getName());
6248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::Function *HelperFunction;
6258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const std::string HelperFunctionName(".helper_" + EF->getName());
6268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(F && "Function marked as exported disappeared in Bitcode");
6288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Create helper function
6308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      {
6318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::StructType *HelperFunctionParameterTy = nullptr;
6328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<bool> isStructInput;
6338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!F->getArgumentList().empty()) {
6358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          std::vector<llvm::Type*> HelperFunctionParameterTys;
6368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (llvm::Function::arg_iterator AI = F->arg_begin(),
6378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                   AE = F->arg_end(); AI != AE; AI++) {
6388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              if (AI->getType()->isPointerTy() && AI->getType()->getPointerElementType()->isStructTy()) {
6398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType()->getPointerElementType());
6408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(true);
6418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              } else {
6428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  HelperFunctionParameterTys.push_back(AI->getType());
6438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  isStructInput.push_back(false);
6448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              }
6458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          HelperFunctionParameterTy =
6478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::StructType::get(mLLVMContext, HelperFunctionParameterTys);
6488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (!EF->checkParameterPacketType(HelperFunctionParameterTy)) {
6518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          fprintf(stderr, "Failed to export function %s: parameter type "
6528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                          "mismatch during creation of helper function.\n",
6538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  EF->getName().c_str());
6548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          const RSExportRecordType *Expected = EF->getParamPacketType();
6568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (Expected) {
6578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Expected:\n");
6588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Expected->getLLVMType()->dump();
6598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (HelperFunctionParameterTy) {
6618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            fprintf(stderr, "Got:\n");
6628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            HelperFunctionParameterTy->dump();
6638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
6648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        std::vector<llvm::Type*> Params;
6678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        if (HelperFunctionParameterTy) {
6688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::PointerType *HelperFunctionParameterTyP =
6698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::PointerType::getUnqual(HelperFunctionParameterTy);
6708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Params.push_back(HelperFunctionParameterTyP);
6718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
6728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::FunctionType * HelperFunctionType =
6748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::FunctionType::get(F->getReturnType(),
6758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    Params,
6768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                    /* IsVarArgs = */false);
6778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction =
6798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Function::Create(HelperFunctionType,
6808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   llvm::GlobalValue::ExternalLinkage,
6818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   HelperFunctionName,
6828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                   M);
6838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->addFnAttr(llvm::Attribute::NoInline);
6858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        HelperFunction->setCallingConv(F->getCallingConv());
6868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // Create helper function body
6888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        {
6898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Argument *HelperFunctionParameter =
6908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              &(*HelperFunction->arg_begin());
6918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::BasicBlock *BB =
6928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::BasicBlock::Create(mLLVMContext, "entry", HelperFunction);
6938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::IRBuilder<> *IB = new llvm::IRBuilder<>(BB);
6948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::SmallVector<llvm::Value*, 6> Params;
6958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::Value *Idx[2];
6968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
6978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          Idx[0] =
6988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::ConstantInt::get(llvm::Type::getInt32Ty(mLLVMContext), 0);
6998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // getelementptr and load instruction for all elements in
7018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // parameter .p
7028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          for (size_t i = 0; i < EF->getNumParameters(); i++) {
7038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // getelementptr
7048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Idx[1] = llvm::ConstantInt::get(
7058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              llvm::Type::getInt32Ty(mLLVMContext), i);
7068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::Value *Ptr = NULL;
7088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            Ptr = IB->CreateInBoundsGEP(HelperFunctionParameter, Idx);
7108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            // Load is only required for non-struct ptrs
7128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            if (isStructInput[i]) {
7138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(Ptr);
7148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            } else {
7158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                llvm::Value *V = IB->CreateLoad(Ptr);
7168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                Params.push_back(V);
7178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            }
7188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          }
7198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          // Call and pass the all elements as parameter to F
7218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::CallInst *CI = IB->CreateCall(F, Params);
7228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          CI->setCallingConv(F->getCallingConv());
7248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          if (F->getReturnType() == llvm::Type::getVoidTy(mLLVMContext))
7268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRetVoid();
7278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          else
7288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            IB->CreateRet(CI);
7298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          delete IB;
7318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        }
7328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
7338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      ExportFuncInfo.push_back(
7358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDString::get(mLLVMContext, HelperFunctionName.c_str()));
7368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }
7378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportFuncMetadata->addOperand(
7398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportFuncInfo));
7408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportFuncInfo.clear();
7418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportForEachInfo(llvm::Module *M) {
7458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachNameMetadata == nullptr) {
7468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata =
7478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_NAME_MN);
7488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mExportForEachSignatureMetadata == nullptr) {
7508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata =
7518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        M->getOrInsertNamedMetadata(RS_EXPORT_FOREACH_MN);
7528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachName;
7558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportForEachInfo;
7568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_foreach_iterator
7588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_foreach_begin(),
7598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_foreach_end();
7608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportForEach *EFE = *I;
7638024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7648024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.push_back(
7658024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, EFE->getName().c_str()));
7668024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7678024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachNameMetadata->addOperand(
7688024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachName));
7698024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachName.clear();
7708024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7718024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.push_back(
7728024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext,
7738024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                            llvm::utostr_32(EFE->getSignatureMetadata())));
7748024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7758024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    mExportForEachSignatureMetadata->addOperand(
7768024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDNode::get(mLLVMContext, ExportForEachInfo));
7778024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportForEachInfo.clear();
7788024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
7798024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
7808024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7818024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::dumpExportTypeInfo(llvm::Module *M) {
7828024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  llvm::SmallVector<llvm::Metadata *, 1> ExportTypeInfo;
7838024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7848024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  for (RSContext::const_export_type_iterator
7858024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          I = mContext->export_types_begin(),
7868024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          E = mContext->export_types_end();
7878024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I != E;
7888024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet       I++) {
7898024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // First, dump type name list to export
7908024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    const RSExportType *ET = I->getValue();
7918024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7928024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.clear();
7938024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    // Type name
7948024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    ExportTypeInfo.push_back(
7958024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        llvm::MDString::get(mLLVMContext, ET->getName().c_str()));
7968024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
7978024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    if (ET->getClass() == RSExportType::ExportClassRecord) {
7988024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      const RSExportRecordType *ERT =
7998024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          static_cast<const RSExportRecordType*>(ET);
8008024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8018024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      if (mExportTypeMetadata == nullptr)
8028024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        mExportTypeMetadata =
8038024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            M->getOrInsertNamedMetadata(RS_EXPORT_TYPE_MN);
8048024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8058024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      mExportTypeMetadata->addOperand(
8068024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          llvm::MDNode::get(mLLVMContext, ExportTypeInfo));
8078024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8088024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      // Now, export struct field information to %[struct name]
8098024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      std::string StructInfoMetadataName("%");
8108024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      StructInfoMetadataName.append(ET->getName());
8118024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::NamedMDNode *StructInfoMetadata =
8128024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet          M->getOrInsertNamedMetadata(StructInfoMetadataName);
8138024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      llvm::SmallVector<llvm::Metadata *, 3> FieldInfo;
8148024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8158024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      slangAssert(StructInfoMetadata->getNumOperands() == 0 &&
8168024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                  "Metadata with same name was created before");
8178024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(),
8188024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet              FE = ERT->fields_end();
8198024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI != FE;
8208024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet           FI++) {
8218024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        const RSExportRecordType::Field *F = *FI;
8228024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8238024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 1. field name
8248024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(llvm::MDString::get(mLLVMContext,
8258024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                                F->getName().c_str()));
8268024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        // 2. field type name
8288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.push_back(
8298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDString::get(mLLVMContext,
8308024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet                                F->getType()->getName().c_str()));
8318024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8328024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        StructInfoMetadata->addOperand(
8338024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet            llvm::MDNode::get(mLLVMContext, FieldInfo));
8348024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet        FieldInfo.clear();
8358024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet      }
8368024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    }   // ET->getClass() == RSExportType::ExportClassRecord
8378024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8388024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8398024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8408024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouilletvoid Backend::HandleTranslationUnitPost(llvm::Module *M) {
8418024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8428024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->is64Bit()) {
8438024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    M->setDataLayout("e-p:32:32-i64:64-v128:64:128-n32-S64");
8448024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8458024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8468024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (!mContext->processExport()) {
8478024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    return;
8488024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  }
8498024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8508024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportVar())
8518024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportVarInfo(M);
8528024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8538024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportFunc())
8548024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportFunctionInfo(M);
8558024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8568024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportForEach())
8578024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportForEachInfo(M);
8588024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
8598024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet  if (mContext->hasExportType())
8608024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet    dumpExportTypeInfo(M);
8618024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet}
8628024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet
863e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
864