blob: 43d843ebc7f1a3247ab883a4924194d406363d89 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines5e3b6772012-03-21 08:02:10 -07002 * Copyright 2010-2012, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_backend.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Stephen Hinese639eb52010-11-08 19:27:20 -080019#include <string>
20#include <vector>
21
Stephen Hines5e6d0d52011-11-22 19:42:41 -080022#include "bcinfo/BitcodeWrapper.h"
23
Stephen Hinese639eb52010-11-08 19:27:20 -080024#include "clang/AST/ASTContext.h"
25#include "clang/AST/Decl.h"
26#include "clang/AST/DeclGroup.h"
27
28#include "clang/Basic/Diagnostic.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Basic/TargetOptions.h"
31
32#include "clang/CodeGen/ModuleBuilder.h"
33
34#include "clang/Frontend/CodeGenOptions.h"
35#include "clang/Frontend/FrontendDiagnostic.h"
36
Tim Murrayee4016d2014-04-10 15:49:08 -070037#include "llvm/IR/IRPrintingPasses.h"
Stephen Hinese639eb52010-11-08 19:27:20 -080038
39#include "llvm/Bitcode/ReaderWriter.h"
40
41#include "llvm/CodeGen/RegAllocRegistry.h"
42#include "llvm/CodeGen/SchedulerRegistry.h"
43
Stephen Hines23c43582013-01-09 20:02:04 -080044#include "llvm/IR/LLVMContext.h"
45#include "llvm/IR/Module.h"
46#include "llvm/IR/Metadata.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070047
Logan Chien9207a2e2011-10-21 15:39:28 +080048#include "llvm/Transforms/IPO/PassManagerBuilder.h"
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070049
Stephen Hines23c43582013-01-09 20:02:04 -080050#include "llvm/IR/DataLayout.h"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070051#include "llvm/Target/TargetMachine.h"
52#include "llvm/Target/TargetOptions.h"
Logan Chien9207a2e2011-10-21 15:39:28 +080053#include "llvm/Support/TargetRegistry.h"
Shih-wei Liao77703262011-07-02 11:30:32 -070054
55#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070056
Stephen Hines6e6578a2011-02-07 18:05:48 -080057#include "slang_assert.h"
Stephen Hines552d8722013-12-18 12:21:50 -080058#include "strip_unknown_attributes.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070059#include "BitWriter_2_9/ReaderWriter_2_9.h"
Stephen Hines9b044ec2011-11-23 16:30:16 -080060#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
Stephen Hinesd711dec2013-01-08 16:23:30 -080061#include "BitWriter_3_2/ReaderWriter_3_2.h"
zonr6315f762010-10-05 15:35:14 +080062
Stephen Hinese639eb52010-11-08 19:27:20 -080063namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080065void Backend::CreateFunctionPasses() {
66 if (!mPerFunctionPasses) {
67 mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
Tim Murrayee4016d2014-04-10 15:49:08 -070068 mPerFunctionPasses->add(new llvm::DataLayoutPass(mpModule));
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080069
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070070 llvm::PassManagerBuilder PMBuilder;
71 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
72 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080073 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080074}
75
76void Backend::CreateModulePasses() {
77 if (!mPerModulePasses) {
78 mPerModulePasses = new llvm::PassManager();
Tim Murrayee4016d2014-04-10 15:49:08 -070079 mPerModulePasses->add(new llvm::DataLayoutPass(mpModule));
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080080
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070081 llvm::PassManagerBuilder PMBuilder;
82 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
83 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070084 if (mCodeGenOpts.UnitAtATime) {
85 PMBuilder.DisableUnitAtATime = 0;
86 } else {
87 PMBuilder.DisableUnitAtATime = 1;
88 }
89
90 if (mCodeGenOpts.UnrollLoops) {
91 PMBuilder.DisableUnrollLoops = 0;
92 } else {
93 PMBuilder.DisableUnrollLoops = 1;
94 }
95
Shih-wei Liaofcc654a2011-06-22 04:47:33 -070096 PMBuilder.populateModulePassManager(*mPerModulePasses);
Stephen Hines552d8722013-12-18 12:21:50 -080097 // Add a pass to strip off unknown/unsupported attributes.
98 mPerModulePasses->add(createStripUnknownAttributesPass());
Zonr Chang3a9ca1f2010-10-06 17:52:56 +080099 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800100}
101
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700102bool Backend::CreateCodeGenPasses() {
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800103 if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700104 return true;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105
106 // Now we add passes for code emitting
107 if (mCodeGenPasses) {
108 return true;
109 } else {
110 mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
Tim Murrayee4016d2014-04-10 15:49:08 -0700111 mCodeGenPasses->add(new llvm::DataLayoutPass(mpModule));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700112 }
113
114 // Create the TargetMachine for generating code.
115 std::string Triple = mpModule->getTargetTriple();
116
117 std::string Error;
118 const llvm::Target* TargetInfo =
119 llvm::TargetRegistry::lookupTarget(Triple, Error);
zonr6315f762010-10-05 15:35:14 +0800120 if (TargetInfo == NULL) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800121 mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700122 return false;
123 }
124
Logan Chienac4e1852011-12-16 13:37:10 +0800125 // Target Machine Options
126 llvm::TargetOptions Options;
127
128 Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700129
130 // Use hardware FPU.
131 //
132 // FIXME: Need to detect the CPU capability and decide whether to use softfp.
133 // To use softfp, change following 2 lines to
134 //
Logan Chienac4e1852011-12-16 13:37:10 +0800135 // Options.FloatABIType = llvm::FloatABI::Soft;
136 // Options.UseSoftFloat = true;
137 Options.FloatABIType = llvm::FloatABI::Hard;
138 Options.UseSoftFloat = false;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700139
140 // BCC needs all unknown symbols resolved at compilation time. So we don't
141 // need any relocation model.
Logan Chienab992e52011-07-20 22:06:52 +0800142 llvm::Reloc::Model RM = llvm::Reloc::Static;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700143
Zonr Chang41ebf532010-10-13 18:29:18 +0800144 // This is set for the linker (specify how large of the virtual addresses we
145 // can access for all unknown symbols.)
Logan Chien9207a2e2011-10-21 15:39:28 +0800146 llvm::CodeModel::Model CM;
Tim Murrayee4016d2014-04-10 15:49:08 -0700147 if (mpModule->getDataLayout()->getPointerSize() == 4) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800148 CM = llvm::CodeModel::Small;
149 } else {
Zonr Chang41ebf532010-10-13 18:29:18 +0800150 // The target may have pointer size greater than 32 (e.g. x86_64
151 // architecture) may need large data address model
Logan Chien9207a2e2011-10-21 15:39:28 +0800152 CM = llvm::CodeModel::Medium;
153 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700154
155 // Setup feature string
156 std::string FeaturesStr;
157 if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
158 llvm::SubtargetFeatures Features;
159
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700160 for (std::vector<std::string>::const_iterator
161 I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
162 I != E;
163 I++)
164 Features.AddFeature(*I);
165
166 FeaturesStr = Features.getString();
167 }
Logan Chien9207a2e2011-10-21 15:39:28 +0800168
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700169 llvm::TargetMachine *TM =
Logan Chien9207a2e2011-10-21 15:39:28 +0800170 TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
Logan Chienac4e1852011-12-16 13:37:10 +0800171 Options, RM, CM);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700172
173 // Register scheduler
174 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
175
176 // Register allocation policy:
177 // createFastRegisterAllocator: fast but bad quality
Logan Chien2c6bad52011-11-15 15:57:33 +0800178 // createGreedyRegisterAllocator: not so fast but good quality
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700179 llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
180 llvm::createFastRegisterAllocator :
Logan Chien2c6bad52011-11-15 15:57:33 +0800181 llvm::createGreedyRegisterAllocator);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700182
183 llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
Shih-wei Liao77703262011-07-02 11:30:32 -0700184 if (mCodeGenOpts.OptimizationLevel == 0) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185 OptLevel = llvm::CodeGenOpt::None;
Shih-wei Liao77703262011-07-02 11:30:32 -0700186 } else if (mCodeGenOpts.OptimizationLevel == 3) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700187 OptLevel = llvm::CodeGenOpt::Aggressive;
Shih-wei Liao77703262011-07-02 11:30:32 -0700188 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189
190 llvm::TargetMachine::CodeGenFileType CGFT =
zonr6315f762010-10-05 15:35:14 +0800191 llvm::TargetMachine::CGFT_AssemblyFile;
Shih-wei Liao77703262011-07-02 11:30:32 -0700192 if (mOT == Slang::OT_Object) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700193 CGFT = llvm::TargetMachine::CGFT_ObjectFile;
Shih-wei Liao77703262011-07-02 11:30:32 -0700194 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700195 if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream,
196 CGFT, OptLevel)) {
Logan Chien9207a2e2011-10-21 15:39:28 +0800197 mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700198 return false;
199 }
200
201 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700202}
203
Logan Chien9207a2e2011-10-21 15:39:28 +0800204Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 const clang::CodeGenOptions &CodeGenOpts,
206 const clang::TargetOptions &TargetOpts,
Stephen Hines3fd0a942011-01-18 12:27:39 -0800207 PragmaList *Pragmas,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700208 llvm::raw_ostream *OS,
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800209 Slang::OutputType OT)
zonr6315f762010-10-05 15:35:14 +0800210 : ASTConsumer(),
zonr6315f762010-10-05 15:35:14 +0800211 mTargetOpts(TargetOpts),
Zonr Chang68fc02c2010-10-13 19:09:19 +0800212 mpModule(NULL),
zonr6315f762010-10-05 15:35:14 +0800213 mpOS(OS),
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800214 mOT(OT),
zonr6315f762010-10-05 15:35:14 +0800215 mGen(NULL),
216 mPerFunctionPasses(NULL),
217 mPerModulePasses(NULL),
218 mCodeGenPasses(NULL),
zonr6315f762010-10-05 15:35:14 +0800219 mLLVMContext(llvm::getGlobalContext()),
Logan Chien9207a2e2011-10-21 15:39:28 +0800220 mDiagEngine(*DiagEngine),
mkopec1c460b372012-01-09 11:21:50 -0500221 mCodeGenOpts(CodeGenOpts),
zonr6315f762010-10-05 15:35:14 +0800222 mPragmas(Pragmas) {
223 FormattedOutStream.setStream(*mpOS,
224 llvm::formatted_raw_ostream::PRESERVE_STREAM);
Stephen Hines0da7f6c2013-03-05 15:19:02 -0800225 mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts,
226 mTargetOpts, mLLVMContext);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700227}
228
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700229void Backend::Initialize(clang::ASTContext &Ctx) {
230 mGen->Initialize(Ctx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700231
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700232 mpModule = mGen->GetModule();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700233}
234
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800235// Encase the Bitcode in a wrapper containing RS version information.
236void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
Stephen Hines5e3b6772012-03-21 08:02:10 -0700237 bcinfo::AndroidBitcodeWrapper wrapper;
238 size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
239 &wrapper, Bitcode.str().length(), getTargetAPI(),
240 SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
241
242 slangAssert(actualWrapperLen > 0);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800243
244 // Write out the bitcode wrapper.
Stephen Hines5e3b6772012-03-21 08:02:10 -0700245 FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800246
247 // Write out the actual encoded bitcode.
248 FormattedOutStream << Bitcode.str();
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800249}
250
Logan Chienfa6ef562011-11-25 13:50:02 +0800251bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
Stephen Hinesde7ac192011-11-28 15:57:01 -0800252 return mGen->HandleTopLevelDecl(D);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700253}
254
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700255void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
Zonr Chang68fc02c2010-10-13 19:09:19 +0800256 HandleTranslationUnitPre(Ctx);
257
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700258 mGen->HandleTranslationUnit(Ctx);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700259
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700260 // Here, we complete a translation unit (whole translation unit is now in LLVM
261 // IR). Now, interact with LLVM backend to generate actual machine code (asm
262 // or machine code, whatever.)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700263
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700264 // Silently ignore if we weren't initialized for some reason.
Zonr Chang41ebf532010-10-13 18:29:18 +0800265 if (!mpModule)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700266 return;
267
268 llvm::Module *M = mGen->ReleaseModule();
269 if (!M) {
270 // The module has been released by IR gen on failures, do not double free.
271 mpModule = NULL;
272 return;
273 }
274
Stephen Hines6e6578a2011-02-07 18:05:48 -0800275 slangAssert(mpModule == M &&
276 "Unexpected module change during LLVM IR generation");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700277
278 // Insert #pragma information into metadata section of module
Stephen Hines3fd0a942011-01-18 12:27:39 -0800279 if (!mPragmas->empty()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700280 llvm::NamedMDNode *PragmaMetadata =
281 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
Stephen Hines3fd0a942011-01-18 12:27:39 -0800282 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700283 I != E;
284 I++) {
285 llvm::SmallVector<llvm::Value*, 2> Pragma;
286 // Name goes first
287 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
288 // And then value
289 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
Shih-wei Liao83f0c622011-06-21 05:34:53 -0700290
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700291 // Create MDNode and insert into PragmaMetadata
292 PragmaMetadata->addOperand(
Stephen Hines18c88292011-07-14 22:46:15 -0700293 llvm::MDNode::get(mLLVMContext, Pragma));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700294 }
295 }
296
Zonr Chang68fc02c2010-10-13 19:09:19 +0800297 HandleTranslationUnitPost(mpModule);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700298
299 // Create passes for optimization and code emission
300
301 // Create and run per-function passes
302 CreateFunctionPasses();
303 if (mPerFunctionPasses) {
304 mPerFunctionPasses->doInitialization();
305
306 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
307 I != E;
308 I++)
309 if (!I->isDeclaration())
310 mPerFunctionPasses->run(*I);
311
312 mPerFunctionPasses->doFinalization();
313 }
314
315 // Create and run module passes
316 CreateModulePasses();
317 if (mPerModulePasses)
318 mPerModulePasses->run(*mpModule);
319
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800320 switch (mOT) {
321 case Slang::OT_Assembly:
322 case Slang::OT_Object: {
zonr6315f762010-10-05 15:35:14 +0800323 if (!CreateCodeGenPasses())
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700324 return;
325
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700326 mCodeGenPasses->doInitialization();
327
328 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
329 I != E;
330 I++)
zonr6315f762010-10-05 15:35:14 +0800331 if (!I->isDeclaration())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700332 mCodeGenPasses->run(*I);
333
334 mCodeGenPasses->doFinalization();
335 break;
336 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800337 case Slang::OT_LLVMAssembly: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700338 llvm::PassManager *LLEmitPM = new llvm::PassManager();
Tim Murrayee4016d2014-04-10 15:49:08 -0700339 LLEmitPM->add(llvm::createPrintModulePass(FormattedOutStream));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700340 LLEmitPM->run(*mpModule);
341 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700342 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800343 case Slang::OT_Bitcode: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700344 llvm::PassManager *BCEmitPM = new llvm::PassManager();
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800345 std::string BCStr;
346 llvm::raw_string_ostream Bitcode(BCStr);
Chris Wailesc9454af2014-06-13 17:25:40 -0700347 unsigned int TargetAPI = getTargetAPI();
Stephen Hines9b044ec2011-11-23 16:30:16 -0800348 switch (TargetAPI) {
349 case SLANG_HC_TARGET_API:
350 case SLANG_HC_MR1_TARGET_API:
351 case SLANG_HC_MR2_TARGET_API: {
352 // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
353 BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
354 break;
355 }
356 case SLANG_ICS_TARGET_API:
357 case SLANG_ICS_MR1_TARGET_API: {
358 // ICS targets must use the LLVM 2.9_func BitcodeWriter
359 BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
360 break;
361 }
362 default: {
Chris Wailes9e3aa072014-06-16 18:52:02 -0700363 if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
364 (TargetAPI < SLANG_MINIMUM_TARGET_API ||
365 TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
Stephen Hines9b044ec2011-11-23 16:30:16 -0800366 slangAssert(false && "Invalid target API value");
367 }
Stephen Hinesd711dec2013-01-08 16:23:30 -0800368 // Switch to the 3.2 BitcodeWriter by default, and don't use
369 // LLVM's included BitcodeWriter at all (for now).
370 BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
371 //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
Stephen Hines9b044ec2011-11-23 16:30:16 -0800372 break;
373 }
Stephen Hines4cc499d2011-08-24 19:06:17 -0700374 }
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800375
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700376 BCEmitPM->run(*mpModule);
Stephen Hines5e6d0d52011-11-22 19:42:41 -0800377 WrapBitcode(Bitcode);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700378 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700379 }
Zonr Chang3a9ca1f2010-10-06 17:52:56 +0800380 case Slang::OT_Nothing: {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700381 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700382 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700383 default: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800384 slangAssert(false && "Unknown output type");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700385 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700386 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700387
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700388 FormattedOutStream.flush();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700389}
390
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700391void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
392 mGen->HandleTagDeclDefinition(D);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700393}
394
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700395void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
396 mGen->CompleteTentativeDefinition(D);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700397}
398
399Backend::~Backend() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700400 delete mpModule;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700401 delete mGen;
402 delete mPerFunctionPasses;
403 delete mPerModulePasses;
404 delete mCodeGenPasses;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700405}
Stephen Hinese639eb52010-11-08 19:27:20 -0800406
407} // namespace slang