kythe.io@v0.0.68-0.20240422202219-7225dbc01741/third_party/souffle/parse_transform.cc (about) 1 /* 2 * Souffle - A Datalog Compiler 3 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved 4 * Licensed under the Universal Permissive License v 1.0 as shown at: 5 * - https://opensource.org/licenses/UPL 6 * - <souffle root>/licenses/SOUFFLE-UPL.txt 7 */ 8 9 // This code was originally in <souffle root>/src/main.cpp. 10 11 #include "absl/log/log.h" 12 #include "third_party/souffle/parse_transform.h" 13 14 #include "Global.h" 15 #include "ast/Clause.h" 16 #include "ast/Node.h" 17 #include "ast/Program.h" 18 #include "ast/TranslationUnit.h" 19 #include "ast/analysis/PrecedenceGraph.h" 20 #include "ast/analysis/SCCGraph.h" 21 #include "ast/analysis/typesystem/Type.h" 22 #include "ast/transform/AddNullariesToAtomlessAggregates.h" 23 #include "ast/transform/ComponentChecker.h" 24 #include "ast/transform/ComponentInstantiation.h" 25 #include "ast/transform/Conditional.h" 26 #include "ast/transform/ExecutionPlanChecker.h" 27 #include "ast/transform/ExpandEqrels.h" 28 #include "ast/transform/Fixpoint.h" 29 #include "ast/transform/FoldAnonymousRecords.h" 30 #include "ast/transform/GroundWitnesses.h" 31 #include "ast/transform/GroundedTermsChecker.h" 32 #include "ast/transform/IOAttributes.h" 33 #include "ast/transform/IODefaults.h" 34 #include "ast/transform/InlineRelations.h" 35 #include "ast/transform/MagicSet.h" 36 #include "ast/transform/MaterializeAggregationQueries.h" 37 #include "ast/transform/MaterializeSingletonAggregation.h" 38 #include "ast/transform/MinimiseProgram.h" 39 #include "ast/transform/NameUnnamedVariables.h" 40 #include "ast/transform/NormaliseGenerators.h" 41 #include "ast/transform/PartitionBodyLiterals.h" 42 #include "ast/transform/Pipeline.h" 43 #include "ast/transform/PragmaChecker.h" 44 #include "ast/transform/ReduceExistentials.h" 45 #include "ast/transform/RemoveBooleanConstraints.h" 46 #include "ast/transform/RemoveEmptyRelations.h" 47 #include "ast/transform/RemoveRedundantRelations.h" 48 #include "ast/transform/RemoveRedundantSums.h" 49 #include "ast/transform/RemoveRelationCopies.h" 50 #include "ast/transform/ReplaceSingletonVariables.h" 51 #include "ast/transform/ResolveAliases.h" 52 #include "ast/transform/ResolveAnonymousRecordAliases.h" 53 #include "ast/transform/SemanticChecker.h" 54 #include "ast/transform/SimplifyAggregateTargetExpression.h" 55 #include "ast/transform/SubsumptionQualifier.h" 56 #include "ast/transform/UniqueAggregationVariables.h" 57 #include "ast2ram/TranslationStrategy.h" 58 #include "ast2ram/UnitTranslator.h" 59 #include "ast2ram/provenance/TranslationStrategy.h" 60 #include "ast2ram/provenance/UnitTranslator.h" 61 #include "ast2ram/seminaive/TranslationStrategy.h" 62 #include "ast2ram/seminaive/UnitTranslator.h" 63 #include "ast2ram/utility/TranslatorContext.h" 64 #include "interpreter/Engine.h" 65 #include "interpreter/ProgInterface.h" 66 #include "parser/ParserDriver.h" 67 #include "ram/Node.h" 68 #include "ram/Program.h" 69 #include "ram/TranslationUnit.h" 70 #include "ram/transform/CollapseFilters.h" 71 #include "ram/transform/Conditional.h" 72 #include "ram/transform/EliminateDuplicates.h" 73 #include "ram/transform/ExpandFilter.h" 74 #include "ram/transform/HoistAggregate.h" 75 #include "ram/transform/HoistConditions.h" 76 #include "ram/transform/IfConversion.h" 77 #include "ram/transform/IfExistsConversion.h" 78 #include "ram/transform/Loop.h" 79 #include "ram/transform/MakeIndex.h" 80 #include "ram/transform/Parallel.h" 81 #include "ram/transform/ReorderConditions.h" 82 #include "ram/transform/ReorderFilterBreak.h" 83 #include "ram/transform/ReportIndex.h" 84 #include "ram/transform/Sequence.h" 85 #include "ram/transform/Transformer.h" 86 #include "ram/transform/TupleId.h" 87 #include "reports/DebugReport.h" 88 #include "reports/ErrorReport.h" 89 #include "souffle/RamTypes.h" 90 #include "souffle/utility/ContainerUtil.h" 91 #include "souffle/utility/FileUtil.h" 92 #include "souffle/utility/MiscUtil.h" 93 #include "souffle/utility/StreamUtil.h" 94 #include "souffle/utility/StringUtil.h" 95 #include "souffle/utility/SubProcess.h" 96 #include "synthesiser/Synthesiser.h" 97 #include <cassert> 98 #include <chrono> 99 #include <cstdio> 100 #include <cstdlib> 101 #include <ctime> 102 #include <iomanip> 103 #include <iostream> 104 #include <map> 105 #include <memory> 106 #include <set> 107 #include <sstream> 108 #include <stdexcept> 109 #include <string> 110 #include <thread> 111 #include <utility> 112 #include <vector> 113 114 namespace souffle { 115 116 std::unique_ptr<ram::TranslationUnit> ParseTransform(const std::string& code) { 117 Global::config().set("jobs", "1"); 118 Global::config().has("verbose", "1"); 119 souffle::ErrorReport errorReport(/*nowarn=*/true); 120 souffle::DebugReport debugReport; 121 souffle::Own<souffle::ast::TranslationUnit> astTranslationUnit = 122 souffle::ParserDriver::parseTranslationUnit(code, errorReport, debugReport); 123 auto& report = astTranslationUnit->getErrorReport(); 124 if (report.getNumIssues() != 0) { 125 LOG(ERROR) << "Souffle parser reported a nonzero diagnostic count."; 126 std::stringstream diagnostics; 127 diagnostics << report; 128 LOG(ERROR) << diagnostics.str(); 129 return nullptr; 130 } 131 132 // ------- rewriting / optimizations ------------- 133 134 /* set up additional global options based on pragma declaratives */ 135 (mk<ast::transform::PragmaChecker>())->apply(*astTranslationUnit); 136 137 /* construct the transformation pipeline */ 138 139 // Equivalence pipeline 140 auto equivalencePipeline = 141 mk<ast::transform::PipelineTransformer>(mk<ast::transform::NameUnnamedVariablesTransformer>(), 142 mk<ast::transform::FixpointTransformer>(mk<ast::transform::MinimiseProgramTransformer>()), 143 mk<ast::transform::ReplaceSingletonVariablesTransformer>(), 144 mk<ast::transform::RemoveRelationCopiesTransformer>(), 145 mk<ast::transform::RemoveEmptyRelationsTransformer>(), 146 mk<ast::transform::RemoveRedundantRelationsTransformer>()); 147 148 // Magic-Set pipeline 149 auto magicPipeline = mk<ast::transform::PipelineTransformer>( 150 mk<ast::transform::ConditionalTransformer>( 151 Global::config().has("magic-transform"), mk<ast::transform::ExpandEqrelsTransformer>()), 152 mk<ast::transform::MagicSetTransformer>(), mk<ast::transform::ResolveAliasesTransformer>(), 153 mk<ast::transform::RemoveRelationCopiesTransformer>(), 154 mk<ast::transform::RemoveEmptyRelationsTransformer>(), 155 mk<ast::transform::RemoveRedundantRelationsTransformer>(), clone(equivalencePipeline)); 156 157 // Partitioning pipeline 158 auto partitionPipeline = 159 mk<ast::transform::PipelineTransformer>(mk<ast::transform::NameUnnamedVariablesTransformer>(), 160 mk<ast::transform::PartitionBodyLiteralsTransformer>(), 161 mk<ast::transform::ReplaceSingletonVariablesTransformer>()); 162 163 // Provenance pipeline 164 auto provenancePipeline = mk<ast::transform::ConditionalTransformer>(Global::config().has("provenance"), 165 mk<ast::transform::PipelineTransformer>(mk<ast::transform::ExpandEqrelsTransformer>(), 166 mk<ast::transform::NameUnnamedVariablesTransformer>())); 167 168 // Main pipeline 169 auto pipeline = mk<ast::transform::PipelineTransformer>(mk<ast::transform::ComponentChecker>(), 170 mk<ast::transform::ComponentInstantiationTransformer>(), 171 mk<ast::transform::IODefaultsTransformer>(), 172 mk<ast::transform::SimplifyAggregateTargetExpressionTransformer>(), 173 mk<ast::transform::UniqueAggregationVariablesTransformer>(), 174 mk<ast::transform::FixpointTransformer>(mk<ast::transform::PipelineTransformer>( 175 mk<ast::transform::ResolveAnonymousRecordAliasesTransformer>(), 176 mk<ast::transform::FoldAnonymousRecords>())), 177 mk<ast::transform::SubsumptionQualifierTransformer>(), mk<ast::transform::SemanticChecker>(), 178 mk<ast::transform::GroundWitnessesTransformer>(), 179 mk<ast::transform::UniqueAggregationVariablesTransformer>(), 180 mk<ast::transform::MaterializeSingletonAggregationTransformer>(), 181 mk<ast::transform::FixpointTransformer>( 182 mk<ast::transform::MaterializeAggregationQueriesTransformer>()), 183 mk<ast::transform::RemoveRedundantSumsTransformer>(), 184 mk<ast::transform::NormaliseGeneratorsTransformer>(), 185 mk<ast::transform::ResolveAliasesTransformer>(), 186 mk<ast::transform::RemoveBooleanConstraintsTransformer>(), 187 mk<ast::transform::ResolveAliasesTransformer>(), mk<ast::transform::MinimiseProgramTransformer>(), 188 mk<ast::transform::InlineUnmarkExcludedTransform>(), 189 mk<ast::transform::InlineRelationsTransformer>(), mk<ast::transform::GroundedTermsChecker>(), 190 mk<ast::transform::ResolveAliasesTransformer>(), 191 mk<ast::transform::RemoveRedundantRelationsTransformer>(), 192 mk<ast::transform::RemoveRelationCopiesTransformer>(), 193 mk<ast::transform::RemoveEmptyRelationsTransformer>(), 194 mk<ast::transform::ReplaceSingletonVariablesTransformer>(), 195 mk<ast::transform::FixpointTransformer>(mk<ast::transform::PipelineTransformer>( 196 mk<ast::transform::ReduceExistentialsTransformer>(), 197 mk<ast::transform::RemoveRedundantRelationsTransformer>())), 198 mk<ast::transform::RemoveRelationCopiesTransformer>(), std::move(partitionPipeline), 199 std::move(equivalencePipeline), mk<ast::transform::RemoveRelationCopiesTransformer>(), 200 std::move(magicPipeline), mk<ast::transform::RemoveEmptyRelationsTransformer>(), 201 mk<ast::transform::AddNullariesToAtomlessAggregatesTransformer>(), 202 mk<ast::transform::ExecutionPlanChecker>(), std::move(provenancePipeline), 203 mk<ast::transform::IOAttributesTransformer>()); 204 205 // Disable unwanted transformations 206 if (Global::config().has("disable-transformers")) { 207 std::vector<std::string> givenTransformers = 208 splitString(Global::config().get("disable-transformers"), ','); 209 pipeline->disableTransformers( 210 std::set<std::string>(givenTransformers.begin(), givenTransformers.end())); 211 } 212 213 // Toggle pipeline verbosity 214 pipeline->setVerbosity(Global::config().has("verbose")); 215 216 // Apply all the transformations 217 pipeline->apply(*astTranslationUnit); 218 219 // ------- execution ------------- 220 /* translate AST to RAM */ 221 debugReport.startSection(); 222 auto translationStrategy = 223 Global::config().has("provenance") 224 ? mk<ast2ram::TranslationStrategy, ast2ram::provenance::TranslationStrategy>() 225 : mk<ast2ram::TranslationStrategy, ast2ram::seminaive::TranslationStrategy>(); 226 auto unitTranslator = Own<ast2ram::UnitTranslator>(translationStrategy->createUnitTranslator()); 227 auto ramTranslationUnit = unitTranslator->translateUnit(*astTranslationUnit); 228 debugReport.endSection("ast-to-ram", "Translate AST to RAM"); 229 230 // Apply RAM transforms 231 { 232 using namespace ram::transform; 233 Own<Transformer> ramTransform = mk<TransformerSequence>( 234 mk<LoopTransformer>(mk<TransformerSequence>(mk<ExpandFilterTransformer>(), 235 mk<HoistConditionsTransformer>(), mk<MakeIndexTransformer>())), 236 mk<IfConversionTransformer>(), mk<IfExistsConversionTransformer>(), 237 mk<CollapseFiltersTransformer>(), mk<TupleIdTransformer>(), 238 mk<LoopTransformer>( 239 mk<TransformerSequence>(mk<HoistAggregateTransformer>(), mk<TupleIdTransformer>())), 240 mk<ExpandFilterTransformer>(), mk<HoistConditionsTransformer>(), 241 mk<CollapseFiltersTransformer>(), mk<EliminateDuplicatesTransformer>(), 242 mk<ReorderConditionsTransformer>(), mk<LoopTransformer>(mk<ReorderFilterBreak>()), 243 mk<ConditionalTransformer>( 244 // job count of 0 means all cores are used. 245 []() -> bool { return std::stoi(Global::config().get("jobs")) != 1; }, 246 mk<ParallelTransformer>()), 247 mk<ReportIndexTransformer>()); 248 249 ramTransform->apply(*ramTranslationUnit); 250 } 251 252 if (ramTranslationUnit->getErrorReport().getNumIssues() != 0) { 253 std::cerr << ramTranslationUnit->getErrorReport(); 254 } 255 256 return ramTranslationUnit; 257 } 258 259 }