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/IR/IRPrintingPasses.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/IR/LLVMContext.h"
45 #include "llvm/IR/Module.h"
46 #include "llvm/IR/Metadata.h"
47
48 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
49
50 #include "llvm/IR/DataLayout.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 "strip_unknown_attributes.h"
59 #include "BitWriter_2_9/ReaderWriter_2_9.h"
60 #include "BitWriter_2_9_func/ReaderWriter_2_9_func.h"
61 #include "BitWriter_3_2/ReaderWriter_3_2.h"
62
63 namespace slang {
64
CreateFunctionPasses()65 void Backend::CreateFunctionPasses() {
66 if (!mPerFunctionPasses) {
67 mPerFunctionPasses = new llvm::FunctionPassManager(mpModule);
68 mPerFunctionPasses->add(new llvm::DataLayoutPass(mpModule));
69
70 llvm::PassManagerBuilder PMBuilder;
71 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
72 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses);
73 }
74 }
75
CreateModulePasses()76 void Backend::CreateModulePasses() {
77 if (!mPerModulePasses) {
78 mPerModulePasses = new llvm::PassManager();
79 mPerModulePasses->add(new llvm::DataLayoutPass(mpModule));
80
81 llvm::PassManagerBuilder PMBuilder;
82 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel;
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.populateModulePassManager(*mPerModulePasses);
97 // Add a pass to strip off unknown/unsupported attributes.
98 mPerModulePasses->add(createStripUnknownAttributesPass());
99 }
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::DataLayoutPass(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->getDataLayout()->getPointerSize() == 4) {
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,
226 mTargetOpts, mLLVMContext);
227 }
228
Initialize(clang::ASTContext & Ctx)229 void Backend::Initialize(clang::ASTContext &Ctx) {
230 mGen->Initialize(Ctx);
231
232 mpModule = mGen->GetModule();
233 }
234
235 // Encase the Bitcode in a wrapper containing RS version information.
WrapBitcode(llvm::raw_string_ostream & Bitcode)236 void Backend::WrapBitcode(llvm::raw_string_ostream &Bitcode) {
237 bcinfo::AndroidBitcodeWrapper wrapper;
238 size_t actualWrapperLen = bcinfo::writeAndroidBitcodeWrapper(
239 &wrapper, Bitcode.str().length(), getTargetAPI(),
240 SlangVersion::CURRENT, mCodeGenOpts.OptimizationLevel);
241
242 slangAssert(actualWrapperLen > 0);
243
244 // Write out the bitcode wrapper.
245 FormattedOutStream.write(reinterpret_cast<char*>(&wrapper), actualWrapperLen);
246
247 // Write out the actual encoded bitcode.
248 FormattedOutStream << Bitcode.str();
249 }
250
HandleTopLevelDecl(clang::DeclGroupRef D)251 bool Backend::HandleTopLevelDecl(clang::DeclGroupRef D) {
252 return mGen->HandleTopLevelDecl(D);
253 }
254
HandleTranslationUnit(clang::ASTContext & Ctx)255 void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) {
256 HandleTranslationUnitPre(Ctx);
257
258 mGen->HandleTranslationUnit(Ctx);
259
260 // Here, we complete a translation unit (whole translation unit is now in LLVM
261 // IR). Now, interact with LLVM backend to generate actual machine code (asm
262 // or machine code, whatever.)
263
264 // Silently ignore if we weren't initialized for some reason.
265 if (!mpModule)
266 return;
267
268 llvm::Module *M = mGen->ReleaseModule();
269 if (!M) {
270 // The module has been released by IR gen on failures, do not double free.
271 mpModule = NULL;
272 return;
273 }
274
275 slangAssert(mpModule == M &&
276 "Unexpected module change during LLVM IR generation");
277
278 // Insert #pragma information into metadata section of module
279 if (!mPragmas->empty()) {
280 llvm::NamedMDNode *PragmaMetadata =
281 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName);
282 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end();
283 I != E;
284 I++) {
285 llvm::SmallVector<llvm::Value*, 2> Pragma;
286 // Name goes first
287 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first));
288 // And then value
289 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second));
290
291 // Create MDNode and insert into PragmaMetadata
292 PragmaMetadata->addOperand(
293 llvm::MDNode::get(mLLVMContext, Pragma));
294 }
295 }
296
297 HandleTranslationUnitPost(mpModule);
298
299 // Create passes for optimization and code emission
300
301 // Create and run per-function passes
302 CreateFunctionPasses();
303 if (mPerFunctionPasses) {
304 mPerFunctionPasses->doInitialization();
305
306 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
307 I != E;
308 I++)
309 if (!I->isDeclaration())
310 mPerFunctionPasses->run(*I);
311
312 mPerFunctionPasses->doFinalization();
313 }
314
315 // Create and run module passes
316 CreateModulePasses();
317 if (mPerModulePasses)
318 mPerModulePasses->run(*mpModule);
319
320 switch (mOT) {
321 case Slang::OT_Assembly:
322 case Slang::OT_Object: {
323 if (!CreateCodeGenPasses())
324 return;
325
326 mCodeGenPasses->doInitialization();
327
328 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end();
329 I != E;
330 I++)
331 if (!I->isDeclaration())
332 mCodeGenPasses->run(*I);
333
334 mCodeGenPasses->doFinalization();
335 break;
336 }
337 case Slang::OT_LLVMAssembly: {
338 llvm::PassManager *LLEmitPM = new llvm::PassManager();
339 LLEmitPM->add(llvm::createPrintModulePass(FormattedOutStream));
340 LLEmitPM->run(*mpModule);
341 break;
342 }
343 case Slang::OT_Bitcode: {
344 llvm::PassManager *BCEmitPM = new llvm::PassManager();
345 std::string BCStr;
346 llvm::raw_string_ostream Bitcode(BCStr);
347 unsigned int TargetAPI = getTargetAPI();
348 switch (TargetAPI) {
349 case SLANG_HC_TARGET_API:
350 case SLANG_HC_MR1_TARGET_API:
351 case SLANG_HC_MR2_TARGET_API: {
352 // Pre-ICS targets must use the LLVM 2.9 BitcodeWriter
353 BCEmitPM->add(llvm_2_9::createBitcodeWriterPass(Bitcode));
354 break;
355 }
356 case SLANG_ICS_TARGET_API:
357 case SLANG_ICS_MR1_TARGET_API: {
358 // ICS targets must use the LLVM 2.9_func BitcodeWriter
359 BCEmitPM->add(llvm_2_9_func::createBitcodeWriterPass(Bitcode));
360 break;
361 }
362 default: {
363 if (TargetAPI != SLANG_DEVELOPMENT_TARGET_API &&
364 (TargetAPI < SLANG_MINIMUM_TARGET_API ||
365 TargetAPI > SLANG_MAXIMUM_TARGET_API)) {
366 slangAssert(false && "Invalid target API value");
367 }
368 // Switch to the 3.2 BitcodeWriter by default, and don't use
369 // LLVM's included BitcodeWriter at all (for now).
370 BCEmitPM->add(llvm_3_2::createBitcodeWriterPass(Bitcode));
371 //BCEmitPM->add(llvm::createBitcodeWriterPass(Bitcode));
372 break;
373 }
374 }
375
376 BCEmitPM->run(*mpModule);
377 WrapBitcode(Bitcode);
378 break;
379 }
380 case Slang::OT_Nothing: {
381 return;
382 }
383 default: {
384 slangAssert(false && "Unknown output type");
385 }
386 }
387
388 FormattedOutStream.flush();
389 }
390
HandleTagDeclDefinition(clang::TagDecl * D)391 void Backend::HandleTagDeclDefinition(clang::TagDecl *D) {
392 mGen->HandleTagDeclDefinition(D);
393 }
394
CompleteTentativeDefinition(clang::VarDecl * D)395 void Backend::CompleteTentativeDefinition(clang::VarDecl *D) {
396 mGen->CompleteTentativeDefinition(D);
397 }
398
~Backend()399 Backend::~Backend() {
400 delete mpModule;
401 delete mGen;
402 delete mPerFunctionPasses;
403 delete mPerModulePasses;
404 delete mCodeGenPasses;
405 }
406
407 } // namespace slang
408