Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:48:11

0001 //===- IslAst.h - Interface to the isl code generator -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // The isl code generator interface takes a Scop and generates a isl_ast. This
0010 // ist_ast can either be returned directly or it can be pretty printed to
0011 // stdout.
0012 //
0013 // A typical isl_ast output looks like this:
0014 //
0015 // for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) {
0016 //   bb2(c2);
0017 // }
0018 //
0019 //===----------------------------------------------------------------------===//
0020 
0021 #ifndef POLLY_ISLAST_H
0022 #define POLLY_ISLAST_H
0023 
0024 #include "polly/ScopPass.h"
0025 #include "llvm/ADT/SmallPtrSet.h"
0026 #include "llvm/IR/PassManager.h"
0027 #include "isl/ctx.h"
0028 
0029 namespace polly {
0030 using llvm::SmallPtrSet;
0031 
0032 class Dependences;
0033 
0034 class IslAst final {
0035 public:
0036   IslAst(const IslAst &) = delete;
0037   IslAst &operator=(const IslAst &) = delete;
0038   IslAst(IslAst &&);
0039   IslAst &operator=(IslAst &&) = delete;
0040 
0041   static IslAst create(Scop &Scop, const Dependences &D);
0042 
0043   isl::ast_node getAst();
0044 
0045   const std::shared_ptr<isl_ctx> getSharedIslCtx() const { return Ctx; }
0046 
0047   /// Get the run-time conditions for the Scop.
0048   isl::ast_expr getRunCondition();
0049 
0050   /// Build run-time condition for scop.
0051   ///
0052   /// @param S     The scop to build the condition for.
0053   /// @param Build The isl_build object to use to build the condition.
0054   ///
0055   /// @returns An ast expression that describes the necessary run-time check.
0056   static isl::ast_expr buildRunCondition(Scop &S, const isl::ast_build &Build);
0057 
0058 private:
0059   Scop &S;
0060   std::shared_ptr<isl_ctx> Ctx;
0061   isl::ast_expr RunCondition;
0062   isl::ast_node Root;
0063 
0064   IslAst(Scop &Scop);
0065 
0066   void init(const Dependences &D);
0067 };
0068 
0069 class IslAstInfo {
0070 public:
0071   using MemoryAccessSet = SmallPtrSet<MemoryAccess *, 4>;
0072 
0073   /// Payload information used to annotate an AST node.
0074   struct IslAstUserPayload {
0075     /// Construct and initialize the payload.
0076     IslAstUserPayload() = default;
0077 
0078     /// Does the dependence analysis determine that there are no loop-carried
0079     /// dependencies?
0080     bool IsParallel = false;
0081 
0082     /// Flag to mark innermost loops.
0083     bool IsInnermost = false;
0084 
0085     /// Flag to mark innermost parallel loops.
0086     bool IsInnermostParallel = false;
0087 
0088     /// Flag to mark outermost parallel loops.
0089     bool IsOutermostParallel = false;
0090 
0091     /// Flag to mark parallel loops which break reductions.
0092     bool IsReductionParallel = false;
0093 
0094     /// The minimal dependence distance for non parallel loops.
0095     isl::pw_aff MinimalDependenceDistance;
0096 
0097     /// The build environment at the time this node was constructed.
0098     isl::ast_build Build;
0099 
0100     /// Set of accesses which break reduction dependences.
0101     MemoryAccessSet BrokenReductions;
0102   };
0103 
0104 private:
0105   Scop &S;
0106   IslAst Ast;
0107 
0108 public:
0109   IslAstInfo(Scop &S, const Dependences &D) : S(S), Ast(IslAst::create(S, D)) {}
0110 
0111   /// Return the isl AST computed by this IslAstInfo.
0112   IslAst &getIslAst() { return Ast; }
0113 
0114   /// Return a copy of the AST root node.
0115   isl::ast_node getAst();
0116 
0117   /// Get the run condition.
0118   ///
0119   /// Only if the run condition evaluates at run-time to a non-zero value, the
0120   /// assumptions that have been taken hold. If the run condition evaluates to
0121   /// zero/false some assumptions do not hold and the original code needs to
0122   /// be executed.
0123   isl::ast_expr getRunCondition();
0124 
0125   void print(raw_ostream &O);
0126 
0127   /// @name Extract information attached to an isl ast (for) node.
0128   ///
0129   ///{
0130   /// Get the complete payload attached to @p Node.
0131   static IslAstUserPayload *getNodePayload(const isl::ast_node &Node);
0132 
0133   /// Is this loop an innermost loop?
0134   static bool isInnermost(const isl::ast_node &Node);
0135 
0136   /// Is this loop a parallel loop?
0137   static bool isParallel(const isl::ast_node &Node);
0138 
0139   /// Is this loop an outermost parallel loop?
0140   static bool isOutermostParallel(const isl::ast_node &Node);
0141 
0142   /// Is this loop an innermost parallel loop?
0143   static bool isInnermostParallel(const isl::ast_node &Node);
0144 
0145   /// Is this loop a reduction parallel loop?
0146   static bool isReductionParallel(const isl::ast_node &Node);
0147 
0148   /// Will the loop be run as thread parallel?
0149   static bool isExecutedInParallel(const isl::ast_node &Node);
0150 
0151   /// Get the nodes schedule or a nullptr if not available.
0152   static isl::union_map getSchedule(const isl::ast_node &Node);
0153 
0154   /// Get minimal dependence distance or nullptr if not available.
0155   static isl::pw_aff getMinimalDependenceDistance(const isl::ast_node &Node);
0156 
0157   /// Get the nodes broken reductions or a nullptr if not available.
0158   static MemoryAccessSet *getBrokenReductions(const isl::ast_node &Node);
0159 
0160   /// Get the nodes build context or a nullptr if not available.
0161   static isl::ast_build getBuild(const isl::ast_node &Node);
0162 
0163   ///}
0164 };
0165 
0166 struct IslAstAnalysis : AnalysisInfoMixin<IslAstAnalysis> {
0167   static AnalysisKey Key;
0168 
0169   using Result = IslAstInfo;
0170 
0171   IslAstInfo run(Scop &S, ScopAnalysisManager &SAM,
0172                  ScopStandardAnalysisResults &SAR);
0173 };
0174 
0175 class IslAstInfoWrapperPass final : public ScopPass {
0176   std::unique_ptr<IslAstInfo> Ast;
0177 
0178 public:
0179   static char ID;
0180 
0181   IslAstInfoWrapperPass() : ScopPass(ID) {}
0182 
0183   IslAstInfo &getAI() { return *Ast; }
0184   const IslAstInfo &getAI() const { return *Ast; }
0185 
0186   /// Build the AST for the given SCoP @p S.
0187   bool runOnScop(Scop &S) override;
0188 
0189   /// Register all analyses and transformation required.
0190   void getAnalysisUsage(AnalysisUsage &AU) const override;
0191 
0192   /// Release the internal memory.
0193   void releaseMemory() override;
0194 
0195   /// Print a source code representation of the program.
0196   void printScop(raw_ostream &OS, Scop &S) const override;
0197 };
0198 
0199 llvm::Pass *createIslAstInfoWrapperPassPass();
0200 llvm::Pass *createIslAstInfoPrinterLegacyPass(llvm::raw_ostream &OS);
0201 
0202 struct IslAstPrinterPass final : PassInfoMixin<IslAstPrinterPass> {
0203   IslAstPrinterPass(raw_ostream &OS) : OS(OS) {}
0204 
0205   PreservedAnalyses run(Scop &S, ScopAnalysisManager &SAM,
0206                         ScopStandardAnalysisResults &, SPMUpdater &U);
0207 
0208   raw_ostream &OS;
0209 };
0210 } // namespace polly
0211 
0212 namespace llvm {
0213 void initializeIslAstInfoWrapperPassPass(llvm::PassRegistry &);
0214 void initializeIslAstInfoPrinterLegacyPassPass(llvm::PassRegistry &);
0215 } // namespace llvm
0216 
0217 #endif // POLLY_ISLAST_H