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