 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
70.5% |
105 / 149 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
90.6% |
135 / 149 |
| |
|
Line Coverage: |
86.9% |
172 / 198 |
| |
 |
|
 |
1 : //===--- 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 "clang/Frontend/ASTConsumers.h"
11 : #include "clang/AST/ASTConsumer.h"
12 : #include "clang/AST/ASTContext.h"
13 : #include "clang/AST/DeclGroup.h"
14 : #include "clang/Basic/TargetInfo.h"
15 : #include "clang/Basic/TargetOptions.h"
16 : #include "clang/CodeGen/CodeGenOptions.h"
17 : #include "clang/CodeGen/ModuleBuilder.h"
18 : #include "clang/Frontend/FrontendDiagnostic.h"
19 : #include "llvm/Module.h"
20 : #include "llvm/PassManager.h"
21 : #include "llvm/ADT/OwningPtr.h"
22 : #include "llvm/Assembly/PrintModulePass.h"
23 : #include "llvm/Analysis/CallGraph.h"
24 : #include "llvm/Analysis/Verifier.h"
25 : #include "llvm/Bitcode/ReaderWriter.h"
26 : #include "llvm/CodeGen/RegAllocRegistry.h"
27 : #include "llvm/CodeGen/SchedulerRegistry.h"
28 : #include "llvm/Support/FormattedStream.h"
29 : #include "llvm/Support/StandardPasses.h"
30 : #include "llvm/Support/Timer.h"
31 : #include "llvm/Target/SubtargetFeature.h"
32 : #include "llvm/Target/TargetData.h"
33 : #include "llvm/Target/TargetMachine.h"
34 : #include "llvm/Target/TargetOptions.h"
35 : #include "llvm/Target/TargetRegistry.h"
36 : using namespace clang;
37 : using namespace llvm;
38 :
39 : namespace {
40 : class BackendConsumer : public ASTConsumer {
41 : Diagnostic &Diags;
42 : BackendAction Action;
43 : const CodeGenOptions &CodeGenOpts;
44 : const LangOptions &LangOpts;
45 : const TargetOptions &TargetOpts;
46 : llvm::raw_ostream *AsmOutStream;
47 : llvm::formatted_raw_ostream FormattedOutStream;
48 : ASTContext *Context;
49 :
50 : Timer LLVMIRGeneration;
51 : Timer CodeGenerationTime;
52 :
53 : llvm::OwningPtr<CodeGenerator> Gen;
54 :
55 : llvm::Module *TheModule;
56 : llvm::TargetData *TheTargetData;
57 :
58 : mutable FunctionPassManager *CodeGenPasses;
59 : mutable PassManager *PerModulePasses;
60 : mutable FunctionPassManager *PerFunctionPasses;
61 :
62 : FunctionPassManager *getCodeGenPasses() const;
63 : PassManager *getPerModulePasses() const;
64 : FunctionPassManager *getPerFunctionPasses() const;
65 :
66 : void CreatePasses();
67 :
68 : /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
69 : ///
70 : /// \return True on success.
71 : bool AddEmitPasses();
72 :
73 : void EmitAssembly();
74 :
75 : public:
76 : BackendConsumer(BackendAction action, Diagnostic &_Diags,
77 : const LangOptions &langopts, const CodeGenOptions &compopts,
78 : const TargetOptions &targetopts, bool TimePasses,
79 : const std::string &infile, llvm::raw_ostream *OS,
80 625: LLVMContext& C) :
81 : Diags(_Diags),
82 : Action(action),
83 : CodeGenOpts(compopts),
84 : LangOpts(langopts),
85 : TargetOpts(targetopts),
86 : AsmOutStream(OS),
87 : LLVMIRGeneration("LLVM IR Generation Time"),
88 : CodeGenerationTime("Code Generation Time"),
89 : Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
90 : TheModule(0), TheTargetData(0),
91 625: CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
92 :
590: branch 0 taken
35: branch 1 taken
93 625: if (AsmOutStream)
94 : FormattedOutStream.setStream(*AsmOutStream,
95 590: formatted_raw_ostream::PRESERVE_STREAM);
96 :
97 625: llvm::TimePassesIsEnabled = TimePasses;
98 625: }
99 :
100 599: ~BackendConsumer() {
599: branch 0 taken
0: branch 1 not taken
599: branch 3 taken
599: branch 4 taken
101 599: delete TheTargetData;
596: branch 0 taken
3: branch 1 taken
596: branch 4 taken
596: branch 5 taken
102 599: delete TheModule;
53: branch 0 taken
546: branch 1 taken
53: branch 3 taken
53: branch 4 taken
103 599: delete CodeGenPasses;
596: branch 0 taken
3: branch 1 taken
596: branch 3 taken
596: branch 4 taken
104 599: delete PerModulePasses;
596: branch 0 taken
3: branch 1 taken
596: branch 3 taken
596: branch 4 taken
105 599: delete PerFunctionPasses;
599: branch 5 taken
0: branch 6 not taken
0: branch 13 not taken
0: branch 14 not taken
106 599: }
107 :
108 625: virtual void Initialize(ASTContext &Ctx) {
109 625: Context = &Ctx;
110 :
0: branch 0 not taken
625: branch 1 taken
111 625: if (llvm::TimePassesIsEnabled)
112 0: LLVMIRGeneration.startTimer();
113 :
114 625: Gen->Initialize(Ctx);
115 :
116 625: TheModule = Gen->GetModule();
117 625: TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
118 :
0: branch 0 not taken
625: branch 1 taken
119 625: if (llvm::TimePassesIsEnabled)
120 0: LLVMIRGeneration.stopTimer();
121 625: }
122 :
123 5785: virtual void HandleTopLevelDecl(DeclGroupRef D) {
124 : PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
125 : Context->getSourceManager(),
126 5785: "LLVM IR generation of declaration");
127 :
0: branch 0 not taken
5785: branch 1 taken
128 5785: if (llvm::TimePassesIsEnabled)
129 0: LLVMIRGeneration.startTimer();
130 :
131 5785: Gen->HandleTopLevelDecl(D);
132 :
0: branch 0 not taken
5785: branch 1 taken
133 5785: if (llvm::TimePassesIsEnabled)
134 0: LLVMIRGeneration.stopTimer();
135 5785: }
136 :
137 625: virtual void HandleTranslationUnit(ASTContext &C) {
138 : {
139 625: PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
0: branch 0 not taken
625: branch 1 taken
140 625: if (llvm::TimePassesIsEnabled)
141 0: LLVMIRGeneration.startTimer();
142 :
143 625: Gen->HandleTranslationUnit(C);
144 :
0: branch 0 not taken
625: branch 1 taken
145 625: if (llvm::TimePassesIsEnabled)
146 0: LLVMIRGeneration.stopTimer();
147 : }
148 :
149 : // EmitAssembly times and registers crash info itself.
150 625: EmitAssembly();
151 :
152 : // Force a flush here in case we never get released.
590: branch 0 taken
35: branch 1 taken
153 625: if (AsmOutStream)
154 590: FormattedOutStream.flush();
155 625: }
156 :
157 1509: virtual void HandleTagDeclDefinition(TagDecl *D) {
158 : PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
159 : Context->getSourceManager(),
160 1509: "LLVM IR generation of declaration");
161 1509: Gen->HandleTagDeclDefinition(D);
162 1509: }
163 :
164 256: virtual void CompleteTentativeDefinition(VarDecl *D) {
165 256: Gen->CompleteTentativeDefinition(D);
166 256: }
167 : };
168 : }
169 :
170 57: FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
57: branch 0 taken
0: branch 1 not taken
171 57: if (!CodeGenPasses) {
172 57: CodeGenPasses = new FunctionPassManager(TheModule);
173 57: CodeGenPasses->add(new TargetData(*TheTargetData));
174 : }
175 :
176 57: return CodeGenPasses;
177 : }
178 :
179 1153: PassManager *BackendConsumer::getPerModulePasses() const {
622: branch 0 taken
531: branch 1 taken
180 1153: if (!PerModulePasses) {
181 622: PerModulePasses = new PassManager();
182 622: PerModulePasses->add(new TargetData(*TheTargetData));
183 : }
184 :
185 1153: return PerModulePasses;
186 : }
187 :
188 652: FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
622: branch 0 taken
30: branch 1 taken
189 652: if (!PerFunctionPasses) {
190 622: PerFunctionPasses = new FunctionPassManager(TheModule);
191 622: PerFunctionPasses->add(new TargetData(*TheTargetData));
192 : }
193 :
194 652: return PerFunctionPasses;
195 : }
196 :
197 622: bool BackendConsumer::AddEmitPasses() {
34: branch 0 taken
588: branch 1 taken
198 622: if (Action == Backend_EmitNothing)
199 34: return true;
200 :
17: branch 0 taken
571: branch 1 taken
201 588: if (Action == Backend_EmitBC) {
202 17: getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
514: branch 0 taken
57: branch 1 taken
203 571: } else if (Action == Backend_EmitLL) {
204 514: getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
205 : } else {
206 57: bool Fast = CodeGenOpts.OptimizationLevel == 0;
207 :
208 : // Create the TargetMachine for generating code.
209 57: std::string Error;
210 57: std::string Triple = TheModule->getTargetTriple();
211 57: const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
0: branch 0 not taken
57: branch 1 taken
212 57: if (!TheTarget) {
213 0: Diags.Report(diag::err_fe_unable_to_create_target) << Error;
214 0: return false;
215 : }
216 :
217 : // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
218 : // being gross, this is also totally broken if we ever care about
219 : // concurrency.
220 57: llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
0: branch 1 not taken
57: branch 2 taken
221 57: if (CodeGenOpts.FloatABI == "soft")
222 0: llvm::FloatABIType = llvm::FloatABI::Soft;
0: branch 1 not taken
57: branch 2 taken
223 57: else if (CodeGenOpts.FloatABI == "hard")
224 0: llvm::FloatABIType = llvm::FloatABI::Hard;
225 : else {
57: branch 1 taken
0: branch 2 not taken
226 57: assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
227 57: llvm::FloatABIType = llvm::FloatABI::Default;
228 : }
229 57: NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
230 57: llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
231 57: UnwindTablesMandatory = CodeGenOpts.UnwindTables;
232 :
233 57: TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
234 :
235 : // FIXME: Parse this earlier.
3: branch 1 taken
54: branch 2 taken
236 57: if (CodeGenOpts.RelocationModel == "static") {
237 3: TargetMachine::setRelocationModel(llvm::Reloc::Static);
54: branch 1 taken
0: branch 2 not taken
238 54: } else if (CodeGenOpts.RelocationModel == "pic") {
239 54: TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
240 : } else {
241 : assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
0: branch 1 not taken
0: branch 2 not taken
242 0: "Invalid PIC model!");
243 0: TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
244 : }
245 : // FIXME: Parse this earlier.
0: branch 1 not taken
57: branch 2 taken
246 57: if (CodeGenOpts.CodeModel == "small") {
247 0: TargetMachine::setCodeModel(llvm::CodeModel::Small);
0: branch 1 not taken
57: branch 2 taken
248 57: } else if (CodeGenOpts.CodeModel == "kernel") {
249 0: TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
0: branch 1 not taken
57: branch 2 taken
250 57: } else if (CodeGenOpts.CodeModel == "medium") {
251 0: TargetMachine::setCodeModel(llvm::CodeModel::Medium);
0: branch 1 not taken
57: branch 2 taken
252 57: } else if (CodeGenOpts.CodeModel == "large") {
253 0: TargetMachine::setCodeModel(llvm::CodeModel::Large);
254 : } else {
57: branch 1 taken
0: branch 2 not taken
255 57: assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
256 57: TargetMachine::setCodeModel(llvm::CodeModel::Default);
257 : }
258 :
259 57: std::vector<const char *> BackendArgs;
260 57: BackendArgs.push_back("clang"); // Fake program name.
0: branch 1 not taken
57: branch 2 taken
261 57: if (!CodeGenOpts.DebugPass.empty()) {
262 0: BackendArgs.push_back("-debug-pass");
263 0: BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
264 : }
0: branch 1 not taken
57: branch 2 taken
265 57: if (!CodeGenOpts.LimitFloatPrecision.empty()) {
266 0: BackendArgs.push_back("-limit-float-precision");
267 0: BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
268 : }
0: branch 0 not taken
57: branch 1 taken
269 57: if (llvm::TimePassesIsEnabled)
270 0: BackendArgs.push_back("-time-passes");
271 57: BackendArgs.push_back(0);
272 : llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
273 57: (char**) &BackendArgs[0]);
274 :
275 57: std::string FeaturesStr;
53: branch 1 taken
4: branch 2 taken
53: branch 4 taken
0: branch 5 not taken
57: branch 6 taken
0: branch 7 not taken
276 57: if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
277 57: SubtargetFeatures Features;
278 57: Features.setCPU(TargetOpts.CPU);
513: branch 2 taken
57: branch 3 taken
279 570: for (std::vector<std::string>::const_iterator
280 57: it = TargetOpts.Features.begin(),
281 57: ie = TargetOpts.Features.end(); it != ie; ++it)
282 513: Features.AddFeature(*it);
283 57: FeaturesStr = Features.getString();
284 : }
285 57: TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
286 :
287 : // Set register scheduler & allocation policy.
288 57: RegisterScheduler::setDefault(createDefaultScheduler);
289 : RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
56: branch 0 taken
1: branch 1 taken
290 57: createLinearScanRegisterAllocator);
291 :
292 : // From llvm-gcc:
293 : // If there are passes we have to run on the entire module, we do codegen
294 : // as a separate "pass" after that happens.
295 : // FIXME: This is disabled right now until bugs can be worked out. Reenable
296 : // this for fast -O0 compiles!
297 57: FunctionPassManager *PM = getCodeGenPasses();
298 57: CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
299 :
1: branch 0 taken
56: branch 1 taken
0: branch 2 not taken
300 57: switch (CodeGenOpts.OptimizationLevel) {
301 1: default: break;
302 56: case 0: OptLevel = CodeGenOpt::None; break;
303 0: case 3: OptLevel = CodeGenOpt::Aggressive; break;
304 : }
305 :
306 : // Normal mode, emit a .s or .o file by running the code generator. Note,
307 : // this also adds codegenerator level optimization passes.
308 57: TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
0: branch 0 not taken
57: branch 1 taken
309 57: if (Action == Backend_EmitObj)
310 0: CGFT = TargetMachine::CGFT_ObjectFile;
0: branch 1 not taken
57: branch 2 taken
311 57: if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel)) {
312 0: Diags.Report(diag::err_fe_unable_to_interface_with_target);
313 0: return false;
57: branch 1 taken
0: branch 2 not taken
57: branch 4 taken
0: branch 5 not taken
57: branch 7 taken
0: branch 8 not taken
57: branch 10 taken
0: branch 11 not taken
314 57: }
315 : }
316 :
317 588: return true;
318 : }
319 :
320 622: void BackendConsumer::CreatePasses() {
321 622: unsigned OptLevel = CodeGenOpts.OptimizationLevel;
322 622: CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
323 :
324 : // Handle disabling of LLVM optimization, where we want to preserve the
325 : // internal module before any optimization.
1: branch 0 taken
621: branch 1 taken
326 622: if (CodeGenOpts.DisableLLVMOpts) {
327 1: OptLevel = 0;
328 1: Inlining = CodeGenOpts.NoInlining;
329 : }
330 :
331 : // In -O0 if checking is disabled, we don't even have per-function passes.
622: branch 0 taken
0: branch 1 not taken
332 622: if (CodeGenOpts.VerifyModule)
333 622: getPerFunctionPasses()->add(createVerifierPass());
334 :
335 : // Assume that standard function passes aren't run for -O0.
30: branch 0 taken
592: branch 1 taken
336 622: if (OptLevel > 0)
337 30: llvm::createStandardFunctionPasses(getPerFunctionPasses(), OptLevel);
338 :
339 622: llvm::Pass *InliningPass = 0;
1: branch 0 taken
25: branch 1 taken
596: branch 2 taken
0: branch 3 not taken
340 622: switch (Inlining) {
341 1: case CodeGenOptions::NoInlining: break;
342 : case CodeGenOptions::NormalInlining: {
343 : // Set the inline threshold following llvm-gcc.
344 : //
345 : // FIXME: Derive these constants in a principled fashion.
346 25: unsigned Threshold = 225;
2: branch 0 taken
23: branch 1 taken
347 25: if (CodeGenOpts.OptimizeSize)
348 2: Threshold = 75;
15: branch 0 taken
8: branch 1 taken
349 23: else if (OptLevel > 2)
350 15: Threshold = 275;
351 25: InliningPass = createFunctionInliningPass(Threshold);
352 25: break;
353 : }
354 : case CodeGenOptions::OnlyAlwaysInlining:
355 596: InliningPass = createAlwaysInlinerPass(); // Respect always_inline
356 : break;
357 : }
358 :
359 : // For now we always create per module passes.
360 622: PassManager *PM = getPerModulePasses();
361 : llvm::createStandardModulePasses(PM, OptLevel, CodeGenOpts.OptimizeSize,
362 : CodeGenOpts.UnitAtATime,
363 : CodeGenOpts.UnrollLoops,
364 : /*SimplifyLibCalls=*/!LangOpts.NoBuiltin,
365 : /*HaveExceptions=*/true,
366 622: InliningPass);
367 622: }
368 :
369 : /// EmitAssembly - Handle interaction with LLVM backend to generate
370 : /// actual machine code.
371 625: void BackendConsumer::EmitAssembly() {
372 : // Silently ignore if we weren't initialized for some reason.
625: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
625: branch 3 taken
373 625: if (!TheModule || !TheTargetData)
374 0: return;
375 :
0: branch 0 not taken
625: branch 1 taken
376 625: TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
377 :
378 : // Make sure IR generation is happy with the module. This is
379 : // released by the module provider.
380 625: Module *M = Gen->ReleaseModule();
3: branch 0 taken
622: branch 1 taken
381 625: if (!M) {
382 : // The module has been released by IR gen on failures, do not
383 : // double free.
384 3: TheModule = 0;
385 3: return;
386 : }
387 :
0: branch 0 not taken
622: branch 1 taken
388 622: assert(TheModule == M && "Unexpected module change during IR generation");
389 :
390 622: CreatePasses();
0: branch 1 not taken
622: branch 2 taken
391 622: if (!AddEmitPasses())
392 : return;
393 :
394 : // Run passes. For now we do all passes at once, but eventually we
395 : // would like to have the option of streaming code generation.
396 :
622: branch 0 taken
0: branch 1 not taken
397 622: if (PerFunctionPasses) {
398 622: PrettyStackTraceString CrashInfo("Per-function optimization");
399 :
400 622: PerFunctionPasses->doInitialization();
4282: branch 4 taken
622: branch 5 taken
401 4904: for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
3080: branch 2 taken
1202: branch 3 taken
402 4282: if (!I->isDeclaration())
403 3080: PerFunctionPasses->run(*I);
404 622: PerFunctionPasses->doFinalization();
405 : }
406 :
622: branch 0 taken
0: branch 1 not taken
407 622: if (PerModulePasses) {
408 622: PrettyStackTraceString CrashInfo("Per-module optimization passes");
409 622: PerModulePasses->run(*M);
410 : }
411 :
57: branch 0 taken
565: branch 1 taken
412 622: if (CodeGenPasses) {
413 57: PrettyStackTraceString CrashInfo("Code generation");
414 57: CodeGenPasses->doInitialization();
780: branch 4 taken
57: branch 5 taken
415 837: for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
626: branch 2 taken
154: branch 3 taken
416 780: if (!I->isDeclaration())
417 626: CodeGenPasses->run(*I);
418 57: CodeGenPasses->doFinalization();
622: branch 1 taken
3: branch 2 taken
419 625: }
420 : }
421 :
422 : ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
423 : Diagnostic &Diags,
424 : const LangOptions &LangOpts,
425 : const CodeGenOptions &CodeGenOpts,
426 : const TargetOptions &TargetOpts,
427 : bool TimePasses,
428 : const std::string& InFile,
429 : llvm::raw_ostream* OS,
430 625: LLVMContext& C) {
431 : return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts,
432 625: TargetOpts, TimePasses, InFile, OS, C);
433 : }
Generated: 2010-02-10 01:31 by zcov