blob: 92b0c8fbc60d0fab603b997cb3fd6d7570ab5546 [file] [log] [blame]
Daniel Dunbar85e44e22008-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
10#include "ASTConsumers.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000011#include "clang/AST/ASTContext.h"
12#include "clang/AST/ASTConsumer.h"
13#include "clang/AST/TranslationUnit.h"
14#include "clang/Basic/TargetInfo.h"
15#include "clang/CodeGen/ModuleBuilder.h"
Daniel Dunbaraa7a0662008-10-23 05:50:47 +000016#include "clang/Driver/CompileOptions.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000017#include "llvm/Module.h"
18#include "llvm/ModuleProvider.h"
19#include "llvm/PassManager.h"
20#include "llvm/ADT/OwningPtr.h"
21#include "llvm/Assembly/PrintModulePass.h"
Daniel Dunbaraa7a0662008-10-23 05:50:47 +000022#include "llvm/Analysis/CallGraph.h"
23#include "llvm/Analysis/Verifier.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000024#include "llvm/Bitcode/ReaderWriter.h"
25#include "llvm/CodeGen/RegAllocRegistry.h"
26#include "llvm/CodeGen/SchedulerRegistry.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000027#include "llvm/Support/raw_ostream.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000028#include "llvm/Support/Compiler.h"
29#include "llvm/System/Path.h"
30#include "llvm/System/Program.h"
Daniel Dunbar9101a632009-02-17 19:47:34 +000031#include "llvm/Target/SubtargetFeature.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000032#include "llvm/Target/TargetData.h"
33#include "llvm/Target/TargetMachine.h"
34#include "llvm/Target/TargetMachineRegistry.h"
Daniel Dunbaraa7a0662008-10-23 05:50:47 +000035#include "llvm/Transforms/Scalar.h"
36#include "llvm/Transforms/IPO.h"
Daniel Dunbar85e44e22008-10-21 23:49:24 +000037using namespace clang;
38using namespace llvm;
39
40namespace {
41 class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer {
42 BackendAction Action;
Daniel Dunbaraa7a0662008-10-23 05:50:47 +000043 CompileOptions CompileOpts;
Daniel Dunbar85e44e22008-10-21 23:49:24 +000044 const std::string &InputFile;
45 std::string OutputFile;
Daniel Dunbar1a27a192008-10-29 08:50:02 +000046 bool GenerateDebugInfo;
47
Daniel Dunbar85e44e22008-10-21 23:49:24 +000048 llvm::OwningPtr<CodeGenerator> Gen;
49
50 llvm::Module *TheModule;
51 llvm::TargetData *TheTargetData;
52 llvm::raw_ostream *AsmOutStream;
53
Nuno Lopes74d92782008-10-24 22:51:00 +000054 mutable llvm::ModuleProvider *ModuleProvider;
Daniel Dunbar85e44e22008-10-21 23:49:24 +000055 mutable FunctionPassManager *CodeGenPasses;
56 mutable PassManager *PerModulePasses;
57 mutable FunctionPassManager *PerFunctionPasses;
58
59 FunctionPassManager *getCodeGenPasses() const;
60 PassManager *getPerModulePasses() const;
61 FunctionPassManager *getPerFunctionPasses() const;
62
63 void CreatePasses();
64
65 /// AddEmitPasses - Add passes necessary to emit assembly or LLVM
66 /// IR.
67 ///
Daniel Dunbar85e44e22008-10-21 23:49:24 +000068 /// \return True on success. On failure \arg Error will be set to
69 /// a user readable error message.
Daniel Dunbar655d5092008-10-23 05:59:43 +000070 bool AddEmitPasses(std::string &Error);
Daniel Dunbar85e44e22008-10-21 23:49:24 +000071
72 void EmitAssembly();
73
74 public:
75 BackendConsumer(BackendAction action, Diagnostic &Diags,
Daniel Dunbar9101a632009-02-17 19:47:34 +000076 const LangOptions &langopts, const CompileOptions &compopts,
Daniel Dunbar85e44e22008-10-21 23:49:24 +000077 const std::string& infile, const std::string& outfile,
Daniel Dunbar1a27a192008-10-29 08:50:02 +000078 bool debug) :
Daniel Dunbar85e44e22008-10-21 23:49:24 +000079 Action(action),
Daniel Dunbaraa7a0662008-10-23 05:50:47 +000080 CompileOpts(compopts),
Daniel Dunbar85e44e22008-10-21 23:49:24 +000081 InputFile(infile),
82 OutputFile(outfile),
Daniel Dunbar1a27a192008-10-29 08:50:02 +000083 GenerateDebugInfo(debug),
Daniel Dunbar9101a632009-02-17 19:47:34 +000084 Gen(CreateLLVMCodeGen(Diags, langopts, InputFile, GenerateDebugInfo)),
Nuno Lopes74d92782008-10-24 22:51:00 +000085 TheModule(0), TheTargetData(0), AsmOutStream(0), ModuleProvider(0),
Chris Lattnere8f70712009-02-18 01:23:44 +000086 CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
87
88 llvm::TimePassesIsEnabled = CompileOpts.TimePasses;
89 }
Daniel Dunbar85e44e22008-10-21 23:49:24 +000090
91 ~BackendConsumer() {
Daniel Dunbar85e44e22008-10-21 23:49:24 +000092 delete AsmOutStream;
93 delete TheTargetData;
Nuno Lopes74d92782008-10-24 22:51:00 +000094 delete ModuleProvider;
Daniel Dunbar85e44e22008-10-21 23:49:24 +000095 delete CodeGenPasses;
96 delete PerModulePasses;
97 delete PerFunctionPasses;
98 }
99
100 virtual void InitializeTU(TranslationUnit& TU) {
101 Gen->InitializeTU(TU);
102
103 TheModule = Gen->GetModule();
Nuno Lopesd41e2b12008-10-24 23:27:18 +0000104 ModuleProvider = new ExistingModuleProvider(TheModule);
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000105 TheTargetData =
106 new llvm::TargetData(TU.getContext().Target.getTargetDescription());
107 }
108
109 virtual void HandleTopLevelDecl(Decl *D) {
110 Gen->HandleTopLevelDecl(D);
111 }
112
113 virtual void HandleTranslationUnit(TranslationUnit& TU) {
114 Gen->HandleTranslationUnit(TU);
Daniel Dunbar622d6d02008-11-11 06:35:39 +0000115
116 EmitAssembly();
117 // Force a flush here in case we never get released.
118 if (AsmOutStream)
119 AsmOutStream->flush();
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000120 }
121
122 virtual void HandleTagDeclDefinition(TagDecl *D) {
123 Gen->HandleTagDeclDefinition(D);
124 }
125 };
126}
127
128FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
129 if (!CodeGenPasses) {
Nuno Lopes74d92782008-10-24 22:51:00 +0000130 CodeGenPasses = new FunctionPassManager(ModuleProvider);
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000131 CodeGenPasses->add(new TargetData(*TheTargetData));
132 }
133
134 return CodeGenPasses;
135}
136
137PassManager *BackendConsumer::getPerModulePasses() const {
138 if (!PerModulePasses) {
139 PerModulePasses = new PassManager();
140 PerModulePasses->add(new TargetData(*TheTargetData));
141 }
142
143 return PerModulePasses;
144}
145
146FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
147 if (!PerFunctionPasses) {
Nuno Lopesd41e2b12008-10-24 23:27:18 +0000148 PerFunctionPasses = new FunctionPassManager(ModuleProvider);
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000149 PerFunctionPasses->add(new TargetData(*TheTargetData));
150 }
151
152 return PerFunctionPasses;
153}
154
Daniel Dunbar655d5092008-10-23 05:59:43 +0000155bool BackendConsumer::AddEmitPasses(std::string &Error) {
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000156 if (OutputFile == "-" || (InputFile == "-" && OutputFile.empty())) {
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000157 AsmOutStream = new raw_stdout_ostream();
158 sys::Program::ChangeStdoutToBinary();
159 } else {
160 if (OutputFile.empty()) {
161 llvm::sys::Path Path(InputFile);
162 Path.eraseSuffix();
163 if (Action == Backend_EmitBC) {
164 Path.appendSuffix("bc");
165 } else if (Action == Backend_EmitLL) {
166 Path.appendSuffix("ll");
167 } else {
168 Path.appendSuffix("s");
169 }
170 OutputFile = Path.toString();
171 }
172
Daniel Dunbar8fc9ba62008-11-13 05:09:21 +0000173 AsmOutStream = new raw_fd_ostream(OutputFile.c_str(), true, Error);
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000174 if (!Error.empty())
175 return false;
176 }
177
178 if (Action == Backend_EmitBC) {
Daniel Dunbare5dbb072008-10-22 17:40:45 +0000179 getPerModulePasses()->add(createBitcodeWriterPass(*AsmOutStream));
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000180 } else if (Action == Backend_EmitLL) {
Daniel Dunbar092a7442008-10-22 03:28:13 +0000181 getPerModulePasses()->add(createPrintModulePass(AsmOutStream));
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000182 } else {
Daniel Dunbar655d5092008-10-23 05:59:43 +0000183 bool Fast = CompileOpts.OptimizationLevel == 0;
184
Daniel Dunbaraed93f22008-10-22 18:29:51 +0000185 // Create the TargetMachine for generating code.
186 const TargetMachineRegistry::entry *TME =
187 TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, Error);
188 if (!TME) {
189 Error = std::string("Unable to get target machine: ") + Error;
190 return false;
191 }
Daniel Dunbar9101a632009-02-17 19:47:34 +0000192
193 std::string FeaturesStr;
194 if (CompileOpts.CPU.size() || CompileOpts.Features.size()) {
195 SubtargetFeatures Features;
196 Features.setCPU(CompileOpts.CPU);
197 for (std::vector<std::string>::iterator
198 it = CompileOpts.Features.begin(),
199 ie = CompileOpts.Features.end(); it != ie; ++it)
200 Features.AddFeature(*it);
201 FeaturesStr = Features.getString();
202 }
203 TargetMachine *TM = TME->CtorFn(*TheModule, FeaturesStr);
Daniel Dunbaraed93f22008-10-22 18:29:51 +0000204
205 // Set register scheduler & allocation policy.
206 RegisterScheduler::setDefault(createDefaultScheduler);
207 RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
208 createLinearScanRegisterAllocator);
209
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000210 // From llvm-gcc:
211 // If there are passes we have to run on the entire module, we do codegen
212 // as a separate "pass" after that happens.
213 // FIXME: This is disabled right now until bugs can be worked out. Reenable
214 // this for fast -O0 compiles!
215 FunctionPassManager *PM = getCodeGenPasses();
216
217 // Normal mode, emit a .s file by running the code generator.
218 // Note, this also adds codegenerator level optimization passes.
219 switch (TM->addPassesToEmitFile(*PM, *AsmOutStream,
220 TargetMachine::AssemblyFile, Fast)) {
221 default:
222 case FileModel::Error:
223 Error = "Unable to interface with target machine!\n";
224 return false;
225 case FileModel::AsmFile:
226 break;
227 }
228
229 if (TM->addPassesToEmitFileFinish(*CodeGenPasses, 0, Fast)) {
230 Error = "Unable to interface with target machine!\n";
231 return false;
232 }
233 }
234
235 return true;
236}
237
238void BackendConsumer::CreatePasses() {
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000239 // In -O0 if checking is disabled, we don't even have per-function passes.
240 if (CompileOpts.VerifyModule)
241 getPerFunctionPasses()->add(createVerifierPass());
242
243 if (CompileOpts.OptimizationLevel > 0) {
244 FunctionPassManager *PM = getPerFunctionPasses();
245 PM->add(createCFGSimplificationPass());
246 if (CompileOpts.OptimizationLevel == 1)
247 PM->add(createPromoteMemoryToRegisterPass());
248 else
249 PM->add(createScalarReplAggregatesPass());
250 PM->add(createInstructionCombiningPass());
251 }
252
253 // For now we always create per module passes.
254 PassManager *PM = getPerModulePasses();
255 if (CompileOpts.OptimizationLevel > 0) {
256 if (CompileOpts.UnitAtATime)
257 PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst
258 PM->add(createCFGSimplificationPass()); // Clean up disgusting code
259 PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas
260 if (CompileOpts.UnitAtATime) {
261 PM->add(createGlobalOptimizerPass()); // Optimize out global vars
262 PM->add(createGlobalDCEPass()); // Remove unused fns and globs
263 PM->add(createIPConstantPropagationPass()); // IP Constant Propagation
264 PM->add(createDeadArgEliminationPass()); // Dead argument elimination
265 }
266 PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE
267 PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
268 if (CompileOpts.UnitAtATime) {
269 PM->add(createPruneEHPass()); // Remove dead EH info
Bill Wendlingaccd9b72008-12-31 19:51:31 +0000270 PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000271 }
272 if (CompileOpts.InlineFunctions)
273 PM->add(createFunctionInliningPass()); // Inline small functions
274 else
275 PM->add(createAlwaysInlinerPass()); // Respect always_inline
276 if (CompileOpts.OptimizationLevel > 2)
277 PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
278 if (CompileOpts.SimplifyLibCalls)
279 PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
280 PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl.
281 PM->add(createJumpThreadingPass()); // Thread jumps.
282 PM->add(createCFGSimplificationPass()); // Merge & remove BBs
283 PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas
284 PM->add(createInstructionCombiningPass()); // Combine silly seq's
285 PM->add(createCondPropagationPass()); // Propagate conditionals
286 PM->add(createTailCallEliminationPass()); // Eliminate tail calls
287 PM->add(createCFGSimplificationPass()); // Merge & remove BBs
288 PM->add(createReassociatePass()); // Reassociate expressions
289 PM->add(createLoopRotatePass()); // Rotate Loop
290 PM->add(createLICMPass()); // Hoist loop invariants
291 PM->add(createLoopUnswitchPass(CompileOpts.OptimizeSize ? true : false));
Devang Patel62237e72008-11-26 05:01:52 +0000292// PM->add(createLoopIndexSplitPass()); // Split loop index
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000293 PM->add(createInstructionCombiningPass());
294 PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
295 PM->add(createLoopDeletionPass()); // Delete dead loops
296 if (CompileOpts.UnrollLoops)
297 PM->add(createLoopUnrollPass()); // Unroll small loops
298 PM->add(createInstructionCombiningPass()); // Clean up after the unroller
299 PM->add(createGVNPass()); // Remove redundancies
300 PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
301 PM->add(createSCCPPass()); // Constant prop with SCCP
302
303 // Run instcombine after redundancy elimination to exploit opportunities
304 // opened up by them.
305 PM->add(createInstructionCombiningPass());
306 PM->add(createCondPropagationPass()); // Propagate conditionals
307 PM->add(createDeadStoreEliminationPass()); // Delete dead stores
308 PM->add(createAggressiveDCEPass()); // Delete dead instructions
309 PM->add(createCFGSimplificationPass()); // Merge & remove BBs
310
311 if (CompileOpts.UnitAtATime) {
312 PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
313 PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
314 }
315
316 if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime)
317 PM->add(createConstantMergePass()); // Merge dup global constants
318 } else {
Daniel Dunbar160cb622008-11-13 05:29:02 +0000319 PM->add(createAlwaysInlinerPass());
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000320 }
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000321}
322
323/// EmitAssembly - Handle interaction with LLVM backend to generate
324/// actual machine code.
325void BackendConsumer::EmitAssembly() {
326 // Silently ignore if we weren't initialized for some reason.
327 if (!TheModule || !TheTargetData)
328 return;
329
Daniel Dunbarbc147792008-10-27 20:40:41 +0000330 // Make sure IR generation is happy with the module. This is
331 // released by the module provider.
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000332 Module *M = Gen->ReleaseModule();
333 if (!M) {
Daniel Dunbarbc147792008-10-27 20:40:41 +0000334 // The module has been released by IR gen on failures, do not
335 // double free.
336 ModuleProvider->releaseModule();
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000337 TheModule = 0;
338 return;
339 }
340
341 assert(TheModule == M && "Unexpected module change during IR generation");
342
343 CreatePasses();
344
345 std::string Error;
Daniel Dunbar655d5092008-10-23 05:59:43 +0000346 if (!AddEmitPasses(Error)) {
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000347 // FIXME: Don't fail this way.
348 llvm::cerr << "ERROR: " << Error << "\n";
349 ::exit(1);
350 }
351
352 // Run passes. For now we do all passes at once, but eventually we
353 // would like to have the option of streaming code generation.
354
355 if (PerFunctionPasses) {
356 PerFunctionPasses->doInitialization();
357 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
358 if (!I->isDeclaration())
359 PerFunctionPasses->run(*I);
360 PerFunctionPasses->doFinalization();
361 }
362
363 if (PerModulePasses)
364 PerModulePasses->run(*M);
365
366 if (CodeGenPasses) {
367 CodeGenPasses->doInitialization();
368 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
369 if (!I->isDeclaration())
370 CodeGenPasses->run(*I);
371 CodeGenPasses->doFinalization();
372 }
373}
374
375ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
376 Diagnostic &Diags,
Daniel Dunbar9101a632009-02-17 19:47:34 +0000377 const LangOptions &LangOpts,
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000378 const CompileOptions &CompileOpts,
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000379 const std::string& InFile,
380 const std::string& OutFile,
381 bool GenerateDebugInfo) {
Chris Lattner57ff05c2009-02-12 01:50:58 +0000382 // FIXME: If optimizing, disable all debug info generation. The LLVM
383 // optimizer and backend is not ready to handle it when optimizations
384 // are enabled.
385 if (CompileOpts.OptimizationLevel > 0)
386 GenerateDebugInfo = false;
Daniel Dunbar9101a632009-02-17 19:47:34 +0000387
388 return new BackendConsumer(Action, Diags, LangOpts, CompileOpts,
Daniel Dunbaraa7a0662008-10-23 05:50:47 +0000389 InFile, OutFile, GenerateDebugInfo);
Daniel Dunbar85e44e22008-10-21 23:49:24 +0000390}