blob: f5d77118857129bcf4b89df81b81548cf686e18e [file] [log] [blame]
//===------ polly/SCEVAffinator.h - Create isl expressions from SCEVs -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Create a polyhedral description for a SCEV value.
//
//===----------------------------------------------------------------------===//
#ifndef POLLY_SCEV_AFFINATOR_H
#define POLLY_SCEV_AFFINATOR_H
#include "polly/Support/ScopHelper.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "isl/isl-noexceptions.h"
namespace polly {
class Scop;
/// The result type of the SCEVAffinator.
///
/// The first element of the pair is the isl representation of the SCEV, the
/// second is the domain under which it is __invalid__.
typedef std::pair<isl::pw_aff, isl::set> PWACtx;
/// Translate a SCEV to an isl::pw_aff and the domain on which it is invalid.
struct SCEVAffinator : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
public:
SCEVAffinator(Scop *S, llvm::LoopInfo &LI);
/// Translate a SCEV to an isl::pw_aff.
///
/// @param E he expression that is translated.
/// @param BB The block in which @p E is executed.
///
/// @returns The isl representation of the SCEV @p E in @p Domain.
PWACtx getPwAff(const llvm::SCEV *E, llvm::BasicBlock *BB = nullptr,
RecordedAssumptionsTy *RecordedAssumptions = nullptr);
/// Take the assumption that @p PWAC is non-negative.
void takeNonNegativeAssumption(
PWACtx &PWAC, RecordedAssumptionsTy *RecordedAssumptions = nullptr);
/// Interpret the PWA in @p PWAC as an unsigned value.
void interpretAsUnsigned(PWACtx &PWAC, unsigned Width);
/// Check an <nsw> AddRec for the loop @p L is cached.
bool hasNSWAddRecForLoop(llvm::Loop *L) const;
/// Return the LoopInfo used by thi object.
llvm::LoopInfo *getLI() const { return &LI; }
private:
/// Key to identify cached expressions.
using CacheKey = std::pair<const llvm::SCEV *, llvm::BasicBlock *>;
/// Map to remembered cached expressions.
llvm::DenseMap<CacheKey, PWACtx> CachedExpressions;
Scop *S;
isl::ctx Ctx;
unsigned NumIterators;
llvm::ScalarEvolution &SE;
llvm::LoopInfo &LI;
llvm::BasicBlock *BB;
RecordedAssumptionsTy *RecordedAssumptions = nullptr;
/// Target data for element size computing.
const llvm::DataLayout &TD;
/// Return the loop for the current block if any.
llvm::Loop *getScope();
/// Return a PWACtx for @p PWA that is always valid.
PWACtx getPWACtxFromPWA(isl::pw_aff PWA);
/// Compute the non-wrapping version of @p PWA for type @p ExprType.
///
/// @param PWA The piece-wise affine function that might wrap.
/// @param Type The type of the SCEV that was translated to @p PWA.
///
/// @returns The expr @p PWA modulo the size constraints of @p ExprType.
isl::pw_aff addModuloSemantic(isl::pw_aff PWA, llvm::Type *ExprType) const;
/// If @p Expr might cause an integer wrap record an assumption.
///
/// @param Expr The SCEV expression that might wrap.
/// @param PWAC The isl representation of @p Expr with the invalid domain.
///
/// @returns The isl representation @p PWAC with a possibly adjusted domain.
PWACtx checkForWrapping(const llvm::SCEV *Expr, PWACtx PWAC) const;
/// Whether to track the value of this expression precisely, rather than
/// assuming it won't wrap.
bool computeModuloForExpr(const llvm::SCEV *Expr);
PWACtx visit(const llvm::SCEV *E);
PWACtx visitConstant(const llvm::SCEVConstant *E);
PWACtx visitPtrToIntExpr(const llvm::SCEVPtrToIntExpr *E);
PWACtx visitTruncateExpr(const llvm::SCEVTruncateExpr *E);
PWACtx visitZeroExtendExpr(const llvm::SCEVZeroExtendExpr *E);
PWACtx visitSignExtendExpr(const llvm::SCEVSignExtendExpr *E);
PWACtx visitAddExpr(const llvm::SCEVAddExpr *E);
PWACtx visitMulExpr(const llvm::SCEVMulExpr *E);
PWACtx visitUDivExpr(const llvm::SCEVUDivExpr *E);
PWACtx visitAddRecExpr(const llvm::SCEVAddRecExpr *E);
PWACtx visitSMaxExpr(const llvm::SCEVSMaxExpr *E);
PWACtx visitSMinExpr(const llvm::SCEVSMinExpr *E);
PWACtx visitUMaxExpr(const llvm::SCEVUMaxExpr *E);
PWACtx visitUMinExpr(const llvm::SCEVUMinExpr *E);
PWACtx visitUnknown(const llvm::SCEVUnknown *E);
PWACtx visitSDivInstruction(llvm::Instruction *SDiv);
PWACtx visitSRemInstruction(llvm::Instruction *SRem);
PWACtx complexityBailout();
friend struct llvm::SCEVVisitor<SCEVAffinator, PWACtx>;
};
} // namespace polly
#endif