/usr/include/llvm-3.9/llvm/Analysis/LoopUnrollAnalyzer.h is in llvm-3.9-dev 1:3.9.1-19ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | //===- llvm/Analysis/LoopUnrollAnalyzer.h - Loop Unroll Analyzer-*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements UnrolledInstAnalyzer class. It's used for predicting
// potential effects that loop unrolling might have, such as enabling constant
// propagation and other optimizations.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOPUNROLLANALYZER_H
#define LLVM_ANALYSIS_LOOPUNROLLANALYZER_H
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/InstVisitor.h"
// This class is used to get an estimate of the optimization effects that we
// could get from complete loop unrolling. It comes from the fact that some
// loads might be replaced with concrete constant values and that could trigger
// a chain of instruction simplifications.
//
// E.g. we might have:
// int a[] = {0, 1, 0};
// v = 0;
// for (i = 0; i < 3; i ++)
// v += b[i]*a[i];
// If we completely unroll the loop, we would get:
// v = b[0]*a[0] + b[1]*a[1] + b[2]*a[2]
// Which then will be simplified to:
// v = b[0]* 0 + b[1]* 1 + b[2]* 0
// And finally:
// v = b[1]
namespace llvm {
class UnrolledInstAnalyzer : private InstVisitor<UnrolledInstAnalyzer, bool> {
typedef InstVisitor<UnrolledInstAnalyzer, bool> Base;
friend class InstVisitor<UnrolledInstAnalyzer, bool>;
struct SimplifiedAddress {
Value *Base = nullptr;
ConstantInt *Offset = nullptr;
};
public:
UnrolledInstAnalyzer(unsigned Iteration,
DenseMap<Value *, Constant *> &SimplifiedValues,
ScalarEvolution &SE, const Loop *L)
: SimplifiedValues(SimplifiedValues), SE(SE), L(L) {
IterationNumber = SE.getConstant(APInt(64, Iteration));
}
// Allow access to the initial visit method.
using Base::visit;
private:
/// \brief A cache of pointer bases and constant-folded offsets corresponding
/// to GEP (or derived from GEP) instructions.
///
/// In order to find the base pointer one needs to perform non-trivial
/// traversal of the corresponding SCEV expression, so it's good to have the
/// results saved.
DenseMap<Value *, SimplifiedAddress> SimplifiedAddresses;
/// \brief SCEV expression corresponding to number of currently simulated
/// iteration.
const SCEV *IterationNumber;
/// \brief A Value->Constant map for keeping values that we managed to
/// constant-fold on the given iteration.
///
/// While we walk the loop instructions, we build up and maintain a mapping
/// of simplified values specific to this iteration. The idea is to propagate
/// any special information we have about loads that can be replaced with
/// constants after complete unrolling, and account for likely simplifications
/// post-unrolling.
DenseMap<Value *, Constant *> &SimplifiedValues;
ScalarEvolution &SE;
const Loop *L;
bool simplifyInstWithSCEV(Instruction *I);
bool visitInstruction(Instruction &I) { return simplifyInstWithSCEV(&I); }
bool visitBinaryOperator(BinaryOperator &I);
bool visitLoad(LoadInst &I);
bool visitCastInst(CastInst &I);
bool visitCmpInst(CmpInst &I);
bool visitPHINode(PHINode &PN);
};
}
#endif
|