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