slang_backend.cpp revision 18c8829f2bd3cbe0d02471588c6643c0a8c6ca3c
1/* 2 * Copyright 2010, 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 "clang/AST/ASTContext.h" 23#include "clang/AST/Decl.h" 24#include "clang/AST/DeclGroup.h" 25 26#include "clang/Basic/Diagnostic.h" 27#include "clang/Basic/TargetInfo.h" 28#include "clang/Basic/TargetOptions.h" 29 30#include "clang/CodeGen/ModuleBuilder.h" 31 32#include "clang/Frontend/CodeGenOptions.h" 33#include "clang/Frontend/FrontendDiagnostic.h" 34 35#include "llvm/Assembly/PrintModulePass.h" 36 37#include "llvm/Bitcode/ReaderWriter.h" 38 39#include "llvm/CodeGen/RegAllocRegistry.h" 40#include "llvm/CodeGen/SchedulerRegistry.h" 41 42#include "llvm/LLVMContext.h" 43#include "llvm/Module.h" 44#include "llvm/Metadata.h" 45 46#include "llvm/Support/PassManagerBuilder.h" 47 48#include "llvm/Target/TargetData.h" 49#include "llvm/Target/TargetMachine.h" 50#include "llvm/Target/TargetOptions.h" 51#include "llvm/Target/TargetRegistry.h" 52 53#include "llvm/MC/SubtargetFeature.h" 54 55#include "slang.h" 56#include "slang_assert.h" 57 58namespace slang { 59 60void Backend::CreateFunctionPasses() { 61 if (!mPerFunctionPasses) { 62 mPerFunctionPasses = new llvm::FunctionPassManager(mpModule); 63 mPerFunctionPasses->add(new llvm::TargetData(mpModule)); 64 65 llvm::PassManagerBuilder PMBuilder; 66 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 67 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses); 68 } 69 return; 70} 71 72void Backend::CreateModulePasses() { 73 if (!mPerModulePasses) { 74 mPerModulePasses = new llvm::PassManager(); 75 mPerModulePasses->add(new llvm::TargetData(mpModule)); 76 77 llvm::PassManagerBuilder PMBuilder; 78 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 79 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 80 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 81 if (mCodeGenOpts.UnitAtATime) { 82 PMBuilder.DisableUnitAtATime = 0; 83 } else { 84 PMBuilder.DisableUnitAtATime = 1; 85 } 86 87 if (mCodeGenOpts.UnrollLoops) { 88 PMBuilder.DisableUnrollLoops = 0; 89 } else { 90 PMBuilder.DisableUnrollLoops = 1; 91 } 92 93 PMBuilder.DisableSimplifyLibCalls = false; 94 PMBuilder.populateModulePassManager(*mPerModulePasses); 95 } 96 return; 97} 98 99bool Backend::CreateCodeGenPasses() { 100 if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object)) 101 return true; 102 103 // Now we add passes for code emitting 104 if (mCodeGenPasses) { 105 return true; 106 } else { 107 mCodeGenPasses = new llvm::FunctionPassManager(mpModule); 108 mCodeGenPasses->add(new llvm::TargetData(mpModule)); 109 } 110 111 // Create the TargetMachine for generating code. 112 std::string Triple = mpModule->getTargetTriple(); 113 114 std::string Error; 115 const llvm::Target* TargetInfo = 116 llvm::TargetRegistry::lookupTarget(Triple, Error); 117 if (TargetInfo == NULL) { 118 mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error; 119 return false; 120 } 121 122 llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim; 123 124 // Use hardware FPU. 125 // 126 // FIXME: Need to detect the CPU capability and decide whether to use softfp. 127 // To use softfp, change following 2 lines to 128 // 129 // llvm::FloatABIType = llvm::FloatABI::Soft; 130 // llvm::UseSoftFloat = true; 131 llvm::FloatABIType = llvm::FloatABI::Hard; 132 llvm::UseSoftFloat = false; 133 134 // BCC needs all unknown symbols resolved at compilation time. So we don't 135 // need any relocation model. 136 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static); 137 138 139 // This is set for the linker (specify how large of the virtual addresses we 140 // can access for all unknown symbols.) 141 if (mpModule->getPointerSize() == llvm::Module::Pointer32) 142 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small); 143 else 144 // The target may have pointer size greater than 32 (e.g. x86_64 145 // architecture) may need large data address model 146 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium); 147 148 // Setup feature string 149 std::string FeaturesStr; 150 if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 151 llvm::SubtargetFeatures Features; 152 153 for (std::vector<std::string>::const_iterator 154 I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end(); 155 I != E; 156 I++) 157 Features.AddFeature(*I); 158 159 FeaturesStr = Features.getString(); 160 } 161 llvm::TargetMachine *TM = 162 TargetInfo->createTargetMachine(Triple, mTargetOpts.CPU, FeaturesStr); 163 164 // Register scheduler 165 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler); 166 167 // Register allocation policy: 168 // createFastRegisterAllocator: fast but bad quality 169 // createLinearScanRegisterAllocator: not so fast but good quality 170 llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? 171 llvm::createFastRegisterAllocator : 172 llvm::createLinearScanRegisterAllocator); 173 174 llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 175 if (mCodeGenOpts.OptimizationLevel == 0) { 176 OptLevel = llvm::CodeGenOpt::None; 177 } else if (mCodeGenOpts.OptimizationLevel == 3) { 178 OptLevel = llvm::CodeGenOpt::Aggressive; 179 } 180 181 llvm::TargetMachine::CodeGenFileType CGFT = 182 llvm::TargetMachine::CGFT_AssemblyFile; 183 if (mOT == Slang::OT_Object) { 184 CGFT = llvm::TargetMachine::CGFT_ObjectFile; 185 } 186 if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream, 187 CGFT, OptLevel)) { 188 mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target); 189 return false; 190 } 191 192 return true; 193} 194 195Backend::Backend(clang::Diagnostic *Diags, 196 const clang::CodeGenOptions &CodeGenOpts, 197 const clang::TargetOptions &TargetOpts, 198 PragmaList *Pragmas, 199 llvm::raw_ostream *OS, 200 Slang::OutputType OT) 201 : ASTConsumer(), 202 mCodeGenOpts(CodeGenOpts), 203 mTargetOpts(TargetOpts), 204 mpModule(NULL), 205 mpOS(OS), 206 mOT(OT), 207 mGen(NULL), 208 mPerFunctionPasses(NULL), 209 mPerModulePasses(NULL), 210 mCodeGenPasses(NULL), 211 mLLVMContext(llvm::getGlobalContext()), 212 mDiags(*Diags), 213 mPragmas(Pragmas) { 214 FormattedOutStream.setStream(*mpOS, 215 llvm::formatted_raw_ostream::PRESERVE_STREAM); 216 mGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext); 217 return; 218} 219 220void Backend::Initialize(clang::ASTContext &Ctx) { 221 mGen->Initialize(Ctx); 222 223 mpModule = mGen->GetModule(); 224 225 return; 226} 227 228void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) { 229 mGen->HandleTopLevelDecl(D); 230 return; 231} 232 233void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) { 234 HandleTranslationUnitPre(Ctx); 235 236 mGen->HandleTranslationUnit(Ctx); 237 238 // Here, we complete a translation unit (whole translation unit is now in LLVM 239 // IR). Now, interact with LLVM backend to generate actual machine code (asm 240 // or machine code, whatever.) 241 242 // Silently ignore if we weren't initialized for some reason. 243 if (!mpModule) 244 return; 245 246 llvm::Module *M = mGen->ReleaseModule(); 247 if (!M) { 248 // The module has been released by IR gen on failures, do not double free. 249 mpModule = NULL; 250 return; 251 } 252 253 slangAssert(mpModule == M && 254 "Unexpected module change during LLVM IR generation"); 255 256 // Insert #pragma information into metadata section of module 257 if (!mPragmas->empty()) { 258 llvm::NamedMDNode *PragmaMetadata = 259 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); 260 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end(); 261 I != E; 262 I++) { 263 llvm::SmallVector<llvm::Value*, 2> Pragma; 264 // Name goes first 265 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first)); 266 // And then value 267 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second)); 268 269 // Create MDNode and insert into PragmaMetadata 270 PragmaMetadata->addOperand( 271 llvm::MDNode::get(mLLVMContext, Pragma)); 272 } 273 } 274 275 HandleTranslationUnitPost(mpModule); 276 277 // Create passes for optimization and code emission 278 279 // Create and run per-function passes 280 CreateFunctionPasses(); 281 if (mPerFunctionPasses) { 282 mPerFunctionPasses->doInitialization(); 283 284 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 285 I != E; 286 I++) 287 if (!I->isDeclaration()) 288 mPerFunctionPasses->run(*I); 289 290 mPerFunctionPasses->doFinalization(); 291 } 292 293 // Create and run module passes 294 CreateModulePasses(); 295 if (mPerModulePasses) 296 mPerModulePasses->run(*mpModule); 297 298 switch (mOT) { 299 case Slang::OT_Assembly: 300 case Slang::OT_Object: { 301 if (!CreateCodeGenPasses()) 302 return; 303 304 mCodeGenPasses->doInitialization(); 305 306 for (llvm::Module::iterator I = mpModule->begin(), E = mpModule->end(); 307 I != E; 308 I++) 309 if (!I->isDeclaration()) 310 mCodeGenPasses->run(*I); 311 312 mCodeGenPasses->doFinalization(); 313 break; 314 } 315 case Slang::OT_LLVMAssembly: { 316 llvm::PassManager *LLEmitPM = new llvm::PassManager(); 317 LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream)); 318 LLEmitPM->run(*mpModule); 319 break; 320 } 321 case Slang::OT_Bitcode: { 322 llvm::PassManager *BCEmitPM = new llvm::PassManager(); 323 BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream)); 324 BCEmitPM->run(*mpModule); 325 break; 326 } 327 case Slang::OT_Nothing: { 328 return; 329 } 330 default: { 331 slangAssert(false && "Unknown output type"); 332 } 333 } 334 335 FormattedOutStream.flush(); 336 337 return; 338} 339 340void Backend::HandleTagDeclDefinition(clang::TagDecl *D) { 341 mGen->HandleTagDeclDefinition(D); 342 return; 343} 344 345void Backend::CompleteTentativeDefinition(clang::VarDecl *D) { 346 mGen->CompleteTentativeDefinition(D); 347 return; 348} 349 350Backend::~Backend() { 351 delete mpModule; 352 delete mGen; 353 delete mPerFunctionPasses; 354 delete mPerModulePasses; 355 delete mCodeGenPasses; 356 return; 357} 358 359} // namespace slang 360