slang_backend.cpp revision fcc654a1f4034978f7534479f9c5c33a92ca8546
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#include "llvm/Target/SubtargetFeature.h" 53 54#include "slang.h" 55#include "slang_assert.h" 56 57namespace slang { 58 59void Backend::CreateFunctionPasses() { 60 if (!mPerFunctionPasses) { 61 mPerFunctionPasses = new llvm::FunctionPassManager(mpModule); 62 mPerFunctionPasses->add(new llvm::TargetData(mpModule)); 63 64 llvm::PassManagerBuilder PMBuilder; 65 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 66 PMBuilder.populateFunctionPassManager(*mPerFunctionPasses); 67 } 68 return; 69} 70 71void Backend::CreateModulePasses() { 72 if (!mPerModulePasses) { 73 mPerModulePasses = new llvm::PassManager(); 74 mPerModulePasses->add(new llvm::TargetData(mpModule)); 75 76 llvm::PassManagerBuilder PMBuilder; 77 PMBuilder.OptLevel = mCodeGenOpts.OptimizationLevel; 78 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 79 PMBuilder.SizeLevel = mCodeGenOpts.OptimizeSize; 80 if (mCodeGenOpts.UnitAtATime) { 81 PMBuilder.DisableUnitAtATime = 0; 82 } else { 83 PMBuilder.DisableUnitAtATime = 1; 84 } 85 86 if (mCodeGenOpts.UnrollLoops) { 87 PMBuilder.DisableUnrollLoops = 0; 88 } else { 89 PMBuilder.DisableUnrollLoops = 1; 90 } 91 92 PMBuilder.DisableSimplifyLibCalls = false; 93 PMBuilder.populateModulePassManager(*mPerModulePasses); 94 } 95 return; 96} 97 98bool Backend::CreateCodeGenPasses() { 99 if ((mOT != Slang::OT_Assembly) && (mOT != Slang::OT_Object)) 100 return true; 101 102 // Now we add passes for code emitting 103 if (mCodeGenPasses) { 104 return true; 105 } else { 106 mCodeGenPasses = new llvm::FunctionPassManager(mpModule); 107 mCodeGenPasses->add(new llvm::TargetData(mpModule)); 108 } 109 110 // Create the TargetMachine for generating code. 111 std::string Triple = mpModule->getTargetTriple(); 112 113 std::string Error; 114 const llvm::Target* TargetInfo = 115 llvm::TargetRegistry::lookupTarget(Triple, Error); 116 if (TargetInfo == NULL) { 117 mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error; 118 return false; 119 } 120 121 llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim; 122 123 // Use hardware FPU. 124 // 125 // FIXME: Need to detect the CPU capability and decide whether to use softfp. 126 // To use softfp, change following 2 lines to 127 // 128 // llvm::FloatABIType = llvm::FloatABI::Soft; 129 // llvm::UseSoftFloat = true; 130 llvm::FloatABIType = llvm::FloatABI::Hard; 131 llvm::UseSoftFloat = false; 132 133 // BCC needs all unknown symbols resolved at compilation time. So we don't 134 // need any relocation model. 135 llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static); 136 137 138 // This is set for the linker (specify how large of the virtual addresses we 139 // can access for all unknown symbols.) 140 if (mpModule->getPointerSize() == llvm::Module::Pointer32) 141 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small); 142 else 143 // The target may have pointer size greater than 32 (e.g. x86_64 144 // architecture) may need large data address model 145 llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium); 146 147 // Setup feature string 148 std::string FeaturesStr; 149 if (mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 150 llvm::SubtargetFeatures Features; 151 152 Features.setCPU(mTargetOpts.CPU); 153 154 for (std::vector<std::string>::const_iterator 155 I = mTargetOpts.Features.begin(), E = mTargetOpts.Features.end(); 156 I != E; 157 I++) 158 Features.AddFeature(*I); 159 160 FeaturesStr = Features.getString(); 161 } 162 llvm::TargetMachine *TM = 163 TargetInfo->createTargetMachine(Triple, FeaturesStr); 164 165 // Register scheduler 166 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler); 167 168 // Register allocation policy: 169 // createFastRegisterAllocator: fast but bad quality 170 // createLinearScanRegisterAllocator: not so fast but good quality 171 llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? 172 llvm::createFastRegisterAllocator : 173 llvm::createLinearScanRegisterAllocator); 174 175 llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 176 if (mCodeGenOpts.OptimizationLevel == 0) 177 OptLevel = llvm::CodeGenOpt::None; 178 else if (mCodeGenOpts.OptimizationLevel == 3) 179 OptLevel = llvm::CodeGenOpt::Aggressive; 180 181 llvm::TargetMachine::CodeGenFileType CGFT = 182 llvm::TargetMachine::CGFT_AssemblyFile; 183 if (mOT == Slang::OT_Object) 184 CGFT = llvm::TargetMachine::CGFT_ObjectFile; 185 if (TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream, 186 CGFT, OptLevel)) { 187 mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target); 188 return false; 189 } 190 191 return true; 192} 193 194Backend::Backend(clang::Diagnostic *Diags, 195 const clang::CodeGenOptions &CodeGenOpts, 196 const clang::TargetOptions &TargetOpts, 197 PragmaList *Pragmas, 198 llvm::raw_ostream *OS, 199 Slang::OutputType OT) 200 : ASTConsumer(), 201 mCodeGenOpts(CodeGenOpts), 202 mTargetOpts(TargetOpts), 203 mpModule(NULL), 204 mpOS(OS), 205 mOT(OT), 206 mGen(NULL), 207 mPerFunctionPasses(NULL), 208 mPerModulePasses(NULL), 209 mCodeGenPasses(NULL), 210 mLLVMContext(llvm::getGlobalContext()), 211 mDiags(*Diags), 212 mPragmas(Pragmas) { 213 FormattedOutStream.setStream(*mpOS, 214 llvm::formatted_raw_ostream::PRESERVE_STREAM); 215 mGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext); 216 return; 217} 218 219void Backend::Initialize(clang::ASTContext &Ctx) { 220 mGen->Initialize(Ctx); 221 222 mpModule = mGen->GetModule(); 223 224 return; 225} 226 227void Backend::HandleTopLevelDecl(clang::DeclGroupRef D) { 228 mGen->HandleTopLevelDecl(D); 229 return; 230} 231 232void Backend::HandleTranslationUnit(clang::ASTContext &Ctx) { 233 HandleTranslationUnitPre(Ctx); 234 235 mGen->HandleTranslationUnit(Ctx); 236 237 // Here, we complete a translation unit (whole translation unit is now in LLVM 238 // IR). Now, interact with LLVM backend to generate actual machine code (asm 239 // or machine code, whatever.) 240 241 // Silently ignore if we weren't initialized for some reason. 242 if (!mpModule) 243 return; 244 245 llvm::Module *M = mGen->ReleaseModule(); 246 if (!M) { 247 // The module has been released by IR gen on failures, do not double free. 248 mpModule = NULL; 249 return; 250 } 251 252 slangAssert(mpModule == M && 253 "Unexpected module change during LLVM IR generation"); 254 255 // Insert #pragma information into metadata section of module 256 if (!mPragmas->empty()) { 257 llvm::NamedMDNode *PragmaMetadata = 258 mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); 259 for (PragmaList::const_iterator I = mPragmas->begin(), E = mPragmas->end(); 260 I != E; 261 I++) { 262 llvm::SmallVector<llvm::Value*, 2> Pragma; 263 // Name goes first 264 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->first)); 265 // And then value 266 Pragma.push_back(llvm::MDString::get(mLLVMContext, I->second)); 267 268 // Create MDNode and insert into PragmaMetadata 269 llvm::ArrayRef<llvm::Value*> PragmaArray(Pragma); 270 PragmaMetadata->addOperand( 271 llvm::MDNode::get(mLLVMContext, PragmaArray)); 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