forked from OSchip/llvm-project
Remove AffineSCEVIterator
We do not use it anymore. It was replaced by SCEVVisitors like the SCEVValidator. llvm-svn: 144229
This commit is contained in:
parent
f317e3ac83
commit
6e9f25a5d5
|
@ -1,292 +0,0 @@
|
|||
//===-- AffineSCEVIterator.h - Iterate the SCEV in an affine way -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The iterator can be used to iterate over the affine component of the SCEV
|
||||
// expression.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef AFFINE_SCEV_ITERATOR_H
|
||||
#define AFFINE_SCEV_ITERATOR_H
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace polly {
|
||||
|
||||
/// @brief The itertor transform the scalar expressions to the form of sum of
|
||||
/// (constant * variable)s, and return the variable/constant pairs one by one
|
||||
/// on the fly.
|
||||
///
|
||||
/// For example, we can write SCEV:
|
||||
/// {{%x,+,sizeof(i32)}<%bb2.preheader>,+,(4 * sizeof(i32))}<%bb1>
|
||||
/// in affine form:
|
||||
/// (4 * sizeof(i32)) * %indvar + sizeof(i32) * %0 + 1 * %x + 0 * 1
|
||||
/// so we can get the follow pair from the iterator:
|
||||
/// {%indvar, (4 * sizeof(i32))}, {%0, sizeof(i32)}, {%x, 1} and {1, 0}
|
||||
/// where %indvar is the induction variable of loop %bb1 and %0 is the induction
|
||||
/// variable of loop %bb2.preheader.
|
||||
///
|
||||
/// In the returned pair,
|
||||
/// The "first" field is the variable part, the "second" field constant part.
|
||||
/// And the translation part of the expression will always return last.
|
||||
///
|
||||
class AffineSCEVIterator : public std::iterator<std::forward_iterator_tag,
|
||||
std::pair<const SCEV*, const SCEV*>, ptrdiff_t>,
|
||||
SCEVVisitor<AffineSCEVIterator,
|
||||
std::pair<const SCEV*, const SCEV*> >
|
||||
{
|
||||
typedef std::iterator<std::forward_iterator_tag,
|
||||
std::pair<const SCEV*, const SCEV*>, ptrdiff_t> super;
|
||||
|
||||
friend struct llvm::SCEVVisitor<AffineSCEVIterator,
|
||||
std::pair<const SCEV*, const SCEV*> >;
|
||||
|
||||
ScalarEvolution *SE;
|
||||
public:
|
||||
typedef super::value_type value_type;
|
||||
typedef super::pointer ptr_type;
|
||||
typedef AffineSCEVIterator Self;
|
||||
private:
|
||||
typedef SCEVNAryExpr::op_iterator scev_op_it;
|
||||
|
||||
// The stack help us remember the SCEVs that not visit yet.
|
||||
SmallVector<const SCEV*, 8> visitStack;
|
||||
|
||||
// The current value of this iterator.
|
||||
value_type val;
|
||||
|
||||
const SCEVConstant* getSCEVOne(const SCEV* S) const {
|
||||
return cast<SCEVConstant>(SE->getConstant(S->getType(), 1));
|
||||
}
|
||||
|
||||
//===-------------------------------------------------------------------===//
|
||||
/// Functions for SCEVVisitor.
|
||||
///
|
||||
/// These function compute the constant part and variable part of the SCEV,
|
||||
/// and return them in a std::pair, where the first field is the variable,
|
||||
/// and the second field is the constant.
|
||||
///
|
||||
value_type visitConstant(const SCEVConstant *S) {
|
||||
return std::make_pair(getSCEVOne(S), S);
|
||||
}
|
||||
|
||||
value_type visitUnknown(const SCEVUnknown* S) {
|
||||
Type *AllocTy;
|
||||
Constant *FieldNo;
|
||||
// We treat these as constant.
|
||||
if (S->isSizeOf (AllocTy) ||
|
||||
S->isAlignOf (AllocTy) ||
|
||||
S->isOffsetOf(AllocTy, FieldNo))
|
||||
return std::make_pair(getSCEVOne(S), S);
|
||||
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitMulExpr(const SCEVMulExpr* S) {
|
||||
SmallVector<const SCEV*, 4> Coeffs, Variables;
|
||||
|
||||
// Do not worry about the Constant * Variable * (Variable + Variable)
|
||||
// MulExpr, we will never get a affine expression from it, so we just
|
||||
// leave it there.
|
||||
for (scev_op_it I = S->op_begin(), E = S->op_end(); I != E; ++I) {
|
||||
// Get the constant part and the variable part of each operand.
|
||||
value_type res = visit(*I);
|
||||
|
||||
Coeffs.push_back(res.second);
|
||||
Variables.push_back(res.first);
|
||||
}
|
||||
|
||||
// Get the constant part and variable part of this MulExpr by
|
||||
// multiply them together.
|
||||
const SCEV *Coeff = SE->getMulExpr(Coeffs);
|
||||
// There maybe "sizeof" and others.
|
||||
// TODO: Assert the allowed coeff type.
|
||||
// assert(Coeff && "Expect Coeff to be a const!");
|
||||
|
||||
const SCEV *Var = SE->getMulExpr(Variables);
|
||||
|
||||
return std::make_pair(Var, Coeff);
|
||||
}
|
||||
|
||||
value_type visitCastExpr(const SCEVCastExpr *S) {
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitTruncateExpr(const SCEVTruncateExpr *S) {
|
||||
return visitCastExpr(S);
|
||||
}
|
||||
|
||||
value_type visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
|
||||
return visitCastExpr(S);
|
||||
}
|
||||
|
||||
value_type visitSignExtendExpr(const SCEVSignExtendExpr *S) {
|
||||
return visitCastExpr(S);
|
||||
}
|
||||
|
||||
value_type visitAddExpr(const SCEVAddExpr *S) {
|
||||
// AddExpr will handled out in visit Next;
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
// AddRecExpr will handled out in visit Next;
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitUDivExpr(const SCEVUDivExpr *S) {
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitSMaxExpr(const SCEVSMaxExpr *S) {
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
value_type visitUMaxExpr(const SCEVUMaxExpr *S) {
|
||||
return std::make_pair(S, getSCEVOne(S));
|
||||
}
|
||||
|
||||
/// Get the next {variable, constant} pair of the SCEV.
|
||||
value_type visitNext() {
|
||||
value_type ret(0, 0);
|
||||
|
||||
if (visitStack.empty())
|
||||
return ret;
|
||||
const SCEV* nextS = visitStack.back();
|
||||
|
||||
if (const SCEVAddRecExpr *ARec = dyn_cast<SCEVAddRecExpr>(nextS)){
|
||||
// Visiting the AddRec, check if its Affine;
|
||||
PHINode *IV = ARec->getLoop()->getCanonicalInductionVariable();
|
||||
// Only decompose the AddRec, if the loop has a canonical induction
|
||||
// variable.
|
||||
if (ARec->isAffine() && IV != 0) {
|
||||
ret = visit(ARec->getStepRecurrence(*SE));
|
||||
if (isa<SCEVConstant>(ret.first)) { // If the step is constant.
|
||||
const SCEV *Start = ARec->getStart();
|
||||
visitStack.back() = Start;
|
||||
|
||||
// The AddRec is expect to be decomposed to
|
||||
//
|
||||
// | start + step * {1, +, 1}<loop>
|
||||
//
|
||||
// Now we get the {1, +, 1}<loop> part.
|
||||
ret.first = SE->getSCEV(IV);
|
||||
|
||||
// Push CouldNotCompute to take the place.
|
||||
visitStack.push_back(SE->getCouldNotCompute());
|
||||
|
||||
return ret;
|
||||
}
|
||||
// The step is not a constant. Then this AddRec is not Affine or
|
||||
// no canonical induction variable found.
|
||||
// Fall through.
|
||||
}
|
||||
}
|
||||
|
||||
// Get the constant part and variable part of the SCEV.
|
||||
ret = visit(nextS);
|
||||
|
||||
// If the reach the last constant
|
||||
if (isa<SCEVConstant>(ret.first) && (visitStack.size() != 1)) {
|
||||
// Else, merge all constant component, we will output it at last.
|
||||
visitStack.front() = SE->getAddExpr(visitStack.front(), ret.second);
|
||||
//assert(isa<SCEVConstant>(visitStack.front().first));
|
||||
// Pop the top constant, because it already merged into the bottom of the Stack
|
||||
// and output it last.
|
||||
visitStack.pop_back();
|
||||
// Try again.
|
||||
return visitNext();
|
||||
}
|
||||
// Not a constant or Stack not empty
|
||||
// If ret is in (xxx) * AddExpr form, we will decompose the AddExpr
|
||||
else if (const SCEVAddExpr *AddExpr = dyn_cast<SCEVAddExpr>(ret.first)) {
|
||||
// Pop the current SCEV, we will decompose it.
|
||||
visitStack.pop_back();
|
||||
assert(AddExpr->getNumOperands() && "AddExpr without operand?");
|
||||
for (scev_op_it I = AddExpr->op_begin(), E = AddExpr->op_end(); I != E; ++I){
|
||||
visitStack.push_back(SE->getMulExpr(ret.second, *I));
|
||||
}
|
||||
// Try again with the new SCEV.
|
||||
return visitNext();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// @brief Create the iterator from a SCEV and the ScalarEvolution analysis.
|
||||
AffineSCEVIterator(const SCEV* S, ScalarEvolution *se ) : SE(se) {
|
||||
// Dont iterate CouldNotCompute.
|
||||
if (isa<SCEVCouldNotCompute>(S))
|
||||
return;
|
||||
|
||||
Type *Ty = S->getType();
|
||||
|
||||
// Init the constant component.
|
||||
visitStack.push_back(SE->getConstant(Ty, 0));
|
||||
|
||||
// Get the first affine component.
|
||||
visitStack.push_back(S);
|
||||
val = visitNext();
|
||||
}
|
||||
|
||||
/// @brief Create an end iterator.
|
||||
inline AffineSCEVIterator() {}
|
||||
|
||||
inline bool operator==(const Self& x) const {
|
||||
return visitStack == x.visitStack;
|
||||
}
|
||||
inline bool operator!=(const Self& x) const { return !operator==(x); }
|
||||
|
||||
/// @brief Return the current (constant * variable) component of the SCEV.
|
||||
///
|
||||
/// @return The "first" field of the pair is the variable part,
|
||||
/// the "second" field of the pair is the constant part.
|
||||
inline value_type operator*() const {
|
||||
assert(val.first && val.second && "Cant dereference iterator!");
|
||||
return val;
|
||||
}
|
||||
|
||||
inline const value_type* operator->() const {
|
||||
assert(val.first && val.second && "Cant dereference iterator!");
|
||||
return &val;
|
||||
}
|
||||
|
||||
inline Self& operator++() { // Preincrement
|
||||
assert(!visitStack.empty() && "Cant ++ iterator!");
|
||||
// Pop the last SCEV.
|
||||
visitStack.pop_back();
|
||||
val = visitNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Self operator++(int) { // Postincrement
|
||||
Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
inline static AffineSCEVIterator affine_begin(const SCEV* S, ScalarEvolution *SE) {
|
||||
return AffineSCEVIterator(S, SE);
|
||||
}
|
||||
|
||||
inline static AffineSCEVIterator affine_end() {
|
||||
return AffineSCEVIterator();
|
||||
}
|
||||
|
||||
} // end namespace polly
|
||||
#endif
|
|
@ -49,12 +49,13 @@
|
|||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Support/ScopHelper.h"
|
||||
#include "polly/Support/SCEVValidator.h"
|
||||
#include "polly/Support/AffineSCEVIterator.h"
|
||||
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/RegionIterator.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "polly/TempScopInfo.h"
|
||||
|
||||
#include "polly/LinkAllPasses.h"
|
||||
#include "polly/Support/AffineSCEVIterator.h"
|
||||
#include "polly/Support/GICHelper.h"
|
||||
#include "polly/Support/ScopHelper.h"
|
||||
#include "polly/Support/SCEVValidator.h"
|
||||
|
@ -25,6 +24,8 @@
|
|||
#include "llvm/Analysis/RegionIterator.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
#define DEBUG_TYPE "polly-analyze-ir"
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
//===- AffSCEVItTester.cpp - Test the affine scev itertor. ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Test the affine scev itertor.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "polly/Support/AffineSCEVIterator.h"
|
||||
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Analysis/Passes.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/Support/InstIterator.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace polly;
|
||||
|
||||
static void printSCEVAffine(raw_ostream &OS, const SCEV* S,
|
||||
ScalarEvolution *SE) {
|
||||
|
||||
for (AffineSCEVIterator I = affine_begin(S, SE), E = affine_end();
|
||||
I != E; ++I) {
|
||||
OS << *I->second << " * " << *I->first;
|
||||
|
||||
// The constant part of the SCEV will always be the last one.
|
||||
if (!isa<SCEVConstant>(S))
|
||||
OS << " + ";
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct AffSCEVItTester : public FunctionPass {
|
||||
static char ID;
|
||||
|
||||
ScalarEvolution *SE;
|
||||
LoopInfo *LI;
|
||||
Function *F;
|
||||
|
||||
explicit AffSCEVItTester() : FunctionPass(ID), SE(0), LI(0), F(0) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
SE = &getAnalysis<ScalarEvolution>();
|
||||
LI = &getAnalysis<LoopInfo>();
|
||||
this->F = &F;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void print(raw_ostream &OS, const Module *M) const {
|
||||
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
|
||||
if (SE->isSCEVable(I->getType())) {
|
||||
OS << *I << '\n';
|
||||
OS << " --> ";
|
||||
const SCEV *SV = SE->getSCEV(&*I);
|
||||
|
||||
if (Loop *L = LI->getLoopFor(I->getParent()))
|
||||
SV = SE->getSCEVAtScope(SV, L);
|
||||
SV->print(OS);
|
||||
OS << "\n";
|
||||
OS << "affine function --> ";
|
||||
printSCEVAffine(OS, SV, SE);
|
||||
OS << "\n";
|
||||
}
|
||||
|
||||
for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
|
||||
PrintLoopInfo(OS, *I);
|
||||
}
|
||||
|
||||
void PrintLoopInfo(raw_ostream &OS, const Loop *L) const{
|
||||
// Print all inner loops first
|
||||
for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
|
||||
PrintLoopInfo(OS, *I);
|
||||
|
||||
OS << "Loop ";
|
||||
WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
|
||||
OS << ": ";
|
||||
|
||||
if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
|
||||
const SCEV *SV = SE->getBackedgeTakenCount(L);
|
||||
OS << "backedge-taken count is ";
|
||||
printSCEVAffine(OS, SV, SE);
|
||||
|
||||
OS << "\nloop count in scev ";
|
||||
SV->print(OS);
|
||||
OS << "\n";
|
||||
}
|
||||
else {
|
||||
OS << "Unpredictable\n";
|
||||
}
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addRequired<ScalarEvolution>();
|
||||
AU.addRequired<LoopInfo>();
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
|
||||
char AffSCEVItTester::ID = 0;
|
||||
|
||||
RegisterPass<AffSCEVItTester> B("print-scev-affine",
|
||||
"Print the SCEV expressions in affine form.",
|
||||
true,
|
||||
true);
|
||||
|
||||
namespace polly {
|
||||
Pass *createAffSCEVItTesterPass() {
|
||||
return new AffSCEVItTester();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
add_polly_library(PollySupport
|
||||
AffSCEVItTester.cpp
|
||||
GICHelper.cpp
|
||||
SCEVValidator.cpp
|
||||
ScopHelper.cpp
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
define void @f(i32* nocapture %a) nounwind {
|
||||
entry:
|
||||
%0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=2]
|
||||
; CHECK: 1 * %0 + 0 * 1
|
||||
%1 = icmp sgt i32 %0, 0 ; <i1> [#uses=1]
|
||||
br i1 %1, label %bb, label %return
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
%i.03 = phi i32 [ 0, %entry ], [ %3, %bb ] ; <i32> [#uses=1]
|
||||
; CHECK: 1 * {0,+,1}<nuw><nsw><%bb> + 0 * 1
|
||||
%2 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=0]
|
||||
; CHECK: 1 * %2 + 0 * 1
|
||||
%3 = add nsw i32 %i.03, 1 ; <i32> [#uses=2]
|
||||
; CHECK: 1 * {0,+,1}<nuw><nsw><%bb> + 1 * 1
|
||||
%exitcond = icmp eq i32 %3, %0 ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %return, label %bb
|
||||
|
||||
return: ; preds = %bb, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @rnd(...)
|
|
@ -1,20 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
define i32 @f(i64 %a, i64 %b, i64 %c, [8 x i32]* nocapture %x) nounwind readonly {
|
||||
entry:
|
||||
%0 = shl i64 %a, 1 ; <i64> [#uses=1]
|
||||
%1 = add nsw i64 %0, %b ; <i64> [#uses=1]
|
||||
; CHECK: 1 * %b + 2 * %a + 0 * 1
|
||||
%2 = shl i64 %1, 1 ; <i64> [#uses=1]
|
||||
; CHECK: 2 * %b + 4 * %a + 0 * 1
|
||||
%3 = add i64 %2, 2 ; <i64> [#uses=1]
|
||||
%4 = mul i64 %a, 3 ; <i64> [#uses=1]
|
||||
%5 = shl i64 %b, 2 ; <i64> [#uses=1]
|
||||
%6 = add nsw i64 %4, 2 ; <i64> [#uses=1]
|
||||
%7 = add nsw i64 %6, %c ; <i64> [#uses=1]
|
||||
%8 = add nsw i64 %7, %5 ; <i64> [#uses=1]
|
||||
%9 = getelementptr inbounds [8 x i32]* %x, i64 %3, i64 %8 ; <i32*> [#uses=1]
|
||||
; CHECK: 1 * %x + sizeof(i32) * %c + (35 * sizeof(i32)) * %a + (20 * sizeof(i32)) * %b + (18 * sizeof(i32)) * 1
|
||||
%10 = load i32* %9, align 4 ; <i32> [#uses=1]
|
||||
ret i32 %10
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
define void @f([8 x i32]* nocapture %x) nounwind {
|
||||
entry:
|
||||
br label %bb5.preheader
|
||||
|
||||
bb2: ; preds = %bb3.preheader, %bb2
|
||||
%k.09 = phi i64 [ 0, %bb3.preheader ], [ %1, %bb2 ] ; <i64> [#uses=2]
|
||||
%tmp19 = add i64 %k.09, %tmp18 ; <i64> [#uses=1]
|
||||
%scevgep = getelementptr [8 x i32]* %x, i64 2, i64 %tmp19 ; <i32*> [#uses=1]
|
||||
; CHECK: sizeof(i32) * {0,+,1}<nuw><nsw><%bb2> + (20 * sizeof(i32)) * {0,+,1}<%bb3.preheader> + (35 * sizeof(i32)) * {0,+,1}<%bb5.preheader> + 1 * %x + (18 * sizeof(i32)) * 1
|
||||
%0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=1]
|
||||
store i32 %0, i32* %scevgep, align 4
|
||||
%1 = add nsw i64 %k.09, 1 ; <i64> [#uses=2]
|
||||
%exitcond = icmp eq i64 %1, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %bb4, label %bb2
|
||||
|
||||
bb4: ; preds = %bb2
|
||||
%2 = add i64 %j.010, 1 ; <i64> [#uses=2]
|
||||
%exitcond20 = icmp eq i64 %2, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond20, label %bb6, label %bb3.preheader
|
||||
|
||||
bb3.preheader: ; preds = %bb5.preheader, %bb4
|
||||
%j.010 = phi i64 [ 0, %bb5.preheader ], [ %2, %bb4 ] ; <i64> [#uses=2]
|
||||
%tmp21 = mul i64 %j.010, 20 ; <i64> [#uses=1]
|
||||
%tmp18 = add i64 %tmp21, %tmp23 ; <i64> [#uses=1]
|
||||
br label %bb2
|
||||
|
||||
bb6: ; preds = %bb4
|
||||
%3 = add i64 %i.012, 1 ; <i64> [#uses=2]
|
||||
%exitcond25 = icmp eq i64 %3, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond25, label %return, label %bb5.preheader
|
||||
|
||||
bb5.preheader: ; preds = %bb6, %entry
|
||||
%i.012 = phi i64 [ 0, %entry ], [ %3, %bb6 ] ; <i64> [#uses=2]
|
||||
%tmp = mul i64 %i.012, 35 ; <i64> [#uses=1]
|
||||
%tmp23 = add i64 %tmp, 2 ; <i64> [#uses=1]
|
||||
br label %bb3.preheader
|
||||
|
||||
return: ; preds = %bb6
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @rnd(...)
|
|
@ -1,20 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, i32* nocapture %x) nounwind readnone {
|
||||
entry:
|
||||
%0 = shl i32 %a, 1 ; <i32> [#uses=1]
|
||||
; CHECK: 2 * %a + 0 * 1
|
||||
%1 = mul i32 %b, 3 ; <i32> [#uses=1]
|
||||
; CHECK: 3 * %b + 0 * 1
|
||||
%2 = shl i32 %d, 2 ; <i32> [#uses=1]
|
||||
; CHECK: 4 * %d + 0 * 1
|
||||
%3 = add nsw i32 %0, 5 ; <i32> [#uses=1]
|
||||
; CHECK: 2 * %a + 5 * 1
|
||||
%4 = add nsw i32 %3, %c ; <i32> [#uses=1]
|
||||
; CHECK: 1 * %c + 2 * %a + 5 * 1
|
||||
%5 = add nsw i32 %4, %1 ; <i32> [#uses=1]
|
||||
; CHECK: 1 * %c + 3 * %b + 2 * %a + 5 * 1
|
||||
%6 = add nsw i32 %5, %2 ; <i32> [#uses=1]
|
||||
; CHECK: 1 * %c + 4 * %d + 3 * %b + 2 * %a + 5 * 1
|
||||
ret i32 %6
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define i32 @f(i32 %a, i32 %b, i32 %c, i64 %d, i8 signext %e, i32 %f, i32 %g, i32 %h) nounwind readnone {
|
||||
entry:
|
||||
%0 = mul i32 %a, 3 ; <i32> [#uses=1]
|
||||
%1 = mul i32 %b, 5 ; <i32> [#uses=1]
|
||||
%2 = mul i32 %1, %c ; <i32> [#uses=1]
|
||||
; CHECK: 5 * (%b * %c) + 0 * 1
|
||||
%3 = mul i32 %2, %f ; <i32> [#uses=1]
|
||||
; CHECK: 5 * (%b * %c * %f) + 0 * 1
|
||||
%4 = sext i8 %e to i32 ; <i32> [#uses=1]
|
||||
%5 = shl i32 %4, 2 ; <i32> [#uses=1]
|
||||
%6 = trunc i64 %d to i32 ; <i32> [#uses=1]
|
||||
%7 = mul i32 %6, %h ; <i32> [#uses=1]
|
||||
%8 = add nsw i32 %0, %g ; <i32> [#uses=1]
|
||||
%9 = add nsw i32 %8, %5 ; <i32> [#uses=1]
|
||||
%10 = add nsw i32 %9, %3 ; <i32> [#uses=1]
|
||||
%11 = add nsw i32 %10, %7 ; <i32> [#uses=1]
|
||||
; CHECK: 1 * %g + 1 * ((trunc i64 %d to i32) * %h) + 5 * (%b * %c * %f) + 4 * (sext i8 %e to i32) + 3 * %a + 0 * 1
|
||||
ret i32 %11
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, i32* nocapture %x) nounwind {
|
||||
entry:
|
||||
br label %bb
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
|
||||
; CHECK: 1 * {0,+,1}<%bb> + 0 * 1
|
||||
%scevgep = getelementptr i32* %x, i64 %indvar ; <i32*> [#uses=1]
|
||||
; CHECK: 4 * {0,+,1}<%bb> + 1 * %x + 0 * 1
|
||||
%i.04 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
|
||||
; CHECK: 1 * {0,+,1}<%bb> + 0 * 1
|
||||
store i32 %i.04, i32* %scevgep, align 4
|
||||
%indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
|
||||
; CHECK: 1 * {0,+,1}<%bb> + 1 * 1
|
||||
%exitcond = icmp eq i64 %indvar.next, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %bb2, label %bb
|
||||
|
||||
bb2: ; preds = %bb
|
||||
ret i32 %a
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, [4 x i32]* nocapture %x) nounwind {
|
||||
entry:
|
||||
br label %bb2.preheader
|
||||
|
||||
bb1: ; preds = %bb2.preheader, %bb1
|
||||
%indvar = phi i64 [ 0, %bb2.preheader ], [ %indvar.next, %bb1 ] ; <i64> [#uses=3]
|
||||
; CHECK: 1 * {0,+,1}<%bb1> + 0 * 1
|
||||
%scevgep = getelementptr [4 x i32]* %x, i64 %indvar, i64 %0 ; <i32*> [#uses=1]
|
||||
; CHECK: 16 * {0,+,1}<%bb1> + 4 * {0,+,1}<%bb2.preheader> + 1 * %x + 0 * 1
|
||||
%tmp = mul i64 %indvar, %0 ; <i64> [#uses=1]
|
||||
; CHECK: 1 * {0,+,{0,+,1}<%bb2.preheader>}<%bb1> + 0 * 1
|
||||
%tmp13 = trunc i64 %tmp to i32 ; <i32> [#uses=1]
|
||||
; CHECK: 1 * {0,+,{0,+,1}<%bb2.preheader>}<%bb1> + 0 * 1
|
||||
store i32 %tmp13, i32* %scevgep, align 4
|
||||
%indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
|
||||
; CHECK: 1 * {0,+,1}<%bb1> + 1 * 1
|
||||
%exitcond = icmp eq i64 %indvar.next, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond, label %bb3, label %bb1
|
||||
|
||||
bb3: ; preds = %bb1
|
||||
%indvar.next12 = add i64 %0, 1 ; <i64> [#uses=2]
|
||||
; CHECK: 1 * {0,+,1}<%bb2.preheader> + 1 * 1
|
||||
%exitcond14 = icmp eq i64 %indvar.next12, 64 ; <i1> [#uses=1]
|
||||
br i1 %exitcond14, label %bb5, label %bb2.preheader
|
||||
|
||||
bb2.preheader: ; preds = %bb3, %entry
|
||||
%0 = phi i64 [ 0, %entry ], [ %indvar.next12, %bb3 ] ; <i64> [#uses=3]
|
||||
; CHECK: 1 * {0,+,1}<%bb2.preheader> + 0 * 1
|
||||
br label %bb1
|
||||
|
||||
bb5: ; preds = %bb3
|
||||
ret i32 %a
|
||||
}
|
Loading…
Reference in New Issue