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