\return The output connections that need codegen and the output blocks
| 47 | |
| 48 | /// \return The output connections that need codegen and the output blocks |
| 49 | std::pair<boost::dynamic_bitset<>, std::vector<llvm::BasicBlock*>> codegenNode( |
| 50 | NodeInstance* node, llvm::BasicBlock* pureTerminator, NodeInstance* lastImpure, |
| 51 | unsigned execInputID, llvm::BasicBlock* block, codegenMetadata& data, Result& res) { |
| 52 | llvm::IRBuilder<> pureBuilder(block); |
| 53 | auto f = data.allocBlock->getParent(); |
| 54 | auto mod = data.allocBlock |
| 55 | -> |
| 56 | #if LLVM_VERSION_LESS_EQUAL(3, 6) |
| 57 | getParent() |
| 58 | ->getParent() |
| 59 | #else |
| 60 | getModule() |
| 61 | #endif |
| 62 | ; |
| 63 | |
| 64 | auto codeBlock = llvm::BasicBlock::Create(node->context().llvmContext(), |
| 65 | boost::uuids::to_string(node->id()) + "_code", f); |
| 66 | llvm::IRBuilder<> builder(codeBlock); |
| 67 | |
| 68 | // get inputs and outputs |
| 69 | std::vector<llvm::Value*> io; |
| 70 | |
| 71 | // add inputs |
| 72 | { |
| 73 | // process pures -- call them again if they're out of date |
| 74 | { |
| 75 | std::vector<NodeInstance*> pureDependencies; |
| 76 | std::vector<llvm::BasicBlock*> pureBBs; |
| 77 | for (const auto& param : node->inputDataConnections) { |
| 78 | if (param.first->type().pure()) { |
| 79 | auto impure = node->type().pure() ? lastImpure : node; |
| 80 | const auto& cache = data.nodeCache[param.first]; |
| 81 | if (cache.lastNodeCodegenned != impure) { |
| 82 | pureDependencies.push_back(param.first); |
| 83 | pureBBs.push_back(llvm::BasicBlock::Create( |
| 84 | node->context().llvmContext(), |
| 85 | boost::uuids::to_string(param.first->id()) + "____" + |
| 86 | boost::uuids::to_string(impure->id()), |
| 87 | f)); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | pureBBs.push_back(codeBlock); |
| 92 | |
| 93 | for (auto idx = 0ull; idx < pureDependencies.size(); ++idx) { |
| 94 | auto pureNode = pureDependencies[idx]; |
| 95 | auto pureCodegenInto = pureBBs[idx]; |
| 96 | auto pureTerminatorBlock = pureBBs[idx + 1]; |
| 97 | |
| 98 | auto impure = node->type().pure() ? lastImpure : node; |
| 99 | codegenNode(pureNode, pureTerminatorBlock, impure, execInputID, pureCodegenInto, |
| 100 | data, res); |
| 101 | } |
| 102 | if (pureDependencies.empty()) { |
| 103 | pureBuilder.CreateBr(codeBlock); |
| 104 | } else { |
| 105 | pureBuilder.CreateBr(pureBBs[0]); |
| 106 | } |
no test coverage detected