slang_backend.cpp revision 5e3b677a3041c86a7f860238dd1f5ff9d111b507
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/LLVMContext.h"
45#include "llvm/Module.h"
46#include "llvm/Metadata.h"
47
48#include "llvm/Transforms/IPO/PassManagerBuilder.h"
49
50#include "llvm/Target/TargetData.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
60namespace slang {
61
62void Backend::CreateFunctionPasses() {
63  if (!mPerFunctionPasses) {
64    mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
65    mPerFunctionPasses->add(new llvm::TargetData(mpModule));
66
67    llvm::PassManagerBuilder PMBuilder;
68    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
69    PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
70  }
71  return;
72}
73
74void Backend::CreateModulePasses() {
75  if (!mPerModulePasses) {
76    mPerModulePasses = new llvm::PassManager();
77    mPerModulePasses->add(new llvm::TargetData(mpModule));
78
79    llvm::PassManagerBuilder PMBuilder;
80    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
81    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
82    PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
83    if (mCodeGenOpts.UnitAtATime) {
84      PMBuilder.DisableUnitAtATime = 0;
85    } else {
86      PMBuilder.DisableUnitAtATime = 1;
87    }
88
89    if (mCodeGenOpts.UnrollLoops) {
90      PMBuilder.DisableUnrollLoops = 0;
91    } else {
92      PMBuilder.DisableUnrollLoops = 1;
93    }
94
95    PMBuilder.DisableSimplifyLibCalls = false;
96    PMBuilder.populateModulePassManager(*mPerModulePasses);
97  }
98  return;
99}
100
101bool Backend::CreateCodeGenPasses() {
102  if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object))
103    return true;
104
105  // Now we add passes for code emitting
106  if (mCodeGenPasses) {
107    return true;
108  } else {
109    mCodeGenPasses = new llvm::FunctionPassManager(mpModule);
110    mCodeGenPasses->add(new llvm::TargetData(mpModule));
111  }
112
113  // Create the TargetMachine for generating code.
114  std::string Triple = mpModule->getTargetTriple();
115
116  std::string Error;
117  const llvm::Target* TargetInfo =
118      llvm::TargetRegistry::lookupTarget(Triple, Error);
119  if (TargetInfo == NULL) {
120    mDiagEngine.Report(clang::diag::err_fe_unable_to_create_target) << Error;
121    return false;
122  }
123
124  llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim;
125
126  // Use hardware FPU.
127  //
128  // FIXME: Need to detect the CPU capability and decide whether to use softfp.
129  // To use softfp, change following 2 lines to
130  //
131  //  llvm::FloatABIType = llvm::FloatABI::Soft;
132  //  llvm::UseSoftFloat = true;
133  llvm::FloatABIType = llvm::FloatABI::Hard;
134  llvm::UseSoftFloat = false;
135
136  // BCC needs all unknown symbols resolved at compilation time. So we don't
137  // need any relocation model.
138  llvm::Reloc::Model RM = llvm::Reloc::Static;
139
140  // This is set for the linker (specify how large of the virtual addresses we
141  // can access for all unknown symbols.)
142  llvm::CodeModel::Model CM;
143  if (mpModule->getPointerSize() == llvm::Module::Pointer32) {
144    CM = llvm::CodeModel::Small;
145  } else {
146    // The target may have pointer size greater than 32 (e.g. x86_64
147    // architecture) may need large data address model
148    CM = llvm::CodeModel::Medium;
149  }
150
151  // Setup feature string
152  std::string FeaturesStr;
153  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
154    llvm::SubtargetFeatures Features;
155
156    for (std::vector<std::string>::const_iterator
157             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
158         I != E;
159         I++)
160      Features.AddFeature(*I);
161
162    FeaturesStr = Features.getString();
163  }
164
165  llvm::TargetMachine *TM =
166    TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
167                                    RM, CM);
168
169  // Register scheduler
170  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
171
172  // Register allocation policy:
173  //  createFastRegisterAllocator: fast but bad quality
174  //  createLinearScanRegisterAllocator: not so fast but good quality
175  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
176                                     llvm::createFastRegisterAllocator :
177                                     llvm::createLinearScanRegisterAllocator);
178
179  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
180  if (mCodeGenOpts.OptimizationLevel == 0) {
181    OptLevel = llvm::CodeGenOpt::None;
182  } else if (mCodeGenOpts.OptimizationLevel == 3) {
183    OptLevel = llvm::CodeGenOpt::Aggressive;
184  }
185
186  llvm::TargetMachine::CodeGenFileType CGFT =
187      llvm::TargetMachine::CGFT_AssemblyFile;
188  if (mOT == Slang::OT_Object) {
189    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
190  }
191  if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream,
192                              CGFT, OptLevel)) {
193    mDiagEngine.Report(clang::diag::err_fe_unable_to_interface_with_target);
194    return false;
195  }
196
197  return true;
198}
199
200Backend::Backend(clang::DiagnosticsEngine *DiagEngine,
201                 const clang::CodeGenOptions &CodeGenOpts,
202                 const clang::TargetOptions &TargetOpts,
203                 PragmaList *Pragmas,
204                 llvm::raw_ostream *OS,
205                 Slang::OutputType OT)
206    : ASTConsumer(),
207      mTargetOpts(TargetOpts),
208      mpModule(NULL),
209      mpOS(OS),
210      mOT(OT),
211      mGen(NULL),
212      mPerFunctionPasses(NULL),
213      mPerModulePasses(NULL),
214      mCodeGenPasses(NULL),
215      mLLVMContext(llvm::getGlobalContext()),
216      mDiagEngine(*DiagEngine),
217      mCodeGenOpts(CodeGenOpts),
218      mPragmas(Pragmas) {
219  FormattedOutStream.setStream(*mpOS,
220                               llvm::formatted_raw_ostream::PRESERVE_STREAM);
221  mGen = CreateLLVMCodeGen(mDiagEngine, "", mCodeGenOpts, mLLVMContext);
222  return;
223}
224
225void Backend::Initialize(clang::ASTContext &Ctx) {
226  mGen->Initialize(Ctx);
227
228  mpModule = mGen->GetModule();
229
230  return;
231}
232
233// Encase the Bitcode in a wrapper containing RS version information.
234void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
235  bcinfo::AndroidBitcodeWrapper wrapper;
236  size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
237      &wrapper, Bitcode.str().length(), getTargetAPI(),
238      SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
239
240  slangAssert(actualWrapperLen > 0);
241
242  // Write out the bitcode wrapper.
243  FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
244
245  // Write out the actual encoded bitcode.
246  FormattedOutStream << Bitcode.str();
247  return;
248}
249
250void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
251  mGen->HandleTopLevelDecl(D);
252  return;
253}
254
255void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
256  HandleTranslationUnitPre(Ctx);
257
258  mGen->HandleTranslationUnit(Ctx);
259
260  // 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.)
263
264  // Silently ignore if we weren't initialized for some reason.
265  if (!mpModule)
266    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
275  slangAssert(mpModule == M &&
276              "Unexpected module change during LLVM IR generation");
277
278  // Insert #pragma information into metadata section of module
279  if (!mPragmas->empty()) {
280    llvm::NamedMDNode *PragmaMetadata =
281        mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
282    for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
283         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));
290
291      // Create MDNode and insert into PragmaMetadata
292      PragmaMetadata->addOperand(
293          llvm::MDNode::get(mLLVMContext, Pragma));
294    }
295  }
296
297  HandleTranslationUnitPost(mpModule);
298
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
320  switch (mOT) {
321    case Slang::OT_Assembly:
322    case Slang::OT_Object: {
323      if (!CreateCodeGenPasses())
324        return;
325
326      mCodeGenPasses->doInitialization();
327
328      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
329          I != E;
330          I++)
331        if (!I->isDeclaration())
332          mCodeGenPasses->run(*I);
333
334      mCodeGenPasses->doFinalization();
335      break;
336    }
337    case Slang::OT_LLVMAssembly: {
338      llvm::PassManager *LLEmitPM = new llvm::PassManager();
339      LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
340      LLEmitPM->run(*mpModule);
341      break;
342    }
343    case Slang::OT_Bitcode: {
344      llvm::PassManager *BCEmitPM = new llvm::PassManager();
345      std::string BCStr;
346      llvm::raw_string_ostream Bitcode(BCStr);
347      if (getTargetAPI() < SLANG_ICS_TARGET_API) {
348        // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
349        BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
350      } else {
351        BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
352      }
353
354      BCEmitPM->run(*mpModule);
355      WrapBitcode(Bitcode);
356      break;
357    }
358    case Slang::OT_Nothing: {
359      return;
360    }
361    default: {
362      slangAssert(false && "Unknown output type");
363    }
364  }
365
366  FormattedOutStream.flush();
367
368  return;
369}
370
371void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
372  mGen->HandleTagDeclDefinition(D);
373  return;
374}
375
376void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
377  mGen->CompleteTentativeDefinition(D);
378  return;
379}
380
381Backend::~Backend() {
382  delete mpModule;
383  delete mGen;
384  delete mPerFunctionPasses;
385  delete mPerModulePasses;
386  delete mCodeGenPasses;
387  return;
388}
389
390}  // namespace slang
391