-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Started parallelizing the generation (#62 from wesuRage/main)
Started parallelizing the generation
- Loading branch information
Showing
16 changed files
with
207 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,11 @@ | ||
def main( ) -> int: | ||
int num := 3; | ||
int quatro := num + 1; | ||
return quatro; | ||
end; | ||
def tigres_de_bengala( int numero) -> int: | ||
int num := numero; | ||
int quatro := num + 1; | ||
return numero ; | ||
end; | ||
|
||
def main( ) -> int: | ||
int num := 3; | ||
int quatro := num + 1; | ||
return tigres_de_bengala( quatro) ; ; | ||
end; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef QUEUE_H | ||
#define QUEUE_H | ||
|
||
extern "C" { | ||
#include "frontend/ast/definitions.h" | ||
} | ||
|
||
#include <future> | ||
#include <mutex> | ||
#include <queue> | ||
#include <condition_variable> | ||
|
||
struct PendingIdentifier { | ||
IdentifierNode *node; | ||
std::promise<llvm::Value*> promise; | ||
}; | ||
|
||
// Tabela de símbolos e fila de pendências | ||
extern std::mutex symbolTableMutex; | ||
extern std::queue<PendingIdentifier> pendingQueue; | ||
extern std::condition_variable pendingCondition; | ||
|
||
llvm::Value* find_or_wait_for_identifier(IdentifierNode *node); | ||
|
||
void process_pending_identifiers_async(); | ||
void process_pending_identifiers_periodically(); | ||
|
||
#endif // QUEUE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
#include "backend/generator/expressions/generate_identifier.hpp" | ||
#include "backend/generator/symbols/identifier_symbol_table.hpp" | ||
#include "backend/generator/parallel/queue.hpp" | ||
|
||
llvm::Value *generate_identifier(IdentifierNode *node) { | ||
const SymbolInfo *id = find_identifier(node->symbol); | ||
|
||
if (!id) { | ||
try { | ||
return find_or_wait_for_identifier(node); | ||
} catch (...) { | ||
throw std::runtime_error("Error: identifier not found!"); | ||
} | ||
|
||
return id->value; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,70 @@ | ||
#include <vector> | ||
#include "backend/generator/generate_ir.hpp" | ||
#include "backend/generator/statements/generate_stmt.hpp" | ||
#include <future> | ||
#include <mutex> | ||
|
||
std::vector<llvm::Value*> generate_ir(AstNode *node, llvm::LLVMContext &Context, llvm::Module &Module, llvm::IRBuilder<> &Builder) { | ||
// Cast the AstNode to ProgramNode as the data in AstNode is assumed to be a ProgramNode | ||
ProgramNode *program = (ProgramNode *)node->data; | ||
// Estrutura intermediária personalizada para armazenar informações de IR | ||
struct IntermediateIR { | ||
std::string blockName; | ||
std::vector<llvm::Instruction*> instructions; | ||
}; | ||
|
||
// Vector to hold the generated LLVM IR values | ||
std::vector<llvm::Value*> IRs; | ||
// Função principal de geração | ||
std::vector<llvm::Value*> generate_ir(AstNode *node, llvm::LLVMContext &mainContext, llvm::Module &mainModule, llvm::IRBuilder<> &mainBuilder) { | ||
ProgramNode *program = static_cast<ProgramNode *>(node->data); | ||
std::vector<std::future<IntermediateIR>> futures; | ||
std::vector<IntermediateIR> intermediateIRs; | ||
|
||
// Iterate over all statements in the program and generate their corresponding IR | ||
// Geração paralela de IR | ||
for (size_t i = 0; i < program->statement_count; ++i) { | ||
// Generate LLVM IR for each statement | ||
llvm::Value *IR = generate_stmt(program->statements[i], Context, Module, Builder); | ||
|
||
// If the generated IR is not null, add it to the result vector | ||
if (IR) { | ||
IRs.push_back(IR); | ||
AstNode *statement = program->statements[i]; | ||
|
||
futures.push_back(std::async(std::launch::async, [statement]() -> IntermediateIR { | ||
// Criar estrutura intermediária para esta thread | ||
IntermediateIR ir; | ||
ir.blockName = "Block_" + std::to_string(std::hash<std::thread::id>{}(std::this_thread::get_id())); | ||
|
||
// Criar contexto, módulo e IRBuilder para esta thread | ||
llvm::LLVMContext threadContext; | ||
llvm::Module threadModule("ThreadModule", threadContext); | ||
llvm::IRBuilder<> threadBuilder(threadContext); | ||
|
||
llvm::Value* result = generate_stmt(statement, threadContext, threadModule, threadBuilder); | ||
if (auto *inst = llvm::dyn_cast<llvm::Instruction>(result)) { | ||
ir.instructions.push_back(inst); // Adicionar instrução gerada | ||
} | ||
|
||
return ir; | ||
})); | ||
} | ||
|
||
// Coletar resultados das threads | ||
for (auto &future : futures) { | ||
try { | ||
intermediateIRs.push_back(future.get()); | ||
} catch (const std::exception &e) { | ||
llvm::errs() << "Exception during future.get(): " << e.what() << "\n"; | ||
} catch (...) { | ||
llvm::errs() << "Unknown exception during future.get()\n"; | ||
} | ||
} | ||
|
||
// Concatenar IRs intermediários no contexto principal | ||
for (const auto &ir : intermediateIRs) { | ||
// Criar um novo bloco no contexto principal | ||
|
||
/* | ||
* O segfault ocorre no getParent | ||
*/ | ||
|
||
llvm::BasicBlock *block = llvm::BasicBlock::Create(mainContext, ir.blockName, mainBuilder.GetInsertBlock()->getParent()); | ||
mainBuilder.SetInsertPoint(block); // Estabelecer ponto de inserção no novo bloco | ||
|
||
// Inserir as instruções no bloco | ||
for (auto *inst : ir.instructions) { | ||
mainBuilder.Insert(inst); // Adicionar instrução ao bloco principal | ||
} | ||
} | ||
|
||
// Return the vector containing the generated IR for the statements | ||
return IRs; | ||
return {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include "backend/generator/expressions/generate_identifier.hpp" | ||
#include "backend/generator/symbols/identifier_symbol_table.hpp" | ||
#include "backend/generator/parallel/queue.hpp" | ||
|
||
std::mutex symbolTableMutex; | ||
std::queue<PendingIdentifier> pendingQueue; | ||
std::condition_variable pendingCondition; | ||
|
||
// Função para encontrar um identificador ou adicionar à fila de pendências | ||
llvm::Value* find_or_wait_for_identifier(IdentifierNode* node) { | ||
std::unique_lock<std::mutex> lock(symbolTableMutex); | ||
|
||
// Tentar encontrar o identificador na tabela de símbolos | ||
const SymbolInfo* id = find_identifier(node->symbol); | ||
if (id) { | ||
return id->value; | ||
} | ||
|
||
// Se não encontrar, criar uma pendência | ||
PendingIdentifier pending{node}; | ||
std::promise<llvm::Value*> promise; | ||
pending.promise = std::move(promise); | ||
auto future = pending.promise.get_future(); | ||
|
||
// Adicionar à fila de pendências | ||
pendingQueue.push(std::move(pending)); | ||
pendingCondition.notify_all(); | ||
|
||
lock.unlock(); // Desbloquear a tabela de símbolos para permitir outros acessos | ||
|
||
// Esperar pela resolução do identificador | ||
return future.get(); | ||
} | ||
|
||
// Processar as pendências de identificadores de forma assíncrona | ||
void process_pending_identifiers_async() { | ||
std::unique_lock<std::mutex> lock(symbolTableMutex); | ||
|
||
// Processar a fila de pendências enquanto houver identificadores pendentes | ||
while (!pendingQueue.empty()) { | ||
PendingIdentifier pending = std::move(pendingQueue.front()); | ||
pendingQueue.pop(); | ||
|
||
// Verificar novamente a tabela de símbolos | ||
const SymbolInfo* id = find_identifier(pending.node->symbol); | ||
if (id) { | ||
// Resolver a pendência, setando o valor | ||
pending.promise.set_value(id->value); | ||
} else { | ||
// Se não encontrar, re-adiciona à fila | ||
pendingQueue.push(std::move(pending)); | ||
} | ||
} | ||
} | ||
|
||
// Função para ser chamada em outro thread que processa as pendências | ||
void process_pending_identifiers_periodically() { | ||
while (true) { | ||
process_pending_identifiers_async(); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include <iostream> | ||
|
||
extern "C" { | ||
#include "frontend/checker/core.h" | ||
#include "frontend/checker/common_types.h" | ||
#include "utils.h" | ||
} | ||
|
||
Checker* init(AstNode* ast) { | ||
|
||
} |