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