#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; llvm::SmallVector< llvm::Value*, 4 > 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::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 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