1#include "Backend.h"
2
3#include <cassert>
4#include <string>
5#include <vector>
6
7#include "clang/AST/ASTContext.h"
8#include "clang/AST/Decl.h"
9#include "clang/AST/DeclGroup.h"
10
11#include "clang/Basic/Diagnostic.h"
12#include "clang/Basic/TargetInfo.h"
13#include "clang/Basic/TargetOptions.h"
14
15#include "clang/CodeGen/ModuleBuilder.h"
16
17#include "clang/Frontend/CodeGenOptions.h"
18#include "clang/Frontend/FrontendDiagnostic.h"
19
20#include "llvm/Assembly/PrintModulePass.h"
21
22#include "llvm/Bitcode/ReaderWriter.h"
23
24#include "llvm/CodeGen/RegAllocRegistry.h"
25#include "llvm/CodeGen/SchedulerRegistry.h"
26
27#include "llvm/Instructions.h"
28#include "llvm/LLVMContext.h"
29#include "llvm/Module.h"
30#include "llvm/Metadata.h"
31
32#include "llvm/MC/SubtargetFeature.h"
33
34#include "llvm/Support/Casting.h"
35#include "llvm/Support/InstIterator.h"
36
37#include "llvm/Target/TargetData.h"
38#include "llvm/Target/TargetMachine.h"
39#include "llvm/Target/TargetOptions.h"
40#include "llvm/Support/TargetRegistry.h"
41
42namespace ndkpc {
43
44void Backend::CreateFunctionPasses() {
45  if (!mpPerFunctionPasses) {
46    mpPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
47    mpPerFunctionPasses->add(new llvm::TargetData(mpModule));
48
49    // FIXME REMOVE
50    //llvm::createStandardFunctionPasses(mpPerFunctionPasses,
51    //                                   mCodeGenOpts.OptimizationLevel);
52    llvm::PassManagerBuilder PMBuilder;
53    PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
54    PMBuilder.populateFunctionPassManager(*mpPerFunctionPasses);
55  }
56  return;
57}
58
59void Backend::CreateModulePasses() {
60  if (!mpPerModulePasses) {
61	  mpPerModulePasses = new llvm::PassManager();
62	  mpPerModulePasses->add(new llvm::TargetData(mpModule));
63
64	  llvm::PassManagerBuilder PMBuilder;
65	  PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
66	  PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize;
67	  if (mCodeGenOpts.UnitAtATime) {
68		  PMBuilder.DisableUnitAtATime = 0;
69	  } else {
70		  PMBuilder.DisableUnitAtATime = 1;
71	  }
72
73	  if (mCodeGenOpts.UnrollLoops) {
74		  PMBuilder.DisableUnrollLoops = 0;
75	  } else {
76		  PMBuilder.DisableUnrollLoops = 1;
77	  }
78
79	  PMBuilder.DisableSimplifyLibCalls = false;
80	  PMBuilder.populateModulePassManager(*mpPerModulePasses);
81  }
82  return;
83}
84
85bool Backend::CreateCodeGenPasses() {
86  if ((mOT != Compiler::OT_Assembly) && (mOT != Compiler::OT_Object))
87    return true;
88
89  // Now we add passes for code emitting
90  if (mpCodeGenPasses) {
91    return true;
92  } else {
93    mpCodeGenPasses = new llvm::FunctionPassManager(mpModule);
94    mpCodeGenPasses->add(new llvm::TargetData(mpModule));
95  }
96
97  // Create the TargetMachine for generating code.
98  std::string Triple = mpModule->getTargetTriple();
99
100  std::string Error;
101  const llvm::Target* TargetInfo =
102      llvm::TargetRegistry::lookupTarget(Triple, Error);
103  if (TargetInfo == NULL) {
104    mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error;
105    return false;
106  }
107
108  llvm::TargetOptions Options;
109  Options.NoFramePointerElim = mCodeGenOpts.DisableFPElim;
110
111  // Use hardware FPU.
112  //
113  // FIXME: Need to detect the CPU capability and decide whether to use softfp.
114  // To use softfp, change following 2 lines to
115  //
116  //  llvm::FloatABIType = llvm::FloatABI::Soft;
117  //  llvm::UseSoftFloat = true;
118  Options.FloatABIType = llvm::FloatABI::Hard;
119  Options.UseSoftFloat = false;
120
121  // BCC needs all unknown symbols resolved at compilation time. So we don't
122  // need any relocation model.
123  llvm::Reloc::Model RelocModel = llvm::Reloc::Static;
124
125  // This is set for the linker (specify how large of the virtual addresses we
126  // can access for all unknown symbols.)
127  llvm::CodeModel::Model CodeModel;
128  if (mpModule->getPointerSize() == llvm::Module::Pointer32)
129    CodeModel = llvm::CodeModel::Small;
130  else
131    // The target may have pointer size greater than 32 (e.g. x86_64
132    // architecture) may need large data address model
133    CodeModel = llvm::CodeModel::Medium;
134
135  // Setup feature string
136  std::string FeaturesStr;
137  if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) {
138    llvm::SubtargetFeatures Features;
139
140    for (std::vector<std::string>::const_iterator
141             I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end();
142         I != E;
143         I++)
144      Features.AddFeature(*I);
145
146    FeaturesStr = Features.getString();
147  }
148  // Setup optimization level
149  llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default;
150  if (mCodeGenOpts.OptimizationLevel == 0)
151    OptLevel = llvm::CodeGenOpt::None;
152  else if (mCodeGenOpts.OptimizationLevel == 3)
153    OptLevel = llvm::CodeGenOpt::Aggressive;
154
155  llvm::TargetMachine *TM =
156      TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr,
157				      Options, RelocModel, CodeModel, OptLevel);
158
159  // Register scheduler
160  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
161
162  // Register allocation policy:
163  //  createFastRegisterAllocator: fast but bad quality
164  //  createLinearScanRegisterAllocator: not so fast but good quality
165  llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ?
166                                     llvm::createFastRegisterAllocator :
167                                     llvm::createGreedyRegisterAllocator);
168
169  llvm::TargetMachine::CodeGenFileType CGFT =
170      llvm::TargetMachine::CGFT_AssemblyFile;
171  if (mOT == Compiler::OT_Object)
172    CGFT = llvm::TargetMachine::CGFT_ObjectFile;
173  if (TM->addPassesToEmitFile(*mpCodeGenPasses, FormattedOutStream,
174                              CGFT, OptLevel)) {
175    mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target);
176    return false;
177  }
178
179  return true;
180}
181
182Backend::Backend(const clang::CodeGenOptions &CodeGenOpts,
183                 const clang::TargetOptions &TargetOpts,
184                 clang::DiagnosticsEngine *Diags,
185                 llvm::raw_ostream *OS,
186                 Compiler::OutputType OT)
187    : ASTConsumer(),
188      mCodeGenOpts(CodeGenOpts),
189      mTargetOpts(TargetOpts),
190      mLLVMContext(llvm::getGlobalContext()),
191      mDiags(*Diags),
192      mpModule(NULL),
193      mpOS(OS),
194      mOT(OT),
195      mpGen(NULL),
196      mpPerFunctionPasses(NULL),
197      mpPerModulePasses(NULL),
198      mpCodeGenPasses(NULL) {
199  FormattedOutStream.setStream(*mpOS,
200                               llvm::formatted_raw_ostream::PRESERVE_STREAM);
201  mpGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext);
202  return;
203}
204
205void Backend::Initialize(clang::ASTContext &Ctx) {
206  mpGen->Initialize(Ctx);
207  mpModule = mpGen->GetModule();
208  return;
209}
210
211bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
212  mpGen->HandleTopLevelDecl(D);
213  return true;
214}
215
216void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
217  mpGen->HandleTranslationUnit(Ctx);
218
219  // Here, we complete a translation unit (whole translation unit is now in LLVM
220  // IR). Now, interact with LLVM backend to generate actual machine code (asm
221  // or machine code, whatever.)
222
223  // Silently ignore if we weren't initialized for some reason.
224  if (!mpModule)
225    return;
226
227  llvm::Module *M = mpGen->ReleaseModule();
228  if (!M) {
229    // The module has been released by IR gen on failures, do not double free.
230    mpModule = NULL;
231    return;
232  }
233
234  assert(mpModule == M &&
235              "Unexpected module change during LLVM IR generation");
236
237  // Handle illigal CallSite
238  for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
239       I != E;
240       ++I) {
241    for (llvm::inst_iterator i = llvm::inst_begin(*I), e = llvm::inst_end(*I);
242         i != e;
243         ++i) {
244      if (llvm::CallInst* CallInst = llvm::dyn_cast<llvm::CallInst>(&*i)) {
245        if (CallInst->isInlineAsm()) {
246          // TODO: Should we reflect source location information to diagnostic
247          //       class and show to users?
248          llvm::errs() << "Inline assembly is illigal. Please don't use it." << "\n";
249          exit(1);
250        }
251      }
252    }
253  }
254
255  // Create and run per-function passes
256  CreateFunctionPasses();
257  if (mpPerFunctionPasses) {
258    mpPerFunctionPasses->doInitialization();
259
260    for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
261         I != E;
262         I++)
263      if (!I->isDeclaration())
264        mpPerFunctionPasses->run(*I);
265
266    mpPerFunctionPasses->doFinalization();
267  }
268
269  // Create and run module passes
270  CreateModulePasses();
271  if (mpPerModulePasses)
272    mpPerModulePasses->run(*mpModule);
273
274  switch (mOT) {
275    case Compiler::OT_Assembly:
276    case Compiler::OT_Object: {
277      if (!CreateCodeGenPasses())
278        return;
279
280      mpCodeGenPasses->doInitialization();
281
282      for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
283          I != E;
284          I++)
285        if (!I->isDeclaration())
286          mpCodeGenPasses->run(*I);
287
288      mpCodeGenPasses->doFinalization();
289      break;
290    }
291    case Compiler::OT_LLVMAssembly: {
292      llvm::PassManager *LLEmitPM = new llvm::PassManager();
293      LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream));
294      LLEmitPM->run(*mpModule);
295      break;
296    }
297    case Compiler::OT_Bitcode: {
298      llvm::PassManager *BCEmitPM = new llvm::PassManager();
299      BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream));
300      BCEmitPM->run(*mpModule);
301      break;
302    }
303    case Compiler::OT_Nothing: {
304      return;
305    }
306    default: {
307      assert(false && "Unknown output type");
308    }
309  }
310
311  FormattedOutStream.flush();
312  return;
313}
314
315void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
316  mpGen->HandleTagDeclDefinition(D);
317  return;
318}
319
320void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
321  mpGen->CompleteTentativeDefinition(D);
322  return;
323}
324
325Backend::~Backend() {
326  delete mpModule;
327  delete mpGen;
328  delete mpPerFunctionPasses;
329  delete mpPerModulePasses;
330  delete mpCodeGenPasses;
331  return;
332}
333
334}
335