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