slang_backend.cpp revision 0da7f6c8201b27938d3b9f048d71fd784cd1df9a
1/*
2 * Copyright 2010-2012, The Android Open Source Project
3 *
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
17#include "slang_backend.h"
18
19#include <string>
20#include <vector>
21
22#include "bcinfo/BitcodeWrapper.h"
23
24#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
37#include "llvm/Assembly/PrintModulePass.h"
38
39#include "llvm/Bitcode/ReaderWriter.h"
40
41#include "llvm/CodeGen/RegAllocRegistry.h"
42#include "llvm/CodeGen/SchedulerRegistry.h"
43
44#include "llvm/IR/LLVMContext.h"
45#include "llvm/IR/Module.h"
46#include "llvm/IR/Metadata.h"
47
48#include "llvm/Transforms/IPO/PassManagerBuilder.h"
49
50#include "llvm/IR/DataLayout.h"
51#include "llvm/Target/TargetMachine.h"
52#include "llvm/Target/TargetOptions.h"
53#include "llvm/Support/TargetRegistry.h"
54
55#include "llvm/MC/SubtargetFeature.h"
56
57#include "slang_assert.h"
58#include "BitWriter_2_9/ReaderWriter_2_9.h"
59#include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
60#include "BitWriter_3_2/ReaderWriter_3_2.h"
61
62namespace slang {
63
64void Backend::CreateFunctionPasses() {
65  if (!mPerFunctionPasses) {
66    mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
67    mPerFunctionPasses->add(new llvm::DataLayout(mpModule));
68
69    llvm::PassManagerBuilder PMBuilder;
70    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
71    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
72  }
73  return;
74}
75
76void Backend::CreateModulePasses() {
77  if (!mPerModulePasses) {
78    mPerModulePasses = new llvm::PassManager();
79    mPerModulePasses->add(new llvm::DataLayout(mpModule));
80
81    llvm::PassManagerBuilder PMBuilder;
82    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
83    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
84    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
85    if (mCodeGenOpts.UnitAtATime) {
86      PMBuilder.DisableUnitAtATime = 0;
87    } else {
88      PMBuilder.DisableUnitAtATime = 1;
89    }
90
91    if (mCodeGenOpts.UnrollLoops) {
92      PMBuilder.DisableUnrollLoops = 0;
93    } else {
94      PMBuilder.DisableUnrollLoops = 1;
95    }
96
97    PMBuilder.DisableSimplifyLibCalls = false;
98    PMBuilder.populateModulePassManager(*mPerModulePasses);
99  }
100  return;
101}
102
103bool Backend::CreateCodeGenPasses() {
104  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
105    return true;
106
107  // Now we add passes for code emitting
108  if (mCodeGenPasses) {
109    return true;
110  } else {
111    mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
112    mCodeGenPasses->add(new llvm::DataLayout(mpModule));
113  }
114
115  // Create the TargetMachine for generating code.
116  std::string Triple = mpModule->getTargetTriple();
117
118  std::string Error;
119  const llvm::Target* TargetInfo =
120      llvm::TargetRegistry::lookupTarget(Triple, Error);
121  if (TargetInfo == NULL) {
122    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
123    return false;
124  }
125
126  // Target Machine Options
127  llvm::TargetOptions Options;
128
129  Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
130
131  // Use hardware FPU.
132  //
133  // FIXME: Need to detect the CPU capability and decide whether to use softfp.
134  // To use softfp, change following 2 lines to
135  //
136  // Options.FloatABIType = llvm::FloatABI::Soft;
137  // Options.UseSoftFloat = true;
138  Options.FloatABIType = llvm::FloatABI::Hard;
139  Options.UseSoftFloat = false;
140
141  // BCC needs all unknown symbols resolved at compilation time. So we don't
142  // need any relocation model.
143  llvm::Reloc::Model RM = llvm::Reloc::Static;
144
145  // This is set for the linker (specify how large of the virtual addresses we
146  // can access for all unknown symbols.)
147  llvm::CodeModel::Model CM;
148  if (mpModule->getPointerSize() == llvm::Module::Pointer32) {
149    CM = llvm::CodeModel::Small;
150  } else {
151    // The target may have pointer size greater than 32 (e.g. x86_64
152    // architecture) may need large data address model
153    CM = llvm::CodeModel::Medium;
154  }
155
156  // Setup feature string
157  std::string FeaturesStr;
158  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
159    llvm::SubtargetFeatures Features;
160
161    for (std::vector<std::string>::const_iterator
162             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
163         I != E;
164         I++)
165      Features.AddFeature(*I);
166
167    FeaturesStr = Features.getString();
168  }
169
170  llvm::TargetMachine *TM =
171    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
172                                    Options, RM, CM);
173
174  // Register scheduler
175  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
176
177  // Register allocation policy:
178  //  createFastRegisterAllocator: fast but bad quality
179  //  createGreedyRegisterAllocator: not so fast but good quality
180  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
181                                     llvm::createFastRegisterAllocator :
182                                     llvm::createGreedyRegisterAllocator);
183
184  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
185  if (mCodeGenOpts.OptimizationLevel == 0) {
186    OptLevel = llvm::CodeGenOpt::None;
187  } else if (mCodeGenOpts.OptimizationLevel == 3) {
188    OptLevel = llvm::CodeGenOpt::Aggressive;
189  }
190
191  llvm::TargetMachine::CodeGenFileType CGFT =
192      llvm::TargetMachine::CGFT_AssemblyFile;
193  if (mOT == Slang::OT_Object) {
194    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
195  }
196  if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream,
197                              CGFT, OptLevel)) {
198    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
199    return false;
200  }
201
202  return true;
203}
204
205Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
206                 const clang::CodeGenOptions &CodeGenOpts,
207                 const clang::TargetOptions &TargetOpts,
208                 PragmaList *Pragmas,
209                 llvm::raw_ostream *OS,
210                 Slang::OutputType OT)
211    : ASTConsumer(),
212      mTargetOpts(TargetOpts),
213      mpModule(NULL),
214      mpOS(OS),
215      mOT(OT),
216      mGen(NULL),
217      mPerFunctionPasses(NULL),
218      mPerModulePasses(NULL),
219      mCodeGenPasses(NULL),
220      mLLVMContext(llvm::getGlobalContext()),
221      mDiagEngine(*DiagEngine),
222      mCodeGenOpts(CodeGenOpts),
223      mPragmas(Pragmas) {
224  FormattedOutStream.setStream(*mpOS,
225                               llvm::formatted_raw_ostream::PRESERVE_STREAM);
226  mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts,
227                           mTargetOpts, mLLVMContext);
228  return;
229}
230
231void Backend::Initialize(clang::ASTContext &Ctx) {
232  mGen->Initialize(Ctx);
233
234  mpModule = mGen->GetModule();
235
236  return;
237}
238
239// Encase the Bitcode in a wrapper containing RS version information.
240void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
241  bcinfo::AndroidBitcodeWrapper wrapper;
242  size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
243      &wrapper, Bitcode.str().length(), getTargetAPI(),
244      SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
245
246  slangAssert(actualWrapperLen > 0);
247
248  // Write out the bitcode wrapper.
249  FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
250
251  // Write out the actual encoded bitcode.
252  FormattedOutStream << Bitcode.str();
253  return;
254}
255
256bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
257  return mGen->HandleTopLevelDecl(D);
258}
259
260void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
261  HandleTranslationUnitPre(Ctx);
262
263  mGen->HandleTranslationUnit(Ctx);
264
265  // Here, we complete a translation unit (whole translation unit is now in LLVM
266  // IR). Now, interact with LLVM backend to generate actual machine code (asm
267  // or machine code, whatever.)
268
269  // Silently ignore if we weren't initialized for some reason.
270  if (!mpModule)
271    return;
272
273  llvm::Module *M = mGen->ReleaseModule();
274  if (!M) {
275    // The module has been released by IR gen on failures, do not double free.
276    mpModule = NULL;
277    return;
278  }
279
280  slangAssert(mpModule == M &&
281              "Unexpected module change during LLVM IR generation");
282
283  // Insert #pragma information into metadata section of module
284  if (!mPragmas->empty()) {
285    llvm::NamedMDNode *PragmaMetadata =
286        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
287    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
288         I != E;
289         I++) {
290      llvm::SmallVector<llvm::Value*, 2> Pragma;
291      // Name goes first
292      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
293      // And then value
294      Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
295
296      // Create MDNode and insert into PragmaMetadata
297      PragmaMetadata->addOperand(
298          llvm::MDNode::get(mLLVMContext, Pragma));
299    }
300  }
301
302  HandleTranslationUnitPost(mpModule);
303
304  // Create passes for optimization and code emission
305
306  // Create and run per-function passes
307  CreateFunctionPasses();
308  if (mPerFunctionPasses) {
309    mPerFunctionPasses->doInitialization();
310
311    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
312         I != E;
313         I++)
314      if (!I->isDeclaration())
315        mPerFunctionPasses->run(*I);
316
317    mPerFunctionPasses->doFinalization();
318  }
319
320  // Create and run module passes
321  CreateModulePasses();
322  if (mPerModulePasses)
323    mPerModulePasses->run(*mpModule);
324
325  switch (mOT) {
326    case Slang::OT_Assembly:
327    case Slang::OT_Object: {
328      if (!CreateCodeGenPasses())
329        return;
330
331      mCodeGenPasses->doInitialization();
332
333      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
334          I != E;
335          I++)
336        if (!I->isDeclaration())
337          mCodeGenPasses->run(*I);
338
339      mCodeGenPasses->doFinalization();
340      break;
341    }
342    case Slang::OT_LLVMAssembly: {
343      llvm::PassManager *LLEmitPM = new llvm::PassManager();
344      LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
345      LLEmitPM->run(*mpModule);
346      break;
347    }
348    case Slang::OT_Bitcode: {
349      llvm::PassManager *BCEmitPM = new llvm::PassManager();
350      std::string BCStr;
351      llvm::raw_string_ostream Bitcode(BCStr);
352      unsigned int TargetAPI = getTargetAPI();
353      switch (TargetAPI) {
354        case SLANG_HC_TARGET_API:
355        case SLANG_HC_MR1_TARGET_API:
356        case SLANG_HC_MR2_TARGET_API: {
357          // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
358          BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
359          break;
360        }
361        case SLANG_ICS_TARGET_API:
362        case SLANG_ICS_MR1_TARGET_API: {
363          // ICS targets must use the LLVM 2.9_func BitcodeWriter
364          BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
365          break;
366        }
367        default: {
368          if (TargetAPI < SLANG_MINIMUM_TARGET_API ||
369              TargetAPI > SLANG_MAXIMUM_TARGET_API) {
370            slangAssert(false && "Invalid target API value");
371          }
372          // Switch to the 3.2 BitcodeWriter by default, and don't use
373          // LLVM's included BitcodeWriter at all (for now).
374          BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
375          //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
376          break;
377        }
378      }
379
380      BCEmitPM->run(*mpModule);
381      WrapBitcode(Bitcode);
382      break;
383    }
384    case Slang::OT_Nothing: {
385      return;
386    }
387    default: {
388      slangAssert(false && "Unknown output type");
389    }
390  }
391
392  FormattedOutStream.flush();
393
394  return;
395}
396
397void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
398  mGen->HandleTagDeclDefinition(D);
399  return;
400}
401
402void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
403  mGen->CompleteTentativeDefinition(D);
404  return;
405}
406
407Backend::~Backend() {
408  delete mpModule;
409  delete mGen;
410  delete mPerFunctionPasses;
411  delete mPerModulePasses;
412  delete mCodeGenPasses;
413  return;
414}
415
416}  // namespace slang
417