clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
126 lines
4.6 KiB
C++
126 lines
4.6 KiB
C++
//===------ 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.
|
|
class SCEVAffinator final : 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 visitVScale(const llvm::SCEVVScale *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 visitSequentialUMinExpr(const llvm::SCEVSequentialUMinExpr *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
|