Optionally model read-only scalars

Even though read-only accesses to scalars outside of a scop do not need to be
modeled to derive valid transformations or to generate valid sequential code,
but information about them is useful when we considering memory footprint
analysis and/or kernel offloading.

llvm-svn: 243981
This commit is contained in:
Tobias Grosser 2015-08-04 13:54:20 +00:00
parent b89951457d
commit dcc3b435ab
4 changed files with 62 additions and 10 deletions

View File

@ -39,21 +39,20 @@ class IslExprBuilder;
typedef DenseMap<const Value *, Value *> ValueMapT;
typedef std::vector<ValueMapT> VectorValueMapT;
/// @brief Check whether an instruction can be synthesized by the code
/// generator.
/// @brief Check whether a value an be synthesized by the code generator.
///
/// Some instructions will be recalculated only from information that is code
/// generated from the polyhedral representation. For such instructions we do
/// not need to ensure that their operands are available during code generation.
/// Some value will be recalculated only from information that is code generated
/// from the polyhedral representation. For such instructions we do not need to
/// ensure that their operands are available during code generation.
///
/// @param I The instruction to check.
/// @param V The value to check.
/// @param LI The LoopInfo analysis.
/// @param SE The scalar evolution database.
/// @param R The region out of which SSA names are parameters.
/// @return If the instruction I can be regenerated from its
/// scalar evolution representation, return true,
/// otherwise return false.
bool canSynthesize(const llvm::Instruction *I, const llvm::LoopInfo *LI,
bool canSynthesize(const llvm::Value *V, const llvm::LoopInfo *LI,
llvm::ScalarEvolution *SE, const llvm::Region *R);
/// @brief Return true iff @p V is an intrinsic that we ignore during code

View File

@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "polly/TempScopInfo.h"
#include "polly/Options.h"
#include "polly/CodeGen/BlockGenerators.h"
#include "polly/LinkAllPasses.h"
#include "polly/ScopDetection.h"
@ -34,6 +35,11 @@
using namespace llvm;
using namespace polly;
static cl::opt<bool> ModelReadOnlyScalars(
"polly-analyze-read-only-scalars",
cl::desc("Model read-only scalar values in the scop description"),
cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory));
#define DEBUG_TYPE "polly-analyze-ir"
//===----------------------------------------------------------------------===//
@ -209,6 +215,21 @@ bool TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R,
AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, UI));
}
if (ModelReadOnlyScalars) {
for (Value *Op : Inst->operands()) {
if (canSynthesize(Op, LI, SE, R))
continue;
if (Instruction *OpInst = dyn_cast<Instruction>(Op))
if (R->contains(OpInst))
continue;
IRAccess ScalarAccess(IRAccess::READ, Op, ZeroOffset, 1, true);
AccFuncMap[Inst->getParent()].push_back(
std::make_pair(ScalarAccess, Inst));
}
}
return AnyCrossStmtUse;
}

View File

@ -42,12 +42,12 @@ static cl::opt<bool> Aligned("enable-polly-aligned",
cl::Hidden, cl::init(false), cl::ZeroOrMore,
cl::cat(PollyCategory));
bool polly::canSynthesize(const Instruction *I, const llvm::LoopInfo *LI,
bool polly::canSynthesize(const Value *V, const llvm::LoopInfo *LI,
ScalarEvolution *SE, const Region *R) {
if (!I || !SE->isSCEVable(I->getType()))
if (!V || !SE->isSCEVable(V->getType()))
return false;
if (const SCEV *Scev = SE->getSCEV(const_cast<Instruction *>(I)))
if (const SCEV *Scev = SE->getSCEV(const_cast<Value *>(V)))
if (!isa<SCEVCouldNotCompute>(Scev))
if (!hasScalarDepsInsideRegion(Scev, R))
return true;

View File

@ -0,0 +1,32 @@
; RUN: opt %loadPolly -polly-analyze-read-only-scalars=false -polly-scops -analyze < %s | FileCheck %s
; RUN: opt %loadPolly -polly-analyze-read-only-scalars=true -polly-scops -analyze < %s | FileCheck %s -check-prefix=SCALARS
; CHECK-NOT: Memref_scalar
; SCALARS: float MemRef_scalar[*] // Element size 4
; SCALARS: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; SCALARS: { Stmt_stmt1[i0] -> MemRef_scalar[] };
define void @foo(float* noalias %A, float %scalar) {
entry:
br label %loop
loop:
%indvar = phi i64 [0, %entry], [%indvar.next, %loop.backedge]
br label %stmt1
stmt1:
%val = load float, float* %A
%sum = fadd float %val, %scalar
store float %sum, float* %A
br label %loop.backedge
loop.backedge:
%indvar.next = add i64 %indvar, 1
%cond = icmp sle i64 %indvar, 100
br i1 %cond, label %loop, label %exit
exit:
ret void
}