5#ifndef HOSHI_LANG_LLVMCODEGENCONTEXT_HPP
6#define HOSHI_LANG_LLVMCODEGENCONTEXT_HPP
8#include <llvm/IR/BasicBlock.h>
9#include <llvm/IR/DIBuilder.h>
10#include <llvm/IR/DerivedTypes.h>
11#include <llvm/IR/Function.h>
12#include <llvm/IR/GlobalVariable.h>
13#include <llvm/IR/IRBuilder.h>
14#include <llvm/IR/LLVMContext.h>
15#include <llvm/IR/Module.h>
16#include <llvm/IR/Type.h>
17#include <llvm/IR/Value.h>
18#include <llvm/IR/Verifier.h>
29#ifdef LLVM_CODEGEN_DEBUG
30#define TIMER(X, Y) { auto start = std::chrono::high_resolution_clock::now(); Y; auto end = std::chrono::high_resolution_clock::now(); std::lock_guard<std::mutex> lock(yoi::consoleMutex); std::cout << X << " took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << " ms" << std::endl; }
50 std::map<yoi::indexT, std::vector<indexT>>
G;
51 std::map<yoi::indexT, std::vector<indexT>>
reverseG;
69 std::map<yoi::indexT, yoi::vec<llvm::PHINode *>>
phiNodes;
83 llvm::BasicBlock *currentBlock,
84 llvm::BasicBlock *fromBlock);
138 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT>,
141 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT>,
144 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT>,
147 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT>,
150 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT>,
153 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT>,
157 std::map<std::tuple<yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT>,
232 llvm::Value *
loadIfDataStructObject(LLVMModuleContext &llvmModCtx,
const std::shared_ptr<IRValueType> &type, llvm::Value *value);
234 std::shared_ptr<IRValueType>
normalizeForeignType(LLVMModuleContext &llvmModCtx,
const std::shared_ptr<IRValueType> &type);
235 llvm::Type *
yoiTypeToLLVMType(LLVMModuleContext &llvmModCtx,
const std::shared_ptr<IRValueType> &type,
bool enforceForeignType =
false);
236 llvm::Type *
getArrayLLVMType(LLVMModuleContext &llvmModCtx,
const std::shared_ptr<IRValueType> &type,
bool enforceForeignType =
false);
250 void callGcFunction(
LLVMModuleContext &llvmModCtx, llvm::Value *objectPtr,
const std::shared_ptr<IRValueType> &yoiType,
bool isIncrease,
bool forceForPermanent =
false,
bool forceForBorrow =
false);
254 const std::shared_ptr<IRValueType> &foreignType,
255 bool convertToForeign =
false);
263 const std::shared_ptr<IRValueType> &valueToStoreType,
264 llvm::Value *arrayPtr,
268 llvm::StructType *structType,
269 llvm::Type *baseType);
275 const std::shared_ptr<IRValueType> &yoiType,
276 const std::function<
void()> &func,
bool enforced =
false);
279 llvm::Value *objectPtr,
llvm::BasicBlock * suspendBB
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT >, yoi::indexT > typeIDMap
llvm::GlobalVariable * RTTITable
std::map< yoi::indexT, llvm::AllocaInst * > namedValues
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT >, llvm::Type * > foreignTypeMap
std::shared_ptr< yoi::IRFunctionDefinition > currentFunctionDef
llvm::BasicBlock * cleanupBB
llvm::BasicBlock * resumeBB
std::map< yoi::wstr, llvm::DIType * > basicDITypeMap
yoi::vec< std::tuple< std::shared_ptr< IRValueType >, llvm::StructType *, llvm::Type * > > arrayToGenerateImplementations
std::map< yoi::indexT, llvm::DIType * > dataStructDataRegionTypeDIMap
std::map< yoi::wstr, llvm::Function * > functionMap
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT >, llvm::DIType * > arrayDataRegionDITypeMap
ValueStackWithPhi valueStackPhi
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT >, llvm::DIType * > structTypeDIMap
std::unique_ptr< llvm::LLVMContext > TheContext
std::map< yoi::wstr, llvm::DICompileUnit * > compileUnits
std::map< yoi::indexT, llvm::BasicBlock * > basicBlockMap
std::map< yoi::indexT, llvm::GlobalVariable * > globalValues
std::unique_ptr< llvm::IRBuilder<> > Builder
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT >, llvm::StructType * > structTypeMap
std::unique_ptr< llvm::Module > TheModule
std::map< yoi::indexT, bool > basicBlockVisited
std::unique_ptr< llvm::DIBuilder > DBuilder
llvm::Function * currentFunction
struct yoi::LLVMCodegen::LLVMModuleContext::@0 currentGeneratorContextBasicBlocks
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT >, llvm::DIType * > arrayTypeDIMap
llvm::GlobalVariable * noneObjectSingleton
llvm::StructType * RTTIEntryType
std::map< yoi::indexT, llvm::StructType * > dataStructDataRegionMap
std::map< yoi::wstr, llvm::Function * > runtimeFunctions
llvm::Value * currentGeneratorContextValue
std::map< std::tuple< yoi::IRValueType::valueType, yoi::indexT, yoi::indexT, yoi::indexT >, llvm::StructType * > arrayTypeMap
ControlFlowAnalysis controlFlowAnalysis
void generateInstruction(LLVMModuleContext &llvmModCtx, const IR &instr, yoi::indexT fromBlock, yoi::indexT toBlock)
llvm::Function * getGcFunction(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &yoiType, bool isIncrease)
void generateRuntimeFunctionImplementations(LLVMModuleContext &llvmModCtx)
llvm::Value * createBasicObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &yoiType, llvm::Value *rawValue)
StackValue promiseInterfaceObjectIfInterface(LLVMModuleContext &llvmModCtx, const StackValue &objectVal)
void generateInterfaceObjectGCFunctionImplementations(LLVMModuleContext &llvmModCtx)
yoi::vec< yoi::wstr > generate()
void generateImplementations(LLVMModuleContext &llvmModCtx)
void generateExportFunctionDecls(LLVMModuleContext &llvmModCtx)
CodegenTaskDispatcher codegenTaskDispatcher
void generateImportFunctionDeclarations(LLVMModuleContext &llvmModCtx)
llvm::Value * createGeneratorContext(LLVMModuleContext &llvmModCtx, llvm::Value *coro_handle)
StackValue wrapInterfaceObjectIfRegressed(LLVMModuleContext &llvmModCtx, const StackValue &objectVal)
llvm::Value * loadIfDataStructObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::Value *value)
llvm::Value * createDynamicArrayObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, const yoi::vec< StackValue > &elements, llvm::Value *size)
void generateGlobalDeclarations(LLVMModuleContext &llvmModCtx)
void generateDeclarations(LLVMModuleContext &llvmModCtx)
void handleBinaryOp(LLVMModuleContext &llvmModCtx, llvm::Instruction::BinaryOps op, bool isFloat, yoi::indexT fromBlock, yoi::indexT toBlock)
void generateMainFunction(LLVMModuleContext &llvmModCtx)
void generateCodeBlock(LLVMModuleContext &llvmModCtx, IRCodeBlock &block, yoi::indexT fromBlock, yoi::indexT toBlock, llvm::BasicBlock *actualFromBlock=nullptr)
llvm::Value * createArrayObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, const yoi::vec< StackValue > &elements)
llvm::Value * loadArrayElement(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::Value *arrayPtr, llvm::Value *index)
void callGcFunction(LLVMModuleContext &llvmModCtx, llvm::Value *objectPtr, const std::shared_ptr< IRValueType > &yoiType, bool isIncrease, bool forceForPermanent=false, bool forceForBorrow=false)
void generateStructDeclarations(LLVMModuleContext &llvmModCtx)
void storeArrayElement(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, const std::shared_ptr< IRValueType > &valueToStoreType, llvm::Value *arrayPtr, llvm::Value *index, llvm::Value *value)
llvm::Module * getModule(LLVMModuleContext &llvmModCtx)
std::pair< std::shared_ptr< IRValueType >, llvm::Value * > ensureObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::Value *val)
void generateForeignStructTypes(LLVMModuleContext &llvmModCtx)
void generateBasicTypeDeclarations(LLVMModuleContext &llvmModCtx)
llvm::Value * handleForeignTypeConv(LLVMModuleContext &llvmModCtx, llvm::Value *val, yoi::indexT foreignTypeIndex, yoi::indexT isArray, bool convertToForeign=false)
void generateWrapperForForeignCallablesIfNotExists(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type)
void generateDataStructDeclarations(LLVMModuleContext &llvmModCtx)
void generateFunctionDeclarations(LLVMModuleContext &llvmModCtx)
void declareRuntimeFunctions(LLVMModuleContext &llvmModCtx)
void generateStructGCFunctionImplementations(LLVMModuleContext &llvmModCtx)
void dumpIR(const yoi::wstr &modulePath, const std::string &filename)
void generateDataStructShallowDeclarations(LLVMModuleContext &llvmModCtx)
bool is_rtti_table_frozen
void generateDescription(LLVMModuleContext &llvmModCtx)
llvm::Type * getArrayLLVMType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, bool enforceForeignType=false)
void generateArrayGCFunctionDeclarations(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::StructType *structType, llvm::Type *baseType)
void generateRTTIImplmentation(LLVMModuleContext &llvmModCtx)
void generateArrayGCFunctionImplementations(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::StructType *structType, llvm::Type *baseType)
llvm::Value * createStructObject(LLVMModuleContext &llvmModCtx, yoi::indexT moduleIndex, yoi::indexT structIndex)
std::map< yoi::wstr, std::unique_ptr< LLVMModuleContext > > llvmModuleContext
StackValue actualizeInterfaceObject(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, llvm::Value *objectPtr, yoi::indexT implIndex)
llvm::Type * yoiTypeToLLVMType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, bool enforceForeignType=false)
void generateFunctionImplementations(LLVMModuleContext &llvmModCtx)
void generateGeneratorContextInitialization(LLVMModuleContext &llvmModCtx)
llvm::Constant * getGlobalInitializer(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type)
void generateIfTargetNotNull(LLVMModuleContext &llvmModCtx, llvm::Value *objectPtr, const std::shared_ptr< IRValueType > &yoiType, const std::function< void()> &func, bool enforced=false)
llvm::Value * unwrapInterfaceObject(LLVMModuleContext &llvmModCtx, const StackValue &objectVal)
void generateFunctionExitCleanup(LLVMModuleContext &llvmModCtx)
void storeYieldValue(LLVMModuleContext &llvmModCtx, llvm::Value *value, const std::shared_ptr< IRValueType > &yoiType)
void handleComparison(LLVMModuleContext &llvmModCtx, llvm::CmpInst::Predicate pred, bool isFloat, yoi::indexT fromBlock, yoi::indexT toBlock)
void storeMember(LLVMModuleContext &llvmModCtx, const StackValue &storeValue, const StackValue &structVal, yoi::indexT memberIndex)
void generateInterfaceObjectGCFunctionDeclarations(LLVMModuleContext &llvmModCtx)
void generateBasicTypeImplementations(LLVMModuleContext &llvmModCtx)
std::shared_ptr< IRValueType > normalizeForeignType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type)
void generateTargetObjectCode(LLVMModuleContext &llvmModCtx, const yoi::wstr &pathToOutput)
llvm::DIType * getDIType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type)
void handleIntrinsicCall(LLVMModuleContext &llvmModCtx, const IR &instr)
void generateStructGCFunctionDeclarations(LLVMModuleContext &llvmModCtx)
llvm::Value * unboxValue(LLVMModuleContext &llvmModCtx, llvm::Value *objectPtr, const std::shared_ptr< IRValueType > &yoiType)
void generateImportFunctionImplementations(LLVMModuleContext &llvmModCtx)
std::shared_ptr< compilerContext > compilerCtx
LLVMModuleContext & getLLVMModuleContext(const yoi::wstr &absolutePath)
std::shared_ptr< IRModule > yoiModule
CodegenObjectCache codegenObjectCache
void generateRTTIDeclaration(LLVMModuleContext &llvmModCtx)
llvm::Function * getLLVMCoroIntrinsic(LLVMModuleContext &llvmModCtx, llvm::Intrinsic::ID Id, llvm::ArrayRef< llvm::Type * > Types={})
llvm::FunctionType * getFunctionType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRFunctionDefinition > &funcDef)
llvm::Type * getDynamicArrayLLVMType(LLVMModuleContext &llvmModCtx, const std::shared_ptr< IRValueType > &type, bool enforceForeignType=false)
void generateGlobalInitializers(LLVMModuleContext &llvmModCtx)
void generateFunction(LLVMModuleContext &llvmModCtx, IRFunctionDefinition &funcDef)
void generateStructShallowDeclarations(LLVMModuleContext &llvmModCtx)
std::map< yoi::indexT, std::vector< indexT > > reverseG
std::map< yoi::indexT, std::vector< indexT > > G
Stack Value struct exposed to original code base for compatibility.
std::shared_ptr< IRValueType > yoiType
StackValue & operator[](yoi::indexT index)
std::map< yoi::indexT, yoi::vec< StackValue > > valueStackStateIn
const ControlFlowAnalysis & cfa
std::map< yoi::indexT, yoi::vec< StackValue > > valueStackStateOut
enum yoi::LLVMCodegen::ValueStackWithPhi::StackState stackState
void push_back(const StackValue &value)
llvm::IRBuilder * builder
void enterNode(yoi::indexT currentState, yoi::indexT fromState, llvm::BasicBlock *currentBlock, llvm::BasicBlock *fromBlock)
std::shared_ptr< IRModule > yoiModule
std::map< yoi::indexT, yoi::vec< llvm::PHINode * > > phiNodes