slang_backend.cpp revision cecd11d2af5d45d8ba322bed61fb48a99c305528
1462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang.hpp" 2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_backend.hpp" 3462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Module.h" /* for class llvm::Module */ 5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Metadata.h" /* for class llvm::NamedMDNode */ 6462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/LLVMContext.h" /* for llvm::getGlobalContext() */ 7462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetMachine.h" /* for class llvm::TargetMachine and llvm::TargetMachine::AssemblyFile */ 9462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetOptions.h" /* for 10462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * variable bool llvm::UseSoftFloat 11462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * FloatABI::ABIType llvm::FloatABIType 12462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * bool llvm::NoZerosInBSS 13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/TargetRegistry.h" /* for class llvm::TargetRegistry */ 15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Target/SubtargetFeature.h" /* for class llvm::SubtargetFeature */ 16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/CodeGen/RegAllocRegistry.h" /* for class llvm::RegisterRegAlloc */ 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/CodeGen/SchedulerRegistry.h" /* for class llvm::RegisterScheduler and llvm::createDefaultScheduler() */ 19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Assembly/PrintModulePass.h" /* for function createPrintModulePass() */ 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "llvm/Bitcode/ReaderWriter.h" /* for function createBitcodeWriterPass() */ 22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/Decl.h" /* for class clang::*Decl */ 24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/DeclGroup.h" /* for class clang::DeclGroupRef */ 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/ASTContext.h" /* for class clang::ASTContext */ 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetInfo.h" /* for class clang::TargetInfo */ 28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/Diagnostic.h" /* for class clang::Diagnostic */ 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetOptions.h" /* for class clang::TargetOptions */ 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h" /* for clang::diag::* */ 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/CodeGen/ModuleBuilder.h" /* for class clang::CodeGenerator */ 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang { 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() { 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mOutputType != SlangCompilerOutput_Assembly && mOutputType != SlangCompilerOutput_Obj) 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Now we add passes for code emitting */ 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenPasses) { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } else { 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses = new llvm::FunctionPassManager(mpModule); 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->add(new llvm::TargetData(*mpTargetData)); 47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create the TargetMachine for generating code. */ 50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string Triple = mpModule->getTargetTriple(); 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string Error; 53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const llvm::Target* TargetInfo = llvm::TargetRegistry::lookupTarget(Triple, Error); 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(TargetInfo == NULL) { 55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error; 56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return false; 57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim; 60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Use hardware FPU. 63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * 64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * FIXME: Need to detect the CPU capability and decide whether to use softfp. To use softfp, change following 2 lines to 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * 66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * llvm::FloatABIType = llvm::FloatABI::Soft; 67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * llvm::UseSoftFloat = true; 68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::FloatABIType = llvm::FloatABI::Hard; 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::UseSoftFloat = false; 71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static); /* ACC needs all unknown symbols resolved at compilation time. 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao So we don't need any relocation model. */ 74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* The target with pointer size greater than 32 (e.g. x86_64 architecture) may need large data address model */ 76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpTargetData->getPointerSizeInBits() > 32) 77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium); 78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao else 79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small); /* This is set for the linker (specify how large of the virtual addresses 80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao we can access for all unknown symbols.) */ 81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* setup feature string */ 83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string FeaturesStr; 84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::SubtargetFeatures Features; 86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Features.setCPU(mTargetOpts.CPU); 88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(std::vector<std::string>::const_iterator it = mTargetOpts.Features.begin(); 90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it != mTargetOpts.Features.end(); 91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it++) 92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Features.AddFeature(*it); 93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FeaturesStr = Features.getString(); 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine *TM = TargetInfo->createTargetMachine(Triple, FeaturesStr); 97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Register scheduler */ 99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler); 100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Register allocation policy: 102f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao * createFastRegisterAllocator: fast but bad quality 103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * createLinearScanRegisterAllocator: not so fast but good quality 104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 105f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? llvm::createFastRegisterAllocator : llvm::createLinearScanRegisterAllocator); 106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenOpts.OptimizationLevel == 0) 109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OptLevel = llvm::CodeGenOpt::None; 110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao else if(mCodeGenOpts.OptimizationLevel == 3) 111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OptLevel = llvm::CodeGenOpt::Aggressive; 112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::CodeGenFileType CGFT = llvm::TargetMachine::CGFT_AssemblyFile;; 114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mOutputType == SlangCompilerOutput_Obj) 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CGFT = llvm::TargetMachine::CGFT_ObjectFile; 116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream, CGFT, OptLevel)) { 117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target); 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return false; 119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 124462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::Backend(Diagnostic &Diags, 125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const CodeGenOptions& CodeGenOpts, 126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const TargetOptions& TargetOpts, 127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const PragmaList& Pragmas, 128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::raw_ostream* OS, 1296b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart SlangCompilerOutputTy OutputType, 1301fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart SourceManager &SourceMgr, 1311fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart bool AllowRSPrefix) : 132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao ASTConsumer(), 133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts(CodeGenOpts), 134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mTargetOpts(TargetOpts), 135cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mSourceMgr(SourceMgr), 136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpOS(OS), 137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mOutputType(OutputType), 138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpTargetData(NULL), 139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen(NULL), 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses(NULL), 141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses(NULL), 1426b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart mCodeGenPasses(NULL), 143cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mAllowRSPrefix(AllowRSPrefix), 144cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mLLVMContext(llvm::getGlobalContext()), 145cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mDiags(Diags), 146cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mpModule(NULL), 147cecd11d2af5d45d8ba322bed61fb48a99c305528Shih-wei Liao mPragmas(Pragmas) 148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao{ 149462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FormattedOutStream.setStream(*mpOS, llvm::formatted_raw_ostream::PRESERVE_STREAM); 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext); 151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::Initialize(ASTContext &Ctx) { 155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->Initialize(Ctx); 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpModule = mGen->GetModule(); 158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpTargetData = new llvm::TargetData(Slang::TargetDescription); 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTopLevelDecl(DeclGroupRef D) { 1646b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart /* Disallow user-defined functions with prefix "rs" */ 1651fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart if (!mAllowRSPrefix) { 1661fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart DeclGroupRef::iterator it; 1671fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart for (it = D.begin(); it != D.end(); it++) { 1681fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart FunctionDecl *FD = dyn_cast<FunctionDecl>(*it); 1691fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart if (!FD || !FD->isThisDeclarationADefinition()) continue; 1701fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart if (FD->getName().startswith("rs")) { 1711fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart mDiags.Report(FullSourceLoc(FD->getLocStart(), mSourceMgr), 1721fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart mDiags.getCustomDiagID(Diagnostic::Error, "invalid function name prefix, \"rs\" is reserved: '%0'")) << FD->getNameAsString(); 1731fd8579fe65b13a26cfaad12d056d2fc9b46475aKirk Stewart } 1746b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart } 1756b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart } 1766b22674f4ef0a6c689c589830f1c44f443520785Kirk Stewart 177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTopLevelDecl(D); 178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTranslationUnit(ASTContext& Ctx) { 182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTranslationUnit(Ctx); 183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Here, we complete a translation unit (whole translation unit is now in LLVM IR). 186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Now, interact with LLVM backend to generate actual machine code (asm or machine 187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * code, whatever.) 188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mpModule || !mpTargetData) /* Silently ignore if we weren't initialized for some reason. */ 191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::Module* M = mGen->ReleaseModule(); 194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!M) { 195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* The module has been released by IR gen on failures, do not double free. */ 196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpModule = NULL; 197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao assert(mpModule == M && "Unexpected module change during LLVM IR generation"); 201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Insert #pragma information into metadata section of module */ 203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mPragmas.empty()) { 204f52a620440fa62257dfdcf2583f0f9df5b855c76Shih-wei Liao llvm::NamedMDNode* PragmaMetadata = mpModule->getOrInsertNamedMetadata(Slang::PragmaMetadataName); 205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(PragmaList::const_iterator it = mPragmas.begin(); 206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it != mPragmas.end(); 207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it++) 208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::SmallVector<llvm::Value*, 2> Pragma; 210462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Name goes first */ 211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, it->first)); 212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* And then value */ 213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, it->second)); 214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create MDNode and insert into PragmaMetadata */ 215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao PragmaMetadata->addOperand( llvm::MDNode::get(mLLVMContext, Pragma.data(), Pragma.size()) ); 216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 219462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao HandleTranslationUnitEx(Ctx); 220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create passes for optimization and code emission */ 222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 223462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create and run per-function passes */ 224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CreateFunctionPasses(); 225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerFunctionPasses) { 226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->doInitialization(); 227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(llvm::Module::iterator I = mpModule->begin(); 229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I != mpModule->end(); 230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I++) 231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!I->isDeclaration()) 232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->run(*I); 233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->doFinalization(); 235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create and run module passes */ 239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CreateModulePasses(); 240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerModulePasses) 241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses->run(*mpModule); 242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao switch(mOutputType) { 244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Assembly: 245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Obj: 246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!CreateCodeGenPasses()) 247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->doInitialization(); 250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 251462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(llvm::Module::iterator I = mpModule->begin(); 252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I != mpModule->end(); 253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I++) 254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!I->isDeclaration()) 255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->run(*I); 256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->doFinalization(); 258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_LL: 261462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 262462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::PassManager* LLEmitPM = new llvm::PassManager(); 263462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream)); 264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao LLEmitPM->run(*mpModule); 265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Bitcode: 269462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 270462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::PassManager* BCEmitPM = new llvm::PassManager(); 271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream)); 272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao BCEmitPM->run(*mpModule); 273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Nothing: 277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao default: 281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao assert(false && "Unknown output type"); 282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FormattedOutStream.flush(); 286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTagDeclDefinition(TagDecl* D) { 291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTagDeclDefinition(D); 292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 293462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::CompleteTentativeDefinition(VarDecl* D) { 296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->CompleteTentativeDefinition(D); 297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() { 301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpModule) 302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mpModule; 303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpTargetData) 304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mpTargetData; 305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mGen) 306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mGen; 307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerFunctionPasses) 308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mPerFunctionPasses; 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerModulePasses) 310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mPerModulePasses; 311462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenPasses) 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mCodeGenPasses; 313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} /* namespace slang */ 317