blob: 9be6786b5f755a995a9a3986da6570c39c695594 [file] [log] [blame]
Daniel Dunbard69bacc2008-10-21 23:49:24 +00001//===--- Backend.cpp - Interface to LLVM backend technologies -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eli Friedman39d7c4d2009-05-18 22:50:54 +000010#include "clang/Frontend/ASTConsumers.h"
Chris Lattner682bf922009-03-29 16:50:03 +000011#include "clang/AST/ASTConsumer.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000012#include "clang/AST/ASTContext.h"
Chris Lattner682bf922009-03-29 16:50:03 +000013#include "clang/AST/DeclGroup.h"
14#include "clang/Basic/TargetInfo.h"
Daniel Dunbard58c03f2009-11-15 06:48:46 +000015#include "clang/Basic/TargetOptions.h"
16#include "clang/CodeGen/CodeGenOptions.h"
17#include "clang/CodeGen/ModuleBuilder.h"
Daniel Dunbar3be0d192009-12-03 09:12:54 +000018#include "clang/Frontend/FrontendDiagnostic.h"
Daniel Dunbard69bacc2008-10-21 23:49:24 +000019#include "llvm/Module.h"
20#include "llvm/ModuleProvider.h"
21#include "llvm/PassManager.h"
22#include "llvm/ADT/OwningPtr.h"
23#include "llvm/Assembly/PrintModulePass.h"
Daniel Dunbar70f92432008-10-23 05:50:47 +000024#include "llvm/Analysis/CallGraph.h"
25#include "llvm/Analysis/Verifier.h"
Daniel Dunbard69bacc2008-10-21 23:49:24 +000026#include "llvm/Bitcode/ReaderWriter.h"
27#include "llvm/CodeGen/RegAllocRegistry.h"
28#include "llvm/CodeGen/SchedulerRegistry.h"
Chris Lattner03eacc72009-07-14 20:39:15 +000029#include "llvm/Support/FormattedStream.h"
Daniel Dunbar10d861e2009-06-03 18:01:18 +000030#include "llvm/Support/StandardPasses.h"
Chris Lattner6f114eb2009-02-18 01:37:30 +000031#include "llvm/Support/Timer.h"
Daniel Dunbara034ba82009-02-17 19:47:34 +000032#include "llvm/Target/SubtargetFeature.h"
Daniel Dunbard69bacc2008-10-21 23:49:24 +000033#include "llvm/Target/TargetData.h"
34#include "llvm/Target/TargetMachine.h"
Daniel Dunbar821e2eb2009-12-12 23:01:36 +000035#include "llvm/Target/TargetOptions.h"
Daniel Dunbarf7d47c02009-07-15 20:25:38 +000036#include "llvm/Target/TargetRegistry.h"
Daniel Dunbard69bacc2008-10-21 23:49:24 +000037using namespace clang;
38using namespace llvm;
39
40namespace {
Benjamin Kramerbd218282009-11-28 10:07:24 +000041 class BackendConsumer : public ASTConsumer {
Daniel Dunbar125bbbe2009-12-04 08:17:40 +000042 Diagnostic &Diags;
Daniel Dunbard69bacc2008-10-21 23:49:24 +000043 BackendAction Action;
Daniel Dunbar3636e1d2009-11-30 08:39:32 +000044 const CodeGenOptions &CodeGenOpts;
45 const LangOptions &LangOpts;
46 const TargetOptions &TargetOpts;
Eli Friedman66d6f042009-05-18 22:20:00 +000047 llvm::raw_ostream *AsmOutStream;
Chris Lattner03eacc72009-07-14 20:39:15 +000048 llvm::formatted_raw_ostream FormattedOutStream;
Chris Lattner49f28ca2009-03-05 08:00:35 +000049 ASTContext *Context;
Daniel Dunbar90f41302008-10-29 08:50:02 +000050
Chris Lattner6f114eb2009-02-18 01:37:30 +000051 Timer LLVMIRGeneration;
52 Timer CodeGenerationTime;
Mike Stump1eb44332009-09-09 15:08:12 +000053
Daniel Dunbard69bacc2008-10-21 23:49:24 +000054 llvm::OwningPtr<CodeGenerator> Gen;
Mike Stump1eb44332009-09-09 15:08:12 +000055
Daniel Dunbard69bacc2008-10-21 23:49:24 +000056 llvm::Module *TheModule;
57 llvm::TargetData *TheTargetData;
Daniel Dunbard69bacc2008-10-21 23:49:24 +000058
Nuno Lopesdd492672008-10-24 22:51:00 +000059 mutable llvm::ModuleProvider *ModuleProvider;
Daniel Dunbard69bacc2008-10-21 23:49:24 +000060 mutable FunctionPassManager *CodeGenPasses;
61 mutable PassManager *PerModulePasses;
62 mutable FunctionPassManager *PerFunctionPasses;
63
64 FunctionPassManager *getCodeGenPasses() const;
65 PassManager *getPerModulePasses() const;
66 FunctionPassManager *getPerFunctionPasses() const;
67
68 void CreatePasses();
69
Daniel Dunbar125bbbe2009-12-04 08:17:40 +000070 /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
Daniel Dunbard69bacc2008-10-21 23:49:24 +000071 ///
Daniel Dunbar3be0d192009-12-03 09:12:54 +000072 /// \return True on success.
73 bool AddEmitPasses();
Daniel Dunbard69bacc2008-10-21 23:49:24 +000074
75 void EmitAssembly();
Mike Stump1eb44332009-09-09 15:08:12 +000076
77 public:
Daniel Dunbar3be0d192009-12-03 09:12:54 +000078 BackendConsumer(BackendAction action, Diagnostic &_Diags,
Chandler Carruth2811ccf2009-11-12 17:24:48 +000079 const LangOptions &langopts, const CodeGenOptions &compopts,
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +000080 const TargetOptions &targetopts, bool TimePasses,
81 const std::string &infile, llvm::raw_ostream *OS,
82 LLVMContext& C) :
Daniel Dunbar3be0d192009-12-03 09:12:54 +000083 Diags(_Diags),
Mike Stump1eb44332009-09-09 15:08:12 +000084 Action(action),
Chandler Carruth2811ccf2009-11-12 17:24:48 +000085 CodeGenOpts(compopts),
Daniel Dunbar3636e1d2009-11-30 08:39:32 +000086 LangOpts(langopts),
Daniel Dunbard58c03f2009-11-15 06:48:46 +000087 TargetOpts(targetopts),
Chris Lattner03eacc72009-07-14 20:39:15 +000088 AsmOutStream(OS),
Chris Lattner6f114eb2009-02-18 01:37:30 +000089 LLVMIRGeneration("LLVM IR Generation Time"),
90 CodeGenerationTime("Code Generation Time"),
Owen Anderson42253cc2009-07-01 17:00:06 +000091 Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
Eli Friedman66d6f042009-05-18 22:20:00 +000092 TheModule(0), TheTargetData(0), ModuleProvider(0),
Chris Lattner44502662009-02-18 01:23:44 +000093 CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
Mike Stump1eb44332009-09-09 15:08:12 +000094
Chris Lattner03eacc72009-07-14 20:39:15 +000095 if (AsmOutStream)
96 FormattedOutStream.setStream(*AsmOutStream,
97 formatted_raw_ostream::PRESERVE_STREAM);
Mike Stump1eb44332009-09-09 15:08:12 +000098
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +000099 llvm::TimePassesIsEnabled = TimePasses;
Chris Lattner44502662009-02-18 01:23:44 +0000100 }
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000101
102 ~BackendConsumer() {
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000103 delete TheTargetData;
Nuno Lopesdd492672008-10-24 22:51:00 +0000104 delete ModuleProvider;
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000105 delete CodeGenPasses;
106 delete PerModulePasses;
107 delete PerFunctionPasses;
108 }
109
Chris Lattner7bb0da02009-03-28 02:18:25 +0000110 virtual void Initialize(ASTContext &Ctx) {
111 Context = &Ctx;
Mike Stump1eb44332009-09-09 15:08:12 +0000112
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000113 if (llvm::TimePassesIsEnabled)
Chris Lattner6f114eb2009-02-18 01:37:30 +0000114 LLVMIRGeneration.startTimer();
Mike Stump1eb44332009-09-09 15:08:12 +0000115
Chris Lattner7bb0da02009-03-28 02:18:25 +0000116 Gen->Initialize(Ctx);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000117
118 TheModule = Gen->GetModule();
Nuno Lopes7d43a312008-10-24 23:27:18 +0000119 ModuleProvider = new ExistingModuleProvider(TheModule);
Chris Lattner7bb0da02009-03-28 02:18:25 +0000120 TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
Mike Stump1eb44332009-09-09 15:08:12 +0000121
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000122 if (llvm::TimePassesIsEnabled)
Chris Lattner6f114eb2009-02-18 01:37:30 +0000123 LLVMIRGeneration.stopTimer();
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000124 }
Mike Stump1eb44332009-09-09 15:08:12 +0000125
Chris Lattner682bf922009-03-29 16:50:03 +0000126 virtual void HandleTopLevelDecl(DeclGroupRef D) {
127 PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
Chris Lattner49f28ca2009-03-05 08:00:35 +0000128 Context->getSourceManager(),
129 "LLVM IR generation of declaration");
Mike Stump1eb44332009-09-09 15:08:12 +0000130
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000131 if (llvm::TimePassesIsEnabled)
Chris Lattner6f114eb2009-02-18 01:37:30 +0000132 LLVMIRGeneration.startTimer();
Chris Lattner682bf922009-03-29 16:50:03 +0000133
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000134 Gen->HandleTopLevelDecl(D);
Chris Lattner6f114eb2009-02-18 01:37:30 +0000135
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000136 if (llvm::TimePassesIsEnabled)
Chris Lattner6f114eb2009-02-18 01:37:30 +0000137 LLVMIRGeneration.stopTimer();
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000138 }
Mike Stump1eb44332009-09-09 15:08:12 +0000139
Chris Lattnerdacbc5d2009-03-28 04:11:33 +0000140 virtual void HandleTranslationUnit(ASTContext &C) {
Chris Lattner49f28ca2009-03-05 08:00:35 +0000141 {
Chris Lattner14f234e2009-03-06 06:46:31 +0000142 PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000143 if (llvm::TimePassesIsEnabled)
Chris Lattner49f28ca2009-03-05 08:00:35 +0000144 LLVMIRGeneration.startTimer();
Chris Lattner6f114eb2009-02-18 01:37:30 +0000145
Chris Lattnerdacbc5d2009-03-28 04:11:33 +0000146 Gen->HandleTranslationUnit(C);
Daniel Dunbard68ba0e2008-11-11 06:35:39 +0000147
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000148 if (llvm::TimePassesIsEnabled)
Chris Lattner49f28ca2009-03-05 08:00:35 +0000149 LLVMIRGeneration.stopTimer();
150 }
Chris Lattner6f114eb2009-02-18 01:37:30 +0000151
Chris Lattner49f28ca2009-03-05 08:00:35 +0000152 // EmitAssembly times and registers crash info itself.
Chris Lattner6f114eb2009-02-18 01:37:30 +0000153 EmitAssembly();
Mike Stump1eb44332009-09-09 15:08:12 +0000154
Daniel Dunbard68ba0e2008-11-11 06:35:39 +0000155 // Force a flush here in case we never get released.
156 if (AsmOutStream)
Chris Lattner03eacc72009-07-14 20:39:15 +0000157 FormattedOutStream.flush();
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000158 }
Mike Stump1eb44332009-09-09 15:08:12 +0000159
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000160 virtual void HandleTagDeclDefinition(TagDecl *D) {
Chris Lattner49f28ca2009-03-05 08:00:35 +0000161 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
162 Context->getSourceManager(),
163 "LLVM IR generation of declaration");
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000164 Gen->HandleTagDeclDefinition(D);
165 }
Douglas Gregorb6c8c8b2009-04-21 17:11:58 +0000166
167 virtual void CompleteTentativeDefinition(VarDecl *D) {
168 Gen->CompleteTentativeDefinition(D);
169 }
Mike Stump1eb44332009-09-09 15:08:12 +0000170 };
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000171}
172
173FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
174 if (!CodeGenPasses) {
Nuno Lopesdd492672008-10-24 22:51:00 +0000175 CodeGenPasses = new FunctionPassManager(ModuleProvider);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000176 CodeGenPasses->add(new TargetData(*TheTargetData));
177 }
178
179 return CodeGenPasses;
180}
181
182PassManager *BackendConsumer::getPerModulePasses() const {
183 if (!PerModulePasses) {
184 PerModulePasses = new PassManager();
185 PerModulePasses->add(new TargetData(*TheTargetData));
186 }
187
188 return PerModulePasses;
189}
190
191FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
192 if (!PerFunctionPasses) {
Nuno Lopes7d43a312008-10-24 23:27:18 +0000193 PerFunctionPasses = new FunctionPassManager(ModuleProvider);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000194 PerFunctionPasses->add(new TargetData(*TheTargetData));
195 }
196
197 return PerFunctionPasses;
198}
199
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000200bool BackendConsumer::AddEmitPasses() {
Daniel Dunbare8e26002009-02-26 22:39:37 +0000201 if (Action == Backend_EmitNothing)
202 return true;
203
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000204 if (Action == Backend_EmitBC) {
Dan Gohmanb8d42392009-09-26 15:06:14 +0000205 getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000206 } else if (Action == Backend_EmitLL) {
Dan Gohmanb8d42392009-09-26 15:06:14 +0000207 getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000208 } else {
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000209 bool Fast = CodeGenOpts.OptimizationLevel == 0;
Daniel Dunbar4c877cc2008-10-23 05:59:43 +0000210
Daniel Dunbar8b7650e2008-10-22 18:29:51 +0000211 // Create the TargetMachine for generating code.
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000212 std::string Error;
Daniel Dunbar82cfa7a2009-07-26 01:27:26 +0000213 std::string Triple = TheModule->getTargetTriple();
Daniel Dunbar9ab76fa2009-08-03 04:21:41 +0000214 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
Daniel Dunbarf7d47c02009-07-15 20:25:38 +0000215 if (!TheTarget) {
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000216 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
Daniel Dunbar8b7650e2008-10-22 18:29:51 +0000217 return false;
218 }
Daniel Dunbara034ba82009-02-17 19:47:34 +0000219
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000220 // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
221 // being gross, this is also totally broken if we ever care about
222 // concurrency.
Daniel Dunbar821e2eb2009-12-12 23:01:36 +0000223 llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
224 if (CodeGenOpts.FloatABI == "soft")
225 llvm::FloatABIType = llvm::FloatABI::Soft;
226 else if (CodeGenOpts.FloatABI == "hard")
227 llvm::FloatABIType = llvm::FloatABI::Hard;
228 else {
229 assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
230 llvm::FloatABIType = llvm::FloatABI::Default;
231 }
232 NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
233 llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
234 UnwindTablesMandatory = CodeGenOpts.UnwindTables;
235
236 TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
237
238 // FIXME: Parse this earlier.
239 if (CodeGenOpts.RelocationModel == "static") {
240 TargetMachine::setRelocationModel(llvm::Reloc::Static);
241 } else if (CodeGenOpts.RelocationModel == "pic") {
242 TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
243 } else {
244 assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
245 "Invalid PIC model!");
246 TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
247 }
248 // FIXME: Parse this earlier.
249 if (CodeGenOpts.CodeModel == "small") {
250 TargetMachine::setCodeModel(llvm::CodeModel::Small);
251 } else if (CodeGenOpts.CodeModel == "kernel") {
252 TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
253 } else if (CodeGenOpts.CodeModel == "medium") {
254 TargetMachine::setCodeModel(llvm::CodeModel::Medium);
255 } else if (CodeGenOpts.CodeModel == "large") {
256 TargetMachine::setCodeModel(llvm::CodeModel::Large);
257 } else {
258 assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
259 TargetMachine::setCodeModel(llvm::CodeModel::Default);
260 }
261
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000262 std::vector<const char *> BackendArgs;
263 BackendArgs.push_back("clang"); // Fake program name.
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000264 if (!CodeGenOpts.DebugPass.empty()) {
265 BackendArgs.push_back("-debug-pass");
266 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
267 }
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000268 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
269 BackendArgs.push_back("-limit-float-precision");
270 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
271 }
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000272 if (llvm::TimePassesIsEnabled)
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000273 BackendArgs.push_back("-time-passes");
Daniel Dunbarf219e7c2009-11-29 07:18:39 +0000274 BackendArgs.push_back(0);
275 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
276 (char**) &BackendArgs[0]);
277
Daniel Dunbara034ba82009-02-17 19:47:34 +0000278 std::string FeaturesStr;
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000279 if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
Daniel Dunbara034ba82009-02-17 19:47:34 +0000280 SubtargetFeatures Features;
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000281 Features.setCPU(TargetOpts.CPU);
Daniel Dunbar3636e1d2009-11-30 08:39:32 +0000282 for (std::vector<std::string>::const_iterator
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000283 it = TargetOpts.Features.begin(),
284 ie = TargetOpts.Features.end(); it != ie; ++it)
Daniel Dunbara034ba82009-02-17 19:47:34 +0000285 Features.AddFeature(*it);
286 FeaturesStr = Features.getString();
287 }
Daniel Dunbar2b1f59f2009-08-04 04:02:57 +0000288 TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
Mike Stump1eb44332009-09-09 15:08:12 +0000289
Daniel Dunbar8b7650e2008-10-22 18:29:51 +0000290 // Set register scheduler & allocation policy.
291 RegisterScheduler::setDefault(createDefaultScheduler);
Mike Stump1eb44332009-09-09 15:08:12 +0000292 RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
293 createLinearScanRegisterAllocator);
Daniel Dunbar8b7650e2008-10-22 18:29:51 +0000294
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000295 // From llvm-gcc:
296 // If there are passes we have to run on the entire module, we do codegen
297 // as a separate "pass" after that happens.
298 // FIXME: This is disabled right now until bugs can be worked out. Reenable
299 // this for fast -O0 compiles!
300 FunctionPassManager *PM = getCodeGenPasses();
Bill Wendling6e9b8f62009-04-29 23:53:23 +0000301 CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
302
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000303 switch (CodeGenOpts.OptimizationLevel) {
Bill Wendling6e9b8f62009-04-29 23:53:23 +0000304 default: break;
305 case 0: OptLevel = CodeGenOpt::None; break;
Bill Wendling6e9b8f62009-04-29 23:53:23 +0000306 case 3: OptLevel = CodeGenOpt::Aggressive; break;
307 }
308
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000309 // Normal mode, emit a .s file by running the code generator.
310 // Note, this also adds codegenerator level optimization passes.
Chris Lattner03eacc72009-07-14 20:39:15 +0000311 switch (TM->addPassesToEmitFile(*PM, FormattedOutStream,
Bill Wendling6e9b8f62009-04-29 23:53:23 +0000312 TargetMachine::AssemblyFile, OptLevel)) {
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000313 default:
314 case FileModel::Error:
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000315 Diags.Report(diag::err_fe_unable_to_interface_with_target);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000316 return false;
317 case FileModel::AsmFile:
318 break;
319 }
Mike Stump1eb44332009-09-09 15:08:12 +0000320
Duncan Sands813a2bb2009-05-31 04:09:57 +0000321 if (TM->addPassesToEmitFileFinish(*CodeGenPasses, (MachineCodeEmitter *)0,
322 OptLevel)) {
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000323 Diags.Report(diag::err_fe_unable_to_interface_with_target);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000324 return false;
325 }
326 }
327
328 return true;
329}
330
331void BackendConsumer::CreatePasses() {
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000332 unsigned OptLevel = CodeGenOpts.OptimizationLevel;
333 CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
Daniel Dunbar8d353142009-11-10 17:50:53 +0000334
335 // Handle disabling of LLVM optimization, where we want to preserve the
336 // internal module before any optimization.
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000337 if (CodeGenOpts.DisableLLVMOpts) {
Daniel Dunbar8d353142009-11-10 17:50:53 +0000338 OptLevel = 0;
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000339 Inlining = CodeGenOpts.NoInlining;
Daniel Dunbar8d353142009-11-10 17:50:53 +0000340 }
341
Daniel Dunbar70f92432008-10-23 05:50:47 +0000342 // In -O0 if checking is disabled, we don't even have per-function passes.
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000343 if (CodeGenOpts.VerifyModule)
Daniel Dunbar70f92432008-10-23 05:50:47 +0000344 getPerFunctionPasses()->add(createVerifierPass());
345
Daniel Dunbar10d861e2009-06-03 18:01:18 +0000346 // Assume that standard function passes aren't run for -O0.
Daniel Dunbar8d353142009-11-10 17:50:53 +0000347 if (OptLevel > 0)
348 llvm::createStandardFunctionPasses(getPerFunctionPasses(), OptLevel);
Daniel Dunbar10d861e2009-06-03 18:01:18 +0000349
350 llvm::Pass *InliningPass = 0;
Daniel Dunbar8d353142009-11-10 17:50:53 +0000351 switch (Inlining) {
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000352 case CodeGenOptions::NoInlining: break;
353 case CodeGenOptions::NormalInlining: {
Daniel Dunbar90de51f2009-12-08 23:15:55 +0000354 // Set the inline threshold following llvm-gcc.
355 //
356 // FIXME: Derive these constants in a principled fashion.
357 unsigned Threshold = 200;
358 if (CodeGenOpts.OptimizeSize)
359 Threshold = 50;
360 else if (OptLevel > 2)
361 Threshold = 250;
Eli Friedmanb9b7dd62009-06-11 20:33:41 +0000362 InliningPass = createFunctionInliningPass(Threshold);
Daniel Dunbar10d861e2009-06-03 18:01:18 +0000363 break;
Eli Friedmanb9b7dd62009-06-11 20:33:41 +0000364 }
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000365 case CodeGenOptions::OnlyAlwaysInlining:
Daniel Dunbar10d861e2009-06-03 18:01:18 +0000366 InliningPass = createAlwaysInlinerPass(); // Respect always_inline
367 break;
Daniel Dunbar70f92432008-10-23 05:50:47 +0000368 }
369
370 // For now we always create per module passes.
371 PassManager *PM = getPerModulePasses();
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000372 llvm::createStandardModulePasses(PM, OptLevel, CodeGenOpts.OptimizeSize,
373 CodeGenOpts.UnitAtATime,
374 CodeGenOpts.UnrollLoops,
Daniel Dunbar3636e1d2009-11-30 08:39:32 +0000375 /*SimplifyLibCalls=*/!LangOpts.NoBuiltin,
Daniel Dunbar10d861e2009-06-03 18:01:18 +0000376 /*HaveExceptions=*/true,
377 InliningPass);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000378}
379
380/// EmitAssembly - Handle interaction with LLVM backend to generate
Mike Stump1eb44332009-09-09 15:08:12 +0000381/// actual machine code.
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000382void BackendConsumer::EmitAssembly() {
383 // Silently ignore if we weren't initialized for some reason.
384 if (!TheModule || !TheTargetData)
385 return;
Mike Stump1eb44332009-09-09 15:08:12 +0000386
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000387 TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000388
Daniel Dunbard611bac2008-10-27 20:40:41 +0000389 // Make sure IR generation is happy with the module. This is
390 // released by the module provider.
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000391 Module *M = Gen->ReleaseModule();
392 if (!M) {
Daniel Dunbard611bac2008-10-27 20:40:41 +0000393 // The module has been released by IR gen on failures, do not
394 // double free.
395 ModuleProvider->releaseModule();
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000396 TheModule = 0;
397 return;
398 }
399
400 assert(TheModule == M && "Unexpected module change during IR generation");
401
402 CreatePasses();
Daniel Dunbar3be0d192009-12-03 09:12:54 +0000403 if (!AddEmitPasses())
404 return;
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000405
406 // Run passes. For now we do all passes at once, but eventually we
407 // would like to have the option of streaming code generation.
408
409 if (PerFunctionPasses) {
Chris Lattner14f234e2009-03-06 06:46:31 +0000410 PrettyStackTraceString CrashInfo("Per-function optimization");
Mike Stump1eb44332009-09-09 15:08:12 +0000411
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000412 PerFunctionPasses->doInitialization();
413 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
414 if (!I->isDeclaration())
415 PerFunctionPasses->run(*I);
416 PerFunctionPasses->doFinalization();
417 }
Mike Stump1eb44332009-09-09 15:08:12 +0000418
Chris Lattner49f28ca2009-03-05 08:00:35 +0000419 if (PerModulePasses) {
Chris Lattner14f234e2009-03-06 06:46:31 +0000420 PrettyStackTraceString CrashInfo("Per-module optimization passes");
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000421 PerModulePasses->run(*M);
Chris Lattner49f28ca2009-03-05 08:00:35 +0000422 }
Mike Stump1eb44332009-09-09 15:08:12 +0000423
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000424 if (CodeGenPasses) {
Chris Lattner14f234e2009-03-06 06:46:31 +0000425 PrettyStackTraceString CrashInfo("Code generation");
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000426 CodeGenPasses->doInitialization();
427 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
428 if (!I->isDeclaration())
429 CodeGenPasses->run(*I);
430 CodeGenPasses->doFinalization();
431 }
432}
433
434ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
435 Diagnostic &Diags,
Daniel Dunbara034ba82009-02-17 19:47:34 +0000436 const LangOptions &LangOpts,
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000437 const CodeGenOptions &CodeGenOpts,
Daniel Dunbard58c03f2009-11-15 06:48:46 +0000438 const TargetOptions &TargetOpts,
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000439 bool TimePasses,
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000440 const std::string& InFile,
Owen Anderson42253cc2009-07-01 17:00:06 +0000441 llvm::raw_ostream* OS,
Owen Anderson8f1ca782009-07-01 23:14:14 +0000442 LLVMContext& C) {
Chandler Carruth2811ccf2009-11-12 17:24:48 +0000443 return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts,
Daniel Dunbarb33fbaa2009-11-30 08:39:52 +0000444 TargetOpts, TimePasses, InFile, OS, C);
Daniel Dunbard69bacc2008-10-21 23:49:24 +0000445}