Goose  Artifact [0cd7048d29]

Artifact 0cd7048d29279fcd58a5eeb9754051c8ae29efa95bf6528849257eaac457be40:

  • File bs/codegen/module.h — part of check-in [de2ecb573c] at 2019-08-02 14:32:59 on branch trunk —
    • Removed ComplexVariable and related support code in llr. This will be replaced with a much better system.
    • Temporaries are now identified both by a cfg identifier, and an index within that cfg.
    (user: achavasse size: 3087)

#ifndef EMPATHY_CODEGEN_MODULE_H
#define EMPATHY_CODEGEN_MODULE_H

namespace llvm
{
    class TargetMachine;
}

namespace empathy::codegen
{
    class Module
    {
        public:
            Module( const string& name );

            bool setupTarget();
            void dumpAsLlvmIr( const string& filename ) const;

            llvm::FunctionType* getOrCreateFuncType( const Context& c, const builtins::FuncType& ftype );

            llvm::Function* buildFuncProto( const Context& c, const builtins::Func& func, const string& name,
                llvm::Function::LinkageTypes linkageType );

            llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func );
            llvm::Function* getOrCreateFunc( const Context& c, const builtins::Func& func, const string& name,
                llvm::Function::LinkageTypes linkageType );

            void runOptimizationPasses();
            bool emitToFile( const string& filename, llvm::TargetMachine::CodeGenFileType type );

        private:
            struct FuncInfos
            {
                llvm::Function* pllvmFunc = nullptr;
                llr::TempStorage< NullInit< llvm::Value* > > temporaries;
            };

            llvm::BasicBlock* buildBasicBlock( const Context& c, FuncInfos& fi, const ptr< llr::BasicBlock >& pBB );

            llvm::Value* buildValue( const Context& c, FuncInfos& fi, const Value& val );

            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::Instruction& instr );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::GetArg& ga );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::Call& call );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::CreateTemporary& ct );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::GetTemporary& gt );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::Phi& p );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::LoadConstInt& lci );
            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::LoadConstStr& lcs );

            llvm::Value* buildInstruction( const Context& c, FuncInfos& fi, const llr::Xor& bo );

            bool buildTerminator( const Context& c, FuncInfos& fi, const llr::Terminator& terminator );
            bool buildTerminator( const Context& c, FuncInfos& fi, const llr::Ret& r );
            bool buildTerminator( const Context& c, FuncInfos& fi, const llr::Branch& b );
            bool buildTerminator( const Context& c, FuncInfos& fi, const llr::CondBranch& cb );

            llvm::Value* createTemporary( FuncInfos& fi, uint32_t cfgId, uint32_t index, llvm::Value* pValue ) const;

            llvm::Module m_llvmModule;
            llvm::IRBuilder<> m_llvmBuilder;
            llvm::TargetMachine* m_targetMachine = nullptr;

            unordered_map< string, llvm::GlobalVariable* > m_strings;
    };
}

#endif