From b5f64317a76ba72601500eeb516dff36ff3e95bf Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Fri, 4 Oct 2024 12:24:33 +0200 Subject: [PATCH 1/2] fix benchmark --- .../nautilus/compiler/ir/IRDumpHandler.cpp | 19 +- .../nautilus/compiler/ir/IRDumpHandler.hpp | 6 +- .../compiler/ir/blocks/BasicBlock.cpp | 33 +- .../compiler/ir/blocks/BasicBlock.hpp | 32 +- .../phases/TraceToIRConversionPhase.cpp | 335 ++++++------------ .../phases/TraceToIRConversionPhase.hpp | 58 ++- 6 files changed, 137 insertions(+), 346 deletions(-) diff --git a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp index 8977b775..98ed9ae1 100644 --- a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp +++ b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.cpp @@ -17,28 +17,24 @@ std::shared_ptr NESIRDumpHandler::create(std::ostream& out) { return std::make_shared(out); } -const BasicBlock* NESIRDumpHandler::getNextLowerOrEqualLevelBasicBlock(const BasicBlock* thenBlock, int ifParentBlockLevel) { +const BasicBlock* NESIRDumpHandler::getNextLowerOrEqualLevelBasicBlock(const BasicBlock* thenBlock) { auto& terminatorOp = thenBlock->getOperations().back(); if (terminatorOp->getOperationType() == Operation::OperationType::BranchOp) { auto branchOp = dynamic_cast(terminatorOp.get()); - if (branchOp->getNextBlockInvocation().getBlock()->getScopeLevel() <= (uint32_t) ifParentBlockLevel) { - return branchOp->getNextBlockInvocation().getBlock(); - } else { - return getNextLowerOrEqualLevelBasicBlock(branchOp->getNextBlockInvocation().getBlock(), ifParentBlockLevel); - } + return getNextLowerOrEqualLevelBasicBlock(branchOp->getNextBlockInvocation().getBlock()); } else if (terminatorOp->getOperationType() == Operation::OperationType::IfOp) { auto ifOp = dynamic_cast(terminatorOp.get()); if (ifOp->getFalseBlockInvocation().getBlock() != nullptr) { - return getNextLowerOrEqualLevelBasicBlock(ifOp->getFalseBlockInvocation().getBlock(), ifParentBlockLevel); + return getNextLowerOrEqualLevelBasicBlock(ifOp->getFalseBlockInvocation().getBlock()); } else { - return getNextLowerOrEqualLevelBasicBlock(ifOp->getTrueBlockInvocation().getBlock(), ifParentBlockLevel); + return getNextLowerOrEqualLevelBasicBlock(ifOp->getTrueBlockInvocation().getBlock()); } } else { // ReturnOp todo changed #3234 return nullptr; } } -void NESIRDumpHandler::dumpHelper(Operation* terminatorOp, int32_t) { +void NESIRDumpHandler::dumpHelper(Operation* terminatorOp) { switch (terminatorOp->getOperationType()) { case Operation::OperationType::BranchOp: { auto branchOp = static_cast(terminatorOp); @@ -47,8 +43,7 @@ void NESIRDumpHandler::dumpHelper(Operation* terminatorOp, int32_t) { } case Operation::OperationType::IfOp: { auto ifOp = static_cast(terminatorOp); - auto lastTerminatorOp = getNextLowerOrEqualLevelBasicBlock(ifOp->getTrueBlockInvocation().getBlock(), - ifOp->getTrueBlockInvocation().getBlock()->getScopeLevel() - 1); // todo can lead to error #3234 + auto lastTerminatorOp = getNextLowerOrEqualLevelBasicBlock(ifOp->getTrueBlockInvocation().getBlock()); dumpHelper(ifOp->getTrueBlockInvocation().getBlock()); dumpHelper(ifOp->getFalseBlockInvocation().getBlock()); if (lastTerminatorOp) { @@ -79,7 +74,7 @@ void NESIRDumpHandler::dumpHelper(const BasicBlock* basicBlock) { out << std::string(4, ' ') << operation->toString() << " :" << toString(operation->getStamp()) << std::endl; } auto& terminatorOp = basicBlock->getOperations().back(); - dumpHelper(terminatorOp.get(), basicBlock->getScopeLevel()); + dumpHelper(terminatorOp.get()); } } diff --git a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.hpp b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.hpp index 29c0e58f..1166b2e7 100644 --- a/nautilus/src/nautilus/compiler/ir/IRDumpHandler.hpp +++ b/nautilus/src/nautilus/compiler/ir/IRDumpHandler.hpp @@ -36,10 +36,8 @@ class NESIRDumpHandler { * function. * @param basicBlock: Initially the block that we want to find the next BB for. Replaced while recursively * traversing NESIR. - * @param blockScopeLevel: The scopeLevel of the initial BB that we are searching the next same/higher level BB for. - * @return IR::BasicBlockPtr: SharedPtr to the next block that resides on the same or on a higher level. */ - const BasicBlock* getNextLowerOrEqualLevelBasicBlock(const BasicBlock* basicBlock, int blockScopeLevel); + const BasicBlock* getNextLowerOrEqualLevelBasicBlock(const BasicBlock* basicBlock); /** * @brief Handle dumping terminator operations(LoopOp, BranchOp, IfOp, ReturnOp) to the 'out' stringstream. @@ -47,7 +45,7 @@ class NESIRDumpHandler { * @param terminatorOp: Terminator operation that we append to the 'out' stringstream. * @param scopeLevel: scopeLevel of the BasicBlock that is terminated by the terminator operation. */ - void dumpHelper(Operation* terminatorOp, int32_t scopeLevel); + void dumpHelper(Operation* terminatorOp); /** * @brief Handle dumping BasicBlocks to the 'out' stringstream. Print all operations, then handle the terminatorOp. diff --git a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp index fd79652a..5245a32c 100644 --- a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp +++ b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.cpp @@ -7,8 +7,7 @@ #include namespace nautilus::compiler::ir { -BasicBlock::BasicBlock(const std::string& identifier, int32_t scopeLevel, std::vector>& operations, std::vector>& arguments) - : identifier(identifier), scopeLevel(scopeLevel), numLoopBackEdges(0), operations(std::move(operations)), arguments(std::move(arguments)) { +BasicBlock::BasicBlock(uint16_t identifier, std::vector>& arguments) : identifier(identifier), operations(), arguments(std::move(arguments)) { } void BasicBlock::addNextBlock(BasicBlock* nextBlock, const std::vector& ops) { @@ -27,32 +26,8 @@ void BasicBlock::addNextBlock(BasicBlock* nextBlock, const std::vectoridentifier = identifier; -} - -uint32_t BasicBlock::getScopeLevel() const { - return scopeLevel; -} - -void BasicBlock::setScopeLevel(uint32_t scopeLevel) { - this->scopeLevel = scopeLevel; -} - -uint32_t BasicBlock::getNumLoopBackEdges() { - return numLoopBackEdges; -} - -void BasicBlock::incrementNumLoopBackEdge() { - ++this->numLoopBackEdges; -} - -bool BasicBlock::isLoopHeaderBlock() { - return numLoopBackEdges > 0; +const std::string BasicBlock::getIdentifier() const { + return std::to_string(identifier); } const std::vector>& BasicBlock::getOperations() const { @@ -82,7 +57,7 @@ uint64_t BasicBlock::getIndexOfArgument(Operation* arg) { void BasicBlock::replaceTerminatorOperation(Operation* loopOperation) { operations.pop_back(); - operations.emplace_back(std::move(loopOperation)); + operations.emplace_back(loopOperation); } BasicBlock* BasicBlock::addOperation(std::unique_ptr operation) { diff --git a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.hpp b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.hpp index de77f6d9..44b0afb2 100644 --- a/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.hpp +++ b/nautilus/src/nautilus/compiler/ir/blocks/BasicBlock.hpp @@ -15,34 +15,11 @@ class BasicBlock { * @param Operations: A list of Operations that are executed in the BasicBlock. * @param nextBlocks : The BasicBlock that is next in the control flow of the execution. */ - explicit BasicBlock(const std::string& identifier, int32_t scopeLevel, - std::vector>& operations, - std::vector>& arguments); + explicit BasicBlock(uint16_t identifier, std::vector>& arguments); virtual ~BasicBlock(); - [[nodiscard]] const std::string& getIdentifier() const; - - void setIdentifier(const std::string& identifier); - - [[nodiscard]] uint32_t getScopeLevel() const; - - void setScopeLevel(uint32_t scopeLevel); - - /** - * @brief Get the number of edges that lead back from the loop body to the loop header. - */ - [[nodiscard]] uint32_t getNumLoopBackEdges(); - - /** - * @brief Increment counter for edges that lead back from the loop body to the loop header. - */ - void incrementNumLoopBackEdge(); - - /** - * @brief Check if the counter for edges that lead back from the loop body to the loop header is > 0. - */ - [[nodiscard]] bool isLoopHeaderBlock(); + [[nodiscard]] const std::string getIdentifier() const; [[nodiscard]] const std::vector>& getOperations() const; @@ -83,15 +60,12 @@ class BasicBlock { uint64_t getIndexOfArgument(Operation* arg); - // void popOperation(); void replaceTerminatorOperation(Operation* newTerminatorOperation); [[nodiscard]] std::pair getNextBlocks(); private: - std::string identifier; - uint32_t scopeLevel; - uint32_t numLoopBackEdges; + uint16_t identifier; std::vector> operations; std::vector> arguments; std::vector predecessors; diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp index 6e1f0610..5e56c7ea 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp @@ -23,124 +23,127 @@ namespace nautilus::tracing { using namespace compiler::ir; +OperationIdentifier createValueIdentifier(value_ref& val) { + return {val.ref}; +} + +OperationIdentifier createValueIdentifier(InputVariant& val) { + if (auto* valRef = std::get_if(&val)) { + return {valRef->ref}; + } + throw NotImplementedException("wrong input variant"); +} + std::shared_ptr TraceToIRConversionPhase::apply(std::shared_ptr trace, const compiler::CompilationUnitID& id) { auto phaseContext = IRConversionContext(std::move(trace), id); return phaseContext.process(); } std::shared_ptr TraceToIRConversionPhase::IRConversionContext::process() { - auto& rootBlock = trace->getBlocks().front(); - processBlock(0, rootBlock); + processBlock(trace->getBlocks().front()); - // trace->getBlock(trace->getReturn().front().blockIndex).operations.back(); auto returnStamp = returnType; - auto functionOperation = std::make_unique("execute", currentBasicBlocks, - /*argumentTypes*/ std::vector {}, - /*arguments*/ std::vector {}, returnStamp); + auto functionOperation = std::make_unique("execute", currentBasicBlocks, std::vector {}, std::vector {}, returnStamp); ir->addRootOperation(std::move(functionOperation)); return ir; } -BasicBlock* TraceToIRConversionPhase::IRConversionContext::processBlock(int32_t scope, Block& block) { +BasicBlock* TraceToIRConversionPhase::IRConversionContext::processBlock(Block& block) { // create new frame and block ValueFrame blockFrame; std::vector> blockArguments; for (auto& arg : block.arguments) { auto argumentIdentifier = createValueIdentifier(arg); - // TODO fix arg type auto blockArgument = std::make_unique(argumentIdentifier, arg.type); blockFrame.setValue(argumentIdentifier, blockArgument.get()); blockArguments.emplace_back(std::move(blockArgument)); } - - auto operations = std::vector> {}; - auto id = std::to_string(block.blockId); - auto& irBasicBlock = currentBasicBlocks.emplace_back(std::make_unique(id, scope, - /*operations*/ operations, - /*arguments*/ blockArguments)); + auto& irBasicBlock = currentBasicBlocks.emplace_back(std::make_unique(block.blockId, blockArguments)); auto irBasicBlockPtr = irBasicBlock.get(); blockMap[block.blockId] = irBasicBlockPtr; for (auto& operation : block.operations) { - processOperation(scope, blockFrame, block, irBasicBlockPtr, operation); + processOperation(blockFrame, block, irBasicBlockPtr, operation); } return irBasicBlockPtr; } -void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t scope, ValueFrame& frame, Block& currentBlock, BasicBlock*& currentIrBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processOperation(ValueFrame& frame, Block& currentBlock, BasicBlock*& currentIrBlock, TraceOperation& operation) { switch (operation.op) { case Op::ADD: { - processAdd(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::SUB: { - processSub(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::DIV: { - processDiv(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::MUL: { - processMul(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } + case Op::MOD: { + processBinaryOperator(frame, currentIrBlock, operation); + return; + } case Op::EQ: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::EQ); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::EQ); return; - }; + } case Op::LT: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::LT); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::LT); return; - }; + } case Op::GT: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::GT); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::GT); return; - }; + } case Op::NEQ: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::NE); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::NE); return; - }; + } case Op::LTE: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::LE); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::LE); return; - }; + } case Op::GTE: { - processEquals(scope, frame, currentIrBlock, operation, CompareOperation::Comparator::GE); + processLogicalComperator(frame, currentIrBlock, operation, CompareOperation::Comparator::GE); return; - }; + } case Op::NEGATE: { - processNegate(scope, frame, currentIrBlock, operation); + processUnaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::NOT: { - processNot(scope, frame, currentIrBlock, operation); + processUnaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::AND: { - processAnd(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::OR: { - processOr(scope, frame, currentIrBlock, operation); + processBinaryOperator(frame, currentIrBlock, operation); return; - }; + } case Op::CMP: { - processCMP(scope, frame, currentBlock, currentIrBlock, operation); + processCMP(frame, currentBlock, currentIrBlock, operation); return; - }; + } case Op::JMP: { - processJMP(scope, frame, currentIrBlock, operation); + processJMP(frame, currentIrBlock, operation); return; - }; + } case Op::CONST: { - processConst(scope, frame, currentIrBlock, operation); + processConst(frame, currentIrBlock, operation); return; - }; - case Op::ASSIGN: - break; + } case Op::RETURN: { returnType = operation.resultType; if (returnType == Type::v) { @@ -149,51 +152,62 @@ void TraceToIRConversionPhase::IRConversionContext::processOperation(int32_t sco auto returnValue = frame.getValue(createValueIdentifier(operation.resultRef)); currentIrBlock->addOperation(returnValue); } - return; - }; + } case Op::LOAD: { - processLoad(scope, frame, currentIrBlock, operation); + processLoad(frame, currentIrBlock, operation); return; }; case Op::STORE: { - processStore(scope, frame, currentIrBlock, operation); + processStore(frame, currentIrBlock, operation); return; }; case Op::CAST: { - processCast(scope, frame, currentIrBlock, operation); + processCast(frame, currentIrBlock, operation); return; }; case Op::CALL: - processCall(scope, frame, currentIrBlock, operation); - return; - case FREE: - break; - case MOD: - processMod(scope, frame, currentIrBlock, operation); + processCall(frame, currentIrBlock, operation); return; case LSH: - processShift(scope, frame, currentIrBlock, operation, compiler::ir::ShiftOperation::LS); + processShift(frame, currentIrBlock, operation, compiler::ir::ShiftOperation::LS); return; case RSH: - processShift(scope, frame, currentIrBlock, operation, compiler::ir::ShiftOperation::RS); + processShift(frame, currentIrBlock, operation, compiler::ir::ShiftOperation::RS); return; case BOR: - processBinaryComp(scope, frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::Type::BOR); + processBinaryComp(frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::Type::BOR); return; case BAND: - processBinaryComp(scope, frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::BAND); + processBinaryComp(frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::BAND); return; case BXOR: - processBinaryComp(scope, frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::XOR); + processBinaryComp(frame, currentIrBlock, operation, compiler::ir::BinaryCompOperation::XOR); return; + default: { + throw NotImplementedException("Operation type is not implemented."); } + } +} - throw NotImplementedException("Type is not implemented."); +template +void TraceToIRConversionPhase::IRConversionContext::processBinaryOperator(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& op) { + auto leftInput = frame.getValue(createValueIdentifier(op.input[0])); + auto rightInput = frame.getValue(createValueIdentifier(op.input[1])); + auto resultIdentifier = createValueIdentifier(op.resultRef); + auto operation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); + frame.setValue(resultIdentifier, operation); } -void TraceToIRConversionPhase::IRConversionContext::processJMP(int32_t scope, ValueFrame& frame, BasicBlock* block, TraceOperation& operation) { - // NES_DEBUG("current block " << block->getIdentifier() << " " << operation); +template +void TraceToIRConversionPhase::IRConversionContext::processUnaryOperator(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& op) { + auto input = frame.getValue(createValueIdentifier(op.input[0])); + auto resultIdentifier = createValueIdentifier(op.resultRef); + auto operation = currentBlock->addOperation(resultIdentifier, input); + frame.setValue(resultIdentifier, operation); +} + +void TraceToIRConversionPhase::IRConversionContext::processJMP(ValueFrame& frame, BasicBlock* block, TraceOperation& operation) { auto blockRef = get(operation.input[0]); BasicBlockInvocation blockInvocation; createBlockArguments(frame, blockInvocation, blockRef); @@ -204,44 +218,29 @@ void TraceToIRConversionPhase::IRConversionContext::processJMP(int32_t scope, Va return; } auto targetBlock = trace->getBlock(blockRef.block); - auto resultTargetBlock = processBlock(scope - 1, trace->getBlock(blockRef.block)); + auto resultTargetBlock = processBlock(trace->getBlock(blockRef.block)); blockMap[blockRef.block] = resultTargetBlock; block->addNextBlock(resultTargetBlock, blockInvocation.getArguments()); } -void TraceToIRConversionPhase::IRConversionContext::processCMP(int32_t scope, ValueFrame& frame, Block&, BasicBlock* currentIrBlock, TraceOperation& operation) { - +void TraceToIRConversionPhase::IRConversionContext::processCMP(ValueFrame& frame, Block&, BasicBlock* currentIrBlock, TraceOperation& operation) { auto valueRef = get(operation.input[0]); auto trueCaseBlockRef = get(operation.input[1]); auto falseCaseBlockRef = get(operation.input[2]); - // if (isBlockInLoop(scope, currentBlock.blockId, trueCaseBlockRef.block)) { - // NES_DEBUG("1. found loop"); - //} else if (isBlockInLoop(scope, currentBlock.blockId, - // falseCaseBlockRef.block)) { - // NES_DEBUG("2. found loop"); - //} else { auto booleanValue = frame.getValue(createValueIdentifier(valueRef)); auto ifOperation = std::make_unique(booleanValue); - auto trueCaseBlock = processBlock(scope + 1, trace->getBlock(trueCaseBlockRef.block)); + auto trueCaseBlock = processBlock(trace->getBlock(trueCaseBlockRef.block)); ifOperation->getTrueBlockInvocation().setBlock(trueCaseBlock); createBlockArguments(frame, ifOperation->getTrueBlockInvocation(), trueCaseBlockRef); - auto falseCaseBlock = processBlock(scope + 1, trace->getBlock(falseCaseBlockRef.block)); + auto falseCaseBlock = processBlock(trace->getBlock(falseCaseBlockRef.block)); ifOperation->getFalseBlockInvocation().setBlock(falseCaseBlock); createBlockArguments(frame, ifOperation->getFalseBlockInvocation(), falseCaseBlockRef); currentIrBlock->addOperation(std::move(ifOperation)); } -std::vector TraceToIRConversionPhase::IRConversionContext::createBlockArguments(BlockRef val) { - std::vector blockArgumentIdentifiers; - for (auto& arg : val.arguments) { - blockArgumentIdentifiers.emplace_back(createValueIdentifier(arg)); - } - return blockArgumentIdentifiers; -} - void TraceToIRConversionPhase::IRConversionContext::createBlockArguments(ValueFrame& frame, BasicBlockInvocation& blockInvocation, BlockRef val) { for (auto& arg : val.arguments) { auto valueIdentifier = createValueIdentifier(arg); @@ -249,57 +248,7 @@ void TraceToIRConversionPhase::IRConversionContext::createBlockArguments(ValueFr } } -OperationIdentifier TraceToIRConversionPhase::IRConversionContext::createValueIdentifier(InputVariant val) { - if (holds_alternative(val)) { - auto valueRef = std::get(val); - return OperationIdentifier(valueRef.ref); - } else - return OperationIdentifier(0); -} - -void TraceToIRConversionPhase::IRConversionContext::processAdd(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto addOperation = std::make_unique(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, addOperation.get()); - currentBlock->addOperation(std::move(addOperation)); -} - -void TraceToIRConversionPhase::IRConversionContext::processSub(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto subOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, subOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processMul(int32_t, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto mulOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, mulOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processDiv(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto divOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, divOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processMod(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto divOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, divOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processBinaryComp(int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, - compiler::ir::BinaryCompOperation::Type type) { +void TraceToIRConversionPhase::IRConversionContext::processBinaryComp(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, compiler::ir::BinaryCompOperation::Type type) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -307,8 +256,7 @@ void TraceToIRConversionPhase::IRConversionContext::processBinaryComp(int32_t, n frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processShift(int32_t, nautilus::tracing::TraceToIRConversionPhase::ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, - compiler::ir::ShiftOperation::ShiftType type) { +void TraceToIRConversionPhase::IRConversionContext::processShift(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, nautilus::tracing::TraceOperation& operation, compiler::ir::ShiftOperation::ShiftType type) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -316,38 +264,7 @@ void TraceToIRConversionPhase::IRConversionContext::processShift(int32_t, nautil frame.setValue(resultIdentifier, divOperation); } -void TraceToIRConversionPhase::IRConversionContext::processNegate(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto input = frame.getValue(createValueIdentifier(operation.input[0])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto negateOperation = currentBlock->addOperation(resultIdentifier, input); - frame.setValue(resultIdentifier, negateOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processNot(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto input = frame.getValue(createValueIdentifier(operation.input[0])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto notOperation = currentBlock->addOperation(resultIdentifier, input); - frame.setValue(resultIdentifier, notOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processLessThan(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, CompareOperation::Comparator::LT); - frame.setValue(resultIdentifier, compareOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processGreaterThan(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto compareOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput, CompareOperation::Comparator::GT); - frame.setValue(resultIdentifier, compareOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processEquals(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation, CompareOperation::Comparator comp) { +void TraceToIRConversionPhase::IRConversionContext::processLogicalComperator(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation, CompareOperation::Comparator comp) { auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); auto resultIdentifier = createValueIdentifier(operation.resultRef); @@ -355,29 +272,7 @@ void TraceToIRConversionPhase::IRConversionContext::processEquals(int32_t, Value frame.setValue(resultIdentifier, compareOperation); } -void TraceToIRConversionPhase::IRConversionContext::processAnd(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto andOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, andOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processOr(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - auto leftInput = frame.getValue(createValueIdentifier(operation.input[0])); - auto rightInput = frame.getValue(createValueIdentifier(operation.input[1])); - auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto orOperation = currentBlock->addOperation(resultIdentifier, leftInput, rightInput); - frame.setValue(resultIdentifier, orOperation); -} - -void TraceToIRConversionPhase::IRConversionContext::processLoad(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - // TODO add load data type - // auto constOperation = - // std::make_shared(createValueIdentifier(operation.result), - // createValueIdentifier(operation.input[0]), - // Operation::BasicType::VOID); - // currentBlock->addOperation(constOperation); +void TraceToIRConversionPhase::IRConversionContext::processLoad(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto address = frame.getValue(createValueIdentifier(operation.input[0])); auto resultIdentifier = createValueIdentifier(operation.resultRef); auto resultType = operation.resultType; @@ -386,19 +281,17 @@ void TraceToIRConversionPhase::IRConversionContext::processLoad(int32_t, ValueFr currentBlock->addOperation(std::move(loadOperation)); } -void TraceToIRConversionPhase::IRConversionContext::processStore(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processStore(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto address = frame.getValue(createValueIdentifier(operation.resultRef)); auto value = frame.getValue(createValueIdentifier(operation.input[0])); currentBlock->addOperation(value, address); } -void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - - auto inputArguments = std::vector {}; +void TraceToIRConversionPhase::IRConversionContext::processCall(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto functionCallTarget = std::get(operation.input[0]); - - for (uint32_t i = 0; i < functionCallTarget.arguments.size(); i++) { - auto input = frame.getValue(createValueIdentifier(functionCallTarget.arguments[i])); + auto inputArguments = std::vector {}; + for (auto& argument : functionCallTarget.arguments) { + auto input = frame.getValue(createValueIdentifier(argument)); inputArguments.emplace_back(input); } @@ -410,36 +303,11 @@ void TraceToIRConversionPhase::IRConversionContext::processCall(int32_t, ValueFr } } -bool TraceToIRConversionPhase::IRConversionContext::isBlockInLoop(uint32_t parentBlockId, uint32_t currentBlockId) { - if (currentBlockId == parentBlockId) { - return true; - } - if (parentBlockId == 8) - return false; - if (currentBlockId == UINT32_MAX) { - currentBlockId = parentBlockId; - } - auto currentBlock = trace->getBlock(currentBlockId); - auto& terminationOp = currentBlock.operations.back(); - if (terminationOp.op == Op::CMP) { - auto trueCaseBlockRef = get(terminationOp.input[0]); - auto falseCaseBlockRef = get(terminationOp.input[1]); - return currentBlock.type == Block::Type::ControlFlowMerge; - // isBlockInLoop(parentBlockId, trueCaseBlockRef.block) || - // isBlockInLoop(parentBlockId, falseCaseBlockRef.block); - } else if (terminationOp.op == Op::JMP) { - auto target = get(terminationOp.input[0]); - return isBlockInLoop(parentBlockId, target.block); - } - return false; -} - -void TraceToIRConversionPhase::IRConversionContext::processConst(int32_t, TraceToIRConversionPhase::ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { +void TraceToIRConversionPhase::IRConversionContext::processConst(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto constant = std::get(operation.input[0]); auto resultIdentifier = createValueIdentifier(operation.resultRef); - auto resultType = (operation.resultType); + auto resultType = operation.resultType; Operation* constOperation; - std::visit( [&](auto&& value) { using T = std::decay_t; @@ -460,8 +328,7 @@ void TraceToIRConversionPhase::IRConversionContext::processConst(int32_t, TraceT frame.setValue(resultIdentifier, constOperation); } -void TraceToIRConversionPhase::IRConversionContext::processCast(int32_t, TraceToIRConversionPhase::ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { - +void TraceToIRConversionPhase::IRConversionContext::processCast(ValueFrame& frame, BasicBlock* currentBlock, TraceOperation& operation) { auto resultIdentifier = createValueIdentifier(operation.resultRef); auto input = frame.getValue(createValueIdentifier(operation.input[0])); auto castOperation = currentBlock->addOperation(resultIdentifier, input, operation.resultType); diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp index f36f7fdb..62b0bc98 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.hpp @@ -45,63 +45,45 @@ class TraceToIRConversionPhase { */ class IRConversionContext { public: - IRConversionContext(std::shared_ptr trace, const compiler::CompilationUnitID& id) : trace(trace), ir(std::make_shared(id)) {} + IRConversionContext(std::shared_ptr trace, const compiler::CompilationUnitID& id) : trace(trace), ir(std::make_shared(id)) { + } std::shared_ptr process(); private: - compiler::ir::BasicBlock* processBlock(int32_t scope, Block& block); + compiler::ir::BasicBlock* processBlock(Block& block); - void processOperation(int32_t scope, ValueFrame& frame, Block& currentBlock, compiler::ir::BasicBlock*& currentIRBlock, TraceOperation& operation); + void processOperation(ValueFrame& frame, Block& currentBlock, compiler::ir::BasicBlock*& currentIRBlock, TraceOperation& operation); - void processJMP(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* block, TraceOperation& operation); + void processJMP(ValueFrame& frame, compiler::ir::BasicBlock* block, TraceOperation& operation); - void processCMP(int32_t scope, ValueFrame& frame, Block& currentBlock, compiler::ir::BasicBlock* currentIRBlock, TraceOperation& operation); + void processCMP(ValueFrame& frame, Block& currentBlock, compiler::ir::BasicBlock* currentIRBlock, TraceOperation& operation); - void processAdd(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processLogicalComperator(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::CompareOperation::Comparator comp); - void processSub(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processNegate(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processNot(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processMul(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processShift(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::ShiftOperation::ShiftType type); - void processDiv(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processBinaryComp(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::BinaryCompOperation::Type type); - void processMod(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processLoad(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processEquals(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::CompareOperation::Comparator comp); + void processStore(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processLessThan(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processCall(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processGreaterThan(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + void processConst(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processNegate(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - void processNot(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processAnd(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processShift(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::ShiftOperation::ShiftType type); - - void processBinaryComp(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation, compiler::ir::BinaryCompOperation::Type type); - - void processOr(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processLoad(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processStore(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processCall(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processConst(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - void processCast(int32_t scope, ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); - - bool isBlockInLoop(uint32_t parentBlock, uint32_t currentBlock); - - std::vector createBlockArguments(BlockRef val); + void processCast(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); void createBlockArguments(ValueFrame& frame, compiler::ir::BasicBlockInvocation& blockInvocation, BlockRef val); - compiler::ir::OperationIdentifier createValueIdentifier(InputVariant val); + template + void processBinaryOperator(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); + template + void processUnaryOperator(ValueFrame& frame, compiler::ir::BasicBlock* currentBlock, TraceOperation& operation); private: std::shared_ptr trace; From f5ca7d1a8a022b9283c8b35c2dd190262f435189 Mon Sep 17 00:00:00 2001 From: Philipp Grulich Date: Fri, 4 Oct 2024 12:29:32 +0200 Subject: [PATCH 2/2] refactor TraceToIRConversionPhase --- .../nautilus/tracing/phases/TraceToIRConversionPhase.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp index 5e56c7ea..bb1ef2c3 100644 --- a/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp +++ b/nautilus/src/nautilus/tracing/phases/TraceToIRConversionPhase.cpp @@ -10,14 +10,11 @@ #include "nautilus/compiler/ir/operations/ConstPtrOperation.hpp" #include "nautilus/compiler/ir/operations/LoadOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/AndOperation.hpp" -#include "nautilus/compiler/ir/operations/LogicalOperations/CompareOperation.hpp" #include "nautilus/compiler/ir/operations/LogicalOperations/OrOperation.hpp" -#include "nautilus/compiler/ir/operations/Operation.hpp" #include "nautilus/compiler/ir/operations/ProxyCallOperation.hpp" #include "nautilus/compiler/ir/operations/StoreOperation.hpp" #include "nautilus/exceptions/NotImplementedException.hpp" #include "nautilus/tracing/TracingUtil.hpp" -#include #include namespace nautilus::tracing { @@ -41,10 +38,7 @@ std::shared_ptr TraceToIRConversionPhase::apply(std::shared_ptr TraceToIRConversionPhase::IRConversionContext::process() { processBlock(trace->getBlocks().front()); - - auto returnStamp = returnType; - auto functionOperation = std::make_unique("execute", currentBasicBlocks, std::vector {}, std::vector {}, returnStamp); - + auto functionOperation = std::make_unique("execute", currentBasicBlocks, std::vector {}, std::vector {}, returnType); ir->addRootOperation(std::move(functionOperation)); return ir; }