slang_backend.cpp revision 462aefd62cc646d2ff753c1d003ef3cd7bbea26
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/Stmt.h" /* for class clang::*Stmt */ 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/StmtVisitor.h" /* for class clang::StmtVisitor */ 26462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/Expr.h" /* for class clang::*Expr */ 27462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/DeclGroup.h" /* for class clang::DeclGroupRef */ 28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/AST/ASTContext.h" /* for class clang::ASTContext */ 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetInfo.h" /* for class clang::TargetInfo */ 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/Diagnostic.h" /* for class clang::Diagnostic */ 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Basic/TargetOptions.h" /* for class clang::TargetOptions */ 33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/Frontend/FrontendDiagnostic.h" /* for clang::diag::* */ 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/CodeGen/ModuleBuilder.h" /* for class clang::CodeGenerator */ 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "clang/CodeGen/CodeGenOptions.h" /* for class clang::CodeGenOptions */ 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace { 40462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao using namespace clang; 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao class CheckFunctionCallVisitor : public StmtVisitor<CheckFunctionCallVisitor> { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao private: 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Diagnostic& mDiags; 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao SourceManager& mSourceMgr; 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 47462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao public: 48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CheckFunctionCallVisitor(Diagnostic& Diags, SourceManager& SourceMgr) : 49462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags(Diags), 50462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mSourceMgr(SourceMgr) 51462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 52462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao void VisitStmt(Stmt* S); 56462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao void VisitCallExpr(CallExpr* Node); 57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao }; 58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao void CheckFunctionCallVisitor::VisitStmt(Stmt* S) { 60462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(Stmt::child_iterator I = S->child_begin(); 61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I != S->child_end(); 62462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I++) 63462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(*I) 64462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Visit(*I); 65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 67462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 68462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao void CheckFunctionCallVisitor::VisitCallExpr(CallExpr* Node) { 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(Node != NULL) { 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const FunctionDecl* Callee = Node->getDirectCallee(); 71462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(Callee != NULL) { 72462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!Callee->getBody() && !Callee->hasPrototype()) { 73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Warn: Function has neither definition nore prototype */ 74462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.Report(FullSourceLoc(Node->getLocStart(), mSourceMgr), 75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.getCustomDiagID(Diagnostic::Warning, "no previous prototype for function '%0'")) << Callee->getName(); 76462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 77462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 78462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 79462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 80462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 81462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 82462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 83462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaonamespace slang { 84462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 85462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool Backend::CreateCodeGenPasses() { 86462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mOutputType != SlangCompilerOutput_Assembly && mOutputType != SlangCompilerOutput_Obj) 87462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 88462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 89462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Now we add passes for code emitting */ 90462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenPasses) { 91462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 92462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } else { 93462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses = new llvm::FunctionPassManager(mpModule); 94462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->add(new llvm::TargetData(*mpTargetData)); 95462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 96462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 97462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create the TargetMachine for generating code. */ 98462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string Triple = mpModule->getTargetTriple(); 99462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 100462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string Error; 101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const llvm::Target* TargetInfo = llvm::TargetRegistry::lookupTarget(Triple, Error); 102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(TargetInfo == NULL) { 103462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.Report(clang::diag::err_fe_unable_to_create_target) << Error; 104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return false; 105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::NoFramePointerElim = mCodeGenOpts.DisableFPElim; 108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Use hardware FPU. 111462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * 112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * FIXME: Need to detect the CPU capability and decide whether to use softfp. To use softfp, change following 2 lines to 113462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * 114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * llvm::FloatABIType = llvm::FloatABI::Soft; 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * llvm::UseSoftFloat = true; 116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::FloatABIType = llvm::FloatABI::Hard; 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::UseSoftFloat = false; 119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setRelocationModel(llvm::Reloc::Static); /* ACC needs all unknown symbols resolved at compilation time. 121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao So we don't need any relocation model. */ 122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* The target with pointer size greater than 32 (e.g. x86_64 architecture) may need large data address model */ 124462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpTargetData->getPointerSizeInBits() > 32) 125462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setCodeModel(llvm::CodeModel::Medium); 126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao else 127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::setCodeModel(llvm::CodeModel::Small); /* This is set for the linker (specify how large of the virtual addresses 128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao we can access for all unknown symbols.) */ 129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* setup feature string */ 131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao std::string FeaturesStr; 132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mTargetOpts.CPU.size() || mTargetOpts.Features.size()) { 133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::SubtargetFeatures Features; 134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Features.setCPU(mTargetOpts.CPU); 136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(std::vector<std::string>::const_iterator it = mTargetOpts.Features.begin(); 138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it != mTargetOpts.Features.end(); 139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it++) 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Features.AddFeature(*it); 141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 142462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FeaturesStr = Features.getString(); 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine *TM = TargetInfo->createTargetMachine(Triple, FeaturesStr); 145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Register scheduler */ 147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler); 148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 149462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Register allocation policy: 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * createLocalRegisterAllocator: fast but bad quality 151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * createLinearScanRegisterAllocator: not so fast but good quality 152462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::RegisterRegAlloc::setDefault((mCodeGenOpts.OptimizationLevel == 0) ? llvm::createLocalRegisterAllocator : llvm::createLinearScanRegisterAllocator); 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::CodeGenOpt::Level OptLevel = llvm::CodeGenOpt::Default; 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenOpts.OptimizationLevel == 0) 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OptLevel = llvm::CodeGenOpt::None; 158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao else if(mCodeGenOpts.OptimizationLevel == 3) 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao OptLevel = llvm::CodeGenOpt::Aggressive; 160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::TargetMachine::CodeGenFileType CGFT = llvm::TargetMachine::CGFT_AssemblyFile;; 162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mOutputType == SlangCompilerOutput_Obj) 163462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CGFT = llvm::TargetMachine::CGFT_ObjectFile; 164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(TM->addPassesToEmitFile(*mCodeGenPasses, FormattedOutStream, CGFT, OptLevel)) { 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags.Report(clang::diag::err_fe_unable_to_interface_with_target); 166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return false; 167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 169462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return true; 170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 172462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::Backend(Diagnostic &Diags, 173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const CodeGenOptions& CodeGenOpts, 174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const TargetOptions& TargetOpts, 175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao const PragmaList& Pragmas, 176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::raw_ostream* OS, 177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao SlangCompilerOutputTy OutputType) : 178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao ASTConsumer(), 179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mLLVMContext(llvm::getGlobalContext()), 180462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mDiags(Diags), 181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenOpts(CodeGenOpts), 182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mTargetOpts(TargetOpts), 183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPragmas(Pragmas), 184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpOS(OS), 185462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mOutputType(OutputType), 186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpModule(NULL), 187462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpTargetData(NULL), 188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen(NULL), 189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses(NULL), 190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses(NULL), 191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses(NULL) 192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao{ 193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FormattedOutStream.setStream(*mpOS, llvm::formatted_raw_ostream::PRESERVE_STREAM); 194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen = CreateLLVMCodeGen(mDiags, "", mCodeGenOpts, mLLVMContext); 195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::Initialize(ASTContext &Ctx) { 199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->Initialize(Ctx); 200462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpModule = mGen->GetModule(); 202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpTargetData = new llvm::TargetData(Slang::TargetDescription); 203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTopLevelDecl(DeclGroupRef D) { 208462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTopLevelDecl(D); 209462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 210462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 211462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 212462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTranslationUnit(ASTContext& Ctx) { 213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Warn if there's any function without prototype declaration or function definition called */ 214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao TranslationUnitDecl* TUDecl = Ctx.getTranslationUnitDecl(); 215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(DeclContext::decl_iterator DI = TUDecl->decls_begin(); 216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao DI != TUDecl->decls_end(); 217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao DI++) 218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 219462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(DI->getKind() == Decl::Function) { 220462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FunctionDecl* FD = static_cast<FunctionDecl*>(*DI); 221462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Stmt* Body = FD->getBody(); 222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(Body != NULL) { 223462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CheckFunctionCallVisitor FunctionCallChecker(mDiags, Ctx.getSourceManager()); 224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FunctionCallChecker.Visit(Body); 225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 229462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTranslationUnit(Ctx); 230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 231462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* 232462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Here, we complete a translation unit (whole translation unit is now in LLVM IR). 233462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * Now, interact with LLVM backend to generate actual machine code (asm or machine 234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * code, whatever.) 235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */ 236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mpModule || !mpTargetData) /* Silently ignore if we weren't initialized for some reason. */ 238462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::Module* M = mGen->ReleaseModule(); 241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!M) { 242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* The module has been released by IR gen on failures, do not double free. */ 243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mpModule = NULL; 244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao assert(mpModule == M && "Unexpected module change during LLVM IR generation"); 248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Insert #pragma information into metadata section of module */ 250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!mPragmas.empty()) { 251462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::NamedMDNode* PragmaMetadata = llvm::NamedMDNode::Create(mLLVMContext, Slang::PragmaMetadataName, NULL, 0, mpModule); 252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(PragmaList::const_iterator it = mPragmas.begin(); 253462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it != mPragmas.end(); 254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao it++) 255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 256462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::SmallVector<llvm::Value*, 2> Pragma; 257462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Name goes first */ 258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, it->first)); 259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* And then value */ 260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao Pragma.push_back(llvm::MDString::get(mLLVMContext, it->second)); 261462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create MDNode and insert into PragmaMetadata */ 262462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao PragmaMetadata->addOperand( llvm::MDNode::get(mLLVMContext, Pragma.data(), Pragma.size()) ); 263462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao HandleTranslationUnitEx(Ctx); 267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create passes for optimization and code emission */ 269462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 270462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create and run per-function passes */ 271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CreateFunctionPasses(); 272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerFunctionPasses) { 273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->doInitialization(); 274462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 275462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(llvm::Module::iterator I = mpModule->begin(); 276462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I != mpModule->end(); 277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I++) 278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!I->isDeclaration()) 279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->run(*I); 280462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 281462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerFunctionPasses->doFinalization(); 282462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 283462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 284462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao /* Create and run module passes */ 286462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao CreateModulePasses(); 287462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerModulePasses) 288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mPerModulePasses->run(*mpModule); 289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 290462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao switch(mOutputType) { 291462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Assembly: 292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Obj: 293462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!CreateCodeGenPasses()) 294462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->doInitialization(); 297462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao for(llvm::Module::iterator I = mpModule->begin(); 299462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I != mpModule->end(); 300462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao I++) 301462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(!I->isDeclaration()) 302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->run(*I); 303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mCodeGenPasses->doFinalization(); 305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_LL: 308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::PassManager* LLEmitPM = new llvm::PassManager(); 310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao LLEmitPM->add(llvm::createPrintModulePass(&FormattedOutStream)); 311462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao LLEmitPM->run(*mpModule); 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 315462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Bitcode: 316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao { 317462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao llvm::PassManager* BCEmitPM = new llvm::PassManager(); 318462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao BCEmitPM->add(llvm::createBitcodeWriterPass(FormattedOutStream)); 319462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao BCEmitPM->run(*mpModule); 320462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao case SlangCompilerOutput_Nothing: 324462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 327462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao default: 328462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao assert(false && "Unknown output type"); 329462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao break; 330462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 331462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 332462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao FormattedOutStream.flush(); 333462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 334462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 335462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 336462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 337462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::HandleTagDeclDefinition(TagDecl* D) { 338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->HandleTagDeclDefinition(D); 339462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 340462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 341462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 342462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid Backend::CompleteTentativeDefinition(VarDecl* D) { 343462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao mGen->CompleteTentativeDefinition(D); 344462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 345462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 346462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 347462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoBackend::~Backend() { 348462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpModule) 349462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mpModule; 350462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mpTargetData) 351462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mpTargetData; 352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mGen) 353462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mGen; 354462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerFunctionPasses) 355462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mPerFunctionPasses; 356462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mPerModulePasses) 357462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mPerModulePasses; 358462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao if(mCodeGenPasses) 359462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao delete mCodeGenPasses; 360462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao return; 361462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 363462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} /* namespace slang */ 364