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