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