This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,598 @@
//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the generic AliasAnalysis interface, which is used as the
// common interface used by all clients of alias analysis information, and
// implemented by all alias analysis implementations. Mod/Ref information is
// also captured by this interface.
//
// Implementations of this interface must implement the various virtual methods,
// which automatically provides functionality for the entire suite of client
// APIs.
//
// This API identifies memory regions with the Location class. The pointer
// component specifies the base memory address of the region. The Size specifies
// the maximum size (in address units) of the memory region, or UnknownSize if
// the size is not known. The TBAA tag identifies the "type" of the memory
// reference; see the TypeBasedAliasAnalysis class for details.
//
// Some non-obvious details include:
// - Pointers that point to two completely different objects in memory never
// alias, regardless of the value of the Size component.
// - NoAlias doesn't imply inequal pointers. The most obvious example of this
// is two pointers to constant memory. Even if they are equal, constant
// memory is never stored to, so there will never be any dependencies.
// In this and other situations, the pointers may be both NoAlias and
// MustAlias at the same time. The current API can only return one result,
// though this is rarely a problem in practice.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
#define LLVM_ANALYSIS_ALIASANALYSIS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
class LoadInst;
class StoreInst;
class VAArgInst;
class DataLayout;
class TargetLibraryInfo;
class Pass;
class AnalysisUsage;
class MemTransferInst;
class MemIntrinsic;
class DominatorTree;
class AliasAnalysis {
protected:
const DataLayout *TD;
const TargetLibraryInfo *TLI;
private:
AliasAnalysis *AA; // Previous Alias Analysis to chain to.
protected:
/// InitializeAliasAnalysis - Subclasses must call this method to initialize
/// the AliasAnalysis interface before any other methods are called. This is
/// typically called by the run* methods of these subclasses. This may be
/// called multiple times.
///
void InitializeAliasAnalysis(Pass *P);
/// getAnalysisUsage - All alias analysis implementations should invoke this
/// directly (using AliasAnalysis::getAnalysisUsage(AU)).
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
public:
static char ID; // Class identification, replacement for typeinfo
AliasAnalysis() : TD(0), TLI(0), AA(0) {}
virtual ~AliasAnalysis(); // We want to be subclassed
/// UnknownSize - This is a special value which can be used with the
/// size arguments in alias queries to indicate that the caller does not
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
/// getDataLayout - Return a pointer to the current DataLayout object, or
/// null if no DataLayout object is available.
///
const DataLayout *getDataLayout() const { return TD; }
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
const TargetLibraryInfo *getTargetLibraryInfo() const { return TLI; }
/// getTypeStoreSize - Return the DataLayout store size for the given type,
/// if known, or a conservative value otherwise.
///
uint64_t getTypeStoreSize(Type *Ty);
//===--------------------------------------------------------------------===//
/// Alias Queries...
///
/// Location - A description of a memory location.
struct Location {
/// Ptr - The address of the start of the location.
const Value *Ptr;
/// Size - The maximum size of the location, in address-units, or
/// UnknownSize if the size is not known. Note that an unknown size does
/// not mean the pointer aliases the entire virtual address space, because
/// there are restrictions on stepping out of one object and into another.
/// See http://llvm.org/docs/LangRef.html#pointeraliasing
uint64_t Size;
/// TBAATag - The metadata node which describes the TBAA type of
/// the location, or null if there is no known unique tag.
const MDNode *TBAATag;
explicit Location(const Value *P = 0, uint64_t S = UnknownSize,
const MDNode *N = 0)
: Ptr(P), Size(S), TBAATag(N) {}
Location getWithNewPtr(const Value *NewPtr) const {
Location Copy(*this);
Copy.Ptr = NewPtr;
return Copy;
}
Location getWithNewSize(uint64_t NewSize) const {
Location Copy(*this);
Copy.Size = NewSize;
return Copy;
}
Location getWithoutTBAATag() const {
Location Copy(*this);
Copy.TBAATag = 0;
return Copy;
}
};
/// getLocation - Fill in Loc with information about the memory reference by
/// the given instruction.
Location getLocation(const LoadInst *LI);
Location getLocation(const StoreInst *SI);
Location getLocation(const VAArgInst *VI);
Location getLocation(const AtomicCmpXchgInst *CXI);
Location getLocation(const AtomicRMWInst *RMWI);
static Location getLocationForSource(const MemTransferInst *MTI);
static Location getLocationForDest(const MemIntrinsic *MI);
/// Alias analysis result - Either we know for sure that it does not alias, we
/// know for sure it must alias, or we don't know anything: The two pointers
/// _might_ alias. This enum is designed so you can do things like:
/// if (AA.alias(P1, P2)) { ... }
/// to check to see if two pointers might alias.
///
/// See docs/AliasAnalysis.html for more information on the specific meanings
/// of these values.
///
enum AliasResult {
NoAlias = 0, ///< No dependencies.
MayAlias, ///< Anything goes.
PartialAlias, ///< Pointers differ, but pointees overlap.
MustAlias ///< Pointers are equal.
};
/// alias - The main low level interface to the alias analysis implementation.
/// Returns an AliasResult indicating whether the two pointers are aliased to
/// each other. This is the interface that must be implemented by specific
/// alias analysis implementations.
virtual AliasResult alias(const Location &LocA, const Location &LocB);
/// alias - A convenience wrapper.
AliasResult alias(const Value *V1, uint64_t V1Size,
const Value *V2, uint64_t V2Size) {
return alias(Location(V1, V1Size), Location(V2, V2Size));
}
/// alias - A convenience wrapper.
AliasResult alias(const Value *V1, const Value *V2) {
return alias(V1, UnknownSize, V2, UnknownSize);
}
/// isNoAlias - A trivial helper function to check to see if the specified
/// pointers are no-alias.
bool isNoAlias(const Location &LocA, const Location &LocB) {
return alias(LocA, LocB) == NoAlias;
}
/// isNoAlias - A convenience wrapper.
bool isNoAlias(const Value *V1, uint64_t V1Size,
const Value *V2, uint64_t V2Size) {
return isNoAlias(Location(V1, V1Size), Location(V2, V2Size));
}
/// isNoAlias - A convenience wrapper.
bool isNoAlias(const Value *V1, const Value *V2) {
return isNoAlias(Location(V1), Location(V2));
}
/// isMustAlias - A convenience wrapper.
bool isMustAlias(const Location &LocA, const Location &LocB) {
return alias(LocA, LocB) == MustAlias;
}
/// isMustAlias - A convenience wrapper.
bool isMustAlias(const Value *V1, const Value *V2) {
return alias(V1, 1, V2, 1) == MustAlias;
}
/// pointsToConstantMemory - If the specified memory location is
/// known to be constant, return true. If OrLocal is true and the
/// specified memory location is known to be "local" (derived from
/// an alloca), return true. Otherwise return false.
virtual bool pointsToConstantMemory(const Location &Loc,
bool OrLocal = false);
/// pointsToConstantMemory - A convenient wrapper.
bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
return pointsToConstantMemory(Location(P), OrLocal);
}
//===--------------------------------------------------------------------===//
/// Simple mod/ref information...
///
/// ModRefResult - Represent the result of a mod/ref query. Mod and Ref are
/// bits which may be or'd together.
///
enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
/// These values define additional bits used to define the
/// ModRefBehavior values.
enum { Nowhere = 0, ArgumentPointees = 4, Anywhere = 8 | ArgumentPointees };
/// ModRefBehavior - Summary of how a function affects memory in the program.
/// Loads from constant globals are not considered memory accesses for this
/// interface. Also, functions may freely modify stack space local to their
/// invocation without having to report it through these interfaces.
enum ModRefBehavior {
/// DoesNotAccessMemory - This function does not perform any non-local loads
/// or stores to memory.
///
/// This property corresponds to the GCC 'const' attribute.
/// This property corresponds to the LLVM IR 'readnone' attribute.
/// This property corresponds to the IntrNoMem LLVM intrinsic flag.
DoesNotAccessMemory = Nowhere | NoModRef,
/// OnlyReadsArgumentPointees - The only memory references in this function
/// (if it has any) are non-volatile loads from objects pointed to by its
/// pointer-typed arguments, with arbitrary offsets.
///
/// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
OnlyReadsArgumentPointees = ArgumentPointees | Ref,
/// OnlyAccessesArgumentPointees - The only memory references in this
/// function (if it has any) are non-volatile loads and stores from objects
/// pointed to by its pointer-typed arguments, with arbitrary offsets.
///
/// This property corresponds to the IntrReadWriteArgMem LLVM intrinsic flag.
OnlyAccessesArgumentPointees = ArgumentPointees | ModRef,
/// OnlyReadsMemory - This function does not perform any non-local stores or
/// volatile loads, but may read from any memory location.
///
/// This property corresponds to the GCC 'pure' attribute.
/// This property corresponds to the LLVM IR 'readonly' attribute.
/// This property corresponds to the IntrReadMem LLVM intrinsic flag.
OnlyReadsMemory = Anywhere | Ref,
/// UnknownModRefBehavior - This indicates that the function could not be
/// classified into one of the behaviors above.
UnknownModRefBehavior = Anywhere | ModRef
};
/// getModRefBehavior - Return the behavior when calling the given call site.
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
/// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known.
virtual ModRefBehavior getModRefBehavior(const Function *F);
/// doesNotAccessMemory - If the specified call is known to never read or
/// write memory, return true. If the call only reads from known-constant
/// memory, it is also legal to return true. Calls that unwind the stack
/// are legal for this predicate.
///
/// Many optimizations (such as CSE and LICM) can be performed on such calls
/// without worrying about aliasing properties, and many calls have this
/// property (e.g. calls to 'sin' and 'cos').
///
/// This property corresponds to the GCC 'const' attribute.
///
bool doesNotAccessMemory(ImmutableCallSite CS) {
return getModRefBehavior(CS) == DoesNotAccessMemory;
}
/// doesNotAccessMemory - If the specified function is known to never read or
/// write memory, return true. For use when the call site is not known.
///
bool doesNotAccessMemory(const Function *F) {
return getModRefBehavior(F) == DoesNotAccessMemory;
}
/// onlyReadsMemory - If the specified call is known to only read from
/// non-volatile memory (or not access memory at all), return true. Calls
/// that unwind the stack are legal for this predicate.
///
/// This property allows many common optimizations to be performed in the
/// absence of interfering store instructions, such as CSE of strlen calls.
///
/// This property corresponds to the GCC 'pure' attribute.
///
bool onlyReadsMemory(ImmutableCallSite CS) {
return onlyReadsMemory(getModRefBehavior(CS));
}
/// onlyReadsMemory - If the specified function is known to only read from
/// non-volatile memory (or not access memory at all), return true. For use
/// when the call site is not known.
///
bool onlyReadsMemory(const Function *F) {
return onlyReadsMemory(getModRefBehavior(F));
}
/// onlyReadsMemory - Return true if functions with the specified behavior are
/// known to only read from non-volatile memory (or not access memory at all).
///
static bool onlyReadsMemory(ModRefBehavior MRB) {
return !(MRB & Mod);
}
/// onlyAccessesArgPointees - Return true if functions with the specified
/// behavior are known to read and write at most from objects pointed to by
/// their pointer-typed arguments (with arbitrary offsets).
///
static bool onlyAccessesArgPointees(ModRefBehavior MRB) {
return !(MRB & Anywhere & ~ArgumentPointees);
}
/// doesAccessArgPointees - Return true if functions with the specified
/// behavior are known to potentially read or write from objects pointed
/// to be their pointer-typed arguments (with arbitrary offsets).
///
static bool doesAccessArgPointees(ModRefBehavior MRB) {
return (MRB & ModRef) && (MRB & ArgumentPointees);
}
/// getModRefInfo - Return information about whether or not an instruction may
/// read or write the specified memory location. An instruction
/// that doesn't read or write memory may be trivially LICM'd for example.
ModRefResult getModRefInfo(const Instruction *I,
const Location &Loc) {
switch (I->getOpcode()) {
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc);
case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc);
case Instruction::AtomicCmpXchg:
return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
case Instruction::AtomicRMW:
return getModRefInfo((const AtomicRMWInst*)I, Loc);
case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
default: return NoModRef;
}
}
/// getModRefInfo - A convenience wrapper.
ModRefResult getModRefInfo(const Instruction *I,
const Value *P, uint64_t Size) {
return getModRefInfo(I, Location(P, Size));
}
/// getModRefInfo (for call sites) - Return information about whether
/// a particular call site modifies or reads the specified memory location.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc);
/// getModRefInfo (for call sites) - A convenience wrapper.
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, uint64_t Size) {
return getModRefInfo(CS, Location(P, Size));
}
/// getModRefInfo (for calls) - Return information about whether
/// a particular call modifies or reads the specified memory location.
ModRefResult getModRefInfo(const CallInst *C, const Location &Loc) {
return getModRefInfo(ImmutableCallSite(C), Loc);
}
/// getModRefInfo (for calls) - A convenience wrapper.
ModRefResult getModRefInfo(const CallInst *C, const Value *P, uint64_t Size) {
return getModRefInfo(C, Location(P, Size));
}
/// getModRefInfo (for invokes) - Return information about whether
/// a particular invoke modifies or reads the specified memory location.
ModRefResult getModRefInfo(const InvokeInst *I,
const Location &Loc) {
return getModRefInfo(ImmutableCallSite(I), Loc);
}
/// getModRefInfo (for invokes) - A convenience wrapper.
ModRefResult getModRefInfo(const InvokeInst *I,
const Value *P, uint64_t Size) {
return getModRefInfo(I, Location(P, Size));
}
/// getModRefInfo (for loads) - Return information about whether
/// a particular load modifies or reads the specified memory location.
ModRefResult getModRefInfo(const LoadInst *L, const Location &Loc);
/// getModRefInfo (for loads) - A convenience wrapper.
ModRefResult getModRefInfo(const LoadInst *L, const Value *P, uint64_t Size) {
return getModRefInfo(L, Location(P, Size));
}
/// getModRefInfo (for stores) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const StoreInst *S, const Location &Loc);
/// getModRefInfo (for stores) - A convenience wrapper.
ModRefResult getModRefInfo(const StoreInst *S, const Value *P, uint64_t Size){
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for fences) - Return information about whether
/// a particular store modifies or reads the specified memory location.
ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) {
// Conservatively correct. (We could possibly be a bit smarter if
// Loc is a alloca that doesn't escape.)
return ModRef;
}
/// getModRefInfo (for fences) - A convenience wrapper.
ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){
return getModRefInfo(S, Location(P, Size));
}
/// getModRefInfo (for cmpxchges) - Return information about whether
/// a particular cmpxchg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc);
/// getModRefInfo (for cmpxchges) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX,
const Value *P, unsigned Size) {
return getModRefInfo(CX, Location(P, Size));
}
/// getModRefInfo (for atomicrmws) - Return information about whether
/// a particular atomicrmw modifies or reads the specified memory location.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc);
/// getModRefInfo (for atomicrmws) - A convenience wrapper.
ModRefResult getModRefInfo(const AtomicRMWInst *RMW,
const Value *P, unsigned Size) {
return getModRefInfo(RMW, Location(P, Size));
}
/// getModRefInfo (for va_args) - Return information about whether
/// a particular va_arg modifies or reads the specified memory location.
ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc);
/// getModRefInfo (for va_args) - A convenience wrapper.
ModRefResult getModRefInfo(const VAArgInst* I, const Value* P, uint64_t Size){
return getModRefInfo(I, Location(P, Size));
}
/// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. See
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
/// for details.
virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2);
/// callCapturesBefore - Return information about whether a particular call
/// site modifies or reads the specified memory location.
ModRefResult callCapturesBefore(const Instruction *I,
const AliasAnalysis::Location &MemLoc,
DominatorTree *DT);
/// callCapturesBefore - A convenience wrapper.
ModRefResult callCapturesBefore(const Instruction *I, const Value *P,
uint64_t Size, DominatorTree *DT) {
return callCapturesBefore(I, Location(P, Size), DT);
}
//===--------------------------------------------------------------------===//
/// Higher level methods for querying mod/ref information.
///
/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
bool canBasicBlockModify(const BasicBlock &BB, const Location &Loc);
/// canBasicBlockModify - A convenience wrapper.
bool canBasicBlockModify(const BasicBlock &BB, const Value *P, uint64_t Size){
return canBasicBlockModify(BB, Location(P, Size));
}
/// canInstructionRangeModify - Return true if it is possible for the
/// execution of the specified instructions to modify the value pointed to by
/// Ptr. The instructions to consider are all of the instructions in the
/// range of [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block.
bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
const Location &Loc);
/// canInstructionRangeModify - A convenience wrapper.
bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
const Value *Ptr, uint64_t Size) {
return canInstructionRangeModify(I1, I2, Location(Ptr, Size));
}
//===--------------------------------------------------------------------===//
/// Methods that clients should call when they transform the program to allow
/// alias analyses to update their internal data structures. Note that these
/// methods may be called on any instruction, regardless of whether or not
/// they have pointer-analysis implications.
///
/// deleteValue - This method should be called whenever an LLVM Value is
/// deleted from the program, for example when an instruction is found to be
/// redundant and is eliminated.
///
virtual void deleteValue(Value *V);
/// copyValue - This method should be used whenever a preexisting value in the
/// program is copied or cloned, introducing a new value. Note that analysis
/// implementations should tolerate clients that use this method to introduce
/// the same value multiple times: if the analysis already knows about a
/// value, it should ignore the request.
///
virtual void copyValue(Value *From, Value *To);
/// addEscapingUse - This method should be used whenever an escaping use is
/// added to a pointer value. Analysis implementations may either return
/// conservative responses for that value in the future, or may recompute
/// some or all internal state to continue providing precise responses.
///
/// Escaping uses are considered by anything _except_ the following:
/// - GEPs or bitcasts of the pointer
/// - Loads through the pointer
/// - Stores through (but not of) the pointer
virtual void addEscapingUse(Use &U);
/// replaceWithNewValue - This method is the obvious combination of the two
/// above, and it provided as a helper to simplify client code.
///
void replaceWithNewValue(Value *Old, Value *New) {
copyValue(Old, New);
deleteValue(Old);
}
};
// Specialize DenseMapInfo for Location.
template<>
struct DenseMapInfo<AliasAnalysis::Location> {
static inline AliasAnalysis::Location getEmptyKey() {
return
AliasAnalysis::Location(DenseMapInfo<const Value *>::getEmptyKey(),
0, 0);
}
static inline AliasAnalysis::Location getTombstoneKey() {
return
AliasAnalysis::Location(DenseMapInfo<const Value *>::getTombstoneKey(),
0, 0);
}
static unsigned getHashValue(const AliasAnalysis::Location &Val) {
return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
DenseMapInfo<const MDNode *>::getHashValue(Val.TBAATag);
}
static bool isEqual(const AliasAnalysis::Location &LHS,
const AliasAnalysis::Location &RHS) {
return LHS.Ptr == RHS.Ptr &&
LHS.Size == RHS.Size &&
LHS.TBAATag == RHS.TBAATag;
}
};
/// isNoAliasCall - Return true if this pointer is returned by a noalias
/// function.
bool isNoAliasCall(const Value *V);
/// isIdentifiedObject - Return true if this pointer refers to a distinct and
/// identifiable object. This returns true for:
/// Global Variables and Functions (but not Global Aliases)
/// Allocas
/// ByVal and NoAlias Arguments
/// NoAlias returns (e.g. calls to malloc)
///
bool isIdentifiedObject(const Value *V);
} // End llvm namespace
#endif

View File

@@ -0,0 +1,437 @@
//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines two classes: AliasSetTracker and AliasSet. These interface
// are used to classify a collection of pointer references into a maximal number
// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
// object refers to memory disjoint from the other sets.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
#define LLVM_ANALYSIS_ALIASSETTRACKER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/Support/ValueHandle.h"
#include <vector>
namespace llvm {
class AliasAnalysis;
class LoadInst;
class StoreInst;
class VAArgInst;
class AliasSetTracker;
class AliasSet;
class AliasSet : public ilist_node<AliasSet> {
friend class AliasSetTracker;
class PointerRec {
Value *Val; // The pointer this record corresponds to.
PointerRec **PrevInList, *NextInList;
AliasSet *AS;
uint64_t Size;
const MDNode *TBAAInfo;
public:
PointerRec(Value *V)
: Val(V), PrevInList(0), NextInList(0), AS(0), Size(0),
TBAAInfo(DenseMapInfo<const MDNode *>::getEmptyKey()) {}
Value *getValue() const { return Val; }
PointerRec *getNext() const { return NextInList; }
bool hasAliasSet() const { return AS != 0; }
PointerRec** setPrevInList(PointerRec **PIL) {
PrevInList = PIL;
return &NextInList;
}
void updateSizeAndTBAAInfo(uint64_t NewSize, const MDNode *NewTBAAInfo) {
if (NewSize > Size) Size = NewSize;
if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey())
// We don't have a TBAAInfo yet. Set it to NewTBAAInfo.
TBAAInfo = NewTBAAInfo;
else if (TBAAInfo != NewTBAAInfo)
// NewTBAAInfo conflicts with TBAAInfo.
TBAAInfo = DenseMapInfo<const MDNode *>::getTombstoneKey();
}
uint64_t getSize() const { return Size; }
/// getTBAAInfo - Return the TBAAInfo, or null if there is no
/// information or conflicting information.
const MDNode *getTBAAInfo() const {
// If we have missing or conflicting TBAAInfo, return null.
if (TBAAInfo == DenseMapInfo<const MDNode *>::getEmptyKey() ||
TBAAInfo == DenseMapInfo<const MDNode *>::getTombstoneKey())
return 0;
return TBAAInfo;
}
AliasSet *getAliasSet(AliasSetTracker &AST) {
assert(AS && "No AliasSet yet!");
if (AS->Forward) {
AliasSet *OldAS = AS;
AS = OldAS->getForwardedTarget(AST);
AS->addRef();
OldAS->dropRef(AST);
}
return AS;
}
void setAliasSet(AliasSet *as) {
assert(AS == 0 && "Already have an alias set!");
AS = as;
}
void eraseFromList() {
if (NextInList) NextInList->PrevInList = PrevInList;
*PrevInList = NextInList;
if (AS->PtrListEnd == &NextInList) {
AS->PtrListEnd = PrevInList;
assert(*AS->PtrListEnd == 0 && "List not terminated right!");
}
delete this;
}
};
PointerRec *PtrList, **PtrListEnd; // Doubly linked list of nodes.
AliasSet *Forward; // Forwarding pointer.
// All instructions without a specific address in this alias set.
std::vector<AssertingVH<Instruction> > UnknownInsts;
// RefCount - Number of nodes pointing to this AliasSet plus the number of
// AliasSets forwarding to it.
unsigned RefCount : 28;
/// AccessType - Keep track of whether this alias set merely refers to the
/// locations of memory, whether it modifies the memory, or whether it does
/// both. The lattice goes from "NoModRef" to either Refs or Mods, then to
/// ModRef as necessary.
///
enum AccessType {
NoModRef = 0, Refs = 1, // Ref = bit 1
Mods = 2, ModRef = 3 // Mod = bit 2
};
unsigned AccessTy : 2;
/// AliasType - Keep track the relationships between the pointers in the set.
/// Lattice goes from MustAlias to MayAlias.
///
enum AliasType {
MustAlias = 0, MayAlias = 1
};
unsigned AliasTy : 1;
// Volatile - True if this alias set contains volatile loads or stores.
bool Volatile : 1;
void addRef() { ++RefCount; }
void dropRef(AliasSetTracker &AST) {
assert(RefCount >= 1 && "Invalid reference count detected!");
if (--RefCount == 0)
removeFromTracker(AST);
}
Instruction *getUnknownInst(unsigned i) const {
assert(i < UnknownInsts.size());
return UnknownInsts[i];
}
public:
/// Accessors...
bool isRef() const { return AccessTy & Refs; }
bool isMod() const { return AccessTy & Mods; }
bool isMustAlias() const { return AliasTy == MustAlias; }
bool isMayAlias() const { return AliasTy == MayAlias; }
// isVolatile - Return true if this alias set contains volatile loads or
// stores.
bool isVolatile() const { return Volatile; }
/// isForwardingAliasSet - Return true if this alias set should be ignored as
/// part of the AliasSetTracker object.
bool isForwardingAliasSet() const { return Forward; }
/// mergeSetIn - Merge the specified alias set into this alias set...
///
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
// Alias Set iteration - Allow access to all of the pointer which are part of
// this alias set...
class iterator;
iterator begin() const { return iterator(PtrList); }
iterator end() const { return iterator(); }
bool empty() const { return PtrList == 0; }
void print(raw_ostream &OS) const;
void dump() const;
/// Define an iterator for alias sets... this is just a forward iterator.
class iterator : public std::iterator<std::forward_iterator_tag,
PointerRec, ptrdiff_t> {
PointerRec *CurNode;
public:
explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}
bool operator==(const iterator& x) const {
return CurNode == x.CurNode;
}
bool operator!=(const iterator& x) const { return !operator==(x); }
const iterator &operator=(const iterator &I) {
CurNode = I.CurNode;
return *this;
}
value_type &operator*() const {
assert(CurNode && "Dereferencing AliasSet.end()!");
return *CurNode;
}
value_type *operator->() const { return &operator*(); }
Value *getPointer() const { return CurNode->getValue(); }
uint64_t getSize() const { return CurNode->getSize(); }
const MDNode *getTBAAInfo() const { return CurNode->getTBAAInfo(); }
iterator& operator++() { // Preincrement
assert(CurNode && "Advancing past AliasSet.end()!");
CurNode = CurNode->getNext();
return *this;
}
iterator operator++(int) { // Postincrement
iterator tmp = *this; ++*this; return tmp;
}
};
private:
// Can only be created by AliasSetTracker. Also, ilist creates one
// to serve as a sentinel.
friend struct ilist_sentinel_traits<AliasSet>;
AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
}
AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION;
void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION;
PointerRec *getSomePointer() const {
return PtrList;
}
/// getForwardedTarget - Return the real alias set this represents. If this
/// has been merged with another set and is forwarding, return the ultimate
/// destination set. This also implements the union-find collapsing as well.
AliasSet *getForwardedTarget(AliasSetTracker &AST) {
if (!Forward) return this;
AliasSet *Dest = Forward->getForwardedTarget(AST);
if (Dest != Forward) {
Dest->addRef();
Forward->dropRef(AST);
Forward = Dest;
}
return Dest;
}
void removeFromTracker(AliasSetTracker &AST);
void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
const MDNode *TBAAInfo,
bool KnownMustAlias = false);
void addUnknownInst(Instruction *I, AliasAnalysis &AA);
void removeUnknownInst(Instruction *I) {
for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
if (UnknownInsts[i] == I) {
UnknownInsts[i] = UnknownInsts.back();
UnknownInsts.pop_back();
--i; --e; // Revisit the moved entry.
}
}
void setVolatile() { Volatile = true; }
public:
/// aliasesPointer - Return true if the specified pointer "may" (or must)
/// alias one of the members in the set.
///
bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo,
AliasAnalysis &AA) const;
bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const;
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
AS.print(OS);
return OS;
}
class AliasSetTracker {
/// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
/// notified whenever a Value is deleted.
class ASTCallbackVH : public CallbackVH {
AliasSetTracker *AST;
virtual void deleted();
virtual void allUsesReplacedWith(Value *);
public:
ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
ASTCallbackVH &operator=(Value *V);
};
/// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to
/// compare and hash the value handle.
struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
AliasAnalysis &AA;
ilist<AliasSet> AliasSets;
typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
ASTCallbackVHDenseMapInfo>
PointerMapType;
// Map from pointers to their node
PointerMapType PointerMap;
public:
/// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
/// the specified alias analysis object to disambiguate load and store
/// addresses.
explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
~AliasSetTracker() { clear(); }
/// add methods - These methods are used to add different types of
/// instructions to the alias sets. Adding a new instruction can result in
/// one of three actions happening:
///
/// 1. If the instruction doesn't alias any other sets, create a new set.
/// 2. If the instruction aliases exactly one set, add it to the set
/// 3. If the instruction aliases multiple sets, merge the sets, and add
/// the instruction to the result.
///
/// These methods return true if inserting the instruction resulted in the
/// addition of a new alias set (i.e., the pointer did not alias anything).
///
bool add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); // Add a location
bool add(LoadInst *LI);
bool add(StoreInst *SI);
bool add(VAArgInst *VAAI);
bool add(Instruction *I); // Dispatch to one of the other add methods...
void add(BasicBlock &BB); // Add all instructions in basic block
void add(const AliasSetTracker &AST); // Add alias relations from another AST
bool addUnknown(Instruction *I);
/// remove methods - These methods are used to remove all entries that might
/// be aliased by the specified instruction. These methods return true if any
/// alias sets were eliminated.
// Remove a location
bool remove(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo);
bool remove(LoadInst *LI);
bool remove(StoreInst *SI);
bool remove(VAArgInst *VAAI);
bool remove(Instruction *I);
void remove(AliasSet &AS);
bool removeUnknown(Instruction *I);
void clear();
/// getAliasSets - Return the alias sets that are active.
///
const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
/// getAliasSetForPointer - Return the alias set that the specified pointer
/// lives in. If the New argument is non-null, this method sets the value to
/// true if a new alias set is created to contain the pointer (because the
/// pointer didn't alias anything).
AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
const MDNode *TBAAInfo,
bool *New = 0);
/// getAliasSetForPointerIfExists - Return the alias set containing the
/// location specified if one exists, otherwise return null.
AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size,
const MDNode *TBAAInfo) {
return findAliasSetForPointer(P, Size, TBAAInfo);
}
/// containsPointer - Return true if the specified location is represented by
/// this alias set, false otherwise. This does not modify the AST object or
/// alias sets.
bool containsPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo) const;
/// getAliasAnalysis - Return the underlying alias analysis object used by
/// this tracker.
AliasAnalysis &getAliasAnalysis() const { return AA; }
/// deleteValue method - This method is used to remove a pointer value from
/// the AliasSetTracker entirely. It should be used when an instruction is
/// deleted from the program to update the AST. If you don't use this, you
/// would have dangling pointers to deleted instructions.
///
void deleteValue(Value *PtrVal);
/// copyValue - This method should be used whenever a preexisting value in the
/// program is copied or cloned, introducing a new value. Note that it is ok
/// for clients that use this method to introduce the same value multiple
/// times: if the tracker already knows about a value, it will ignore the
/// request.
///
void copyValue(Value *From, Value *To);
typedef ilist<AliasSet>::iterator iterator;
typedef ilist<AliasSet>::const_iterator const_iterator;
const_iterator begin() const { return AliasSets.begin(); }
const_iterator end() const { return AliasSets.end(); }
iterator begin() { return AliasSets.begin(); }
iterator end() { return AliasSets.end(); }
void print(raw_ostream &OS) const;
void dump() const;
private:
friend class AliasSet;
void removeAliasSet(AliasSet *AS);
// getEntryFor - Just like operator[] on the map, except that it creates an
// entry for the pointer if it doesn't already exist.
AliasSet::PointerRec &getEntryFor(Value *V) {
AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
if (Entry == 0)
Entry = new AliasSet::PointerRec(V);
return *Entry;
}
AliasSet &addPointer(Value *P, uint64_t Size, const MDNode *TBAAInfo,
AliasSet::AccessType E,
bool &NewSet) {
NewSet = false;
AliasSet &AS = getAliasSetForPointer(P, Size, TBAAInfo, &NewSet);
AS.AccessTy |= E;
return AS;
}
AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size,
const MDNode *TBAAInfo);
AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
};
inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
AST.print(OS);
return OS;
}
} // End llvm namespace
#endif

View File

@@ -0,0 +1,342 @@
//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Shared implementation of BlockFrequency for IR and Machine Instructions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
#include <vector>
namespace llvm {
class BlockFrequencyInfo;
class MachineBlockFrequencyInfo;
/// BlockFrequencyImpl implements block frequency algorithm for IR and
/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
/// for the entry block and then propagates frequencies using branch weights
/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
/// algorithm can find "backedges" by itself.
template<class BlockT, class FunctionT, class BlockProbInfoT>
class BlockFrequencyImpl {
DenseMap<const BlockT *, BlockFrequency> Freqs;
BlockProbInfoT *BPI;
FunctionT *Fn;
typedef GraphTraits< Inverse<BlockT *> > GT;
const uint32_t EntryFreq;
std::string getBlockName(BasicBlock *BB) const {
return BB->getName().str();
}
std::string getBlockName(MachineBasicBlock *MBB) const {
std::string str;
raw_string_ostream ss(str);
ss << "BB#" << MBB->getNumber();
if (const BasicBlock *BB = MBB->getBasicBlock())
ss << " derived from LLVM BB " << BB->getName();
return ss.str();
}
void setBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] = Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
}
/// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
/// edge probability.
BlockFrequency getEdgeFreq(BlockT *Src, BlockT *Dst) const {
BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
return getBlockFreq(Src) * Prob;
}
/// incBlockFreq - Increase BB block frequency by FREQ.
///
void incBlockFreq(BlockT *BB, BlockFrequency Freq) {
Freqs[BB] += Freq;
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
<< " --> " << Freqs[BB] << "\n");
}
/// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
///
void divBlockFreq(BlockT *BB, BranchProbability Prob) {
uint64_t N = Prob.getNumerator();
assert(N && "Illegal division by zero!");
uint64_t D = Prob.getDenominator();
uint64_t Freq = (Freqs[BB].getFrequency() * D) / N;
// Should we assert it?
if (Freq > UINT32_MAX)
Freq = UINT32_MAX;
Freqs[BB] = BlockFrequency(Freq);
DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
<< ") --> " << Freqs[BB] << "\n");
}
// All blocks in postorder.
std::vector<BlockT *> POT;
// Map Block -> Position in reverse-postorder list.
DenseMap<BlockT *, unsigned> RPO;
// Cycle Probability for each bloch.
DenseMap<BlockT *, uint32_t> CycleProb;
// (reverse-)postorder traversal iterators.
typedef typename std::vector<BlockT *>::iterator pot_iterator;
typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
pot_iterator pot_begin() { return POT.begin(); }
pot_iterator pot_end() { return POT.end(); }
rpot_iterator rpot_begin() { return POT.rbegin(); }
rpot_iterator rpot_end() { return POT.rend(); }
rpot_iterator rpot_at(BlockT *BB) {
rpot_iterator I = rpot_begin();
unsigned idx = RPO[BB];
assert(idx);
std::advance(I, idx - 1);
assert(*I == BB);
return I;
}
/// isReachable - Returns if BB block is reachable from the entry.
///
bool isReachable(BlockT *BB) {
return RPO.count(BB);
}
/// isBackedge - Return if edge Src -> Dst is a backedge.
///
bool isBackedge(BlockT *Src, BlockT *Dst) {
assert(isReachable(Src));
assert(isReachable(Dst));
unsigned a = RPO[Src];
unsigned b = RPO[Dst];
return a >= b;
}
/// getSingleBlockPred - return single BB block predecessor or NULL if
/// BB has none or more predecessors.
BlockT *getSingleBlockPred(BlockT *BB) {
typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
if (PI == PE)
return 0;
BlockT *Pred = *PI;
++PI;
if (PI != PE)
return 0;
return Pred;
}
void doBlock(BlockT *BB, BlockT *LoopHead,
SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
setBlockFreq(BB, 0);
if (BB == LoopHead) {
setBlockFreq(BB, EntryFreq);
return;
}
if(BlockT *Pred = getSingleBlockPred(BB)) {
if (BlocksInLoop.count(Pred))
setBlockFreq(BB, getEdgeFreq(Pred, BB));
// TODO: else? irreducible, ignore it for now.
return;
}
bool isInLoop = false;
bool isLoopHead = false;
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
PI != PE; ++PI) {
BlockT *Pred = *PI;
if (isReachable(Pred) && isBackedge(Pred, BB)) {
isLoopHead = true;
} else if (BlocksInLoop.count(Pred)) {
incBlockFreq(BB, getEdgeFreq(Pred, BB));
isInLoop = true;
}
// TODO: else? irreducible.
}
if (!isInLoop)
return;
if (!isLoopHead)
return;
assert(EntryFreq >= CycleProb[BB]);
uint32_t CProb = CycleProb[BB];
uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1;
divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
}
/// doLoop - Propagate block frequency down through the loop.
void doLoop(BlockT *Head, BlockT *Tail) {
DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
<< getBlockName(Tail) << ")\n");
SmallPtrSet<BlockT *, 8> BlocksInLoop;
for (rpot_iterator I = rpot_at(Head), E = rpot_at(Tail); ; ++I) {
BlockT *BB = *I;
doBlock(BB, Head, BlocksInLoop);
BlocksInLoop.insert(BB);
if (I == E)
break;
}
// Compute loop's cyclic probability using backedges probabilities.
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
PI != PE; ++PI) {
BlockT *Pred = *PI;
assert(Pred);
if (isReachable(Pred) && isBackedge(Pred, Head)) {
uint64_t N = getEdgeFreq(Pred, Head).getFrequency();
uint64_t D = getBlockFreq(Head).getFrequency();
assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!");
uint64_t Res = (N * EntryFreq) / D;
assert(Res <= UINT32_MAX);
CycleProb[Head] += (uint32_t) Res;
DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res
<< " --> " << CycleProb[Head] << "\n");
}
}
}
friend class BlockFrequencyInfo;
friend class MachineBlockFrequencyInfo;
BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { }
void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
Fn = fn;
BPI = bpi;
// Clear everything.
RPO.clear();
POT.clear();
CycleProb.clear();
Freqs.clear();
BlockT *EntryBlock = fn->begin();
std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT));
unsigned RPOidx = 0;
for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
BlockT *BB = *I;
RPO[BB] = ++RPOidx;
DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
}
// Travel over all blocks in postorder.
for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
BlockT *BB = *I;
BlockT *LastTail = 0;
DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
for (typename GT::ChildIteratorType
PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
PI != PE; ++PI) {
BlockT *Pred = *PI;
if (isReachable(Pred) && isBackedge(Pred, BB)
&& (!LastTail || RPO[Pred] > RPO[LastTail]))
LastTail = Pred;
}
if (LastTail)
doLoop(BB, LastTail);
}
// At the end assume the whole function as a loop, and travel over it once
// again.
doLoop(*(rpot_begin()), *(pot_begin()));
}
public:
/// getBlockFreq - Return block frequency. Return 0 if we don't have it.
BlockFrequency getBlockFreq(const BlockT *BB) const {
typename DenseMap<const BlockT *, BlockFrequency>::const_iterator
I = Freqs.find(BB);
if (I != Freqs.end())
return I->second;
return 0;
}
void print(raw_ostream &OS) const {
OS << "\n\n---- Block Freqs ----\n";
for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
BlockT *BB = I++;
OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
for (typename GraphTraits<BlockT *>::ChildIteratorType
SI = GraphTraits<BlockT *>::child_begin(BB),
SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
BlockT *Succ = *SI;
OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ)
<< " = " << getEdgeFreq(BB, Succ) << "\n";
}
}
}
void dump() const {
print(dbgs());
}
};
}
#endif

View File

@@ -0,0 +1,55 @@
//========-------- BlockFrequencyInfo.h - Block Frequency Analysis -------========//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loops should be simplified before this analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H
#include "llvm/Pass.h"
#include "llvm/Support/BlockFrequency.h"
#include <climits>
namespace llvm {
class BranchProbabilityInfo;
template<class BlockT, class FunctionT, class BranchProbInfoT>
class BlockFrequencyImpl;
/// BlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate
/// IR basic block frequencies.
class BlockFrequencyInfo : public FunctionPass {
BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
public:
static char ID;
BlockFrequencyInfo();
~BlockFrequencyInfo();
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
void print(raw_ostream &O, const Module *M) const;
/// getblockFreq - Return block frequency. Return 0 if we don't have the
/// information. Please note that initial frequency is equal to 1024. It means
/// that we should not rely on the value itself, but only on the comparison to
/// the other block frequencies. We do this to avoid using of floating points.
///
BlockFrequency getBlockFreq(const BasicBlock *BB) const;
};
}
#endif

View File

@@ -0,0 +1,148 @@
//===--- BranchProbabilityInfo.h - Branch Probability Analysis --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is used to evaluate branch probabilties.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
namespace llvm {
class LoopInfo;
class raw_ostream;
/// \brief Analysis pass providing branch probability information.
///
/// This is a function analysis pass which provides information on the relative
/// probabilities of each "edge" in the function's CFG where such an edge is
/// defined by a pair (PredBlock and an index in the successors). The
/// probability of an edge from one block is always relative to the
/// probabilities of other edges from the block. The probabilites of all edges
/// from a block sum to exactly one (100%).
/// We use a pair (PredBlock and an index in the successors) to uniquely
/// identify an edge, since we can have multiple edges from Src to Dst.
/// As an example, we can have a switch which jumps to Dst with value 0 and
/// value 10.
class BranchProbabilityInfo : public FunctionPass {
public:
static char ID;
BranchProbabilityInfo() : FunctionPass(ID) {
initializeBranchProbabilityInfoPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnFunction(Function &F);
void print(raw_ostream &OS, const Module *M = 0) const;
/// \brief Get an edge's probability, relative to other out-edges of the Src.
///
/// This routine provides access to the fractional probability between zero
/// (0%) and one (100%) of this edge executing, relative to other edges
/// leaving the 'Src' block. The returned probability is never zero, and can
/// only be one if the source block has only one successor.
BranchProbability getEdgeProbability(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the probability of going from Src to Dst.
///
/// It returns the sum of all probabilities for edges from Src to Dst.
BranchProbability getEdgeProbability(const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Test if an edge is hot relative to other out-edges of the Src.
///
/// Check whether this edge out of the source block is 'hot'. We define hot
/// as having a relative probability >= 80%.
bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Retrieve the hot successor of a block if one exists.
///
/// Given a basic block, look through its successors and if one exists for
/// which \see isEdgeHot would return true, return that successor block.
BasicBlock *getHotSucc(BasicBlock *BB) const;
/// \brief Print an edge's probability.
///
/// Retrieves an edge's probability similarly to \see getEdgeProbability, but
/// then prints that probability to the provided stream. That stream is then
/// returned.
raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
const BasicBlock *Dst) const;
/// \brief Get the raw edge weight calculated for the edge.
///
/// This returns the raw edge weight. It is guaranteed to fall between 1 and
/// UINT32_MAX. Note that the raw edge weight is not meaningful in isolation.
/// This interface should be very carefully, and primarily by routines that
/// are updating the analysis by later calling setEdgeWeight.
uint32_t getEdgeWeight(const BasicBlock *Src,
unsigned IndexInSuccessors) const;
/// \brief Get the raw edge weight calculated for the block pair.
///
/// This returns the sum of all raw edge weights from Src to Dst.
/// It is guaranteed to fall between 1 and UINT32_MAX.
uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const;
/// \brief Set the raw edge weight for a given edge.
///
/// This allows a pass to explicitly set the edge weight for an edge. It can
/// be used when updating the CFG to update and preserve the branch
/// probability information. Read the implementation of how these edge
/// weights are calculated carefully before using!
void setEdgeWeight(const BasicBlock *Src, unsigned IndexInSuccessors,
uint32_t Weight);
private:
// Since we allow duplicate edges from one basic block to another, we use
// a pair (PredBlock and an index in the successors) to specify an edge.
typedef std::pair<const BasicBlock *, unsigned> Edge;
// Default weight value. Used when we don't have information about the edge.
// TODO: DEFAULT_WEIGHT makes sense during static predication, when none of
// the successors have a weight yet. But it doesn't make sense when providing
// weight to an edge that may have siblings with non-zero weights. This can
// be handled various ways, but it's probably fine for an edge with unknown
// weight to just "inherit" the non-zero weight of an adjacent successor.
static const uint32_t DEFAULT_WEIGHT = 16;
DenseMap<Edge, uint32_t> Weights;
/// \brief Handle to the LoopInfo analysis.
LoopInfo *LI;
/// \brief Track the last function we run over for printing.
Function *LastF;
/// \brief Track the set of blocks directly succeeded by a returning block.
SmallPtrSet<BasicBlock *, 16> PostDominatedByUnreachable;
/// \brief Get sum of the block successors' weights.
uint32_t getSumForBlock(const BasicBlock *BB) const;
bool calcUnreachableHeuristics(BasicBlock *BB);
bool calcMetadataWeights(BasicBlock *BB);
bool calcPointerHeuristics(BasicBlock *BB);
bool calcLoopBranchHeuristics(BasicBlock *BB);
bool calcZeroHeuristics(BasicBlock *BB);
bool calcFloatingPointHeuristics(BasicBlock *BB);
bool calcInvokeHeuristics(BasicBlock *BB);
};
}
#endif

View File

@@ -0,0 +1,114 @@
//===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines external functions that can be called to explicitly
// instantiate the CFG printer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
#include "llvm/Assembly/Writer.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/GraphWriter.h"
namespace llvm {
template<>
struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
static std::string getGraphName(const Function *F) {
return "CFG for '" + F->getName().str() + "' function";
}
static std::string getSimpleNodeLabel(const BasicBlock *Node,
const Function *) {
if (!Node->getName().empty())
return Node->getName().str();
std::string Str;
raw_string_ostream OS(Str);
WriteAsOperand(OS, Node, false);
return OS.str();
}
static std::string getCompleteNodeLabel(const BasicBlock *Node,
const Function *) {
std::string Str;
raw_string_ostream OS(Str);
if (Node->getName().empty()) {
WriteAsOperand(OS, Node, false);
OS << ":";
}
OS << *Node;
std::string OutStr = OS.str();
if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
// Process string output to make it nicer...
for (unsigned i = 0; i != OutStr.length(); ++i)
if (OutStr[i] == '\n') { // Left justify
OutStr[i] = '\\';
OutStr.insert(OutStr.begin()+i+1, 'l');
} else if (OutStr[i] == ';') { // Delete comments!
unsigned Idx = OutStr.find('\n', i+1); // Find end of line
OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
--i;
}
return OutStr;
}
std::string getNodeLabel(const BasicBlock *Node,
const Function *Graph) {
if (isSimple())
return getSimpleNodeLabel(Node, Graph);
else
return getCompleteNodeLabel(Node, Graph);
}
static std::string getEdgeSourceLabel(const BasicBlock *Node,
succ_const_iterator I) {
// Label source of conditional branches with "T" or "F"
if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
if (BI->isConditional())
return (I == succ_begin(Node)) ? "T" : "F";
// Label source of switch edges with the associated value.
if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
unsigned SuccNo = I.getSuccessorIndex();
if (SuccNo == 0) return "def";
std::string Str;
raw_string_ostream OS(Str);
SwitchInst::ConstCaseIt Case =
SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
OS << Case.getCaseValue()->getValue();
return OS.str();
}
return "";
}
};
} // End llvm namespace
namespace llvm {
class FunctionPass;
FunctionPass *createCFGPrinterPass ();
FunctionPass *createCFGOnlyPrinterPass ();
} // End llvm namespace
#endif

View File

@@ -0,0 +1,378 @@
//===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This interface is used to build and manipulate a call graph, which is a very
// useful tool for interprocedural optimization.
//
// Every function in a module is represented as a node in the call graph. The
// callgraph node keeps track of which functions the are called by the function
// corresponding to the node.
//
// A call graph may contain nodes where the function that they correspond to is
// null. These 'external' nodes are used to represent control flow that is not
// represented (or analyzable) in the module. In particular, this analysis
// builds one external node such that:
// 1. All functions in the module without internal linkage will have edges
// from this external node, indicating that they could be called by
// functions outside of the module.
// 2. All functions whose address is used for something more than a direct
// call, for example being stored into a memory location will also have an
// edge from this external node. Since they may be called by an unknown
// caller later, they must be tracked as such.
//
// There is a second external node added for calls that leave this module.
// Functions have a call edge to the external node iff:
// 1. The function is external, reflecting the fact that they could call
// anything without internal linkage or that has its address taken.
// 2. The function contains an indirect function call.
//
// As an extension in the future, there may be multiple nodes with a null
// function. These will be used when we can prove (through pointer analysis)
// that an indirect call site can call only a specific set of functions.
//
// Because of these properties, the CallGraph captures a conservative superset
// of all of the caller-callee relationships, which is useful for
// transformations.
//
// The CallGraph class also attempts to figure out what the root of the
// CallGraph is, which it currently does by looking for a function named 'main'.
// If no function named 'main' is found, the external node is used as the entry
// node, reflecting the fact that any function without internal linkage could
// be called into (which is common for libraries).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CALLGRAPH_H
#define LLVM_ANALYSIS_CALLGRAPH_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/IncludeFile.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
class Function;
class Module;
class CallGraphNode;
//===----------------------------------------------------------------------===//
// CallGraph class definition
//
class CallGraph {
protected:
Module *Mod; // The module this call graph represents
typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
FunctionMapTy FunctionMap; // Map from a function to its node
public:
static char ID; // Class identification, replacement for typeinfo
//===---------------------------------------------------------------------
// Accessors.
//
typedef FunctionMapTy::iterator iterator;
typedef FunctionMapTy::const_iterator const_iterator;
/// getModule - Return the module the call graph corresponds to.
///
Module &getModule() const { return *Mod; }
inline iterator begin() { return FunctionMap.begin(); }
inline iterator end() { return FunctionMap.end(); }
inline const_iterator begin() const { return FunctionMap.begin(); }
inline const_iterator end() const { return FunctionMap.end(); }
// Subscripting operators, return the call graph node for the provided
// function
inline const CallGraphNode *operator[](const Function *F) const {
const_iterator I = FunctionMap.find(F);
assert(I != FunctionMap.end() && "Function not in callgraph!");
return I->second;
}
inline CallGraphNode *operator[](const Function *F) {
const_iterator I = FunctionMap.find(F);
assert(I != FunctionMap.end() && "Function not in callgraph!");
return I->second;
}
/// Returns the CallGraphNode which is used to represent undetermined calls
/// into the callgraph. Override this if you want behavioral inheritance.
virtual CallGraphNode* getExternalCallingNode() const { return 0; }
virtual CallGraphNode* getCallsExternalNode() const { return 0; }
/// Return the root/main method in the module, or some other root node, such
/// as the externalcallingnode. Overload these if you behavioral
/// inheritance.
virtual CallGraphNode* getRoot() { return 0; }
virtual const CallGraphNode* getRoot() const { return 0; }
//===---------------------------------------------------------------------
// Functions to keep a call graph up to date with a function that has been
// modified.
//
/// removeFunctionFromModule - Unlink the function from this module, returning
/// it. Because this removes the function from the module, the call graph
/// node is destroyed. This is only valid if the function does not call any
/// other functions (ie, there are no edges in it's CGN). The easiest way to
/// do this is to dropAllReferences before calling this.
///
Function *removeFunctionFromModule(CallGraphNode *CGN);
Function *removeFunctionFromModule(Function *F) {
return removeFunctionFromModule((*this)[F]);
}
/// getOrInsertFunction - This method is identical to calling operator[], but
/// it will insert a new CallGraphNode for the specified function if one does
/// not already exist.
CallGraphNode *getOrInsertFunction(const Function *F);
/// spliceFunction - Replace the function represented by this node by another.
/// This does not rescan the body of the function, so it is suitable when
/// splicing the body of one function to another while also updating all
/// callers from the old function to the new.
///
void spliceFunction(const Function *From, const Function *To);
//===---------------------------------------------------------------------
// Pass infrastructure interface glue code.
//
protected:
CallGraph() {}
public:
virtual ~CallGraph() { destroy(); }
/// initialize - Call this method before calling other methods,
/// re/initializes the state of the CallGraph.
///
void initialize(Module &M);
void print(raw_ostream &o, Module *) const;
void dump() const;
protected:
// destroy - Release memory for the call graph
virtual void destroy();
};
//===----------------------------------------------------------------------===//
// CallGraphNode class definition.
//
class CallGraphNode {
friend class CallGraph;
AssertingVH<Function> F;
// CallRecord - This is a pair of the calling instruction (a call or invoke)
// and the callgraph node being called.
public:
typedef std::pair<WeakVH, CallGraphNode*> CallRecord;
private:
std::vector<CallRecord> CalledFunctions;
/// NumReferences - This is the number of times that this CallGraphNode occurs
/// in the CalledFunctions array of this or other CallGraphNodes.
unsigned NumReferences;
CallGraphNode(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void operator=(const CallGraphNode &) LLVM_DELETED_FUNCTION;
void DropRef() { --NumReferences; }
void AddRef() { ++NumReferences; }
public:
typedef std::vector<CallRecord> CalledFunctionsVector;
// CallGraphNode ctor - Create a node for the specified function.
inline CallGraphNode(Function *f) : F(f), NumReferences(0) {}
~CallGraphNode() {
assert(NumReferences == 0 && "Node deleted while references remain");
}
//===---------------------------------------------------------------------
// Accessor methods.
//
typedef std::vector<CallRecord>::iterator iterator;
typedef std::vector<CallRecord>::const_iterator const_iterator;
// getFunction - Return the function that this call graph node represents.
Function *getFunction() const { return F; }
inline iterator begin() { return CalledFunctions.begin(); }
inline iterator end() { return CalledFunctions.end(); }
inline const_iterator begin() const { return CalledFunctions.begin(); }
inline const_iterator end() const { return CalledFunctions.end(); }
inline bool empty() const { return CalledFunctions.empty(); }
inline unsigned size() const { return (unsigned)CalledFunctions.size(); }
/// getNumReferences - Return the number of other CallGraphNodes in this
/// CallGraph that reference this node in their callee list.
unsigned getNumReferences() const { return NumReferences; }
// Subscripting operator - Return the i'th called function.
//
CallGraphNode *operator[](unsigned i) const {
assert(i < CalledFunctions.size() && "Invalid index");
return CalledFunctions[i].second;
}
/// dump - Print out this call graph node.
///
void dump() const;
void print(raw_ostream &OS) const;
//===---------------------------------------------------------------------
// Methods to keep a call graph up to date with a function that has been
// modified
//
/// removeAllCalledFunctions - As the name implies, this removes all edges
/// from this CallGraphNode to any functions it calls.
void removeAllCalledFunctions() {
while (!CalledFunctions.empty()) {
CalledFunctions.back().second->DropRef();
CalledFunctions.pop_back();
}
}
/// stealCalledFunctionsFrom - Move all the callee information from N to this
/// node.
void stealCalledFunctionsFrom(CallGraphNode *N) {
assert(CalledFunctions.empty() &&
"Cannot steal callsite information if I already have some");
std::swap(CalledFunctions, N->CalledFunctions);
}
/// addCalledFunction - Add a function to the list of functions called by this
/// one.
void addCalledFunction(CallSite CS, CallGraphNode *M) {
assert(!CS.getInstruction() ||
!CS.getCalledFunction() ||
!CS.getCalledFunction()->isIntrinsic());
CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
M->AddRef();
}
void removeCallEdge(iterator I) {
I->second->DropRef();
*I = CalledFunctions.back();
CalledFunctions.pop_back();
}
/// removeCallEdgeFor - This method removes the edge in the node for the
/// specified call site. Note that this method takes linear time, so it
/// should be used sparingly.
void removeCallEdgeFor(CallSite CS);
/// removeAnyCallEdgeTo - This method removes all call edges from this node
/// to the specified callee function. This takes more time to execute than
/// removeCallEdgeTo, so it should not be used unless necessary.
void removeAnyCallEdgeTo(CallGraphNode *Callee);
/// removeOneAbstractEdgeTo - Remove one edge associated with a null callsite
/// from this node to the specified callee function.
void removeOneAbstractEdgeTo(CallGraphNode *Callee);
/// replaceCallEdge - This method replaces the edge in the node for the
/// specified call site with a new one. Note that this method takes linear
/// time, so it should be used sparingly.
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
/// allReferencesDropped - This is a special function that should only be
/// used by the CallGraph class.
void allReferencesDropped() {
NumReferences = 0;
}
};
//===----------------------------------------------------------------------===//
// GraphTraits specializations for call graphs so that they can be treated as
// graphs by the generic graph algorithms.
//
// Provide graph traits for tranversing call graphs using standard graph
// traversals.
template <> struct GraphTraits<CallGraphNode*> {
typedef CallGraphNode NodeType;
typedef CallGraphNode::CallRecord CGNPairTy;
typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
static inline ChildIteratorType child_begin(NodeType *N) {
return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
}
static inline ChildIteratorType child_end (NodeType *N) {
return map_iterator(N->end(), CGNDerefFun(CGNDeref));
}
static CallGraphNode *CGNDeref(CGNPairTy P) {
return P.second;
}
};
template <> struct GraphTraits<const CallGraphNode*> {
typedef const CallGraphNode NodeType;
typedef NodeType::const_iterator ChildIteratorType;
static NodeType *getEntryNode(const CallGraphNode *CGN) { return CGN; }
static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
};
template<> struct GraphTraits<CallGraph*> : public GraphTraits<CallGraphNode*> {
static NodeType *getEntryNode(CallGraph *CGN) {
return CGN->getExternalCallingNode(); // Start at the external node!
}
typedef std::pair<const Function*, CallGraphNode*> PairTy;
typedef std::pointer_to_unary_function<PairTy, CallGraphNode&> DerefFun;
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<CallGraph::iterator, DerefFun> nodes_iterator;
static nodes_iterator nodes_begin(CallGraph *CG) {
return map_iterator(CG->begin(), DerefFun(CGdereference));
}
static nodes_iterator nodes_end (CallGraph *CG) {
return map_iterator(CG->end(), DerefFun(CGdereference));
}
static CallGraphNode &CGdereference(PairTy P) {
return *P.second;
}
};
template<> struct GraphTraits<const CallGraph*> :
public GraphTraits<const CallGraphNode*> {
static NodeType *getEntryNode(const CallGraph *CGN) {
return CGN->getExternalCallingNode();
}
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef CallGraph::const_iterator nodes_iterator;
static nodes_iterator nodes_begin(const CallGraph *CG) { return CG->begin(); }
static nodes_iterator nodes_end (const CallGraph *CG) { return CG->end(); }
};
} // End llvm namespace
// Make sure that any clients of this file link in CallGraph.cpp
FORCE_DEFINING_FILE_TO_BE_LINKED(CallGraph)
#endif

View File

@@ -0,0 +1,107 @@
//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the CallGraphSCCPass class, which is used for passes which
// are implemented as bottom-up traversals on the call graph. Because there may
// be cycles in the call graph, passes of this type operate on the call-graph in
// SCC order: that is, they process function bottom-up, except for recursive
// functions, which they process all at once.
//
// These passes are inherently interprocedural, and are required to keep the
// call graph up-to-date if they do anything which could modify it.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Pass.h"
namespace llvm {
class CallGraphNode;
class CallGraph;
class PMStack;
class CallGraphSCC;
class CallGraphSCCPass : public Pass {
public:
explicit CallGraphSCCPass(char &pid) : Pass(PT_CallGraphSCC, pid) {}
/// createPrinterPass - Get a pass that prints the Module
/// corresponding to a CallGraph.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
/// doInitialization - This method is called before the SCC's of the program
/// has been processed, allowing the pass to do initialization as necessary.
virtual bool doInitialization(CallGraph &CG) {
return false;
}
/// runOnSCC - This method should be implemented by the subclass to perform
/// whatever action is necessary for the specified SCC. Note that
/// non-recursive (or only self-recursive) functions will have an SCC size of
/// 1, where recursive portions of the call graph will have SCC size > 1.
///
/// SCC passes that add or delete functions to the SCC are required to update
/// the SCC list, otherwise stale pointers may be dereferenced.
///
virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
/// doFinalization - This method is called after the SCC's of the program has
/// been processed, allowing the pass to do final cleanup as necessary.
virtual bool doFinalization(CallGraph &CG) {
return false;
}
/// Assign pass manager to manager this pass
virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_CallGraphPassManager;
}
/// getAnalysisUsage - For this class, we declare that we require and preserve
/// the call graph. If the derived class implements this method, it should
/// always explicitly call the implementation here.
virtual void getAnalysisUsage(AnalysisUsage &Info) const;
};
/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
class CallGraphSCC {
void *Context; // The CGPassManager object that is vending this.
std::vector<CallGraphNode*> Nodes;
public:
CallGraphSCC(void *context) : Context(context) {}
void initialize(CallGraphNode*const*I, CallGraphNode*const*E) {
Nodes.assign(I, E);
}
bool isSingular() const { return Nodes.size() == 1; }
unsigned size() const { return Nodes.size(); }
/// ReplaceNode - This informs the SCC and the pass manager that the specified
/// Old node has been deleted, and New is to be used in its place.
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
typedef std::vector<CallGraphNode*>::const_iterator iterator;
iterator begin() const { return Nodes.begin(); }
iterator end() const { return Nodes.end(); }
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,27 @@
//===-- CallPrinter.h - Call graph printer external interface ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines external functions that can be called to explicitly
// instantiate the call graph printer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CALLPRINTER_H
#define LLVM_ANALYSIS_CALLPRINTER_H
namespace llvm {
class ModulePass;
ModulePass *createCallGraphViewerPass();
ModulePass *createCallGraphPrinterPass();
} // end namespace llvm
#endif

View File

@@ -0,0 +1,62 @@
//===----- llvm/Analysis/CaptureTracking.h - Pointer capture ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains routines that help determine which pointers are captured.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CAPTURETRACKING_H
#define LLVM_ANALYSIS_CAPTURETRACKING_H
namespace llvm {
class Value;
class Use;
/// PointerMayBeCaptured - Return true if this pointer value may be captured
/// by the enclosing function (which is required to exist). This routine can
/// be expensive, so consider caching the results. The boolean ReturnCaptures
/// specifies whether returning the value (or part of it) from the function
/// counts as capturing it or not. The boolean StoreCaptures specified
/// whether storing the value (or part of it) into memory anywhere
/// automatically counts as capturing it or not.
bool PointerMayBeCaptured(const Value *V,
bool ReturnCaptures,
bool StoreCaptures);
/// This callback is used in conjunction with PointerMayBeCaptured. In
/// addition to the interface here, you'll need to provide your own getters
/// to see whether anything was captured.
struct CaptureTracker {
virtual ~CaptureTracker();
/// tooManyUses - The depth of traversal has breached a limit. There may be
/// capturing instructions that will not be passed into captured().
virtual void tooManyUses() = 0;
/// shouldExplore - This is the use of a value derived from the pointer.
/// To prune the search (ie., assume that none of its users could possibly
/// capture) return false. To search it, return true.
///
/// U->getUser() is always an Instruction.
virtual bool shouldExplore(Use *U);
/// captured - Information about the pointer was captured by the user of
/// use U. Return true to stop the traversal or false to continue looking
/// for more capturing instructions.
virtual bool captured(Use *U) = 0;
};
/// PointerMayBeCaptured - Visit the value and the values derived from it and
/// find values which appear to be capturing the pointer value. This feeds
/// results into and is controlled by the CaptureTracker object.
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker);
} // end namespace llvm
#endif

View File

@@ -0,0 +1,93 @@
//===- CodeMetrics.h - Code cost measurements -------------------*- 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 various weight measurements for code, helping
// the Inliner and other passes decide whether to duplicate its contents.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CODEMETRICS_H
#define LLVM_ANALYSIS_CODEMETRICS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
class BasicBlock;
class Function;
class Instruction;
class DataLayout;
class TargetTransformInfo;
class Value;
/// \brief Check whether a call will lower to something small.
///
/// This tests checks whether this callsite will lower to something
/// significantly cheaper than a traditional call, often a single
/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
/// return true, so will this function.
bool callIsSmall(ImmutableCallSite CS);
/// \brief Utility to calculate the size and a few similar metrics for a set
/// of basic blocks.
struct CodeMetrics {
/// \brief True if this function contains a call to setjmp or other functions
/// with attribute "returns twice" without having the attribute itself.
bool exposesReturnsTwice;
/// \brief True if this function calls itself.
bool isRecursive;
/// \brief True if this function cannot be duplicated.
///
/// True if this function contains one or more indirect branches, or it contains
/// one or more 'noduplicate' instructions.
bool notDuplicatable;
/// \brief True if this function calls alloca (in the C sense).
bool usesDynamicAlloca;
/// \brief Number of instructions in the analyzed blocks.
unsigned NumInsts;
/// \brief Number of analyzed blocks.
unsigned NumBlocks;
/// \brief Keeps track of basic block code size estimates.
DenseMap<const BasicBlock *, unsigned> NumBBInsts;
/// \brief Keep track of the number of calls to 'big' functions.
unsigned NumCalls;
/// \brief The number of calls to internal functions with a single caller.
///
/// These are likely targets for future inlining, likely exposed by
/// interleaved devirtualization.
unsigned NumInlineCandidates;
/// \brief How many instructions produce vector values.
///
/// The inliner is more aggressive with inlining vector kernels.
unsigned NumVectorInsts;
/// \brief How many 'ret' instructions the blocks contain.
unsigned NumRets;
CodeMetrics()
: exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
/// \brief Add information about a block to the current state.
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
};
}
#endif

View File

@@ -0,0 +1,102 @@
//===-- ConstantFolding.h - Fold instructions into constants --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares routines for folding instructions into constants when all
// operands are constants, for example "sub i32 1, 0" -> "1".
//
// Also, to supplement the basic VMCore ConstantExpr simplifications,
// this file declares some additional folding routines that can make use of
// DataLayout information. These functions cannot go in VMCore due to library
// dependency issues.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CONSTANTFOLDING_H
#define LLVM_ANALYSIS_CONSTANTFOLDING_H
namespace llvm {
class Constant;
class ConstantExpr;
class Instruction;
class DataLayout;
class TargetLibraryInfo;
class Function;
class Type;
template<typename T>
class ArrayRef;
/// ConstantFoldInstruction - Try to constant fold the specified instruction.
/// If successful, the constant result is returned, if not, null is returned.
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
Constant *ConstantFoldInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified operands. If successful, the constant result is returned, if not,
/// null is returned. Note that this function can fail when attempting to
/// fold instructions like loads and stores, which have no constant expression
/// form.
///
Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
ArrayRef<Constant *> Ops,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
/// instruction (icmp/fcmp) with the specified operands. If it fails, it
/// returns a constant expression of the specified operands.
///
Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
Constant *LHS, Constant *RHS,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is
/// returned if successful; if not, null is returned.
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
ArrayRef<unsigned> Idxs);
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout *TD = 0);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
/// constant expression, or null if something is funny and we can't decide.
Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE);
/// ConstantFoldLoadThroughGEPIndices - Given a constant and getelementptr
/// indices (with an *implied* zero pointer index that is not in the list),
/// return the constant value being addressed by a virtual load, or null if
/// something is funny and we can't decide.
Constant *ConstantFoldLoadThroughGEPIndices(Constant *C,
ArrayRef<Constant*> Indices);
/// canConstantFoldCallTo - Return true if its even possible to fold a call to
/// the specified function.
bool canConstantFoldCallTo(const Function *F);
/// ConstantFoldCall - Attempt to constant fold a call to the specified function
/// with the specified arguments, returning null if unsuccessful.
Constant *ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands,
const TargetLibraryInfo *TLI = 0);
}
#endif

View File

@@ -0,0 +1,93 @@
//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements an iterator to walk through the constants referenced by
// a method. This is used by the Bitcode & Assembly writers to build constant
// pools.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
#include "llvm/Support/InstIterator.h"
namespace llvm {
class Constant;
class constant_iterator : public std::iterator<std::forward_iterator_tag,
const Constant, ptrdiff_t> {
const_inst_iterator InstI; // Method instruction iterator
unsigned OpIdx; // Operand index
typedef constant_iterator _Self;
inline bool isAtConstant() const {
assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
"isAtConstant called with invalid arguments!");
return isa<Constant>(InstI->getOperand(OpIdx));
}
public:
inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
// Advance to first constant... if we are not already at constant or end
if (InstI != inst_end(F) && // InstI is valid?
(InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
operator++();
}
inline constant_iterator(const Function *F, bool) // end ctor
: InstI(inst_end(F)), OpIdx(0) {
}
inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
InstI == x.InstI; }
inline bool operator!=(const _Self& x) const { return !operator==(x); }
inline pointer operator*() const {
assert(isAtConstant() && "Dereferenced an iterator at the end!");
return cast<Constant>(InstI->getOperand(OpIdx));
}
inline pointer operator->() const { return operator*(); }
inline _Self& operator++() { // Preincrement implementation
++OpIdx;
do {
unsigned NumOperands = InstI->getNumOperands();
while (OpIdx < NumOperands && !isAtConstant()) {
++OpIdx;
}
if (OpIdx < NumOperands) return *this; // Found a constant!
++InstI;
OpIdx = 0;
} while (!InstI.atEnd());
return *this; // At the end of the method
}
inline _Self operator++(int) { // Postincrement
_Self tmp = *this; ++*this; return tmp;
}
inline bool atEnd() const { return InstI.atEnd(); }
};
inline constant_iterator constant_begin(const Function *F) {
return constant_iterator(F);
}
inline constant_iterator constant_end(const Function *F) {
return constant_iterator(F, true);
}
} // End llvm namespace
#endif

View File

@@ -0,0 +1,142 @@
//===-- DOTGraphTraitsPass.h - Print/View dotty graphs-----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Templates to create dotty viewer and printer passes for GraphTraits graphs.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
namespace llvm {
template <class Analysis, bool Simple>
class DOTGraphTraitsViewer : public FunctionPass {
public:
DOTGraphTraitsViewer(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
virtual bool runOnFunction(Function &F) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
ViewGraph(Graph, Name, Simple, Title);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
template <class Analysis, bool Simple>
class DOTGraphTraitsPrinter : public FunctionPass {
public:
DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
: FunctionPass(ID), Name(GraphName) {}
virtual bool runOnFunction(Function &F) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string Filename = Name + "." + F.getName().str() + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
std::string Title = GraphName + " for '" + F.getName().str() + "' function";
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
template <class Analysis, bool Simple>
class DOTGraphTraitsModuleViewer : public ModulePass {
public:
DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
virtual bool runOnModule(Module &M) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
ViewGraph(Graph, Name, Simple, Title);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
template <class Analysis, bool Simple>
class DOTGraphTraitsModulePrinter : public ModulePass {
public:
DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
: ModulePass(ID), Name(GraphName) {}
virtual bool runOnModule(Module &M) {
Analysis *Graph = &getAnalysis<Analysis>();
std::string Filename = Name + ".dot";
std::string ErrorInfo;
errs() << "Writing '" << Filename << "'...";
raw_fd_ostream File(Filename.c_str(), ErrorInfo);
std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
private:
std::string Name;
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,895 @@
//===-- llvm/Analysis/DependenceAnalysis.h -------------------- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// DependenceAnalysis is an LLVM pass that analyses dependences between memory
// accesses. Currently, it is an implementation of the approach described in
//
// Practical Dependence Testing
// Goff, Kennedy, Tseng
// PLDI 1991
//
// There's a single entry point that analyzes the dependence between a pair
// of memory references in a function, returning either NULL, for no dependence,
// or a more-or-less detailed description of the dependence between them.
//
// This pass exists to support the DependenceGraph pass. There are two separate
// passes because there's a useful separation of concerns. A dependence exists
// if two conditions are met:
//
// 1) Two instructions reference the same memory location, and
// 2) There is a flow of control leading from one instruction to the other.
//
// DependenceAnalysis attacks the first condition; DependenceGraph will attack
// the second (it's not yet ready).
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// Plausible changes:
// Return a set of more precise dependences instead of just one dependence
// summarizing all.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
namespace llvm {
class AliasAnalysis;
class Loop;
class LoopInfo;
class ScalarEvolution;
class SCEV;
class SCEVConstant;
class raw_ostream;
/// Dependence - This class represents a dependence between two memory
/// memory references in a function. It contains minimal information and
/// is used in the very common situation where the compiler is unable to
/// determine anything beyond the existence of a dependence; that is, it
/// represents a confused dependence (see also FullDependence). In most
/// cases (for output, flow, and anti dependences), the dependence implies
/// an ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class Dependence {
public:
Dependence(Instruction *Source,
Instruction *Destination) :
Src(Source), Dst(Destination) {}
virtual ~Dependence() {}
/// Dependence::DVEntry - Each level in the distance/direction vector
/// has a direction (or perhaps a union of several directions), and
/// perhaps a distance.
struct DVEntry {
enum { NONE = 0,
LT = 1,
EQ = 2,
LE = 3,
GT = 4,
NE = 5,
GE = 6,
ALL = 7 };
unsigned char Direction : 3; // Init to ALL, then refine.
bool Scalar : 1; // Init to true.
bool PeelFirst : 1; // Peeling the first iteration will break dependence.
bool PeelLast : 1; // Peeling the last iteration will break the dependence.
bool Splitable : 1; // Splitting the loop will break dependence.
const SCEV *Distance; // NULL implies no distance available.
DVEntry() : Direction(ALL), Scalar(true), PeelFirst(false),
PeelLast(false), Splitable(false), Distance(NULL) { }
};
/// getSrc - Returns the source instruction for this dependence.
///
Instruction *getSrc() const { return Src; }
/// getDst - Returns the destination instruction for this dependence.
///
Instruction *getDst() const { return Dst; }
/// isInput - Returns true if this is an input dependence.
///
bool isInput() const;
/// isOutput - Returns true if this is an output dependence.
///
bool isOutput() const;
/// isFlow - Returns true if this is a flow (aka true) dependence.
///
bool isFlow() const;
/// isAnti - Returns true if this is an anti dependence.
///
bool isAnti() const;
/// isOrdered - Returns true if dependence is Output, Flow, or Anti
///
bool isOrdered() const { return isOutput() || isFlow() || isAnti(); }
/// isUnordered - Returns true if dependence is Input
///
bool isUnordered() const { return isInput(); }
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
virtual bool isLoopIndependent() const { return true; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
virtual bool isConfused() const { return true; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
virtual bool isConsistent() const { return false; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
virtual unsigned getLevels() const { return 0; }
/// getDirection - Returns the direction associated with a particular
/// level.
virtual unsigned getDirection(unsigned Level) const { return DVEntry::ALL; }
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
virtual const SCEV *getDistance(unsigned Level) const { return NULL; }
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
virtual bool isPeelFirst(unsigned Level) const { return false; }
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
virtual bool isPeelLast(unsigned Level) const { return false; }
/// isSplitable - Returns true if splitting this loop will break
/// the dependence.
virtual bool isSplitable(unsigned Level) const { return false; }
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
virtual bool isScalar(unsigned Level) const;
/// dump - For debugging purposes, dumps a dependence to OS.
///
void dump(raw_ostream &OS) const;
private:
Instruction *Src, *Dst;
friend class DependenceAnalysis;
};
/// FullDependence - This class represents a dependence between two memory
/// references in a function. It contains detailed information about the
/// dependence (direction vectors, etc.) and is used when the compiler is
/// able to accurately analyze the interaction of the references; that is,
/// it is not a confused dependence (see Dependence). In most cases
/// (for output, flow, and anti dependences), the dependence implies an
/// ordering, where the source must precede the destination; in contrast,
/// input dependences are unordered.
class FullDependence : public Dependence {
public:
FullDependence(Instruction *Src,
Instruction *Dst,
bool LoopIndependent,
unsigned Levels);
~FullDependence() {
delete[] DV;
}
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
bool isLoopIndependent() const { return LoopIndependent; }
/// isConfused - Returns true if this dependence is confused
/// (the compiler understands nothing and makes worst-case
/// assumptions).
bool isConfused() const { return false; }
/// isConsistent - Returns true if this dependence is consistent
/// (occurs every time the source and destination are executed).
bool isConsistent() const { return Consistent; }
/// getLevels - Returns the number of common loops surrounding the
/// source and destination of the dependence.
unsigned getLevels() const { return Levels; }
/// getDirection - Returns the direction associated with a particular
/// level.
unsigned getDirection(unsigned Level) const;
/// getDistance - Returns the distance (or NULL) associated with a
/// particular level.
const SCEV *getDistance(unsigned Level) const;
/// isPeelFirst - Returns true if peeling the first iteration from
/// this loop will break this dependence.
bool isPeelFirst(unsigned Level) const;
/// isPeelLast - Returns true if peeling the last iteration from
/// this loop will break this dependence.
bool isPeelLast(unsigned Level) const;
/// isSplitable - Returns true if splitting the loop will break
/// the dependence.
bool isSplitable(unsigned Level) const;
/// isScalar - Returns true if a particular level is scalar; that is,
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
bool isScalar(unsigned Level) const;
private:
unsigned short Levels;
bool LoopIndependent;
bool Consistent; // Init to true, then refine.
DVEntry *DV;
friend class DependenceAnalysis;
};
/// DependenceAnalysis - This class is the main dependence-analysis driver.
///
class DependenceAnalysis : public FunctionPass {
void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
public:
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
/// FullDependence) with as much information as can be gleaned.
/// The flag PossiblyLoopIndependent should be set by the caller
/// if it appears that control flow can reach from Src to Dst
/// without traversing a loop back edge.
Dependence *depends(Instruction *Src,
Instruction *Dst,
bool PossiblyLoopIndependent);
/// getSplitIteration - Give a dependence that's splittable at some
/// particular level, return the iteration that should be used to split
/// the loop.
///
/// Generally, the dependence analyzer will be used to build
/// a dependence graph for a function (basically a map from instructions
/// to dependences). Looking for cycles in the graph shows us loops
/// that cannot be trivially vectorized/parallelized.
///
/// We can try to improve the situation by examining all the dependences
/// that make up the cycle, looking for ones we can break.
/// Sometimes, peeling the first or last iteration of a loop will break
/// dependences, and there are flags for those possibilities.
/// Sometimes, splitting a loop at some other iteration will do the trick,
/// and we've got a flag for that case. Rather than waste the space to
/// record the exact iteration (since we rarely know), we provide
/// a method that calculates the iteration. It's a drag that it must work
/// from scratch, but wonderful in that it's possible.
///
/// Here's an example:
///
/// for (i = 0; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// There's a loop-carried flow dependence from the store to the load,
/// found by the weak-crossing SIV test. The dependence will have a flag,
/// indicating that the dependence can be broken by splitting the loop.
/// Calling getSplitIteration will return 5.
/// Splitting the loop breaks the dependence, like so:
///
/// for (i = 0; i <= 5; i++)
/// A[i] = ...
/// ... = A[11 - i]
/// for (i = 6; i < 10; i++)
/// A[i] = ...
/// ... = A[11 - i]
///
/// breaks the dependence and allows us to vectorize/parallelize
/// both loops.
const SCEV *getSplitIteration(const Dependence *Dep, unsigned Level);
private:
AliasAnalysis *AA;
ScalarEvolution *SE;
LoopInfo *LI;
Function *F;
/// Subscript - This private struct represents a pair of subscripts from
/// a pair of potentially multi-dimensional array references. We use a
/// vector of them to guide subscript partitioning.
struct Subscript {
const SCEV *Src;
const SCEV *Dst;
enum ClassificationKind { ZIV, SIV, RDIV, MIV, NonLinear } Classification;
SmallBitVector Loops;
SmallBitVector GroupLoops;
SmallBitVector Group;
};
struct CoefficientInfo {
const SCEV *Coeff;
const SCEV *PosPart;
const SCEV *NegPart;
const SCEV *Iterations;
};
struct BoundInfo {
const SCEV *Iterations;
const SCEV *Upper[8];
const SCEV *Lower[8];
unsigned char Direction;
unsigned char DirSet;
};
/// Constraint - This private class represents a constraint, as defined
/// in the paper
///
/// Practical Dependence Testing
/// Goff, Kennedy, Tseng
/// PLDI 1991
///
/// There are 5 kinds of constraint, in a hierarchy.
/// 1) Any - indicates no constraint, any dependence is possible.
/// 2) Line - A line ax + by = c, where a, b, and c are parameters,
/// representing the dependence equation.
/// 3) Distance - The value d of the dependence distance;
/// 4) Point - A point <x, y> representing the dependence from
/// iteration x to iteration y.
/// 5) Empty - No dependence is possible.
class Constraint {
private:
enum ConstraintKind { Empty, Point, Distance, Line, Any } Kind;
ScalarEvolution *SE;
const SCEV *A;
const SCEV *B;
const SCEV *C;
const Loop *AssociatedLoop;
public:
/// isEmpty - Return true if the constraint is of kind Empty.
bool isEmpty() const { return Kind == Empty; }
/// isPoint - Return true if the constraint is of kind Point.
bool isPoint() const { return Kind == Point; }
/// isDistance - Return true if the constraint is of kind Distance.
bool isDistance() const { return Kind == Distance; }
/// isLine - Return true if the constraint is of kind Line.
/// Since Distance's can also be represented as Lines, we also return
/// true if the constraint is of kind Distance.
bool isLine() const { return Kind == Line || Kind == Distance; }
/// isAny - Return true if the constraint is of kind Any;
bool isAny() const { return Kind == Any; }
/// getX - If constraint is a point <X, Y>, returns X.
/// Otherwise assert.
const SCEV *getX() const;
/// getY - If constraint is a point <X, Y>, returns Y.
/// Otherwise assert.
const SCEV *getY() const;
/// getA - If constraint is a line AX + BY = C, returns A.
/// Otherwise assert.
const SCEV *getA() const;
/// getB - If constraint is a line AX + BY = C, returns B.
/// Otherwise assert.
const SCEV *getB() const;
/// getC - If constraint is a line AX + BY = C, returns C.
/// Otherwise assert.
const SCEV *getC() const;
/// getD - If constraint is a distance, returns D.
/// Otherwise assert.
const SCEV *getD() const;
/// getAssociatedLoop - Returns the loop associated with this constraint.
const Loop *getAssociatedLoop() const;
/// setPoint - Change a constraint to Point.
void setPoint(const SCEV *X, const SCEV *Y, const Loop *CurrentLoop);
/// setLine - Change a constraint to Line.
void setLine(const SCEV *A, const SCEV *B,
const SCEV *C, const Loop *CurrentLoop);
/// setDistance - Change a constraint to Distance.
void setDistance(const SCEV *D, const Loop *CurrentLoop);
/// setEmpty - Change a constraint to Empty.
void setEmpty();
/// setAny - Change a constraint to Any.
void setAny(ScalarEvolution *SE);
/// dump - For debugging purposes. Dumps the constraint
/// out to OS.
void dump(raw_ostream &OS) const;
};
/// establishNestingLevels - Examines the loop nesting of the Src and Dst
/// instructions and establishes their shared loops. Sets the variables
/// CommonLevels, SrcLevels, and MaxLevels.
/// The source and destination instructions needn't be contained in the same
/// loop. The routine establishNestingLevels finds the level of most deeply
/// nested loop that contains them both, CommonLevels. An instruction that's
/// not contained in a loop is at level = 0. MaxLevels is equal to the level
/// of the source plus the level of the destination, minus CommonLevels.
/// This lets us allocate vectors MaxLevels in length, with room for every
/// distinct loop referenced in both the source and destination subscripts.
/// The variable SrcLevels is the nesting depth of the source instruction.
/// It's used to help calculate distinct loops referenced by the destination.
/// Here's the map from loops to levels:
/// 0 - unused
/// 1 - outermost common loop
/// ... - other common loops
/// CommonLevels - innermost common loop
/// ... - loops containing Src but not Dst
/// SrcLevels - innermost loop containing Src but not Dst
/// ... - loops containing Dst but not Src
/// MaxLevels - innermost loop containing Dst but not Src
/// Consider the follow code fragment:
/// for (a = ...) {
/// for (b = ...) {
/// for (c = ...) {
/// for (d = ...) {
/// A[] = ...;
/// }
/// }
/// for (e = ...) {
/// for (f = ...) {
/// for (g = ...) {
/// ... = A[];
/// }
/// }
/// }
/// }
/// }
/// If we're looking at the possibility of a dependence between the store
/// to A (the Src) and the load from A (the Dst), we'll note that they
/// have 2 loops in common, so CommonLevels will equal 2 and the direction
/// vector for Result will have 2 entries. SrcLevels = 4 and MaxLevels = 7.
/// A map from loop names to level indices would look like
/// a - 1
/// b - 2 = CommonLevels
/// c - 3
/// d - 4 = SrcLevels
/// e - 5
/// f - 6
/// g - 7 = MaxLevels
void establishNestingLevels(const Instruction *Src,
const Instruction *Dst);
unsigned CommonLevels, SrcLevels, MaxLevels;
/// mapSrcLoop - Given one of the loops containing the source, return
/// its level index in our numbering scheme.
unsigned mapSrcLoop(const Loop *SrcLoop) const;
/// mapDstLoop - Given one of the loops containing the destination,
/// return its level index in our numbering scheme.
unsigned mapDstLoop(const Loop *DstLoop) const;
/// isLoopInvariant - Returns true if Expression is loop invariant
/// in LoopNest.
bool isLoopInvariant(const SCEV *Expression, const Loop *LoopNest) const;
/// removeMatchingExtensions - Examines a subscript pair.
/// If the source and destination are identically sign (or zero)
/// extended, it strips off the extension in an effort to
/// simplify the actual analysis.
void removeMatchingExtensions(Subscript *Pair);
/// collectCommonLoops - Finds the set of loops from the LoopNest that
/// have a level <= CommonLevels and are referred to by the SCEV Expression.
void collectCommonLoops(const SCEV *Expression,
const Loop *LoopNest,
SmallBitVector &Loops) const;
/// checkSrcSubscript - Examines the SCEV Src, returning true iff it's
/// linear. Collect the set of loops mentioned by Src.
bool checkSrcSubscript(const SCEV *Src,
const Loop *LoopNest,
SmallBitVector &Loops);
/// checkDstSubscript - Examines the SCEV Dst, returning true iff it's
/// linear. Collect the set of loops mentioned by Dst.
bool checkDstSubscript(const SCEV *Dst,
const Loop *LoopNest,
SmallBitVector &Loops);
/// isKnownPredicate - Compare X and Y using the predicate Pred.
/// Basically a wrapper for SCEV::isKnownPredicate,
/// but tries harder, especially in the presence of sign and zero
/// extensions and symbolics.
bool isKnownPredicate(ICmpInst::Predicate Pred,
const SCEV *X,
const SCEV *Y) const;
/// collectUpperBound - All subscripts are the same type (on my machine,
/// an i64). The loop bound may be a smaller type. collectUpperBound
/// find the bound, if available, and zero extends it to the Type T.
/// (I zero extend since the bound should always be >= 0.)
/// If no upper bound is available, return NULL.
const SCEV *collectUpperBound(const Loop *l, Type *T) const;
/// collectConstantUpperBound - Calls collectUpperBound(), then
/// attempts to cast it to SCEVConstant. If the cast fails,
/// returns NULL.
const SCEVConstant *collectConstantUpperBound(const Loop *l, Type *T) const;
/// classifyPair - Examines the subscript pair (the Src and Dst SCEVs)
/// and classifies it as either ZIV, SIV, RDIV, MIV, or Nonlinear.
/// Collects the associated loops in a set.
Subscript::ClassificationKind classifyPair(const SCEV *Src,
const Loop *SrcLoopNest,
const SCEV *Dst,
const Loop *DstLoopNest,
SmallBitVector &Loops);
/// testZIV - Tests the ZIV subscript pair (Src and Dst) for dependence.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testZIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testSIV - Tests the SIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j], where
/// i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction vector entry and, when possible,
/// the distance vector entry.
/// If the dependence isn't proven to exist,
/// marks the Result as inconsistent.
bool testSIV(const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// testRDIV - Tests the RDIV subscript pair (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*j]
/// where i and j are induction variables, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// With minor algebra, this test can also be used for things like
/// [c1 + a1*i + a2*j][c2].
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Marks the Result as inconsistent.
bool testRDIV(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// testMIV - Tests the MIV subscript pair (Src and Dst) for dependence.
/// Returns true if dependence disproved.
/// Can sometimes refine direction vectors.
bool testMIV(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// strongSIVtest - Tests the strong SIV subscript pair (Src and Dst)
/// for dependence.
/// Things of the form [c1 + a*i] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction and distance.
bool strongSIVtest(const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakCrossingSIVtest - Tests the weak-crossing SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2 - a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// Marks the dependence as splitable.
bool weakCrossingSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint,
const SCEV *&SplitIter) const;
/// ExactSIVtest - Tests the SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a1*i] and [c2 + a2*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a1 and a2 are constant.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
bool exactSIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroSrcSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1] and [c2 + a*i],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroDstSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroSrcSIVtest(const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// weakZeroDstSIVtest - Tests the weak-zero SIV subscript pair
/// (Src and Dst) for dependence.
/// Things of the form [c1 + a*i] and [c2],
/// where i is an induction variable, c1 and c2 are loop invariant,
/// and a is a constant. See also weakZeroSrcSIVtest.
/// Returns true if any possible dependence is disproved.
/// If there might be a dependence, returns false.
/// Sets appropriate direction entry.
/// Set consistent to false.
/// If loop peeling will break the dependence, mark appropriately.
bool weakZeroDstSIVtest(const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *CurrentLoop,
unsigned Level,
FullDependence &Result,
Constraint &NewConstraint) const;
/// exactRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that symbolicRDIVtest doesn't,
/// and vice versa.
bool exactRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop,
FullDependence &Result) const;
/// symbolicRDIVtest - Tests the RDIV subscript pair for dependence.
/// Things of the form [c1 + a*i] and [c2 + b*j],
/// where i and j are induction variable, c1 and c2 are loop invariant,
/// and a and b are constants.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Works in some cases that exactRDIVtest doesn't,
/// and vice versa. Can also be used as a backup for
/// ordinary SIV tests.
bool symbolicRDIVtest(const SCEV *SrcCoeff,
const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
const Loop *SrcLoop,
const Loop *DstLoop) const;
/// gcdMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Can sometimes disprove the equal direction for 1 or more loops.
// Can handle some symbolics that even the SIV tests don't get,
/// so we use it as a backup for everything.
bool gcdMIVtest(const SCEV *Src,
const SCEV *Dst,
FullDependence &Result) const;
/// banerjeeMIVtest - Tests an MIV subscript pair for dependence.
/// Returns true if any possible dependence is disproved.
/// Marks the result as inconsistent.
/// Computes directions.
bool banerjeeMIVtest(const SCEV *Src,
const SCEV *Dst,
const SmallBitVector &Loops,
FullDependence &Result) const;
/// collectCoefficientInfo - Walks through the subscript,
/// collecting each coefficient, the associated loop bounds,
/// and recording its positive and negative parts for later use.
CoefficientInfo *collectCoeffInfo(const SCEV *Subscript,
bool SrcFlag,
const SCEV *&Constant) const;
/// getPositivePart - X^+ = max(X, 0).
///
const SCEV *getPositivePart(const SCEV *X) const;
/// getNegativePart - X^- = min(X, 0).
///
const SCEV *getNegativePart(const SCEV *X) const;
/// getLowerBound - Looks through all the bounds info and
/// computes the lower bound given the current direction settings
/// at each level.
const SCEV *getLowerBound(BoundInfo *Bound) const;
/// getUpperBound - Looks through all the bounds info and
/// computes the upper bound given the current direction settings
/// at each level.
const SCEV *getUpperBound(BoundInfo *Bound) const;
/// exploreDirections - Hierarchically expands the direction vector
/// search space, combining the directions of discovered dependences
/// in the DirSet field of Bound. Returns the number of distinct
/// dependences discovered. If the dependence is disproved,
/// it will return 0.
unsigned exploreDirections(unsigned Level,
CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
const SmallBitVector &Loops,
unsigned &DepthExpanded,
const SCEV *Delta) const;
/// testBounds - Returns true iff the current bounds are plausible.
///
bool testBounds(unsigned char DirKind,
unsigned Level,
BoundInfo *Bound,
const SCEV *Delta) const;
/// findBoundsALL - Computes the upper and lower bounds for level K
/// using the * direction. Records them in Bound.
void findBoundsALL(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsLT - Computes the upper and lower bounds for level K
/// using the < direction. Records them in Bound.
void findBoundsLT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsGT - Computes the upper and lower bounds for level K
/// using the > direction. Records them in Bound.
void findBoundsGT(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// findBoundsEQ - Computes the upper and lower bounds for level K
/// using the = direction. Records them in Bound.
void findBoundsEQ(CoefficientInfo *A,
CoefficientInfo *B,
BoundInfo *Bound,
unsigned K) const;
/// intersectConstraints - Updates X with the intersection
/// of the Constraints X and Y. Returns true if X has changed.
bool intersectConstraints(Constraint *X,
const Constraint *Y);
/// propagate - Review the constraints, looking for opportunities
/// to simplify a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagate(const SCEV *&Src,
const SCEV *&Dst,
SmallBitVector &Loops,
SmallVector<Constraint, 4> &Constraints,
bool &Consistent);
/// propagateDistance - Attempt to propagate a distance
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateDistance(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// propagatePoint - Attempt to propagate a point
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
bool propagatePoint(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint);
/// propagateLine - Attempt to propagate a line
/// constraint into a subscript pair (Src and Dst).
/// Return true if some simplification occurs.
/// If the simplification isn't exact (that is, if it is conservative
/// in terms of dependence), set consistent to false.
bool propagateLine(const SCEV *&Src,
const SCEV *&Dst,
Constraint &CurConstraint,
bool &Consistent);
/// findCoefficient - Given a linear SCEV,
/// return the coefficient corresponding to specified loop.
/// If there isn't one, return the SCEV constant 0.
/// For example, given a*i + b*j + c*k, returning the coefficient
/// corresponding to the j loop would yield b.
const SCEV *findCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// zeroCoefficient - Given a linear SCEV,
/// return the SCEV given by zeroing out the coefficient
/// corresponding to the specified loop.
/// For example, given a*i + b*j + c*k, zeroing the coefficient
/// corresponding to the j loop would yield a*i + c*k.
const SCEV *zeroCoefficient(const SCEV *Expr,
const Loop *TargetLoop) const;
/// addToCoefficient - Given a linear SCEV Expr,
/// return the SCEV given by adding some Value to the
/// coefficient corresponding to the specified TargetLoop.
/// For example, given a*i + b*j + c*k, adding 1 to the coefficient
/// corresponding to the j loop would yield a*i + (b+1)*j + c*k.
const SCEV *addToCoefficient(const SCEV *Expr,
const Loop *TargetLoop,
const SCEV *Value) const;
/// updateDirection - Update direction vector entry
/// based on the current constraint.
void updateDirection(Dependence::DVEntry &Level,
const Constraint &CurConstraint) const;
public:
static char ID; // Class identification, replacement for typeinfo
DependenceAnalysis() : FunctionPass(ID) {
initializeDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
bool runOnFunction(Function &F);
void releaseMemory();
void getAnalysisUsage(AnalysisUsage &) const;
void print(raw_ostream &, const Module * = 0) const;
}; // class DependenceAnalysis
/// createDependenceAnalysisPass - This creates an instance of the
/// DependenceAnalysis pass.
FunctionPass *createDependenceAnalysisPass();
} // namespace llvm
#endif

View File

@@ -0,0 +1,30 @@
//===-- DomPrinter.h - Dom printer external interface ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines external functions that can be called to explicitly
// instantiate the dominance tree printer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOMPRINTER_H
#define LLVM_ANALYSIS_DOMPRINTER_H
namespace llvm {
class FunctionPass;
FunctionPass *createDomPrinterPass();
FunctionPass *createDomOnlyPrinterPass();
FunctionPass *createDomViewerPass();
FunctionPass *createDomOnlyViewerPass();
FunctionPass *createPostDomPrinterPass();
FunctionPass *createPostDomOnlyPrinterPass();
FunctionPass *createPostDomViewerPass();
FunctionPass *createPostDomOnlyViewerPass();
} // End llvm namespace
#endif

View File

@@ -0,0 +1,190 @@
//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DominanceFrontier class, which calculate and holds the
// dominance frontier for a function.
//
// This should be considered deprecated, don't add any more uses of this data
// structure.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
#define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
#include "llvm/Analysis/Dominators.h"
#include <map>
#include <set>
namespace llvm {
//===----------------------------------------------------------------------===//
/// DominanceFrontierBase - Common base class for computing forward and inverse
/// dominance frontiers for a function.
///
class DominanceFrontierBase : public FunctionPass {
public:
typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
protected:
DomSetMapType Frontiers;
std::vector<BasicBlock*> Roots;
const bool IsPostDominators;
public:
DominanceFrontierBase(char &ID, bool isPostDom)
: FunctionPass(ID), IsPostDominators(isPostDom) {}
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
/// isPostDominator - Returns true if analysis based of postdoms
///
bool isPostDominator() const { return IsPostDominators; }
virtual void releaseMemory() { Frontiers.clear(); }
// Accessor interface:
typedef DomSetMapType::iterator iterator;
typedef DomSetMapType::const_iterator const_iterator;
iterator begin() { return Frontiers.begin(); }
const_iterator begin() const { return Frontiers.begin(); }
iterator end() { return Frontiers.end(); }
const_iterator end() const { return Frontiers.end(); }
iterator find(BasicBlock *B) { return Frontiers.find(B); }
const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
assert(find(BB) == end() && "Block already in DominanceFrontier!");
return Frontiers.insert(std::make_pair(BB, frontier)).first;
}
/// removeBlock - Remove basic block BB's frontier.
void removeBlock(BasicBlock *BB) {
assert(find(BB) != end() && "Block is not in DominanceFrontier!");
for (iterator I = begin(), E = end(); I != E; ++I)
I->second.erase(BB);
Frontiers.erase(BB);
}
void addToFrontier(iterator I, BasicBlock *Node) {
assert(I != end() && "BB is not in DominanceFrontier!");
I->second.insert(Node);
}
void removeFromFrontier(iterator I, BasicBlock *Node) {
assert(I != end() && "BB is not in DominanceFrontier!");
assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
I->second.erase(Node);
}
/// compareDomSet - Return false if two domsets match. Otherwise
/// return true;
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
std::set<BasicBlock *> tmpSet;
for (DomSetType::const_iterator I = DS2.begin(),
E = DS2.end(); I != E; ++I)
tmpSet.insert(*I);
for (DomSetType::const_iterator I = DS1.begin(),
E = DS1.end(); I != E; ) {
BasicBlock *Node = *I++;
if (tmpSet.erase(Node) == 0)
// Node is in DS1 but not in DS2.
return true;
}
if (!tmpSet.empty())
// There are nodes that are in DS2 but not in DS1.
return true;
// DS1 and DS2 matches.
return false;
}
/// compare - Return true if the other dominance frontier base matches
/// this dominance frontier base. Otherwise return false.
bool compare(DominanceFrontierBase &Other) const {
DomSetMapType tmpFrontiers;
for (DomSetMapType::const_iterator I = Other.begin(),
E = Other.end(); I != E; ++I)
tmpFrontiers.insert(std::make_pair(I->first, I->second));
for (DomSetMapType::iterator I = tmpFrontiers.begin(),
E = tmpFrontiers.end(); I != E; ) {
BasicBlock *Node = I->first;
const_iterator DFI = find(Node);
if (DFI == end())
return true;
if (compareDomSet(I->second, DFI->second))
return true;
++I;
tmpFrontiers.erase(Node);
}
if (!tmpFrontiers.empty())
return true;
return false;
}
/// print - Convert to human readable form
///
virtual void print(raw_ostream &OS, const Module* = 0) const;
/// dump - Dump the dominance frontier to dbgs().
void dump() const;
};
//===-------------------------------------
/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
/// used to compute a forward dominator frontiers.
///
class DominanceFrontier : public DominanceFrontierBase {
virtual void anchor();
public:
static char ID; // Pass ID, replacement for typeid
DominanceFrontier() :
DominanceFrontierBase(ID, false) {
initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
}
BasicBlock *getRoot() const {
assert(Roots.size() == 1 && "Should always have entry node!");
return Roots[0];
}
virtual bool runOnFunction(Function &) {
Frontiers.clear();
DominatorTree &DT = getAnalysis<DominatorTree>();
Roots = DT.getRoots();
assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
calculate(DT, DT[Roots[0]]);
return false;
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<DominatorTree>();
}
const DomSetType &calculate(const DominatorTree &DT,
const DomTreeNode *Node);
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,289 @@
//=== llvm/Analysis/DominatorInternals.h - Dominator Calculation -*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/Dominators.h"
//===----------------------------------------------------------------------===//
//
// DominatorTree construction - This pass constructs immediate dominator
// information for a flow-graph based on the algorithm described in this
// document:
//
// A Fast Algorithm for Finding Dominators in a Flowgraph
// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
//
// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
// out that the theoretically slower O(n*log(n)) implementation is actually
// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
//
//===----------------------------------------------------------------------===//
namespace llvm {
template<class GraphT>
unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
typename GraphT::NodeType* V, unsigned N) {
// This is more understandable as a recursive algorithm, but we can't use the
// recursive algorithm due to stack depth issues. Keep it here for
// documentation purposes.
#if 0
InfoRec &VInfo = DT.Info[DT.Roots[i]];
VInfo.DFSNum = VInfo.Semi = ++N;
VInfo.Label = V;
Vertex.push_back(V); // Vertex[n] = V;
for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
InfoRec &SuccVInfo = DT.Info[*SI];
if (SuccVInfo.Semi == 0) {
SuccVInfo.Parent = V;
N = DTDFSPass(DT, *SI, N);
}
}
#else
bool IsChildOfArtificialExit = (N != 0);
SmallVector<std::pair<typename GraphT::NodeType*,
typename GraphT::ChildIteratorType>, 32> Worklist;
Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
while (!Worklist.empty()) {
typename GraphT::NodeType* BB = Worklist.back().first;
typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
DT.Info[BB];
// First time we visited this BB?
if (NextSucc == GraphT::child_begin(BB)) {
BBInfo.DFSNum = BBInfo.Semi = ++N;
BBInfo.Label = BB;
DT.Vertex.push_back(BB); // Vertex[n] = V;
if (IsChildOfArtificialExit)
BBInfo.Parent = 1;
IsChildOfArtificialExit = false;
}
// store the DFS number of the current BB - the reference to BBInfo might
// get invalidated when processing the successors.
unsigned BBDFSNum = BBInfo.DFSNum;
// If we are done with this block, remove it from the worklist.
if (NextSucc == GraphT::child_end(BB)) {
Worklist.pop_back();
continue;
}
// Increment the successor number for the next time we get to it.
++Worklist.back().second;
// Visit the successor next, if it isn't already visited.
typename GraphT::NodeType* Succ = *NextSucc;
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
DT.Info[Succ];
if (SuccVInfo.Semi == 0) {
SuccVInfo.Parent = BBDFSNum;
Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
}
}
#endif
return N;
}
template<class GraphT>
typename GraphT::NodeType*
Eval(DominatorTreeBase<typename GraphT::NodeType>& DT,
typename GraphT::NodeType *VIn, unsigned LastLinked) {
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
DT.Info[VIn];
if (VInInfo.DFSNum < LastLinked)
return VIn;
SmallVector<typename GraphT::NodeType*, 32> Work;
SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
if (VInInfo.Parent >= LastLinked)
Work.push_back(VIn);
while (!Work.empty()) {
typename GraphT::NodeType* V = Work.back();
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
DT.Info[V];
typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
// Process Ancestor first
if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) {
Work.push_back(VAncestor);
continue;
}
Work.pop_back();
// Update VInfo based on Ancestor info
if (VInfo.Parent < LastLinked)
continue;
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
DT.Info[VAncestor];
typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
typename GraphT::NodeType* VLabel = VInfo.Label;
if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
VInfo.Label = VAncestorLabel;
VInfo.Parent = VAInfo.Parent;
}
return VInInfo.Label;
}
template<class FuncT, class NodeT>
void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
FuncT& F) {
typedef GraphTraits<NodeT> GraphT;
unsigned N = 0;
bool MultipleRoots = (DT.Roots.size() > 1);
if (MultipleRoots) {
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
DT.Info[NULL];
BBInfo.DFSNum = BBInfo.Semi = ++N;
BBInfo.Label = NULL;
DT.Vertex.push_back(NULL); // Vertex[n] = V;
}
// Step #1: Number blocks in depth-first order and initialize variables used
// in later stages of the algorithm.
for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
i != e; ++i)
N = DFSPass<GraphT>(DT, DT.Roots[i], N);
// it might be that some blocks did not get a DFS number (e.g., blocks of
// infinite loops). In these cases an artificial exit node is required.
MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
// When naively implemented, the Lengauer-Tarjan algorithm requires a separate
// bucket for each vertex. However, this is unnecessary, because each vertex
// is only placed into a single bucket (that of its semidominator), and each
// vertex's bucket is processed before it is added to any bucket itself.
//
// Instead of using a bucket per vertex, we use a single array Buckets that
// has two purposes. Before the vertex V with preorder number i is processed,
// Buckets[i] stores the index of the first element in V's bucket. After V's
// bucket is processed, Buckets[i] stores the index of the next element in the
// bucket containing V, if any.
SmallVector<unsigned, 32> Buckets;
Buckets.resize(N + 1);
for (unsigned i = 1; i <= N; ++i)
Buckets[i] = i;
for (unsigned i = N; i >= 2; --i) {
typename GraphT::NodeType* W = DT.Vertex[i];
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
DT.Info[W];
// Step #2: Implicitly define the immediate dominator of vertices
for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
}
// Step #3: Calculate the semidominators of all vertices
// initialize the semi dominator to point to the parent node
WInfo.Semi = WInfo.Parent;
typedef GraphTraits<Inverse<NodeT> > InvTraits;
for (typename InvTraits::ChildIteratorType CI =
InvTraits::child_begin(W),
E = InvTraits::child_end(W); CI != E; ++CI) {
typename InvTraits::NodeType *N = *CI;
if (DT.Info.count(N)) { // Only if this predecessor is reachable!
unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
if (SemiU < WInfo.Semi)
WInfo.Semi = SemiU;
}
}
// If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
// necessarily parent(V). In this case, set idom(V) here and avoid placing
// V into a bucket.
if (WInfo.Semi == WInfo.Parent) {
DT.IDoms[W] = DT.Vertex[WInfo.Parent];
} else {
Buckets[i] = Buckets[WInfo.Semi];
Buckets[WInfo.Semi] = i;
}
}
if (N >= 1) {
typename GraphT::NodeType* Root = DT.Vertex[1];
for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
DT.IDoms[V] = Root;
}
}
// Step #4: Explicitly define the immediate dominator of each vertex
for (unsigned i = 2; i <= N; ++i) {
typename GraphT::NodeType* W = DT.Vertex[i];
typename GraphT::NodeType*& WIDom = DT.IDoms[W];
if (WIDom != DT.Vertex[DT.Info[W].Semi])
WIDom = DT.IDoms[WIDom];
}
if (DT.Roots.empty()) return;
// Add a node for the root. This node might be the actual root, if there is
// one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
// which postdominates all real exits if there are multiple exit blocks, or
// an infinite loop.
typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;
DT.DomTreeNodes[Root] = DT.RootNode =
new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0);
// Loop over all of the reachable blocks in the function...
for (unsigned i = 2; i <= N; ++i) {
typename GraphT::NodeType* W = DT.Vertex[i];
DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
if (BBNode) continue; // Haven't calculated this node yet?
typename GraphT::NodeType* ImmDom = DT.getIDom(W);
assert(ImmDom || DT.DomTreeNodes[NULL]);
// Get or calculate the node for the immediate dominator
DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
DT.getNodeForBlock(ImmDom);
// Add a new tree node for this BasicBlock, and link it as a child of
// IDomNode
DomTreeNodeBase<typename GraphT::NodeType> *C =
new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode);
DT.DomTreeNodes[W] = IDomNode->addChild(C);
}
// Free temporary memory used to construct idom's
DT.IDoms.clear();
DT.Info.clear();
std::vector<typename GraphT::NodeType*>().swap(DT.Vertex);
DT.updateDFSNumbers();
}
}
#endif

View File

@@ -0,0 +1,920 @@
//===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DominatorTree class, which provides fast and efficient
// dominance queries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOMINATORS_H
#define LLVM_ANALYSIS_DOMINATORS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
namespace llvm {
//===----------------------------------------------------------------------===//
/// DominatorBase - Base class that other, more interesting dominator analyses
/// inherit from.
///
template <class NodeT>
class DominatorBase {
protected:
std::vector<NodeT*> Roots;
const bool IsPostDominators;
inline explicit DominatorBase(bool isPostDom) :
Roots(), IsPostDominators(isPostDom) {}
public:
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
inline const std::vector<NodeT*> &getRoots() const { return Roots; }
/// isPostDominator - Returns true if analysis based of postdoms
///
bool isPostDominator() const { return IsPostDominators; }
};
//===----------------------------------------------------------------------===//
// DomTreeNode - Dominator Tree Node
template<class NodeT> class DominatorTreeBase;
struct PostDominatorTree;
class MachineBasicBlock;
template <class NodeT>
class DomTreeNodeBase {
NodeT *TheBB;
DomTreeNodeBase<NodeT> *IDom;
std::vector<DomTreeNodeBase<NodeT> *> Children;
int DFSNumIn, DFSNumOut;
template<class N> friend class DominatorTreeBase;
friend struct PostDominatorTree;
public:
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
const_iterator;
iterator begin() { return Children.begin(); }
iterator end() { return Children.end(); }
const_iterator begin() const { return Children.begin(); }
const_iterator end() const { return Children.end(); }
NodeT *getBlock() const { return TheBB; }
DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
return Children;
}
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
: TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
Children.push_back(C);
return C;
}
size_t getNumChildren() const {
return Children.size();
}
void clearAllChildren() {
Children.clear();
}
bool compare(const DomTreeNodeBase<NodeT> *Other) const {
if (getNumChildren() != Other->getNumChildren())
return true;
SmallPtrSet<const NodeT *, 4> OtherChildren;
for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
const NodeT *Nd = (*I)->getBlock();
OtherChildren.insert(Nd);
}
for (const_iterator I = begin(), E = end(); I != E; ++I) {
const NodeT *N = (*I)->getBlock();
if (OtherChildren.count(N) == 0)
return true;
}
return false;
}
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
assert(IDom && "No immediate dominator?");
if (IDom != NewIDom) {
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
std::find(IDom->Children.begin(), IDom->Children.end(), this);
assert(I != IDom->Children.end() &&
"Not in immediate dominator children set!");
// I am no longer your child...
IDom->Children.erase(I);
// Switch to new dominator
IDom = NewIDom;
IDom->Children.push_back(this);
}
}
/// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
/// not call them.
unsigned getDFSNumIn() const { return DFSNumIn; }
unsigned getDFSNumOut() const { return DFSNumOut; }
private:
// Return true if this node is dominated by other. Use this only if DFS info
// is valid.
bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
return this->DFSNumIn >= other->DFSNumIn &&
this->DFSNumOut <= other->DFSNumOut;
}
};
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<BasicBlock>);
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
template<class NodeT>
inline raw_ostream &operator<<(raw_ostream &o,
const DomTreeNodeBase<NodeT> *Node) {
if (Node->getBlock())
WriteAsOperand(o, Node->getBlock(), false);
else
o << " <<exit node>>";
o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";
return o << "\n";
}
template<class NodeT>
inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
unsigned Lev) {
o.indent(2*Lev) << "[" << Lev << "] " << N;
for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
E = N->end(); I != E; ++I)
PrintDomTree<NodeT>(*I, o, Lev+1);
}
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
//===----------------------------------------------------------------------===//
/// DominatorTree - Calculate the immediate dominator tree for a function.
///
template<class FuncT, class N>
void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
FuncT& F);
template<class NodeT>
class DominatorTreeBase : public DominatorBase<NodeT> {
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
assert(A != B);
assert(isReachableFromEntry(B));
assert(isReachableFromEntry(A));
const DomTreeNodeBase<NodeT> *IDom;
while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
B = IDom; // Walk up the tree
return IDom != 0;
}
protected:
typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType;
DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode;
bool DFSInfoValid;
unsigned int SlowQueries;
// Information record used during immediate dominators computation.
struct InfoRec {
unsigned DFSNum;
unsigned Parent;
unsigned Semi;
NodeT *Label;
InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
};
DenseMap<NodeT*, NodeT*> IDoms;
// Vertex - Map the DFS number to the BasicBlock*
std::vector<NodeT*> Vertex;
// Info - Collection of information used during the computation of idoms.
DenseMap<NodeT*, InfoRec> Info;
void reset() {
for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
E = DomTreeNodes.end(); I != E; ++I)
delete I->second;
DomTreeNodes.clear();
IDoms.clear();
this->Roots.clear();
Vertex.clear();
RootNode = 0;
}
// NewBB is split and now it has one successor. Update dominator tree to
// reflect this change.
template<class N, class GraphT>
void Split(DominatorTreeBase<typename GraphT::NodeType>& DT,
typename GraphT::NodeType* NewBB) {
assert(std::distance(GraphT::child_begin(NewBB),
GraphT::child_end(NewBB)) == 1 &&
"NewBB should have a single successor!");
typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB);
std::vector<typename GraphT::NodeType*> PredBlocks;
typedef GraphTraits<Inverse<N> > InvTraits;
for (typename InvTraits::ChildIteratorType PI =
InvTraits::child_begin(NewBB),
PE = InvTraits::child_end(NewBB); PI != PE; ++PI)
PredBlocks.push_back(*PI);
assert(!PredBlocks.empty() && "No predblocks?");
bool NewBBDominatesNewBBSucc = true;
for (typename InvTraits::ChildIteratorType PI =
InvTraits::child_begin(NewBBSucc),
E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) {
typename InvTraits::NodeType *ND = *PI;
if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
DT.isReachableFromEntry(ND)) {
NewBBDominatesNewBBSucc = false;
break;
}
}
// Find NewBB's immediate dominator and create new dominator tree node for
// NewBB.
NodeT *NewBBIDom = 0;
unsigned i = 0;
for (i = 0; i < PredBlocks.size(); ++i)
if (DT.isReachableFromEntry(PredBlocks[i])) {
NewBBIDom = PredBlocks[i];
break;
}
// It's possible that none of the predecessors of NewBB are reachable;
// in that case, NewBB itself is unreachable, so nothing needs to be
// changed.
if (!NewBBIDom)
return;
for (i = i + 1; i < PredBlocks.size(); ++i) {
if (DT.isReachableFromEntry(PredBlocks[i]))
NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
}
// Create the new dominator tree node... and set the idom of NewBB.
DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
// If NewBB strictly dominates other blocks, then it is now the immediate
// dominator of NewBBSucc. Update the dominator tree as appropriate.
if (NewBBDominatesNewBBSucc) {
DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
}
}
public:
explicit DominatorTreeBase(bool isPostDom)
: DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
virtual ~DominatorTreeBase() { reset(); }
/// compare - Return false if the other dominator tree base matches this
/// dominator tree base. Otherwise return true.
bool compare(DominatorTreeBase &Other) const {
const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
if (DomTreeNodes.size() != OtherDomTreeNodes.size())
return true;
for (typename DomTreeNodeMapType::const_iterator
I = this->DomTreeNodes.begin(),
E = this->DomTreeNodes.end(); I != E; ++I) {
NodeT *BB = I->first;
typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB);
if (OI == OtherDomTreeNodes.end())
return true;
DomTreeNodeBase<NodeT>* MyNd = I->second;
DomTreeNodeBase<NodeT>* OtherNd = OI->second;
if (MyNd->compare(OtherNd))
return true;
}
return false;
}
virtual void releaseMemory() { reset(); }
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const {
return DomTreeNodes.lookup(BB);
}
/// getRootNode - This returns the entry node for the CFG of the function. If
/// this tree represents the post-dominance relations for a function, however,
/// this root may be a node with the block == NULL. This is the case when
/// there are multiple exit nodes from a particular function. Consumers of
/// post-dominance information must be capable of dealing with this
/// possibility.
///
DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; }
const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; }
/// properlyDominates - Returns true iff A dominates B and A != B.
/// Note that this is not a constant time operation!
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) {
if (A == 0 || B == 0)
return false;
if (A == B)
return false;
return dominates(A, B);
}
bool properlyDominates(const NodeT *A, const NodeT *B);
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
bool isReachableFromEntry(const NodeT* A) const {
assert(!this->isPostDominator() &&
"This is not implemented for post dominators");
return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
}
inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const {
return A;
}
/// dominates - Returns true iff A dominates B. Note that this is not a
/// constant time operation!
///
inline bool dominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) {
// A node trivially dominates itself.
if (B == A)
return true;
// An unreachable node is dominated by anything.
if (!isReachableFromEntry(B))
return true;
// And dominates nothing.
if (!isReachableFromEntry(A))
return false;
// Compare the result of the tree walk and the dfs numbers, if expensive
// checks are enabled.
#ifdef XDEBUG
assert((!DFSInfoValid ||
(dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) &&
"Tree walk disagrees with dfs numbers!");
#endif
if (DFSInfoValid)
return B->DominatedBy(A);
// If we end up with too many slow queries, just update the
// DFS numbers on the theory that we are going to keep querying.
SlowQueries++;
if (SlowQueries > 32) {
updateDFSNumbers();
return B->DominatedBy(A);
}
return dominatedBySlowTreeWalk(A, B);
}
bool dominates(const NodeT *A, const NodeT *B);
NodeT *getRoot() const {
assert(this->Roots.size() == 1 && "Should always have entry node!");
return this->Roots[0];
}
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) {
assert(A->getParent() == B->getParent() &&
"Two blocks are not in same function");
// If either A or B is a entry block then it is nearest common dominator
// (for forward-dominators).
if (!this->isPostDominator()) {
NodeT &Entry = A->getParent()->front();
if (A == &Entry || B == &Entry)
return &Entry;
}
// If B dominates A then B is nearest common dominator.
if (dominates(B, A))
return B;
// If A dominates B then A is nearest common dominator.
if (dominates(A, B))
return A;
DomTreeNodeBase<NodeT> *NodeA = getNode(A);
DomTreeNodeBase<NodeT> *NodeB = getNode(B);
// Collect NodeA dominators set.
SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
NodeADoms.insert(NodeA);
DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
while (IDomA) {
NodeADoms.insert(IDomA);
IDomA = IDomA->getIDom();
}
// Walk NodeB immediate dominators chain and find common dominator node.
DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();
while (IDomB) {
if (NodeADoms.count(IDomB) != 0)
return IDomB->getBlock();
IDomB = IDomB->getIDom();
}
return NULL;
}
const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
// Cast away the const qualifiers here. This is ok since
// const is re-introduced on the return type.
return findNearestCommonDominator(const_cast<NodeT *>(A),
const_cast<NodeT *>(B));
}
//===--------------------------------------------------------------------===//
// API to update (Post)DominatorTree information based on modifications to
// the CFG...
/// addNewBlock - Add a new node to the dominator tree information. This
/// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
assert(getNode(BB) == 0 && "Block already in dominator tree!");
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
return DomTreeNodes[BB] =
IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
}
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
void changeImmediateDominator(DomTreeNodeBase<NodeT> *N,
DomTreeNodeBase<NodeT> *NewIDom) {
assert(N && NewIDom && "Cannot change null node pointers!");
DFSInfoValid = false;
N->setIDom(NewIDom);
}
void changeImmediateDominator(NodeT *BB, NodeT *NewBB) {
changeImmediateDominator(getNode(BB), getNode(NewBB));
}
/// eraseNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
void eraseNode(NodeT *BB) {
DomTreeNodeBase<NodeT> *Node = getNode(BB);
assert(Node && "Removing node that isn't in dominator tree.");
assert(Node->getChildren().empty() && "Node is not a leaf node.");
// Remove node from immediate dominator's children list.
DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
if (IDom) {
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
std::find(IDom->Children.begin(), IDom->Children.end(), Node);
assert(I != IDom->Children.end() &&
"Not in immediate dominator children set!");
// I am no longer your child...
IDom->Children.erase(I);
}
DomTreeNodes.erase(BB);
delete Node;
}
/// removeNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Invalidates any node pointing to removed
/// block.
void removeNode(NodeT *BB) {
assert(getNode(BB) && "Removing node that isn't in dominator tree.");
DomTreeNodes.erase(BB);
}
/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
void splitBlock(NodeT* NewBB) {
if (this->IsPostDominators)
this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB);
else
this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB);
}
/// print - Convert to human readable form
///
void print(raw_ostream &o) const {
o << "=============================--------------------------------\n";
if (this->isPostDominator())
o << "Inorder PostDominator Tree: ";
else
o << "Inorder Dominator Tree: ";
if (!this->DFSInfoValid)
o << "DFSNumbers invalid: " << SlowQueries << " slow queries.";
o << "\n";
// The postdom tree can have a null root if there are no returns.
if (getRootNode())
PrintDomTree<NodeT>(getRootNode(), o, 1);
}
protected:
template<class GraphT>
friend typename GraphT::NodeType* Eval(
DominatorTreeBase<typename GraphT::NodeType>& DT,
typename GraphT::NodeType* V,
unsigned LastLinked);
template<class GraphT>
friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
typename GraphT::NodeType* V,
unsigned N);
template<class FuncT, class N>
friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT,
FuncT& F);
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order.
void updateDFSNumbers() {
unsigned DFSNum = 0;
SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
if (!ThisRoot)
return;
// Even in the case of multiple exits that form the post dominator root
// nodes, do not iterate over all exits, but start from the virtual root
// node. Otherwise bbs, that are not post dominated by any exit but by the
// virtual root node, will never be assigned a DFS number.
WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
ThisRoot->DFSNumIn = DFSNum++;
while (!WorkStack.empty()) {
DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
typename DomTreeNodeBase<NodeT>::iterator ChildIt =
WorkStack.back().second;
// If we visited all of the children of this node, "recurse" back up the
// stack setting the DFOutNum.
if (ChildIt == Node->end()) {
Node->DFSNumOut = DFSNum++;
WorkStack.pop_back();
} else {
// Otherwise, recursively visit this child.
DomTreeNodeBase<NodeT> *Child = *ChildIt;
++WorkStack.back().second;
WorkStack.push_back(std::make_pair(Child, Child->begin()));
Child->DFSNumIn = DFSNum++;
}
}
SlowQueries = 0;
DFSInfoValid = true;
}
DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
if (DomTreeNodeBase<NodeT> *Node = getNode(BB))
return Node;
// Haven't calculated this node yet? Get or calculate the node for the
// immediate dominator.
NodeT *IDom = getIDom(BB);
assert(IDom || this->DomTreeNodes[NULL]);
DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
// Add a new tree node for this BasicBlock, and link it as a child of
// IDomNode
DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode);
return this->DomTreeNodes[BB] = IDomNode->addChild(C);
}
inline NodeT *getIDom(NodeT *BB) const {
return IDoms.lookup(BB);
}
inline void addRoot(NodeT* BB) {
this->Roots.push_back(BB);
}
public:
/// recalculate - compute a dominator tree for the given function
template<class FT>
void recalculate(FT& F) {
typedef GraphTraits<FT*> TraitsTy;
reset();
this->Vertex.push_back(0);
if (!this->IsPostDominators) {
// Initialize root
NodeT *entry = TraitsTy::getEntryNode(&F);
this->Roots.push_back(entry);
this->IDoms[entry] = 0;
this->DomTreeNodes[entry] = 0;
Calculate<FT, NodeT*>(*this, F);
} else {
// Initialize the roots list
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
E = TraitsTy::nodes_end(&F); I != E; ++I) {
if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
addRoot(I);
// Prepopulate maps so that we don't get iterator invalidation issues later.
this->IDoms[I] = 0;
this->DomTreeNodes[I] = 0;
}
Calculate<FT, Inverse<NodeT*> >(*this, F);
}
}
};
// These two functions are declared out of line as a workaround for building
// with old (< r147295) versions of clang because of pr11642.
template<class NodeT>
bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
if (A == B)
return true;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
template<class NodeT>
bool
DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) {
if (A == B)
return false;
// Cast away the const qualifiers here. This is ok since
// this function doesn't actually return the values returned
// from getNode.
return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B)));
}
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<BasicBlock>);
class BasicBlockEdge {
const BasicBlock *Start;
const BasicBlock *End;
public:
BasicBlockEdge(const BasicBlock *Start_, const BasicBlock *End_) :
Start(Start_), End(End_) { }
const BasicBlock *getStart() const {
return Start;
}
const BasicBlock *getEnd() const {
return End;
}
bool isSingleEdge() const;
};
//===-------------------------------------
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
/// compute a normal dominator tree.
///
class DominatorTree : public FunctionPass {
public:
static char ID; // Pass ID, replacement for typeid
DominatorTreeBase<BasicBlock>* DT;
DominatorTree() : FunctionPass(ID) {
initializeDominatorTreePass(*PassRegistry::getPassRegistry());
DT = new DominatorTreeBase<BasicBlock>(false);
}
~DominatorTree() {
delete DT;
}
DominatorTreeBase<BasicBlock>& getBase() { return *DT; }
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
inline const std::vector<BasicBlock*> &getRoots() const {
return DT->getRoots();
}
inline BasicBlock *getRoot() const {
return DT->getRoot();
}
inline DomTreeNode *getRootNode() const {
return DT->getRootNode();
}
/// compare - Return false if the other dominator tree matches this
/// dominator tree. Otherwise return true.
inline bool compare(DominatorTree &Other) const {
DomTreeNode *R = getRootNode();
DomTreeNode *OtherR = Other.getRootNode();
if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
return true;
if (DT->compare(Other.getBase()))
return true;
return false;
}
virtual bool runOnFunction(Function &F);
virtual void verifyAnalysis() const;
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
inline bool dominates(const DomTreeNode* A, const DomTreeNode* B) const {
return DT->dominates(A, B);
}
inline bool dominates(const BasicBlock* A, const BasicBlock* B) const {
return DT->dominates(A, B);
}
// dominates - Return true if Def dominates a use in User. This performs
// the special checks necessary if Def and User are in the same basic block.
// Note that Def doesn't dominate a use in Def itself!
bool dominates(const Instruction *Def, const Use &U) const;
bool dominates(const Instruction *Def, const Instruction *User) const;
bool dominates(const Instruction *Def, const BasicBlock *BB) const;
bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
bool properlyDominates(const DomTreeNode *A, const DomTreeNode *B) const {
return DT->properlyDominates(A, B);
}
bool properlyDominates(const BasicBlock *A, const BasicBlock *B) const {
return DT->properlyDominates(A, B);
}
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
inline const BasicBlock *findNearestCommonDominator(const BasicBlock *A,
const BasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
inline DomTreeNode *operator[](BasicBlock *BB) const {
return DT->getNode(BB);
}
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
inline DomTreeNode *getNode(BasicBlock *BB) const {
return DT->getNode(BB);
}
/// addNewBlock - Add a new node to the dominator tree information. This
/// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
return DT->addNewBlock(BB, DomBB);
}
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
inline void changeImmediateDominator(BasicBlock *N, BasicBlock* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
inline void changeImmediateDominator(DomTreeNode *N, DomTreeNode* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
/// eraseNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
inline void eraseNode(BasicBlock *BB) {
DT->eraseNode(BB);
}
/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
inline void splitBlock(BasicBlock* NewBB) {
DT->splitBlock(NewBB);
}
bool isReachableFromEntry(const BasicBlock* A) const {
return DT->isReachableFromEntry(A);
}
bool isReachableFromEntry(const Use &U) const;
virtual void releaseMemory() {
DT->releaseMemory();
}
virtual void print(raw_ostream &OS, const Module* M= 0) const;
};
//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.
///
template <> struct GraphTraits<DomTreeNode*> {
typedef DomTreeNode NodeType;
typedef NodeType::iterator ChildIteratorType;
static NodeType *getEntryNode(NodeType *N) {
return N;
}
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->end();
}
typedef df_iterator<DomTreeNode*> nodes_iterator;
static nodes_iterator nodes_begin(DomTreeNode *N) {
return df_begin(getEntryNode(N));
}
static nodes_iterator nodes_end(DomTreeNode *N) {
return df_end(getEntryNode(N));
}
};
template <> struct GraphTraits<DominatorTree*>
: public GraphTraits<DomTreeNode*> {
static NodeType *getEntryNode(DominatorTree *DT) {
return DT->getRootNode();
}
static nodes_iterator nodes_begin(DominatorTree *N) {
return df_begin(getEntryNode(N));
}
static nodes_iterator nodes_end(DominatorTree *N) {
return df_end(getEntryNode(N));
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,66 @@
//===- llvm/Analysis/FindUsedTypes.h - Find all Types in use ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is used to seek out all of the types in use by the program.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_FINDUSEDTYPES_H
#define LLVM_ANALYSIS_FINDUSEDTYPES_H
#include "llvm/ADT/SetVector.h"
#include "llvm/Pass.h"
namespace llvm {
class Type;
class Value;
class FindUsedTypes : public ModulePass {
SetVector<Type *> UsedTypes;
public:
static char ID; // Pass identification, replacement for typeid
FindUsedTypes() : ModulePass(ID) {
initializeFindUsedTypesPass(*PassRegistry::getPassRegistry());
}
/// getTypes - After the pass has been run, return the set containing all of
/// the types used in the module.
///
const SetVector<Type *> &getTypes() const { return UsedTypes; }
/// Print the types found in the module. If the optional Module parameter is
/// passed in, then the types are printed symbolically if possible, using the
/// symbol table from the module.
///
void print(raw_ostream &o, const Module *M) const;
private:
/// IncorporateType - Incorporate one type and all of its subtypes into the
/// collection of used types.
///
void IncorporateType(Type *Ty);
/// IncorporateValue - Incorporate all of the types used by this value.
///
void IncorporateValue(const Value *V);
public:
/// run - This incorporates all types used by the specified module
bool runOnModule(Module &M);
/// getAnalysisUsage - We do not modify anything.
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,184 @@
//===- llvm/Analysis/IVUsers.h - Induction Variable Users -------*- 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 bookkeeping for "interesting" users of expressions
// computed from induction variables.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_IVUSERS_H
#define LLVM_ANALYSIS_IVUSERS_H
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/Support/ValueHandle.h"
namespace llvm {
class DominatorTree;
class Instruction;
class Value;
class ScalarEvolution;
class SCEV;
class IVUsers;
class DataLayout;
/// IVStrideUse - Keep track of one use of a strided induction variable.
/// The Expr member keeps track of the expression, User is the actual user
/// instruction of the operand, and 'OperandValToReplace' is the operand of
/// the User that is the use.
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
friend class IVUsers;
public:
IVStrideUse(IVUsers *P, Instruction* U, Value *O)
: CallbackVH(U), Parent(P), OperandValToReplace(O) {
}
/// getUser - Return the user instruction for this use.
Instruction *getUser() const {
return cast<Instruction>(getValPtr());
}
/// setUser - Assign a new user instruction for this use.
void setUser(Instruction *NewUser) {
setValPtr(NewUser);
}
/// getOperandValToReplace - Return the Value of the operand in the user
/// instruction that this IVStrideUse is representing.
Value *getOperandValToReplace() const {
return OperandValToReplace;
}
/// setOperandValToReplace - Assign a new Value as the operand value
/// to replace.
void setOperandValToReplace(Value *Op) {
OperandValToReplace = Op;
}
/// getPostIncLoops - Return the set of loops for which the expression has
/// been adjusted to use post-inc mode.
const PostIncLoopSet &getPostIncLoops() const {
return PostIncLoops;
}
/// transformToPostInc - Transform the expression to post-inc form for the
/// given loop.
void transformToPostInc(const Loop *L);
private:
/// Parent - a pointer to the IVUsers that owns this IVStrideUse.
IVUsers *Parent;
/// OperandValToReplace - The Value of the operand in the user instruction
/// that this IVStrideUse is representing.
WeakVH OperandValToReplace;
/// PostIncLoops - The set of loops for which Expr has been adjusted to
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
PostIncLoopSet PostIncLoops;
/// Deleted - Implementation of CallbackVH virtual function to
/// receive notification when the User is deleted.
virtual void deleted();
};
template<> struct ilist_traits<IVStrideUse>
: public ilist_default_traits<IVStrideUse> {
// createSentinel is used to get hold of a node that marks the end of
// the list...
// The sentinel is relative to this instance, so we use a non-static
// method.
IVStrideUse *createSentinel() const {
// since i(p)lists always publicly derive from the corresponding
// traits, placing a data member in this class will augment i(p)list.
// But since the NodeTy is expected to publicly derive from
// ilist_node<NodeTy>, there is a legal viable downcast from it
// to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
// NodeTy, which becomes the sentinel. Dereferencing the sentinel is
// forbidden (save the ilist_node<NodeTy>) so no one will ever notice
// the superposition.
return static_cast<IVStrideUse*>(&Sentinel);
}
static void destroySentinel(IVStrideUse*) {}
IVStrideUse *provideInitialHead() const { return createSentinel(); }
IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
static void noteHead(IVStrideUse*, IVStrideUse*) {}
private:
mutable ilist_node<IVStrideUse> Sentinel;
};
class IVUsers : public LoopPass {
friend class IVStrideUse;
Loop *L;
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
DataLayout *TD;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
/// we are interested in.
ilist<IVStrideUse> IVUses;
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
virtual void releaseMemory();
public:
static char ID; // Pass ID, replacement for typeid
IVUsers();
Loop *getLoop() const { return L; }
/// AddUsersIfInteresting - Inspect the specified Instruction. If it is a
/// reducible SCEV, recursively add its users to the IVUsesByStride set and
/// return true. Otherwise, return false.
bool AddUsersIfInteresting(Instruction *I);
IVStrideUse &AddUser(Instruction *User, Value *Operand);
/// getReplacementExpr - Return a SCEV expression which computes the
/// value of the OperandValToReplace of the given IVStrideUse.
const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
/// getExpr - Return the expression for the use.
const SCEV *getExpr(const IVStrideUse &IU) const;
const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
typedef ilist<IVStrideUse>::iterator iterator;
typedef ilist<IVStrideUse>::const_iterator const_iterator;
iterator begin() { return IVUses.begin(); }
iterator end() { return IVUses.end(); }
const_iterator begin() const { return IVUses.begin(); }
const_iterator end() const { return IVUses.end(); }
bool empty() const { return IVUses.empty(); }
bool isIVUserOrOperand(Instruction *Inst) const {
return Processed.count(Inst);
}
void print(raw_ostream &OS, const Module* = 0) const;
/// dump - This method is used for debugging.
void dump() const;
protected:
bool AddUsersImpl(Instruction *I, SmallPtrSet<Loop*,16> &SimpleLoopNests);
};
Pass *createIVUsersPass();
}
#endif

View File

@@ -0,0 +1,143 @@
//===- InlineCost.h - Cost analysis for inliner -----------------*- 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 heuristics for inlining decisions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H
#include "llvm/Analysis/CodeMetrics.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include <cassert>
#include <climits>
namespace llvm {
class CallSite;
class DataLayout;
class Function;
class TargetTransformInfo;
namespace InlineConstants {
// Various magic constants used to adjust heuristics.
const int InstrCost = 5;
const int IndirectCallThreshold = 100;
const int CallPenalty = 25;
const int LastCallToStaticBonus = -15000;
const int ColdccPenalty = 2000;
const int NoreturnPenalty = 10000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
}
/// \brief Represents the cost of inlining a function.
///
/// This supports special values for functions which should "always" or
/// "never" be inlined. Otherwise, the cost represents a unitless amount;
/// smaller values increase the likelihood of the function being inlined.
///
/// Objects of this type also provide the adjusted threshold for inlining
/// based on the information available for a particular callsite. They can be
/// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric.
class InlineCost {
enum SentinelValues {
AlwaysInlineCost = INT_MIN,
NeverInlineCost = INT_MAX
};
/// \brief The estimated cost of inlining this callsite.
const int Cost;
/// \brief The adjusted threshold against which this cost was computed.
const int Threshold;
// Trivial constructor, interesting logic in the factory functions below.
InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {}
public:
static InlineCost get(int Cost, int Threshold) {
assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
return InlineCost(Cost, Threshold);
}
static InlineCost getAlways() {
return InlineCost(AlwaysInlineCost, 0);
}
static InlineCost getNever() {
return InlineCost(NeverInlineCost, 0);
}
/// \brief Test whether the inline cost is low enough for inlining.
operator bool() const {
return Cost < Threshold;
}
bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isNever() const { return Cost == NeverInlineCost; }
bool isVariable() const { return !isAlways() && !isNever(); }
/// \brief Get the inline cost estimate.
/// It is an error to call this on an "always" or "never" InlineCost.
int getCost() const {
assert(isVariable() && "Invalid access of InlineCost");
return Cost;
}
/// \brief Get the cost delta from the threshold for inlining.
/// Only valid if the cost is of the variable kind. Returns a negative
/// value if the cost is too high to inline.
int getCostDelta() const { return Threshold - getCost(); }
};
/// \brief Cost analyzer used by inliner.
class InlineCostAnalysis : public CallGraphSCCPass {
const DataLayout *TD;
const TargetTransformInfo *TTI;
public:
static char ID;
InlineCostAnalysis();
~InlineCostAnalysis();
// Pass interface implementation.
void getAnalysisUsage(AnalysisUsage &AU) const;
bool runOnSCC(CallGraphSCC &SCC);
/// \brief Get an InlineCost object representing the cost of inlining this
/// callsite.
///
/// Note that threshold is passed into this function. Only costs below the
/// threshold are computed with any accuracy. The threshold can be used to
/// bound the computation necessary to determine whether the cost is
/// sufficiently low to warrant inlining.
///
/// Also note that calling this function *dynamically* computes the cost of
/// inlining the callsite. It is an expensive, heavyweight call.
InlineCost getInlineCost(CallSite CS, int Threshold);
/// \brief Get an InlineCost with the callee explicitly specified.
/// This allows you to calculate the cost of inlining a function via a
/// pointer. This behaves exactly as the version with no explicit callee
/// parameter in all other respects.
//
// Note: This is used by out-of-tree passes, please do not remove without
// adding a replacement API.
InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
/// \brief Minimal filter to detect invalid constructs for inlining.
bool isInlineViable(Function &Callee);
};
}
#endif

View File

@@ -0,0 +1,274 @@
//===-- InstructionSimplify.h - Fold instructions into simpler forms ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares routines for folding instructions into simpler forms
// that do not require creating new instructions. This does constant folding
// ("add i32 1, 1" -> "2") but can also handle non-constant operands, either
// returning a constant ("and i32 %x, 0" -> "0") or an already existing value
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
// then it dominates the original instruction.
//
// These routines implicitly resolve undef uses. The easiest way to be safe when
// using these routines to obtain simplified values for existing instructions is
// to always replace all uses of the instructions with the resulting simplified
// values. This will prevent other code from seeing the same undef uses and
// resolving them to different values.
//
// These routines are designed to tolerate moderately incomplete IR, such as
// instructions that are not connected to basic blocks yet. However, they do
// require that all the IR that they encounter be valid. In particular, they
// require that all non-constant values be defined in the same function, and the
// same call context of that function (and not split between caller and callee
// contexts of a directly recursive call, for example).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#include "llvm/IR/User.h"
namespace llvm {
template<typename T>
class ArrayRef;
class DominatorTree;
class Instruction;
class DataLayout;
class FastMathFlags;
class TargetLibraryInfo;
class Type;
class Value;
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FAdd, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FSub, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// Given operands for an FMul, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFMulInst(Value *LHS, Value *RHS,
FastMathFlags FMF,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
//=== Helper functions for higher up the class hierarchy.
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Given a function and iterators over arguments, see if we can fold
/// the result.
///
/// If this call could not be simplified returns null.
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
User::op_iterator ArgEnd, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Given a function and set of arguments, see if we can fold the
/// result.
///
/// If this call could not be simplified returns null.
Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Replace all uses of 'I' with 'SimpleV' and simplify the uses
/// recursively.
///
/// This first performs a normal RAUW of I with SimpleV. It then recursively
/// attempts to simplify those users updated by the operation. The 'I'
/// instruction must not be equal to the simplified value 'SimpleV'.
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
/// \brief Recursively attempt to simplify an instruction.
///
/// This routine uses SimplifyInstruction to simplify 'I', and if successful
/// replaces uses of 'I' with the simplified value. It then recurses on each
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
const DataLayout *TD = 0,
const TargetLibraryInfo *TLI = 0,
const DominatorTree *DT = 0);
} // end namespace llvm
#endif

View File

@@ -0,0 +1,153 @@
//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the Interval class, which
// represents a set of CFG nodes and is a portion of an interval partition.
//
// Intervals have some interesting and useful properties, including the
// following:
// 1. The header node of an interval dominates all of the elements of the
// interval
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INTERVAL_H
#define LLVM_ANALYSIS_INTERVAL_H
#include "llvm/ADT/GraphTraits.h"
#include <vector>
namespace llvm {
class BasicBlock;
class raw_ostream;
//===----------------------------------------------------------------------===//
//
/// Interval Class - An Interval is a set of nodes defined such that every node
/// in the interval has all of its predecessors in the interval (except for the
/// header)
///
class Interval {
/// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
/// interval. Also, any loops in this interval must go through the HeaderNode.
///
BasicBlock *HeaderNode;
public:
typedef std::vector<BasicBlock*>::iterator succ_iterator;
typedef std::vector<BasicBlock*>::iterator pred_iterator;
typedef std::vector<BasicBlock*>::iterator node_iterator;
inline Interval(BasicBlock *Header) : HeaderNode(Header) {
Nodes.push_back(Header);
}
inline Interval(const Interval &I) // copy ctor
: HeaderNode(I.HeaderNode), Nodes(I.Nodes), Successors(I.Successors) {}
inline BasicBlock *getHeaderNode() const { return HeaderNode; }
/// Nodes - The basic blocks in this interval.
///
std::vector<BasicBlock*> Nodes;
/// Successors - List of BasicBlocks that are reachable directly from nodes in
/// this interval, but are not in the interval themselves.
/// These nodes necessarily must be header nodes for other intervals.
///
std::vector<BasicBlock*> Successors;
/// Predecessors - List of BasicBlocks that have this Interval's header block
/// as one of their successors.
///
std::vector<BasicBlock*> Predecessors;
/// contains - Find out if a basic block is in this interval
inline bool contains(BasicBlock *BB) const {
for (unsigned i = 0; i < Nodes.size(); ++i)
if (Nodes[i] == BB) return true;
return false;
// I don't want the dependency on <algorithm>
//return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
}
/// isSuccessor - find out if a basic block is a successor of this Interval
inline bool isSuccessor(BasicBlock *BB) const {
for (unsigned i = 0; i < Successors.size(); ++i)
if (Successors[i] == BB) return true;
return false;
// I don't want the dependency on <algorithm>
//return find(Successors.begin(), Successors.end(), BB) != Successors.end();
}
/// Equality operator. It is only valid to compare two intervals from the
/// same partition, because of this, all we have to check is the header node
/// for equality.
///
inline bool operator==(const Interval &I) const {
return HeaderNode == I.HeaderNode;
}
/// isLoop - Find out if there is a back edge in this interval...
bool isLoop() const;
/// print - Show contents in human readable format...
void print(raw_ostream &O) const;
};
/// succ_begin/succ_end - define methods so that Intervals may be used
/// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
///
inline Interval::succ_iterator succ_begin(Interval *I) {
return I->Successors.begin();
}
inline Interval::succ_iterator succ_end(Interval *I) {
return I->Successors.end();
}
/// pred_begin/pred_end - define methods so that Intervals may be used
/// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
///
inline Interval::pred_iterator pred_begin(Interval *I) {
return I->Predecessors.begin();
}
inline Interval::pred_iterator pred_end(Interval *I) {
return I->Predecessors.end();
}
template <> struct GraphTraits<Interval*> {
typedef Interval NodeType;
typedef Interval::succ_iterator ChildIteratorType;
static NodeType *getEntryNode(Interval *I) { return I; }
/// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
static inline ChildIteratorType child_begin(NodeType *N) {
return succ_begin(N);
}
static inline ChildIteratorType child_end(NodeType *N) {
return succ_end(N);
}
};
template <> struct GraphTraits<Inverse<Interval*> > {
typedef Interval NodeType;
typedef Interval::pred_iterator ChildIteratorType;
static NodeType *getEntryNode(Inverse<Interval *> G) { return G.Graph; }
static inline ChildIteratorType child_begin(NodeType *N) {
return pred_begin(N);
}
static inline ChildIteratorType child_end(NodeType *N) {
return pred_end(N);
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,259 @@
//===- IntervalIterator.h - Interval Iterator Declaration -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines an iterator that enumerates the intervals in a control flow
// graph of some sort. This iterator is parametric, allowing iterator over the
// following types of graphs:
//
// 1. A Function* object, composed of BasicBlock nodes.
// 2. An IntervalPartition& object, composed of Interval nodes.
//
// This iterator is defined to walk the control flow graph, returning intervals
// in depth first order. These intervals are completely filled in except for
// the predecessor fields (the successor information is filled in however).
//
// By default, the intervals created by this iterator are deleted after they
// are no longer any use to the iterator. This behavior can be changed by
// passing a false value into the intervals_begin() function. This causes the
// IOwnMem member to be set, and the intervals to not be deleted.
//
// It is only safe to use this if all of the intervals are deleted by the caller
// and all of the intervals are processed. However, the user of the iterator is
// not allowed to modify or delete the intervals until after the iterator has
// been used completely. The IntervalPartition class uses this functionality.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
#define LLVM_ANALYSIS_INTERVALITERATOR_H
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <set>
#include <vector>
namespace llvm {
// getNodeHeader - Given a source graph node and the source graph, return the
// BasicBlock that is the header node. This is the opposite of
// getSourceGraphNode.
//
inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }
// getSourceGraphNode - Given a BasicBlock and the source graph, return the
// source graph node that corresponds to the BasicBlock. This is the opposite
// of getNodeHeader.
//
inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
return BB;
}
inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
return IP->getBlockInterval(BB);
}
// addNodeToInterval - This method exists to assist the generic ProcessNode
// with the task of adding a node to the new interval, depending on the
// type of the source node. In the case of a CFG source graph (BasicBlock
// case), the BasicBlock itself is added to the interval.
//
inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
Int->Nodes.push_back(BB);
}
// addNodeToInterval - This method exists to assist the generic ProcessNode
// with the task of adding a node to the new interval, depending on the
// type of the source node. In the case of a CFG source graph (BasicBlock
// case), the BasicBlock itself is added to the interval. In the case of
// an IntervalPartition source graph (Interval case), all of the member
// BasicBlocks are added to the interval.
//
inline void addNodeToInterval(Interval *Int, Interval *I) {
// Add all of the nodes in I as new nodes in Int.
copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes));
}
template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy*>,
class IGT = GraphTraits<Inverse<NodeTy*> > >
class IntervalIterator {
std::vector<std::pair<Interval*, typename Interval::succ_iterator> > IntStack;
std::set<BasicBlock*> Visited;
OrigContainer_t *OrigContainer;
bool IOwnMem; // If True, delete intervals when done with them
// See file header for conditions of use
public:
typedef IntervalIterator<NodeTy, OrigContainer_t> _Self;
typedef std::forward_iterator_tag iterator_category;
IntervalIterator() {} // End iterator, empty stack
IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
OrigContainer = M;
if (!ProcessInterval(&M->front())) {
llvm_unreachable("ProcessInterval should never fail for first interval!");
}
}
IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
OrigContainer = &IP;
if (!ProcessInterval(IP.getRootInterval())) {
llvm_unreachable("ProcessInterval should never fail for first interval!");
}
}
inline ~IntervalIterator() {
if (IOwnMem)
while (!IntStack.empty()) {
delete operator*();
IntStack.pop_back();
}
}
inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
inline bool operator!=(const _Self& x) const { return !operator==(x); }
inline const Interval *operator*() const { return IntStack.back().first; }
inline Interval *operator*() { return IntStack.back().first; }
inline const Interval *operator->() const { return operator*(); }
inline Interval *operator->() { return operator*(); }
_Self& operator++() { // Preincrement
assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
do {
// All of the intervals on the stack have been visited. Try visiting
// their successors now.
Interval::succ_iterator &SuccIt = IntStack.back().second,
EndIt = succ_end(IntStack.back().first);
while (SuccIt != EndIt) { // Loop over all interval succs
bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
++SuccIt; // Increment iterator
if (Done) return *this; // Found a new interval! Use it!
}
// Free interval memory... if necessary
if (IOwnMem) delete IntStack.back().first;
// We ran out of successors for this interval... pop off the stack
IntStack.pop_back();
} while (!IntStack.empty());
return *this;
}
inline _Self operator++(int) { // Postincrement
_Self tmp = *this; ++*this; return tmp;
}
private:
// ProcessInterval - This method is used during the construction of the
// interval graph. It walks through the source graph, recursively creating
// an interval per invocation until the entire graph is covered. This uses
// the ProcessNode method to add all of the nodes to the interval.
//
// This method is templated because it may operate on two different source
// graphs: a basic block graph, or a preexisting interval graph.
//
bool ProcessInterval(NodeTy *Node) {
BasicBlock *Header = getNodeHeader(Node);
if (Visited.count(Header)) return false;
Interval *Int = new Interval(Header);
Visited.insert(Header); // The header has now been visited!
// Check all of our successors to see if they are in the interval...
for (typename GT::ChildIteratorType I = GT::child_begin(Node),
E = GT::child_end(Node); I != E; ++I)
ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));
IntStack.push_back(std::make_pair(Int, succ_begin(Int)));
return true;
}
// ProcessNode - This method is called by ProcessInterval to add nodes to the
// interval being constructed, and it is also called recursively as it walks
// the source graph. A node is added to the current interval only if all of
// its predecessors are already in the graph. This also takes care of keeping
// the successor set of an interval up to date.
//
// This method is templated because it may operate on two different source
// graphs: a basic block graph, or a preexisting interval graph.
//
void ProcessNode(Interval *Int, NodeTy *Node) {
assert(Int && "Null interval == bad!");
assert(Node && "Null Node == bad!");
BasicBlock *NodeHeader = getNodeHeader(Node);
if (Visited.count(NodeHeader)) { // Node already been visited?
if (Int->contains(NodeHeader)) { // Already in this interval...
return;
} else { // In other interval, add as successor
if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
Int->Successors.push_back(NodeHeader);
}
} else { // Otherwise, not in interval yet
for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
E = IGT::child_end(Node); I != E; ++I) {
if (!Int->contains(*I)) { // If pred not in interval, we can't be
if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
Int->Successors.push_back(NodeHeader);
return; // See you later
}
}
// If we get here, then all of the predecessors of BB are in the interval
// already. In this case, we must add BB to the interval!
addNodeToInterval(Int, Node);
Visited.insert(NodeHeader); // The node has now been visited!
if (Int->isSuccessor(NodeHeader)) {
// If we were in the successor list from before... remove from succ list
Int->Successors.erase(std::remove(Int->Successors.begin(),
Int->Successors.end(), NodeHeader),
Int->Successors.end());
}
// Now that we have discovered that Node is in the interval, perhaps some
// of its successors are as well?
for (typename GT::ChildIteratorType It = GT::child_begin(Node),
End = GT::child_end(Node); It != End; ++It)
ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
}
}
};
typedef IntervalIterator<BasicBlock, Function> function_interval_iterator;
typedef IntervalIterator<Interval, IntervalPartition>
interval_part_interval_iterator;
inline function_interval_iterator intervals_begin(Function *F,
bool DeleteInts = true) {
return function_interval_iterator(F, DeleteInts);
}
inline function_interval_iterator intervals_end(Function *) {
return function_interval_iterator();
}
inline interval_part_interval_iterator
intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
return interval_part_interval_iterator(IP, DeleteIntervals);
}
inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
return interval_part_interval_iterator();
}
} // End llvm namespace
#endif

View File

@@ -0,0 +1,111 @@
//===- IntervalPartition.h - Interval partition Calculation -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the IntervalPartition class, which
// calculates and represents the interval partition of a function, or a
// preexisting interval partition.
//
// In this way, the interval partition may be used to reduce a flow graph down
// to its degenerate single node interval partition (unless it is irreducible).
//
// TODO: The IntervalPartition class should take a bool parameter that tells
// whether it should add the "tails" of an interval to an interval itself or if
// they should be represented as distinct intervals.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
#define LLVM_ANALYSIS_INTERVALPARTITION_H
#include "llvm/Analysis/Interval.h"
#include "llvm/Pass.h"
#include <map>
namespace llvm {
//===----------------------------------------------------------------------===//
//
// IntervalPartition - This class builds and holds an "interval partition" for
// a function. This partition divides the control flow graph into a set of
// maximal intervals, as defined with the properties above. Intuitively, an
// interval is a (possibly nonexistent) loop with a "tail" of non looping
// nodes following it.
//
class IntervalPartition : public FunctionPass {
typedef std::map<BasicBlock*, Interval*> IntervalMapTy;
IntervalMapTy IntervalMap;
typedef std::vector<Interval*> IntervalListTy;
Interval *RootInterval;
std::vector<Interval*> Intervals;
public:
static char ID; // Pass identification, replacement for typeid
IntervalPartition() : FunctionPass(ID), RootInterval(0) {
initializeIntervalPartitionPass(*PassRegistry::getPassRegistry());
}
// run - Calculate the interval partition for this function
virtual bool runOnFunction(Function &F);
// IntervalPartition ctor - Build a reduced interval partition from an
// existing interval graph. This takes an additional boolean parameter to
// distinguish it from a copy constructor. Always pass in false for now.
//
IntervalPartition(IntervalPartition &I, bool);
// print - Show contents in human readable format...
virtual void print(raw_ostream &O, const Module* = 0) const;
// getRootInterval() - Return the root interval that contains the starting
// block of the function.
inline Interval *getRootInterval() { return RootInterval; }
// isDegeneratePartition() - Returns true if the interval partition contains
// a single interval, and thus cannot be simplified anymore.
bool isDegeneratePartition() { return Intervals.size() == 1; }
// TODO: isIrreducible - look for triangle graph.
// getBlockInterval - Return the interval that a basic block exists in.
inline Interval *getBlockInterval(BasicBlock *BB) {
IntervalMapTy::iterator I = IntervalMap.find(BB);
return I != IntervalMap.end() ? I->second : 0;
}
// getAnalysisUsage - Implement the Pass API
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
// Interface to Intervals vector...
const std::vector<Interval*> &getIntervals() const { return Intervals; }
// releaseMemory - Reset state back to before function was analyzed
void releaseMemory();
private:
// addIntervalToPartition - Add an interval to the internal list of intervals,
// and then add mappings from all of the basic blocks in the interval to the
// interval itself (in the IntervalMap).
//
void addIntervalToPartition(Interval *I);
// updatePredecessors - Interval generation only sets the successor fields of
// the interval data structures. After interval generation is complete,
// run through all of the intervals and propagate successor info as
// predecessor info.
//
void updatePredecessors(Interval *Int);
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,81 @@
//===- LazyValueInfo.h - Value constraint analysis --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for lazy computation of value constraint
// information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LAZYVALUEINFO_H
#define LLVM_ANALYSIS_LAZYVALUEINFO_H
#include "llvm/Pass.h"
namespace llvm {
class Constant;
class DataLayout;
class TargetLibraryInfo;
class Value;
/// LazyValueInfo - This pass computes, caches, and vends lazy value constraint
/// information.
class LazyValueInfo : public FunctionPass {
class DataLayout *TD;
class TargetLibraryInfo *TLI;
void *PImpl;
LazyValueInfo(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
void operator=(const LazyValueInfo&) LLVM_DELETED_FUNCTION;
public:
static char ID;
LazyValueInfo() : FunctionPass(ID), PImpl(0) {
initializeLazyValueInfoPass(*PassRegistry::getPassRegistry());
}
~LazyValueInfo() { assert(PImpl == 0 && "releaseMemory not called"); }
/// Tristate - This is used to return true/false/dunno results.
enum Tristate {
Unknown = -1, False = 0, True = 1
};
// Public query interface.
/// getPredicateOnEdge - Determine whether the specified value comparison
/// with a constant is known to be true or false on the specified CFG edge.
/// Pred is a CmpInst predicate.
Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
BasicBlock *FromBB, BasicBlock *ToBB);
/// getConstant - Determine whether the specified value is known to be a
/// constant at the end of the specified block. Return null if not.
Constant *getConstant(Value *V, BasicBlock *BB);
/// getConstantOnEdge - Determine whether the specified value is known to be a
/// constant on the specified edge. Return null if not.
Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB);
/// threadEdge - Inform the analysis cache that we have threaded an edge from
/// PredBB to OldSucc to be from PredBB to NewSucc instead.
void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc);
/// eraseBlock - Inform the analysis cache that we have erased a block.
void eraseBlock(BasicBlock *BB);
// Implementation boilerplate.
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void releaseMemory();
virtual bool runOnFunction(Function &F);
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,73 @@
//===- LibCallAliasAnalysis.h - Implement AliasAnalysis for libcalls ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the LibCallAliasAnalysis class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Pass.h"
namespace llvm {
class LibCallInfo;
struct LibCallFunctionInfo;
/// LibCallAliasAnalysis - Alias analysis driven from LibCallInfo.
struct LibCallAliasAnalysis : public FunctionPass, public AliasAnalysis {
static char ID; // Class identification
LibCallInfo *LCI;
explicit LibCallAliasAnalysis(LibCallInfo *LC = 0)
: FunctionPass(ID), LCI(LC) {
initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
}
explicit LibCallAliasAnalysis(char &ID, LibCallInfo *LC)
: FunctionPass(ID), LCI(LC) {
initializeLibCallAliasAnalysisPass(*PassRegistry::getPassRegistry());
}
~LibCallAliasAnalysis();
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Location &Loc);
ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) {
// TODO: Could compare two direct calls against each other if we cared to.
return AliasAnalysis::getModRefInfo(CS1, CS2);
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnFunction(Function &F) {
InitializeAliasAnalysis(this); // set up super class
return false;
}
/// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it
/// should override this to adjust the this pointer as needed for the
/// specified pass info.
virtual void *getAdjustedAnalysisPointer(const void *PI) {
if (PI == &AliasAnalysis::ID)
return (AliasAnalysis*)this;
return this;
}
private:
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
ImmutableCallSite CS,
const Location &Loc);
};
} // End of llvm namespace
#endif

View File

@@ -0,0 +1,167 @@
//===- LibCallSemantics.h - Describe library semantics --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines interfaces that can be used to describe language specific
// runtime library interfaces (e.g. libc, libm, etc) to LLVM optimizers.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LIBCALLSEMANTICS_H
#define LLVM_ANALYSIS_LIBCALLSEMANTICS_H
#include "llvm/Analysis/AliasAnalysis.h"
namespace llvm {
/// LibCallLocationInfo - This struct describes a set of memory locations that
/// are accessed by libcalls. Identification of a location is doing with a
/// simple callback function.
///
/// For example, the LibCallInfo may be set up to model the behavior of
/// standard libm functions. The location that they may be interested in is
/// an abstract location that represents errno for the current target. In
/// this case, a location for errno is anything such that the predicate
/// returns true. On Mac OS/X, this predicate would return true if the
/// pointer is the result of a call to "__error()".
///
/// Locations can also be defined in a constant-sensitive way. For example,
/// it is possible to define a location that returns true iff it is passed
/// into the call as a specific argument. This is useful for modeling things
/// like "printf", which can store to memory, but only through pointers passed
/// with a '%n' constraint.
///
struct LibCallLocationInfo {
// TODO: Flags: isContextSensitive etc.
/// isLocation - Return a LocResult if the specified pointer refers to this
/// location for the specified call site. This returns "Yes" if we can tell
/// that the pointer *does definitely* refer to the location, "No" if we can
/// tell that the location *definitely does not* refer to the location, and
/// returns "Unknown" if we cannot tell for certain.
enum LocResult {
Yes, No, Unknown
};
LocResult (*isLocation)(ImmutableCallSite CS,
const AliasAnalysis::Location &Loc);
};
/// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
/// records the behavior of one libcall that is known by the optimizer. This
/// captures things like the side effects of the call. Side effects are
/// modeled both universally (in the readnone/readonly) sense, but also
/// potentially against a set of abstract locations defined by the optimizer.
/// This allows an optimizer to define that some libcall (e.g. sqrt) is
/// side-effect free except that it might modify errno (thus, the call is
/// *not* universally readonly). Or it might say that the side effects
/// are unknown other than to say that errno is not modified.
///
struct LibCallFunctionInfo {
/// Name - This is the name of the libcall this describes.
const char *Name;
/// TODO: Constant folding function: Constant* vector -> Constant*.
/// UniversalBehavior - This captures the absolute mod/ref behavior without
/// any specific context knowledge. For example, if the function is known
/// to be readonly, this would be set to 'ref'. If known to be readnone,
/// this is set to NoModRef.
AliasAnalysis::ModRefResult UniversalBehavior;
/// LocationMRInfo - This pair captures info about whether a specific
/// location is modified or referenced by a libcall.
struct LocationMRInfo {
/// LocationID - ID # of the accessed location or ~0U for array end.
unsigned LocationID;
/// MRInfo - Mod/Ref info for this location.
AliasAnalysis::ModRefResult MRInfo;
};
/// DetailsType - Indicate the sense of the LocationDetails array. This
/// controls how the LocationDetails array is interpreted.
enum {
/// DoesOnly - If DetailsType is set to DoesOnly, then we know that the
/// *only* mod/ref behavior of this function is captured by the
/// LocationDetails array. If we are trying to say that 'sqrt' can only
/// modify errno, we'd have the {errnoloc,mod} in the LocationDetails
/// array and have DetailsType set to DoesOnly.
DoesOnly,
/// DoesNot - If DetailsType is set to DoesNot, then the sense of the
/// LocationDetails array is completely inverted. This means that we *do
/// not* know everything about the side effects of this libcall, but we do
/// know things that the libcall cannot do. This is useful for complex
/// functions like 'ctime' which have crazy mod/ref behavior, but are
/// known to never read or write errno. In this case, we'd have
/// {errnoloc,modref} in the LocationDetails array and DetailsType would
/// be set to DoesNot, indicating that ctime does not read or write the
/// errno location.
DoesNot
} DetailsType;
/// LocationDetails - This is a pointer to an array of LocationMRInfo
/// structs which indicates the behavior of the libcall w.r.t. specific
/// locations. For example, if this libcall is known to only modify
/// 'errno', it would have a LocationDetails array with the errno ID and
/// 'mod' in it. See the DetailsType field for how this is interpreted.
///
/// In the "DoesOnly" case, this information is 'may' information for: there
/// is no guarantee that the specified side effect actually does happen,
/// just that it could. In the "DoesNot" case, this is 'must not' info.
///
/// If this pointer is null, no details are known.
///
const LocationMRInfo *LocationDetails;
};
/// LibCallInfo - Abstract interface to query about library call information.
/// Instances of this class return known information about some set of
/// libcalls.
///
class LibCallInfo {
// Implementation details of this object, private.
mutable void *Impl;
mutable const LibCallLocationInfo *Locations;
mutable unsigned NumLocations;
public:
LibCallInfo() : Impl(0), Locations(0), NumLocations(0) {}
virtual ~LibCallInfo();
//===------------------------------------------------------------------===//
// Accessor Methods: Efficient access to contained data.
//===------------------------------------------------------------------===//
/// getLocationInfo - Return information about the specified LocationID.
const LibCallLocationInfo &getLocationInfo(unsigned LocID) const;
/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
/// the specified function if we have it. If not, return null.
const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;
//===------------------------------------------------------------------===//
// Implementation Methods: Subclasses should implement these.
//===------------------------------------------------------------------===//
/// getLocationInfo - Return descriptors for the locations referenced by
/// this set of libcalls.
virtual unsigned getLocationInfo(const LibCallLocationInfo *&Array) const {
return 0;
}
/// getFunctionInfoArray - Return an array of descriptors that describe the
/// set of libcalls represented by this LibCallInfo object. This array is
/// terminated by an entry with a NULL name.
virtual const LibCallFunctionInfo *getFunctionInfoArray() const = 0;
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,49 @@
//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines lint interfaces that can be used for some sanity checking
// of input to the system, and for checking that transformations
// haven't done something bad. In contrast to the Verifier, the Lint checker
// checks for undefined behavior or constructions with likely unintended
// behavior.
//
// To see what specifically is checked, look at Lint.cpp
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LINT_H
#define LLVM_ANALYSIS_LINT_H
namespace llvm {
class FunctionPass;
class Module;
class Function;
/// @brief Create a lint pass.
///
/// Check a module or function.
FunctionPass *createLintPass();
/// @brief Check a module.
///
/// This should only be used for debugging, because it plays games with
/// PassManagers and stuff.
void lintModule(
const Module &M ///< The module to be checked
);
// lintFunction - Check a function.
void lintFunction(
const Function &F ///< The function to be checked
);
} // End llvm namespace
#endif

View File

@@ -0,0 +1,57 @@
//===- Loads.h - Local load analysis --------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares simple local analyses for load instructions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOADS_H
#define LLVM_ANALYSIS_LOADS_H
#include "llvm/IR/BasicBlock.h"
namespace llvm {
class AliasAnalysis;
class DataLayout;
class MDNode;
/// isSafeToLoadUnconditionally - Return true if we know that executing a load
/// from this value cannot trap. If it is not obviously safe to load from the
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
unsigned Align, const DataLayout *TD = 0);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at
/// the memory address *Ptr locally available within a small number of
/// instructions. If the value is available, return it.
///
/// If not, return the iterator for the last validated instruction that the
/// value would be live through. If we scanned the entire block and didn't
/// find something that invalidates *Ptr or provides it, ScanFrom would be
/// left at begin() and this returns null. ScanFrom could also be left
///
/// MaxInstsToScan specifies the maximum instructions to scan in the block.
/// If it is set to 0, it will scan the whole block. You can also optionally
/// specify an alias analysis implementation, which makes this more precise.
///
/// If TBAATag is non-null and a load or store is found, the TBAA tag from the
/// load or store is recorded there. If there is no TBAA tag or if no access
/// is found, it is left unmodified.
Value *FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan = 6,
AliasAnalysis *AA = 0,
MDNode **TBAATag = 0);
}
#endif

View File

@@ -0,0 +1,124 @@
//===- llvm/Analysis/LoopDependenceAnalysis.h --------------- -*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// LoopDependenceAnalysis is an LLVM pass that analyses dependences in memory
// accesses in loops.
//
// Please note that this is work in progress and the interface is subject to
// change.
//
// TODO: adapt as interface progresses
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
class AliasAnalysis;
class AnalysisUsage;
class ScalarEvolution;
class SCEV;
class Value;
class raw_ostream;
class LoopDependenceAnalysis : public LoopPass {
AliasAnalysis *AA;
ScalarEvolution *SE;
/// L - The loop we are currently analysing.
Loop *L;
/// TODO: doc
enum DependenceResult { Independent = 0, Dependent = 1, Unknown = 2 };
/// TODO: doc
struct Subscript {
/// TODO: Add distance, direction, breaking conditions, ...
};
/// DependencePair - Represents a data dependence relation between to memory
/// reference instructions.
struct DependencePair : public FastFoldingSetNode {
Value *A;
Value *B;
DependenceResult Result;
SmallVector<Subscript, 4> Subscripts;
DependencePair(const FoldingSetNodeID &ID, Value *a, Value *b) :
FastFoldingSetNode(ID), A(a), B(b), Result(Unknown), Subscripts() {}
};
/// findOrInsertDependencePair - Return true if a DependencePair for the
/// given Values already exists, false if a new DependencePair had to be
/// created. The third argument is set to the pair found or created.
bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
/// getLoops - Collect all loops of the loop nest L in which
/// a given SCEV is variant.
void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
/// isLoopInvariant - True if a given SCEV is invariant in all loops of the
/// loop nest starting at the innermost loop L.
bool isLoopInvariant(const SCEV*) const;
/// isAffine - An SCEV is affine with respect to the loop nest starting at
/// the innermost loop L if it is of the form A+B*X where A, B are invariant
/// in the loop nest and X is a induction variable in the loop nest.
bool isAffine(const SCEV*) const;
/// TODO: doc
bool isZIVPair(const SCEV*, const SCEV*) const;
bool isSIVPair(const SCEV*, const SCEV*) const;
DependenceResult analyseZIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseMIV(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const;
DependenceResult analysePair(DependencePair*) const;
public:
static char ID; // Class identification, replacement for typeinfo
LoopDependenceAnalysis() : LoopPass(ID) {
initializeLoopDependenceAnalysisPass(*PassRegistry::getPassRegistry());
}
/// isDependencePair - Check whether two values can possibly give rise to
/// a data dependence: that is the case if both are instructions accessing
/// memory and at least one of those accesses is a write.
bool isDependencePair(const Value*, const Value*) const;
/// depends - Return a boolean indicating if there is a data dependence
/// between two instructions.
bool depends(Value*, Value*);
bool runOnLoop(Loop*, LPPassManager&);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage&) const;
void print(raw_ostream&, const Module* = 0) const;
private:
FoldingSet<DependencePair> Pairs;
BumpPtrAllocator PairAllocator;
}; // class LoopDependenceAnalysis
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//
LoopPass *createLoopDependenceAnalysisPass();
} // namespace llvm
#endif /* LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H */

View File

@@ -0,0 +1,710 @@
//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the LoopInfo class that is used to identify natural loops
// and determine the loop depth of various nodes of the CFG. A natural loop
// has exactly one entry-point, which is called the header. Note that natural
// loops may actually be several loops that share the same header node.
//
// This analysis calculates the nesting structure of loops in a function. For
// each natural loop identified, this analysis identifies natural loops
// contained entirely within the loop and the basic blocks the make up the loop.
//
// It can calculate on the fly various bits of information, for example:
//
// * whether there is a preheader for the loop
// * the number of back edges to the header
// * whether or not a particular block branches out of the loop
// * the successor blocks of the loop
// * the loop depth
// * etc...
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOPINFO_H
#define LLVM_ANALYSIS_LOOPINFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Pass.h"
#include <algorithm>
namespace llvm {
template<typename T>
inline void RemoveFromVector(std::vector<T*> &V, T *N) {
typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
assert(I != V.end() && "N is not in this list!");
V.erase(I);
}
class DominatorTree;
class LoopInfo;
class Loop;
class PHINode;
class raw_ostream;
template<class N, class M> class LoopInfoBase;
template<class N, class M> class LoopBase;
//===----------------------------------------------------------------------===//
/// LoopBase class - Instances of this class are used to represent loops that
/// are detected in the flow graph
///
template<class BlockT, class LoopT>
class LoopBase {
LoopT *ParentLoop;
// SubLoops - Loops contained entirely within this one.
std::vector<LoopT *> SubLoops;
// Blocks - The list of blocks in this loop. First entry is the header node.
std::vector<BlockT*> Blocks;
LoopBase(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
const LoopBase<BlockT, LoopT>&
operator=(const LoopBase<BlockT, LoopT> &) LLVM_DELETED_FUNCTION;
public:
/// Loop ctor - This creates an empty loop.
LoopBase() : ParentLoop(0) {}
~LoopBase() {
for (size_t i = 0, e = SubLoops.size(); i != e; ++i)
delete SubLoops[i];
}
/// getLoopDepth - Return the nesting level of this loop. An outer-most
/// loop has depth 1, for consistency with loop depth values used for basic
/// blocks, where depth 0 is used for blocks not inside any loops.
unsigned getLoopDepth() const {
unsigned D = 1;
for (const LoopT *CurLoop = ParentLoop; CurLoop;
CurLoop = CurLoop->ParentLoop)
++D;
return D;
}
BlockT *getHeader() const { return Blocks.front(); }
LoopT *getParentLoop() const { return ParentLoop; }
/// setParentLoop is a raw interface for bypassing addChildLoop.
void setParentLoop(LoopT *L) { ParentLoop = L; }
/// contains - Return true if the specified loop is contained within in
/// this loop.
///
bool contains(const LoopT *L) const {
if (L == this) return true;
if (L == 0) return false;
return contains(L->getParentLoop());
}
/// contains - Return true if the specified basic block is in this loop.
///
bool contains(const BlockT *BB) const {
return std::find(block_begin(), block_end(), BB) != block_end();
}
/// contains - Return true if the specified instruction is in this loop.
///
template<class InstT>
bool contains(const InstT *Inst) const {
return contains(Inst->getParent());
}
/// iterator/begin/end - Return the loops contained entirely within this loop.
///
const std::vector<LoopT *> &getSubLoops() const { return SubLoops; }
std::vector<LoopT *> &getSubLoopsVector() { return SubLoops; }
typedef typename std::vector<LoopT *>::const_iterator iterator;
typedef typename std::vector<LoopT *>::const_reverse_iterator
reverse_iterator;
iterator begin() const { return SubLoops.begin(); }
iterator end() const { return SubLoops.end(); }
reverse_iterator rbegin() const { return SubLoops.rbegin(); }
reverse_iterator rend() const { return SubLoops.rend(); }
bool empty() const { return SubLoops.empty(); }
/// getBlocks - Get a list of the basic blocks which make up this loop.
///
const std::vector<BlockT*> &getBlocks() const { return Blocks; }
std::vector<BlockT*> &getBlocksVector() { return Blocks; }
typedef typename std::vector<BlockT*>::const_iterator block_iterator;
block_iterator block_begin() const { return Blocks.begin(); }
block_iterator block_end() const { return Blocks.end(); }
/// getNumBlocks - Get the number of blocks in this loop in constant time.
unsigned getNumBlocks() const {
return Blocks.size();
}
/// isLoopExiting - True if terminator in the block can branch to another
/// block that is outside of the current loop.
///
bool isLoopExiting(const BlockT *BB) const {
typedef GraphTraits<const BlockT*> BlockTraits;
for (typename BlockTraits::ChildIteratorType SI =
BlockTraits::child_begin(BB),
SE = BlockTraits::child_end(BB); SI != SE; ++SI) {
if (!contains(*SI))
return true;
}
return false;
}
/// getNumBackEdges - Calculate the number of back edges to the loop header
///
unsigned getNumBackEdges() const {
unsigned NumBackEdges = 0;
BlockT *H = getHeader();
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType I =
InvBlockTraits::child_begin(H),
E = InvBlockTraits::child_end(H); I != E; ++I)
if (contains(*I))
++NumBackEdges;
return NumBackEdges;
}
//===--------------------------------------------------------------------===//
// APIs for simple analysis of the loop.
//
// Note that all of these methods can fail on general loops (ie, there may not
// be a preheader, etc). For best success, the loop simplification and
// induction variable canonicalization pass should be used to normalize loops
// for easy analysis. These methods assume canonical loops.
/// getExitingBlocks - Return all blocks inside the loop that have successors
/// outside of the loop. These are the blocks _inside of the current loop_
/// which branch out. The returned list is always unique.
///
void getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const;
/// getExitingBlock - If getExitingBlocks would return exactly one block,
/// return that block. Otherwise return null.
BlockT *getExitingBlock() const;
/// getExitBlocks - Return all of the successor blocks of this loop. These
/// are the blocks _outside of the current loop_ which are branched to.
///
void getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const;
/// getExitBlock - If getExitBlocks would return exactly one block,
/// return that block. Otherwise return null.
BlockT *getExitBlock() const;
/// Edge type.
typedef std::pair<const BlockT*, const BlockT*> Edge;
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
void getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const;
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
/// from outside of the loop. If this is the case, the block branching to the
/// header of the loop is the preheader node.
///
/// This method returns null if there is no preheader for the loop.
///
BlockT *getLoopPreheader() const;
/// getLoopPredecessor - If the given loop's header has exactly one unique
/// predecessor outside the loop, return it. Otherwise return null.
/// This is less strict that the loop "preheader" concept, which requires
/// the predecessor to have exactly one successor.
///
BlockT *getLoopPredecessor() const;
/// getLoopLatch - If there is a single latch block for this loop, return it.
/// A latch block is a block that contains a branch back to the header.
BlockT *getLoopLatch() const;
//===--------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
//
/// addBasicBlockToLoop - This method is used by other analyses to update loop
/// information. NewBB is set to be a new member of the current loop.
/// Because of this, it is added as a member of all parent loops, and is added
/// to the specified LoopInfo object as being in the current basic block. It
/// is not valid to replace the loop header with this method.
///
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LI);
/// replaceChildLoopWith - This is used when splitting loops up. It replaces
/// the OldChild entry in our children list with NewChild, and updates the
/// parent pointer of OldChild to be null and the NewChild to be this loop.
/// This updates the loop depth of the new child.
void replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild);
/// addChildLoop - Add the specified loop to be a child of this loop. This
/// updates the loop depth of the new child.
///
void addChildLoop(LoopT *NewChild) {
assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
NewChild->ParentLoop = static_cast<LoopT *>(this);
SubLoops.push_back(NewChild);
}
/// removeChildLoop - This removes the specified child from being a subloop of
/// this loop. The loop is not deleted, as it will presumably be inserted
/// into another loop.
LoopT *removeChildLoop(iterator I) {
assert(I != SubLoops.end() && "Cannot remove end iterator!");
LoopT *Child = *I;
assert(Child->ParentLoop == this && "Child is not a child of this loop!");
SubLoops.erase(SubLoops.begin()+(I-begin()));
Child->ParentLoop = 0;
return Child;
}
/// addBlockEntry - This adds a basic block directly to the basic block list.
/// This should only be used by transformations that create new loops. Other
/// transformations should use addBasicBlockToLoop.
void addBlockEntry(BlockT *BB) {
Blocks.push_back(BB);
}
/// moveToHeader - This method is used to move BB (which must be part of this
/// loop) to be the loop header of the loop (the block that dominates all
/// others).
void moveToHeader(BlockT *BB) {
if (Blocks[0] == BB) return;
for (unsigned i = 0; ; ++i) {
assert(i != Blocks.size() && "Loop does not contain BB!");
if (Blocks[i] == BB) {
Blocks[i] = Blocks[0];
Blocks[0] = BB;
return;
}
}
}
/// removeBlockFromLoop - This removes the specified basic block from the
/// current loop, updating the Blocks as appropriate. This does not update
/// the mapping in the LoopInfo class.
void removeBlockFromLoop(BlockT *BB) {
RemoveFromVector(Blocks, BB);
}
/// verifyLoop - Verify loop structure
void verifyLoop() const;
/// verifyLoop - Verify loop structure of this loop and all nested loops.
void verifyLoopNest(DenseSet<const LoopT*> *Loops) const;
void print(raw_ostream &OS, unsigned Depth = 0) const;
protected:
friend class LoopInfoBase<BlockT, LoopT>;
explicit LoopBase(BlockT *BB) : ParentLoop(0) {
Blocks.push_back(BB);
}
};
template<class BlockT, class LoopT>
raw_ostream& operator<<(raw_ostream &OS, const LoopBase<BlockT, LoopT> &Loop) {
Loop.print(OS);
return OS;
}
// Implementation in LoopInfoImpl.h
#ifdef __GNUC__
__extension__ extern template class LoopBase<BasicBlock, Loop>;
#endif
class Loop : public LoopBase<BasicBlock, Loop> {
public:
Loop() {}
/// isLoopInvariant - Return true if the specified value is loop invariant
///
bool isLoopInvariant(Value *V) const;
/// hasLoopInvariantOperands - Return true if all the operands of the
/// specified instruction are loop invariant.
bool hasLoopInvariantOperands(Instruction *I) const;
/// makeLoopInvariant - If the given value is an instruction inside of the
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
/// Return true if the value after any hoisting is loop invariant. This
/// function can be used as a slightly more aggressive replacement for
/// isLoopInvariant.
///
/// If InsertPt is specified, it is the point to hoist instructions to.
/// If null, the terminator of the loop preheader is used.
///
bool makeLoopInvariant(Value *V, bool &Changed,
Instruction *InsertPt = 0) const;
/// makeLoopInvariant - If the given instruction is inside of the
/// loop and it can be hoisted, do so to make it trivially loop-invariant.
/// Return true if the instruction after any hoisting is loop invariant. This
/// function can be used as a slightly more aggressive replacement for
/// isLoopInvariant.
///
/// If InsertPt is specified, it is the point to hoist instructions to.
/// If null, the terminator of the loop preheader is used.
///
bool makeLoopInvariant(Instruction *I, bool &Changed,
Instruction *InsertPt = 0) const;
/// getCanonicalInductionVariable - Check to see if the loop has a canonical
/// induction variable: an integer recurrence that starts at 0 and increments
/// by one each time through the loop. If so, return the phi node that
/// corresponds to it.
///
/// The IndVarSimplify pass transforms loops to have a canonical induction
/// variable.
///
PHINode *getCanonicalInductionVariable() const;
/// isLCSSAForm - Return true if the Loop is in LCSSA form
bool isLCSSAForm(DominatorTree &DT) const;
/// isLoopSimplifyForm - Return true if the Loop is in the form that
/// the LoopSimplify form transforms loops to, which is sometimes called
/// normal form.
bool isLoopSimplifyForm() const;
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
bool isSafeToClone() const;
/// Returns true if the loop is annotated parallel.
///
/// A parallel loop can be assumed to not contain any dependencies between
/// iterations by the compiler. That is, any loop-carried dependency checking
/// can be skipped completely when parallelizing the loop on the target
/// machine. Thus, if the parallel loop information originates from the
/// programmer, e.g. via the OpenMP parallel for pragma, it is the
/// programmer's responsibility to ensure there are no loop-carried
/// dependencies. The final execution order of the instructions across
/// iterations is not guaranteed, thus, the end result might or might not
/// implement actual concurrent execution of instructions across multiple
/// iterations.
bool isAnnotatedParallel() const;
/// hasDedicatedExits - Return true if no exit block for the loop
/// has a predecessor that is outside the loop.
bool hasDedicatedExits() const;
/// getUniqueExitBlocks - Return all unique successor blocks of this loop.
/// These are the blocks _outside of the current loop_ which are branched to.
/// This assumes that loop exits are in canonical form.
///
void getUniqueExitBlocks(SmallVectorImpl<BasicBlock *> &ExitBlocks) const;
/// getUniqueExitBlock - If getUniqueExitBlocks would return exactly one
/// block, return that block. Otherwise return null.
BasicBlock *getUniqueExitBlock() const;
void dump() const;
private:
friend class LoopInfoBase<BasicBlock, Loop>;
explicit Loop(BasicBlock *BB) : LoopBase<BasicBlock, Loop>(BB) {}
};
//===----------------------------------------------------------------------===//
/// LoopInfo - This class builds and contains all of the top level loop
/// structures in the specified function.
///
template<class BlockT, class LoopT>
class LoopInfoBase {
// BBMap - Mapping of basic blocks to the inner most loop they occur in
DenseMap<BlockT *, LoopT *> BBMap;
std::vector<LoopT *> TopLevelLoops;
friend class LoopBase<BlockT, LoopT>;
friend class LoopInfo;
void operator=(const LoopInfoBase &) LLVM_DELETED_FUNCTION;
LoopInfoBase(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
LoopInfoBase() { }
~LoopInfoBase() { releaseMemory(); }
void releaseMemory() {
for (typename std::vector<LoopT *>::iterator I =
TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I)
delete *I; // Delete all of the loops...
BBMap.clear(); // Reset internal state of analysis
TopLevelLoops.clear();
}
/// iterator/begin/end - The interface to the top-level loops in the current
/// function.
///
typedef typename std::vector<LoopT *>::const_iterator iterator;
typedef typename std::vector<LoopT *>::const_reverse_iterator
reverse_iterator;
iterator begin() const { return TopLevelLoops.begin(); }
iterator end() const { return TopLevelLoops.end(); }
reverse_iterator rbegin() const { return TopLevelLoops.rbegin(); }
reverse_iterator rend() const { return TopLevelLoops.rend(); }
bool empty() const { return TopLevelLoops.empty(); }
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
/// block is in no loop (for example the entry node), null is returned.
///
LoopT *getLoopFor(const BlockT *BB) const {
return BBMap.lookup(const_cast<BlockT*>(BB));
}
/// operator[] - same as getLoopFor...
///
const LoopT *operator[](const BlockT *BB) const {
return getLoopFor(BB);
}
/// getLoopDepth - Return the loop nesting level of the specified block. A
/// depth of 0 means the block is not inside any loop.
///
unsigned getLoopDepth(const BlockT *BB) const {
const LoopT *L = getLoopFor(BB);
return L ? L->getLoopDepth() : 0;
}
// isLoopHeader - True if the block is a loop header node
bool isLoopHeader(BlockT *BB) const {
const LoopT *L = getLoopFor(BB);
return L && L->getHeader() == BB;
}
/// removeLoop - This removes the specified top-level loop from this loop info
/// object. The loop is not deleted, as it will presumably be inserted into
/// another loop.
LoopT *removeLoop(iterator I) {
assert(I != end() && "Cannot remove end iterator!");
LoopT *L = *I;
assert(L->getParentLoop() == 0 && "Not a top-level loop!");
TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin()));
return L;
}
/// changeLoopFor - Change the top-level loop that contains BB to the
/// specified loop. This should be used by transformations that restructure
/// the loop hierarchy tree.
void changeLoopFor(BlockT *BB, LoopT *L) {
if (!L) {
BBMap.erase(BB);
return;
}
BBMap[BB] = L;
}
/// changeTopLevelLoop - Replace the specified loop in the top-level loops
/// list with the indicated loop.
void changeTopLevelLoop(LoopT *OldLoop,
LoopT *NewLoop) {
typename std::vector<LoopT *>::iterator I =
std::find(TopLevelLoops.begin(), TopLevelLoops.end(), OldLoop);
assert(I != TopLevelLoops.end() && "Old loop not at top level!");
*I = NewLoop;
assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 &&
"Loops already embedded into a subloop!");
}
/// addTopLevelLoop - This adds the specified loop to the collection of
/// top-level loops.
void addTopLevelLoop(LoopT *New) {
assert(New->getParentLoop() == 0 && "Loop already in subloop!");
TopLevelLoops.push_back(New);
}
/// removeBlock - This method completely removes BB from all data structures,
/// including all of the Loop objects it is nested in and our mapping from
/// BasicBlocks to loops.
void removeBlock(BlockT *BB) {
typename DenseMap<BlockT *, LoopT *>::iterator I = BBMap.find(BB);
if (I != BBMap.end()) {
for (LoopT *L = I->second; L; L = L->getParentLoop())
L->removeBlockFromLoop(BB);
BBMap.erase(I);
}
}
// Internals
static bool isNotAlreadyContainedIn(const LoopT *SubLoop,
const LoopT *ParentLoop) {
if (SubLoop == 0) return true;
if (SubLoop == ParentLoop) return false;
return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
}
/// Create the loop forest using a stable algorithm.
void Analyze(DominatorTreeBase<BlockT> &DomTree);
// Debugging
void print(raw_ostream &OS) const;
};
// Implementation in LoopInfoImpl.h
#ifdef __GNUC__
__extension__ extern template class LoopInfoBase<BasicBlock, Loop>;
#endif
class LoopInfo : public FunctionPass {
LoopInfoBase<BasicBlock, Loop> LI;
friend class LoopBase<BasicBlock, Loop>;
void operator=(const LoopInfo &) LLVM_DELETED_FUNCTION;
LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
public:
static char ID; // Pass identification, replacement for typeid
LoopInfo() : FunctionPass(ID) {
initializeLoopInfoPass(*PassRegistry::getPassRegistry());
}
LoopInfoBase<BasicBlock, Loop>& getBase() { return LI; }
/// iterator/begin/end - The interface to the top-level loops in the current
/// function.
///
typedef LoopInfoBase<BasicBlock, Loop>::iterator iterator;
typedef LoopInfoBase<BasicBlock, Loop>::reverse_iterator reverse_iterator;
inline iterator begin() const { return LI.begin(); }
inline iterator end() const { return LI.end(); }
inline reverse_iterator rbegin() const { return LI.rbegin(); }
inline reverse_iterator rend() const { return LI.rend(); }
bool empty() const { return LI.empty(); }
/// getLoopFor - Return the inner most loop that BB lives in. If a basic
/// block is in no loop (for example the entry node), null is returned.
///
inline Loop *getLoopFor(const BasicBlock *BB) const {
return LI.getLoopFor(BB);
}
/// operator[] - same as getLoopFor...
///
inline const Loop *operator[](const BasicBlock *BB) const {
return LI.getLoopFor(BB);
}
/// getLoopDepth - Return the loop nesting level of the specified block. A
/// depth of 0 means the block is not inside any loop.
///
inline unsigned getLoopDepth(const BasicBlock *BB) const {
return LI.getLoopDepth(BB);
}
// isLoopHeader - True if the block is a loop header node
inline bool isLoopHeader(BasicBlock *BB) const {
return LI.isLoopHeader(BB);
}
/// runOnFunction - Calculate the natural loop information.
///
virtual bool runOnFunction(Function &F);
virtual void verifyAnalysis() const;
virtual void releaseMemory() { LI.releaseMemory(); }
virtual void print(raw_ostream &O, const Module* M = 0) const;
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// removeLoop - This removes the specified top-level loop from this loop info
/// object. The loop is not deleted, as it will presumably be inserted into
/// another loop.
inline Loop *removeLoop(iterator I) { return LI.removeLoop(I); }
/// changeLoopFor - Change the top-level loop that contains BB to the
/// specified loop. This should be used by transformations that restructure
/// the loop hierarchy tree.
inline void changeLoopFor(BasicBlock *BB, Loop *L) {
LI.changeLoopFor(BB, L);
}
/// changeTopLevelLoop - Replace the specified loop in the top-level loops
/// list with the indicated loop.
inline void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) {
LI.changeTopLevelLoop(OldLoop, NewLoop);
}
/// addTopLevelLoop - This adds the specified loop to the collection of
/// top-level loops.
inline void addTopLevelLoop(Loop *New) {
LI.addTopLevelLoop(New);
}
/// removeBlock - This method completely removes BB from all data structures,
/// including all of the Loop objects it is nested in and our mapping from
/// BasicBlocks to loops.
void removeBlock(BasicBlock *BB) {
LI.removeBlock(BB);
}
/// updateUnloop - Update LoopInfo after removing the last backedge from a
/// loop--now the "unloop". This updates the loop forest and parent loops for
/// each block so that Unloop is no longer referenced, but the caller must
/// actually delete the Unloop object.
void updateUnloop(Loop *Unloop);
/// replacementPreservesLCSSAForm - Returns true if replacing From with To
/// everywhere is guaranteed to preserve LCSSA form.
bool replacementPreservesLCSSAForm(Instruction *From, Value *To) {
// Preserving LCSSA form is only problematic if the replacing value is an
// instruction.
Instruction *I = dyn_cast<Instruction>(To);
if (!I) return true;
// If both instructions are defined in the same basic block then replacement
// cannot break LCSSA form.
if (I->getParent() == From->getParent())
return true;
// If the instruction is not defined in a loop then it can safely replace
// anything.
Loop *ToLoop = getLoopFor(I->getParent());
if (!ToLoop) return true;
// If the replacing instruction is defined in the same loop as the original
// instruction, or in a loop that contains it as an inner loop, then using
// it as a replacement will not break LCSSA form.
return ToLoop->contains(getLoopFor(From->getParent()));
}
};
// Allow clients to walk the list of nested loops...
template <> struct GraphTraits<const Loop*> {
typedef const Loop NodeType;
typedef LoopInfo::iterator ChildIteratorType;
static NodeType *getEntryNode(const Loop *L) { return L; }
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->end();
}
};
template <> struct GraphTraits<Loop*> {
typedef Loop NodeType;
typedef LoopInfo::iterator ChildIteratorType;
static NodeType *getEntryNode(Loop *L) { return L; }
static inline ChildIteratorType child_begin(NodeType *N) {
return N->begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->end();
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,570 @@
//===- llvm/Analysis/LoopInfoImpl.h - Natural Loop Calculator ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the generic implementation of LoopInfo used for both Loops and
// MachineLoops.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
#define LLVM_ANALYSIS_LOOPINFOIMPL_H
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm {
//===----------------------------------------------------------------------===//
// APIs for simple analysis of the loop. See header notes.
/// getExitingBlocks - Return all blocks inside the loop that have successors
/// outside of the loop. These are the blocks _inside of the current loop_
/// which branch out. The returned list is always unique.
///
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitingBlocks(SmallVectorImpl<BlockT *> &ExitingBlocks) const {
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
std::sort(LoopBBs.begin(), LoopBBs.end());
typedef GraphTraits<BlockT*> BlockTraits;
for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
for (typename BlockTraits::ChildIteratorType I =
BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
I != E; ++I)
if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) {
// Not in current loop? It must be an exit block.
ExitingBlocks.push_back(*BI);
break;
}
}
/// getExitingBlock - If getExitingBlocks would return exactly one block,
/// return that block. Otherwise return null.
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getExitingBlock() const {
SmallVector<BlockT*, 8> ExitingBlocks;
getExitingBlocks(ExitingBlocks);
if (ExitingBlocks.size() == 1)
return ExitingBlocks[0];
return 0;
}
/// getExitBlocks - Return all of the successor blocks of this loop. These
/// are the blocks _outside of the current loop_ which are branched to.
///
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitBlocks(SmallVectorImpl<BlockT*> &ExitBlocks) const {
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
std::sort(LoopBBs.begin(), LoopBBs.end());
typedef GraphTraits<BlockT*> BlockTraits;
for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
for (typename BlockTraits::ChildIteratorType I =
BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
I != E; ++I)
if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
// Not in current loop? It must be an exit block.
ExitBlocks.push_back(*I);
}
/// getExitBlock - If getExitBlocks would return exactly one block,
/// return that block. Otherwise return null.
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getExitBlock() const {
SmallVector<BlockT*, 8> ExitBlocks;
getExitBlocks(ExitBlocks);
if (ExitBlocks.size() == 1)
return ExitBlocks[0];
return 0;
}
/// getExitEdges - Return all pairs of (_inside_block_,_outside_block_).
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const {
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
array_pod_sort(LoopBBs.begin(), LoopBBs.end());
typedef GraphTraits<BlockT*> BlockTraits;
for (block_iterator BI = block_begin(), BE = block_end(); BI != BE; ++BI)
for (typename BlockTraits::ChildIteratorType I =
BlockTraits::child_begin(*BI), E = BlockTraits::child_end(*BI);
I != E; ++I)
if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
// Not in current loop? It must be an exit block.
ExitEdges.push_back(Edge(*BI, *I));
}
/// getLoopPreheader - If there is a preheader for this loop, return it. A
/// loop has a preheader if there is only one edge to the header of the loop
/// from outside of the loop. If this is the case, the block branching to the
/// header of the loop is the preheader node.
///
/// This method returns null if there is no preheader for the loop.
///
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const {
// Keep track of nodes outside the loop branching to the header...
BlockT *Out = getLoopPredecessor();
if (!Out) return 0;
// Make sure there is only one exit out of the preheader.
typedef GraphTraits<BlockT*> BlockTraits;
typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out);
++SI;
if (SI != BlockTraits::child_end(Out))
return 0; // Multiple exits from the block, must not be a preheader.
// The predecessor has exactly one successor, so it is a preheader.
return Out;
}
/// getLoopPredecessor - If the given loop's header has exactly one unique
/// predecessor outside the loop, return it. Otherwise return null.
/// This is less strict that the loop "preheader" concept, which requires
/// the predecessor to have exactly one successor.
///
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getLoopPredecessor() const {
// Keep track of nodes outside the loop branching to the header...
BlockT *Out = 0;
// Loop over the predecessors of the header node...
BlockT *Header = getHeader();
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header),
PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
typename InvBlockTraits::NodeType *N = *PI;
if (!contains(N)) { // If the block is not in the loop...
if (Out && Out != N)
return 0; // Multiple predecessors outside the loop
Out = N;
}
}
// Make sure there is only one exit out of the preheader.
assert(Out && "Header of loop has no predecessors from outside loop?");
return Out;
}
/// getLoopLatch - If there is a single latch block for this loop, return it.
/// A latch block is a block that contains a branch back to the header.
template<class BlockT, class LoopT>
BlockT *LoopBase<BlockT, LoopT>::getLoopLatch() const {
BlockT *Header = getHeader();
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header);
typename InvBlockTraits::ChildIteratorType PE =
InvBlockTraits::child_end(Header);
BlockT *Latch = 0;
for (; PI != PE; ++PI) {
typename InvBlockTraits::NodeType *N = *PI;
if (contains(N)) {
if (Latch) return 0;
Latch = N;
}
}
return Latch;
}
//===----------------------------------------------------------------------===//
// APIs for updating loop information after changing the CFG
//
/// addBasicBlockToLoop - This method is used by other analyses to update loop
/// information. NewBB is set to be a new member of the current loop.
/// Because of this, it is added as a member of all parent loops, and is added
/// to the specified LoopInfo object as being in the current basic block. It
/// is not valid to replace the loop header with this method.
///
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase<BlockT, LoopT> &LIB) {
assert((Blocks.empty() || LIB[getHeader()] == this) &&
"Incorrect LI specified for this loop!");
assert(NewBB && "Cannot add a null basic block to the loop!");
assert(LIB[NewBB] == 0 && "BasicBlock already in the loop!");
LoopT *L = static_cast<LoopT *>(this);
// Add the loop mapping to the LoopInfo object...
LIB.BBMap[NewBB] = L;
// Add the basic block to this loop and all parent loops...
while (L) {
L->Blocks.push_back(NewBB);
L = L->getParentLoop();
}
}
/// replaceChildLoopWith - This is used when splitting loops up. It replaces
/// the OldChild entry in our children list with NewChild, and updates the
/// parent pointer of OldChild to be null and the NewChild to be this loop.
/// This updates the loop depth of the new child.
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::
replaceChildLoopWith(LoopT *OldChild, LoopT *NewChild) {
assert(OldChild->ParentLoop == this && "This loop is already broken!");
assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
typename std::vector<LoopT *>::iterator I =
std::find(SubLoops.begin(), SubLoops.end(), OldChild);
assert(I != SubLoops.end() && "OldChild not in loop!");
*I = NewChild;
OldChild->ParentLoop = 0;
NewChild->ParentLoop = static_cast<LoopT *>(this);
}
/// verifyLoop - Verify loop structure
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::verifyLoop() const {
#ifndef NDEBUG
assert(!Blocks.empty() && "Loop header is missing");
// Setup for using a depth-first iterator to visit every block in the loop.
SmallVector<BlockT*, 8> ExitBBs;
getExitBlocks(ExitBBs);
llvm::SmallPtrSet<BlockT*, 8> VisitSet;
VisitSet.insert(ExitBBs.begin(), ExitBBs.end());
df_ext_iterator<BlockT*, llvm::SmallPtrSet<BlockT*, 8> >
BI = df_ext_begin(getHeader(), VisitSet),
BE = df_ext_end(getHeader(), VisitSet);
// Keep track of the number of BBs visited.
unsigned NumVisited = 0;
// Sort the blocks vector so that we can use binary search to do quick
// lookups.
SmallVector<BlockT*, 128> LoopBBs(block_begin(), block_end());
std::sort(LoopBBs.begin(), LoopBBs.end());
// Check the individual blocks.
for ( ; BI != BE; ++BI) {
BlockT *BB = *BI;
bool HasInsideLoopSuccs = false;
bool HasInsideLoopPreds = false;
SmallVector<BlockT *, 2> OutsideLoopPreds;
typedef GraphTraits<BlockT*> BlockTraits;
for (typename BlockTraits::ChildIteratorType SI =
BlockTraits::child_begin(BB), SE = BlockTraits::child_end(BB);
SI != SE; ++SI)
if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *SI)) {
HasInsideLoopSuccs = true;
break;
}
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(BB), PE = InvBlockTraits::child_end(BB);
PI != PE; ++PI) {
BlockT *N = *PI;
if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), N))
HasInsideLoopPreds = true;
else
OutsideLoopPreds.push_back(N);
}
if (BB == getHeader()) {
assert(!OutsideLoopPreds.empty() && "Loop is unreachable!");
} else if (!OutsideLoopPreds.empty()) {
// A non-header loop shouldn't be reachable from outside the loop,
// though it is permitted if the predecessor is not itself actually
// reachable.
BlockT *EntryBB = BB->getParent()->begin();
for (df_iterator<BlockT *> NI = df_begin(EntryBB),
NE = df_end(EntryBB); NI != NE; ++NI)
for (unsigned i = 0, e = OutsideLoopPreds.size(); i != e; ++i)
assert(*NI != OutsideLoopPreds[i] &&
"Loop has multiple entry points!");
}
assert(HasInsideLoopPreds && "Loop block has no in-loop predecessors!");
assert(HasInsideLoopSuccs && "Loop block has no in-loop successors!");
assert(BB != getHeader()->getParent()->begin() &&
"Loop contains function entry block!");
NumVisited++;
}
assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
// Check the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)
// Each block in each subloop should be contained within this loop.
for (block_iterator BI = (*I)->block_begin(), BE = (*I)->block_end();
BI != BE; ++BI) {
assert(std::binary_search(LoopBBs.begin(), LoopBBs.end(), *BI) &&
"Loop does not contain all the blocks of a subloop!");
}
// Check the parent loop pointer.
if (ParentLoop) {
assert(std::find(ParentLoop->begin(), ParentLoop->end(), this) !=
ParentLoop->end() &&
"Loop is not a subloop of its parent!");
}
#endif
}
/// verifyLoop - Verify loop structure of this loop and all nested loops.
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::verifyLoopNest(
DenseSet<const LoopT*> *Loops) const {
Loops->insert(static_cast<const LoopT *>(this));
// Verify this loop.
verifyLoop();
// Verify the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)
(*I)->verifyLoopNest(Loops);
}
template<class BlockT, class LoopT>
void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth) const {
OS.indent(Depth*2) << "Loop at depth " << getLoopDepth()
<< " containing: ";
for (unsigned i = 0; i < getBlocks().size(); ++i) {
if (i) OS << ",";
BlockT *BB = getBlocks()[i];
WriteAsOperand(OS, BB, false);
if (BB == getHeader()) OS << "<header>";
if (BB == getLoopLatch()) OS << "<latch>";
if (isLoopExiting(BB)) OS << "<exiting>";
}
OS << "\n";
for (iterator I = begin(), E = end(); I != E; ++I)
(*I)->print(OS, Depth+2);
}
//===----------------------------------------------------------------------===//
/// Stable LoopInfo Analysis - Build a loop tree using stable iterators so the
/// result does / not depend on use list (block predecessor) order.
///
/// Discover a subloop with the specified backedges such that: All blocks within
/// this loop are mapped to this loop or a subloop. And all subloops within this
/// loop have their parent loop set to this loop or a subloop.
template<class BlockT, class LoopT>
static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
LoopInfoBase<BlockT, LoopT> *LI,
DominatorTreeBase<BlockT> &DomTree) {
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
unsigned NumBlocks = 0;
unsigned NumSubloops = 0;
// Perform a backward CFG traversal using a worklist.
std::vector<BlockT *> ReverseCFGWorklist(Backedges.begin(), Backedges.end());
while (!ReverseCFGWorklist.empty()) {
BlockT *PredBB = ReverseCFGWorklist.back();
ReverseCFGWorklist.pop_back();
LoopT *Subloop = LI->getLoopFor(PredBB);
if (!Subloop) {
if (!DomTree.isReachableFromEntry(PredBB))
continue;
// This is an undiscovered block. Map it to the current loop.
LI->changeLoopFor(PredBB, L);
++NumBlocks;
if (PredBB == L->getHeader())
continue;
// Push all block predecessors on the worklist.
ReverseCFGWorklist.insert(ReverseCFGWorklist.end(),
InvBlockTraits::child_begin(PredBB),
InvBlockTraits::child_end(PredBB));
}
else {
// This is a discovered block. Find its outermost discovered loop.
while (LoopT *Parent = Subloop->getParentLoop())
Subloop = Parent;
// If it is already discovered to be a subloop of this loop, continue.
if (Subloop == L)
continue;
// Discover a subloop of this loop.
Subloop->setParentLoop(L);
++NumSubloops;
NumBlocks += Subloop->getBlocks().capacity();
PredBB = Subloop->getHeader();
// Continue traversal along predecessors that are not loop-back edges from
// within this subloop tree itself. Note that a predecessor may directly
// reach another subloop that is not yet discovered to be a subloop of
// this loop, which we must traverse.
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(PredBB),
PE = InvBlockTraits::child_end(PredBB); PI != PE; ++PI) {
if (LI->getLoopFor(*PI) != Subloop)
ReverseCFGWorklist.push_back(*PI);
}
}
}
L->getSubLoopsVector().reserve(NumSubloops);
L->getBlocksVector().reserve(NumBlocks);
}
namespace {
/// Populate all loop data in a stable order during a single forward DFS.
template<class BlockT, class LoopT>
class PopulateLoopsDFS {
typedef GraphTraits<BlockT*> BlockTraits;
typedef typename BlockTraits::ChildIteratorType SuccIterTy;
LoopInfoBase<BlockT, LoopT> *LI;
DenseSet<const BlockT *> VisitedBlocks;
std::vector<std::pair<BlockT*, SuccIterTy> > DFSStack;
public:
PopulateLoopsDFS(LoopInfoBase<BlockT, LoopT> *li):
LI(li) {}
void traverse(BlockT *EntryBlock);
protected:
void insertIntoLoop(BlockT *Block);
BlockT *dfsSource() { return DFSStack.back().first; }
SuccIterTy &dfsSucc() { return DFSStack.back().second; }
SuccIterTy dfsSuccEnd() { return BlockTraits::child_end(dfsSource()); }
void pushBlock(BlockT *Block) {
DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block)));
}
};
} // anonymous
/// Top-level driver for the forward DFS within the loop.
template<class BlockT, class LoopT>
void PopulateLoopsDFS<BlockT, LoopT>::traverse(BlockT *EntryBlock) {
pushBlock(EntryBlock);
VisitedBlocks.insert(EntryBlock);
while (!DFSStack.empty()) {
// Traverse the leftmost path as far as possible.
while (dfsSucc() != dfsSuccEnd()) {
BlockT *BB = *dfsSucc();
++dfsSucc();
if (!VisitedBlocks.insert(BB).second)
continue;
// Push the next DFS successor onto the stack.
pushBlock(BB);
}
// Visit the top of the stack in postorder and backtrack.
insertIntoLoop(dfsSource());
DFSStack.pop_back();
}
}
/// Add a single Block to its ancestor loops in PostOrder. If the block is a
/// subloop header, add the subloop to its parent in PostOrder, then reverse the
/// Block and Subloop vectors of the now complete subloop to achieve RPO.
template<class BlockT, class LoopT>
void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
LoopT *Subloop = LI->getLoopFor(Block);
if (Subloop && Block == Subloop->getHeader()) {
// We reach this point once per subloop after processing all the blocks in
// the subloop.
if (Subloop->getParentLoop())
Subloop->getParentLoop()->getSubLoopsVector().push_back(Subloop);
else
LI->addTopLevelLoop(Subloop);
// For convenience, Blocks and Subloops are inserted in postorder. Reverse
// the lists, except for the loop header, which is always at the beginning.
std::reverse(Subloop->getBlocksVector().begin()+1,
Subloop->getBlocksVector().end());
std::reverse(Subloop->getSubLoopsVector().begin(),
Subloop->getSubLoopsVector().end());
Subloop = Subloop->getParentLoop();
}
for (; Subloop; Subloop = Subloop->getParentLoop())
Subloop->getBlocksVector().push_back(Block);
}
/// Analyze LoopInfo discovers loops during a postorder DominatorTree traversal
/// interleaved with backward CFG traversals within each subloop
/// (discoverAndMapSubloop). The backward traversal skips inner subloops, so
/// this part of the algorithm is linear in the number of CFG edges. Subloop and
/// Block vectors are then populated during a single forward CFG traversal
/// (PopulateLoopDFS).
///
/// During the two CFG traversals each block is seen three times:
/// 1) Discovered and mapped by a reverse CFG traversal.
/// 2) Visited during a forward DFS CFG traversal.
/// 3) Reverse-inserted in the loop in postorder following forward DFS.
///
/// The Block vectors are inclusive, so step 3 requires loop-depth number of
/// insertions per block.
template<class BlockT, class LoopT>
void LoopInfoBase<BlockT, LoopT>::
Analyze(DominatorTreeBase<BlockT> &DomTree) {
// Postorder traversal of the dominator tree.
DomTreeNodeBase<BlockT>* DomRoot = DomTree.getRootNode();
for (po_iterator<DomTreeNodeBase<BlockT>*> DomIter = po_begin(DomRoot),
DomEnd = po_end(DomRoot); DomIter != DomEnd; ++DomIter) {
BlockT *Header = DomIter->getBlock();
SmallVector<BlockT *, 4> Backedges;
// Check each predecessor of the potential loop header.
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
for (typename InvBlockTraits::ChildIteratorType PI =
InvBlockTraits::child_begin(Header),
PE = InvBlockTraits::child_end(Header); PI != PE; ++PI) {
BlockT *Backedge = *PI;
// If Header dominates predBB, this is a new loop. Collect the backedges.
if (DomTree.dominates(Header, Backedge)
&& DomTree.isReachableFromEntry(Backedge)) {
Backedges.push_back(Backedge);
}
}
// Perform a backward CFG traversal to discover and map blocks in this loop.
if (!Backedges.empty()) {
LoopT *L = new LoopT(Header);
discoverAndMapSubloop(L, ArrayRef<BlockT*>(Backedges), this, DomTree);
}
}
// Perform a single forward CFG traversal to populate block and subloop
// vectors for all loops.
PopulateLoopsDFS<BlockT, LoopT> DFS(this);
DFS.traverse(DomRoot->getBlock());
}
// Debugging
template<class BlockT, class LoopT>
void LoopInfoBase<BlockT, LoopT>::print(raw_ostream &OS) const {
for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
TopLevelLoops[i]->print(OS);
#if 0
for (DenseMap<BasicBlock*, LoopT*>::const_iterator I = BBMap.begin(),
E = BBMap.end(); I != E; ++I)
OS << "BB '" << I->first->getName() << "' level = "
<< I->second->getLoopDepth() << "\n";
#endif
}
} // End llvm namespace
#endif

View File

@@ -0,0 +1,181 @@
//===--------- LoopIterator.h - Iterate over loop blocks --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This file defines iterators to visit the basic blocks within a loop.
//
// These iterators currently visit blocks within subloops as well.
// Unfortunately we have no efficient way of summarizing loop exits which would
// allow skipping subloops during traversal.
//
// If you want to visit all blocks in a loop and don't need an ordered traveral,
// use Loop::block_begin() instead.
//
// This is intentionally designed to work with ill-formed loops in which the
// backedge has been deleted. The only prerequisite is that all blocks
// contained within the loop according to the most recent LoopInfo analysis are
// reachable from the loop header.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
#define LLVM_ANALYSIS_LOOPITERATOR_H
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm {
class LoopBlocksTraversal;
/// Store the result of a depth first search within basic blocks contained by a
/// single loop.
///
/// TODO: This could be generalized for any CFG region, or the entire CFG.
class LoopBlocksDFS {
public:
/// Postorder list iterators.
typedef std::vector<BasicBlock*>::const_iterator POIterator;
typedef std::vector<BasicBlock*>::const_reverse_iterator RPOIterator;
friend class LoopBlocksTraversal;
private:
Loop *L;
/// Map each block to its postorder number. A block is only mapped after it is
/// preorder visited by DFS. It's postorder number is initially zero and set
/// to nonzero after it is finished by postorder traversal.
DenseMap<BasicBlock*, unsigned> PostNumbers;
std::vector<BasicBlock*> PostBlocks;
public:
LoopBlocksDFS(Loop *Container) :
L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) {
PostBlocks.reserve(Container->getNumBlocks());
}
Loop *getLoop() const { return L; }
/// Traverse the loop blocks and store the DFS result.
void perform(LoopInfo *LI);
/// Return true if postorder numbers are assigned to all loop blocks.
bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); }
/// Iterate over the cached postorder blocks.
POIterator beginPostorder() const {
assert(isComplete() && "bad loop DFS");
return PostBlocks.begin();
}
POIterator endPostorder() const { return PostBlocks.end(); }
/// Reverse iterate over the cached postorder blocks.
RPOIterator beginRPO() const {
assert(isComplete() && "bad loop DFS");
return PostBlocks.rbegin();
}
RPOIterator endRPO() const { return PostBlocks.rend(); }
/// Return true if this block has been preorder visited.
bool hasPreorder(BasicBlock *BB) const { return PostNumbers.count(BB); }
/// Return true if this block has a postorder number.
bool hasPostorder(BasicBlock *BB) const {
DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
return I != PostNumbers.end() && I->second;
}
/// Get a block's postorder number.
unsigned getPostorder(BasicBlock *BB) const {
DenseMap<BasicBlock*, unsigned>::const_iterator I = PostNumbers.find(BB);
assert(I != PostNumbers.end() && "block not visited by DFS");
assert(I->second && "block not finished by DFS");
return I->second;
}
/// Get a block's reverse postorder number.
unsigned getRPO(BasicBlock *BB) const {
return 1 + PostBlocks.size() - getPostorder(BB);
}
void clear() {
PostNumbers.clear();
PostBlocks.clear();
}
};
/// Specialize po_iterator_storage to record postorder numbers.
template<> class po_iterator_storage<LoopBlocksTraversal, true> {
LoopBlocksTraversal &LBT;
public:
po_iterator_storage(LoopBlocksTraversal &lbs) : LBT(lbs) {}
// These functions are defined below.
bool insertEdge(BasicBlock *From, BasicBlock *To);
void finishPostorder(BasicBlock *BB);
};
/// Traverse the blocks in a loop using a depth-first search.
class LoopBlocksTraversal {
public:
/// Graph traversal iterator.
typedef po_iterator<BasicBlock*, LoopBlocksTraversal, true> POTIterator;
private:
LoopBlocksDFS &DFS;
LoopInfo *LI;
public:
LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo) :
DFS(Storage), LI(LInfo) {}
/// Postorder traversal over the graph. This only needs to be done once.
/// po_iterator "automatically" calls back to visitPreorder and
/// finishPostorder to record the DFS result.
POTIterator begin() {
assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing");
assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph");
return po_ext_begin(DFS.L->getHeader(), *this);
}
POTIterator end() {
// po_ext_end interface requires a basic block, but ignores its value.
return po_ext_end(DFS.L->getHeader(), *this);
}
/// Called by po_iterator upon reaching a block via a CFG edge. If this block
/// is contained in the loop and has not been visited, then mark it preorder
/// visited and return true.
///
/// TODO: If anyone is interested, we could record preorder numbers here.
bool visitPreorder(BasicBlock *BB) {
if (!DFS.L->contains(LI->getLoopFor(BB)))
return false;
return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second;
}
/// Called by po_iterator each time it advances, indicating a block's
/// postorder.
void finishPostorder(BasicBlock *BB) {
assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder");
DFS.PostBlocks.push_back(BB);
DFS.PostNumbers[BB] = DFS.PostBlocks.size();
}
};
inline bool po_iterator_storage<LoopBlocksTraversal, true>::
insertEdge(BasicBlock *From, BasicBlock *To) {
return LBT.visitPreorder(To);
}
inline void po_iterator_storage<LoopBlocksTraversal, true>::
finishPostorder(BasicBlock *BB) {
LBT.finishPostorder(BB);
}
} // End namespace llvm
#endif

View File

@@ -0,0 +1,160 @@
//===- LoopPass.h - LoopPass class ----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines LoopPass class. All loop optimization
// and transformation passes are derived from LoopPass.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_LOOPPASS_H
#define LLVM_ANALYSIS_LOOPPASS_H
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
#include <deque>
namespace llvm {
class LPPassManager;
class Function;
class PMStack;
class LoopPass : public Pass {
public:
explicit LoopPass(char &pid) : Pass(PT_Loop, pid) {}
/// getPrinterPass - Get a pass to print the function corresponding
/// to a Loop.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
// runOnLoop - This method should be implemented by the subclass to perform
// whatever action is necessary for the specified Loop.
virtual bool runOnLoop(Loop *L, LPPassManager &LPM) = 0;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
// Initialization and finalization hooks.
virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
return false;
}
// Finalization hook does not supply Loop because at this time
// loop nest is completely different.
virtual bool doFinalization() { return false; }
// Check if this pass is suitable for the current LPPassManager, if
// available. This pass P is not suitable for a LPPassManager if P
// is not preserving higher level analysis info used by other
// LPPassManager passes. In such case, pop LPPassManager from the
// stack. This will force assignPassManager() to create new
// LPPassManger as expected.
void preparePassManager(PMStack &PMS);
/// Assign pass manager to manage this pass
virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT);
/// Return what kind of Pass Manager can manage this pass.
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_LoopPassManager;
}
//===--------------------------------------------------------------------===//
/// SimpleAnalysis - Provides simple interface to update analysis info
/// maintained by various passes. Note, if required this interface can
/// be extracted into a separate abstract class but it would require
/// additional use of multiple inheritance in Pass class hierarchy, something
/// we are trying to avoid.
/// Each loop pass can override these simple analysis hooks to update
/// desired analysis information.
/// cloneBasicBlockAnalysis - Clone analysis info associated with basic block.
virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {}
/// deleteAnalysisValue - Delete analysis info associated with value V.
virtual void deleteAnalysisValue(Value *V, Loop *L) {}
};
class LPPassManager : public FunctionPass, public PMDataManager {
public:
static char ID;
explicit LPPassManager();
/// run - Execute all of the passes scheduled for execution. Keep track of
/// whether any of the passes modifies the module, and if so, return true.
bool runOnFunction(Function &F);
/// Pass Manager itself does not invalidate any analysis info.
// LPPassManager needs LoopInfo.
void getAnalysisUsage(AnalysisUsage &Info) const;
virtual const char *getPassName() const {
return "Loop Pass Manager";
}
virtual PMDataManager *getAsPMDataManager() { return this; }
virtual Pass *getAsPass() { return this; }
/// Print passes managed by this manager
void dumpPassStructure(unsigned Offset);
LoopPass *getContainedPass(unsigned N) {
assert(N < PassVector.size() && "Pass number out of range!");
LoopPass *LP = static_cast<LoopPass *>(PassVector[N]);
return LP;
}
virtual PassManagerType getPassManagerType() const {
return PMT_LoopPassManager;
}
public:
// Delete loop from the loop queue and loop nest (LoopInfo).
void deleteLoopFromQueue(Loop *L);
// Insert loop into the loop queue and add it as a child of the
// given parent.
void insertLoop(Loop *L, Loop *ParentLoop);
// Insert a loop into the loop queue.
void insertLoopIntoQueue(Loop *L);
// Reoptimize this loop. LPPassManager will re-insert this loop into the
// queue. This allows LoopPass to change loop nest for the loop. This
// utility may send LPPassManager into infinite loops so use caution.
void redoLoop(Loop *L);
//===--------------------------------------------------------------------===//
/// SimpleAnalysis - Provides simple interface to update analysis info
/// maintained by various passes. Note, if required this interface can
/// be extracted into a separate abstract class but it would require
/// additional use of multiple inheritance in Pass class hierarchy, something
/// we are trying to avoid.
/// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for
/// all passes that implement simple analysis interface.
void cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L);
/// deleteSimpleAnalysisValue - Invoke deleteAnalysisValue hook for all passes
/// that implement simple analysis interface.
void deleteSimpleAnalysisValue(Value *V, Loop *L);
private:
std::deque<Loop *> LQ;
bool skipThisLoop;
bool redoThisLoop;
LoopInfo *LI;
Loop *CurrentLoop;
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,268 @@
//===- llvm/Analysis/MemoryBuiltins.h- Calls to memory builtins -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This family of functions identifies calls to builtin functions that allocate
// or free memory.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_MEMORYBUILTINS_H
#define LLVM_ANALYSIS_MEMORYBUILTINS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Operator.h"
#include "llvm/InstVisitor.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
namespace llvm {
class CallInst;
class PointerType;
class DataLayout;
class TargetLibraryInfo;
class Type;
class Value;
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates or reallocates memory (either malloc, calloc, realloc, or strdup
/// like).
bool isAllocationFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a function that returns a
/// NoAlias pointer (including malloc/calloc/realloc/strdup-like functions).
bool isNoAliasFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates uninitialized memory (such as malloc).
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates zero-filled memory (such as calloc).
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// allocates memory (either malloc, calloc, or strdup like).
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
/// \brief Tests if a value is a call or invoke to a library function that
/// reallocates memory (such as realloc).
bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
//===----------------------------------------------------------------------===//
// malloc Call Utility Functions.
//
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
const CallInst *extractMallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractMallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
}
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
const CallInst *isArrayMalloc(const Value *I, const DataLayout *TD,
const TargetLibraryInfo *TLI);
/// getMallocType - Returns the PointerType resulting from the malloc call.
/// The PointerType depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
PointerType *getMallocType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
/// The Type depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
/// 1: PointerType is the bitcast's result type.
/// >1: Unique PointerType cannot be determined, return NULL.
Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
Value *getMallocArraySize(CallInst *CI, const DataLayout *TD,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
//===----------------------------------------------------------------------===//
// calloc Call Utility Functions.
//
/// extractCallocCall - Returns the corresponding CallInst if the instruction
/// is a calloc call.
const CallInst *extractCallocCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *extractCallocCall(Value *I,
const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(extractCallocCall((const Value*)I, TLI));
}
//===----------------------------------------------------------------------===//
// free Call Utility Functions.
//
/// isFreeCall - Returns non-null if the value is a call to the builtin free()
const CallInst *isFreeCall(const Value *I, const TargetLibraryInfo *TLI);
static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
return const_cast<CallInst*>(isFreeCall((const Value*)I, TLI));
}
//===----------------------------------------------------------------------===//
// Utility functions to compute size of objects.
//
/// \brief Compute the size of the object pointed by Ptr. Returns true and the
/// object size in Size if successful, and false otherwise. In this context, by
/// object we mean the region of memory starting at Ptr to the end of the
/// underlying object pointed to by Ptr.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *TD,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
typedef std::pair<APInt, APInt> SizeOffsetType;
/// \brief Evaluate the size and offset of an object ponted by a Value*
/// statically. Fails if size or offset are not known at compile time.
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
const DataLayout *TD;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
SmallPtrSet<Instruction *, 8> SeenInsts;
APInt align(APInt Size, uint64_t Align);
SizeOffsetType unknown() {
return std::make_pair(APInt(), APInt());
}
public:
ObjectSizeOffsetVisitor(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
bool knownSize(SizeOffsetType &SizeOffset) {
return SizeOffset.first.getBitWidth() > 1;
}
bool knownOffset(SizeOffsetType &SizeOffset) {
return SizeOffset.second.getBitWidth() > 1;
}
bool bothKnown(SizeOffsetType &SizeOffset) {
return knownSize(SizeOffset) && knownOffset(SizeOffset);
}
SizeOffsetType visitAllocaInst(AllocaInst &I);
SizeOffsetType visitArgument(Argument &A);
SizeOffsetType visitCallSite(CallSite CS);
SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetType visitGEPOperator(GEPOperator &GEP);
SizeOffsetType visitGlobalAlias(GlobalAlias &GA);
SizeOffsetType visitGlobalVariable(GlobalVariable &GV);
SizeOffsetType visitIntToPtrInst(IntToPtrInst&);
SizeOffsetType visitLoadInst(LoadInst &I);
SizeOffsetType visitPHINode(PHINode&);
SizeOffsetType visitSelectInst(SelectInst &I);
SizeOffsetType visitUndefValue(UndefValue&);
SizeOffsetType visitInstruction(Instruction &I);
};
typedef std::pair<Value*, Value*> SizeOffsetEvalType;
/// \brief Evaluate the size and offset of an object ponted by a Value*.
/// May create code to compute the result at run-time.
class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
typedef IRBuilder<true, TargetFolder> BuilderTy;
typedef std::pair<WeakVH, WeakVH> WeakEvalType;
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
const DataLayout *TD;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
IntegerType *IntTy;
Value *Zero;
CacheMapTy CacheMap;
PtrSetTy SeenVals;
SizeOffsetEvalType unknown() {
return std::make_pair((Value*)0, (Value*)0);
}
SizeOffsetEvalType compute_(Value *V);
public:
ObjectSizeOffsetEvaluator(const DataLayout *TD, const TargetLibraryInfo *TLI,
LLVMContext &Context);
SizeOffsetEvalType compute(Value *V);
bool knownSize(SizeOffsetEvalType SizeOffset) {
return SizeOffset.first;
}
bool knownOffset(SizeOffsetEvalType SizeOffset) {
return SizeOffset.second;
}
bool anyKnown(SizeOffsetEvalType SizeOffset) {
return knownSize(SizeOffset) || knownOffset(SizeOffset);
}
bool bothKnown(SizeOffsetEvalType SizeOffset) {
return knownSize(SizeOffset) && knownOffset(SizeOffset);
}
SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
SizeOffsetEvalType visitCallSite(CallSite CS);
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
SizeOffsetEvalType visitIntToPtrInst(IntToPtrInst&);
SizeOffsetEvalType visitLoadInst(LoadInst &I);
SizeOffsetEvalType visitPHINode(PHINode &PHI);
SizeOffsetEvalType visitSelectInst(SelectInst &I);
SizeOffsetEvalType visitInstruction(Instruction &I);
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,445 @@
//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MemoryDependenceAnalysis analysis pass.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Pass.h"
#include "llvm/Support/ValueHandle.h"
namespace llvm {
class Function;
class FunctionPass;
class Instruction;
class CallSite;
class AliasAnalysis;
class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
class PHITransAddr;
/// MemDepResult - A memory dependence query can return one of three different
/// answers, described below.
class MemDepResult {
enum DepType {
/// Invalid - Clients of MemDep never see this.
Invalid = 0,
/// Clobber - This is a dependence on the specified instruction which
/// clobbers the desired value. The pointer member of the MemDepResult
/// pair holds the instruction that clobbers the memory. For example,
/// this occurs when we see a may-aliased store to the memory location we
/// care about.
///
/// There are several cases that may be interesting here:
/// 1. Loads are clobbered by may-alias stores.
/// 2. Loads are considered clobbered by partially-aliased loads. The
/// client may choose to analyze deeper into these cases.
Clobber,
/// Def - This is a dependence on the specified instruction which
/// defines/produces the desired memory location. The pointer member of
/// the MemDepResult pair holds the instruction that defines the memory.
/// Cases of interest:
/// 1. This could be a load or store for dependence queries on
/// load/store. The value loaded or stored is the produced value.
/// Note that the pointer operand may be different than that of the
/// queried pointer due to must aliases and phi translation. Note
/// that the def may not be the same type as the query, the pointers
/// may just be must aliases.
/// 2. For loads and stores, this could be an allocation instruction. In
/// this case, the load is loading an undef value or a store is the
/// first store to (that part of) the allocation.
/// 3. Dependence queries on calls return Def only when they are
/// readonly calls or memory use intrinsics with identical callees
/// and no intervening clobbers. No validation is done that the
/// operands to the calls are the same.
Def,
/// Other - This marker indicates that the query has no known dependency
/// in the specified block. More detailed state info is encoded in the
/// upper part of the pair (i.e. the Instruction*)
Other
};
/// If DepType is "Other", the upper part of the pair
/// (i.e. the Instruction* part) is instead used to encode more detailed
/// type information as follows
enum OtherType {
/// NonLocal - This marker indicates that the query has no dependency in
/// the specified block. To find out more, the client should query other
/// predecessor blocks.
NonLocal = 0x4,
/// NonFuncLocal - This marker indicates that the query has no
/// dependency in the specified function.
NonFuncLocal = 0x8,
/// Unknown - This marker indicates that the query dependency
/// is unknown.
Unknown = 0xc
};
typedef PointerIntPair<Instruction*, 2, DepType> PairTy;
PairTy Value;
explicit MemDepResult(PairTy V) : Value(V) {}
public:
MemDepResult() : Value(0, Invalid) {}
/// get methods: These are static ctor methods for creating various
/// MemDepResult kinds.
static MemDepResult getDef(Instruction *Inst) {
assert(Inst && "Def requires inst");
return MemDepResult(PairTy(Inst, Def));
}
static MemDepResult getClobber(Instruction *Inst) {
assert(Inst && "Clobber requires inst");
return MemDepResult(PairTy(Inst, Clobber));
}
static MemDepResult getNonLocal() {
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(NonLocal), Other));
}
static MemDepResult getNonFuncLocal() {
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(NonFuncLocal), Other));
}
static MemDepResult getUnknown() {
return MemDepResult(
PairTy(reinterpret_cast<Instruction*>(Unknown), Other));
}
/// isClobber - Return true if this MemDepResult represents a query that is
/// an instruction clobber dependency.
bool isClobber() const { return Value.getInt() == Clobber; }
/// isDef - Return true if this MemDepResult represents a query that is
/// an instruction definition dependency.
bool isDef() const { return Value.getInt() == Def; }
/// isNonLocal - Return true if this MemDepResult represents a query that
/// is transparent to the start of the block, but where a non-local hasn't
/// been done.
bool isNonLocal() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonLocal);
}
/// isNonFuncLocal - Return true if this MemDepResult represents a query
/// that is transparent to the start of the function.
bool isNonFuncLocal() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
}
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(Unknown);
}
/// getInst() - If this is a normal dependency, return the instruction that
/// is depended on. Otherwise, return null.
Instruction *getInst() const {
if (Value.getInt() == Other) return NULL;
return Value.getPointer();
}
bool operator==(const MemDepResult &M) const { return Value == M.Value; }
bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
bool operator<(const MemDepResult &M) const { return Value < M.Value; }
bool operator>(const MemDepResult &M) const { return Value > M.Value; }
private:
friend class MemoryDependenceAnalysis;
/// Dirty - Entries with this marker occur in a LocalDeps map or
/// NonLocalDeps map when the instruction they previously referenced was
/// removed from MemDep. In either case, the entry may include an
/// instruction pointer. If so, the pointer is an instruction in the
/// block where scanning can start from, saving some work.
///
/// In a default-constructed MemDepResult object, the type will be Dirty
/// and the instruction pointer will be null.
///
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
/// state.
bool isDirty() const { return Value.getInt() == Invalid; }
static MemDepResult getDirty(Instruction *Inst) {
return MemDepResult(PairTy(Inst, Invalid));
}
};
/// NonLocalDepEntry - This is an entry in the NonLocalDepInfo cache. For
/// each BasicBlock (the BB entry) it keeps a MemDepResult.
class NonLocalDepEntry {
BasicBlock *BB;
MemDepResult Result;
public:
NonLocalDepEntry(BasicBlock *bb, MemDepResult result)
: BB(bb), Result(result) {}
// This is used for searches.
NonLocalDepEntry(BasicBlock *bb) : BB(bb) {}
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return BB; }
void setResult(const MemDepResult &R) { Result = R; }
const MemDepResult &getResult() const { return Result; }
bool operator<(const NonLocalDepEntry &RHS) const {
return BB < RHS.BB;
}
};
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
/// (potentially phi translated) address that was live in the block.
class NonLocalDepResult {
NonLocalDepEntry Entry;
Value *Address;
public:
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
: Entry(bb, result), Address(address) {}
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return Entry.getBB(); }
void setResult(const MemDepResult &R, Value *Addr) {
Entry.setResult(R);
Address = Addr;
}
const MemDepResult &getResult() const { return Entry.getResult(); }
/// getAddress - Return the address of this pointer in this block. This can
/// be different than the address queried for the non-local result because
/// of phi translation. This returns null if the address was not available
/// in a block (i.e. because phi translation failed) or if this is a cached
/// result and that address was deleted.
///
/// The address is always null for a non-local 'call' dependence.
Value *getAddress() const { return Address; }
};
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
/// given memory operation, what preceding memory operations it depends on.
/// It builds on alias analysis information, and tries to provide a lazy,
/// caching interface to a common kind of alias information query.
///
/// The dependency information returned is somewhat unusual, but is pragmatic.
/// If queried about a store or call that might modify memory, the analysis
/// will return the instruction[s] that may either load from that memory or
/// store to it. If queried with a load or call that can never modify memory,
/// the analysis will return calls and stores that might modify the pointer,
/// but generally does not return loads unless a) they are volatile, or
/// b) they load from *must-aliased* pointers. Returning a dependence on
/// must-alias'd pointers instead of all pointers interacts well with the
/// internal caching mechanism.
///
class MemoryDependenceAnalysis : public FunctionPass {
// A map from instructions to their dependency.
typedef DenseMap<Instruction*, MemDepResult> LocalDepMapType;
LocalDepMapType LocalDeps;
public:
typedef std::vector<NonLocalDepEntry> NonLocalDepInfo;
private:
/// ValueIsLoadPair - This is a pair<Value*, bool> where the bool is true if
/// the dependence is a read only dependence, false if read/write.
typedef PointerIntPair<const Value*, 1, bool> ValueIsLoadPair;
/// BBSkipFirstBlockPair - This pair is used when caching information for a
/// block. If the pointer is null, the cache value is not a full query that
/// starts at the specified block. If non-null, the bool indicates whether
/// or not the contents of the block was skipped.
typedef PointerIntPair<BasicBlock*, 1, bool> BBSkipFirstBlockPair;
/// NonLocalPointerInfo - This record is the information kept for each
/// (value, is load) pair.
struct NonLocalPointerInfo {
/// Pair - The pair of the block and the skip-first-block flag.
BBSkipFirstBlockPair Pair;
/// NonLocalDeps - The results of the query for each relevant block.
NonLocalDepInfo NonLocalDeps;
/// Size - The maximum size of the dereferences of the
/// pointer. May be UnknownSize if the sizes are unknown.
uint64_t Size;
/// TBAATag - The TBAA tag associated with dereferences of the
/// pointer. May be null if there are no tags or conflicting tags.
const MDNode *TBAATag;
NonLocalPointerInfo() : Size(AliasAnalysis::UnknownSize), TBAATag(0) {}
};
/// CachedNonLocalPointerInfo - This map stores the cached results of doing
/// a pointer lookup at the bottom of a block. The key of this map is the
/// pointer+isload bit, the value is a list of <bb->result> mappings.
typedef DenseMap<ValueIsLoadPair,
NonLocalPointerInfo> CachedNonLocalPointerInfo;
CachedNonLocalPointerInfo NonLocalPointerDeps;
// A map from instructions to their non-local pointer dependencies.
typedef DenseMap<Instruction*,
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
/// PerInstNLInfo - This is the instruction we keep for each cached access
/// that we have for an instruction. The pointer is an owning pointer and
/// the bool indicates whether we have any dirty bits in the set.
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
// A map from instructions to their non-local dependencies.
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
NonLocalDepMapType NonLocalDeps;
// A reverse mapping from dependencies to the dependees. This is
// used when removing instructions to keep the cache coherent.
typedef DenseMap<Instruction*,
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
ReverseDepMapType ReverseLocalDeps;
// A reverse mapping from dependencies to the non-local dependees.
ReverseDepMapType ReverseNonLocalDeps;
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
DataLayout *TD;
DominatorTree *DT;
OwningPtr<PredIteratorCache> PredCache;
public:
MemoryDependenceAnalysis();
~MemoryDependenceAnalysis();
static char ID;
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
bool runOnFunction(Function &);
/// Clean up memory in between runs
void releaseMemory();
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
/// and Alias Analysis.
///
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
/// getDependency - Return the instruction on which a memory operation
/// depends. See the class comment for more details. It is illegal to call
/// this on non-memory instructions.
MemDepResult getDependency(Instruction *QueryInst);
/// getNonLocalCallDependency - Perform a full dependency query for the
/// specified call, returning the set of blocks that the value is
/// potentially live across. The returned set of results will include a
/// "NonLocal" result for all blocks where the value is live across.
///
/// This method assumes the instruction returns a "NonLocal" dependency
/// within its own block.
///
/// This returns a reference to an internal data structure that may be
/// invalidated on the next non-local query or when an instruction is
/// removed. Clients must copy this data if they want it around longer than
/// that.
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
/// getNonLocalPointerDependency - Perform a full dependency query for an
/// access to the specified (non-volatile) memory location, returning the
/// set of instructions that either define or clobber the value.
///
/// This method assumes the pointer has a "NonLocal" dependency within BB.
void getNonLocalPointerDependency(const AliasAnalysis::Location &Loc,
bool isLoad, BasicBlock *BB,
SmallVectorImpl<NonLocalDepResult> &Result);
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
/// invalidateCachedPointerInfo - This method is used to invalidate cached
/// information about the specified pointer, because it may be too
/// conservative in memdep. This is an optional call that can be used when
/// the client detects an equivalence between the pointer and some other
/// value and replaces the other value with ptr. This can make Ptr available
/// in more places that cached info does not necessarily keep.
void invalidateCachedPointerInfo(Value *Ptr);
/// invalidateCachedPredecessors - Clear the PredIteratorCache info.
/// This needs to be done when the CFG changes, e.g., due to splitting
/// critical edges.
void invalidateCachedPredecessors();
/// getPointerDependencyFrom - Return the instruction on which a memory
/// location depends. If isLoad is true, this routine ignores may-aliases
/// with read-only operations. If isLoad is false, this routine ignores
/// may-aliases with reads from read-only locations. If possible, pass
/// the query instruction as well; this function may take advantage of
/// the metadata annotated to the query instruction to refine the result.
///
/// Note that this is an uncached query, and thus may be inefficient.
///
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
bool isLoad,
BasicBlock::iterator ScanIt,
BasicBlock *BB,
Instruction *QueryInst = 0);
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
/// looks at a memory location for a load (specified by MemLocBase, Offs,
/// and Size) and compares it against a load. If the specified load could
/// be safely widened to a larger integer load that is 1) still efficient,
/// 2) safe for the target, and 3) would provide the specified memory
/// location value, then this function returns the size in bytes of the
/// load width to use. If not, this returns zero.
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
int64_t MemLocOffs,
unsigned MemLocSize,
const LoadInst *LI,
const DataLayout &TD);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
bool getNonLocalPointerDepFromBB(const PHITransAddr &Pointer,
const AliasAnalysis::Location &Loc,
bool isLoad, BasicBlock *BB,
SmallVectorImpl<NonLocalDepResult> &Result,
DenseMap<BasicBlock*, Value*> &Visited,
bool SkipFirstBlock = false);
MemDepResult GetNonLocalInfoForBlock(const AliasAnalysis::Location &Loc,
bool isLoad, BasicBlock *BB,
NonLocalDepInfo *Cache,
unsigned NumSortedEntries);
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,121 @@
//===- PHITransAddr.h - PHI Translation for Addresses -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the PHITransAddr class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PHITRANSADDR_H
#define LLVM_ANALYSIS_PHITRANSADDR_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Instruction.h"
namespace llvm {
class DominatorTree;
class DataLayout;
class TargetLibraryInfo;
/// PHITransAddr - An address value which tracks and handles phi translation.
/// As we walk "up" the CFG through predecessors, we need to ensure that the
/// address we're tracking is kept up to date. For example, if we're analyzing
/// an address of "&A[i]" and walk through the definition of 'i' which is a PHI
/// node, we *must* phi translate i to get "&A[j]" or else we will analyze an
/// incorrect pointer in the predecessor block.
///
/// This is designed to be a relatively small object that lives on the stack and
/// is copyable.
///
class PHITransAddr {
/// Addr - The actual address we're analyzing.
Value *Addr;
/// TD - The target data we are playing with if known, otherwise null.
const DataLayout *TD;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
PHITransAddr(Value *addr, const DataLayout *td) : Addr(addr), TD(td), TLI(0) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
InstInputs.push_back(I);
}
Value *getAddr() const { return Addr; }
/// NeedsPHITranslationFromBlock - Return true if moving from the specified
/// BasicBlock to its predecessors requires PHI translation.
bool NeedsPHITranslationFromBlock(BasicBlock *BB) const {
// We do need translation if one of our input instructions is defined in
// this block.
for (unsigned i = 0, e = InstInputs.size(); i != e; ++i)
if (InstInputs[i]->getParent() == BB)
return true;
return false;
}
/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true
/// if we have some hope of doing it. This should be used as a filter to
/// avoid calling PHITranslateValue in hopeless situations.
bool IsPotentiallyPHITranslatable() const;
/// PHITranslateValue - PHI translate the current address up the CFG from
/// CurBB to Pred, updating our state to reflect any needed changes. If the
/// dominator tree DT is non-null, the translated value must dominate
/// PredBB. This returns true on failure and sets Addr to null.
bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree *DT);
/// PHITranslateWithInsertion - PHI translate this value into the specified
/// predecessor block, inserting a computation of the value if it is
/// unavailable.
///
/// All newly created instructions are added to the NewInsts list. This
/// returns null on failure.
///
Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts);
void dump() const;
/// Verify - Check internal consistency of this data structure. If the
/// structure is valid, it returns true. If invalid, it prints errors and
/// returns false.
bool Verify() const;
private:
Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB,
const DominatorTree *DT);
/// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated
/// version of 'V' for the edge PredBB->CurBB into the end of the PredBB
/// block. All newly created instructions are added to the NewInsts list.
/// This returns null on failure.
///
Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
BasicBlock *PredBB, const DominatorTree &DT,
SmallVectorImpl<Instruction*> &NewInsts);
/// AddAsInput - If the specified value is an instruction, add it as an input.
Value *AddAsInput(Value *V) {
// If V is an instruction, it is now an input.
if (Instruction *VI = dyn_cast<Instruction>(V))
InstInputs.push_back(VI);
return V;
}
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,219 @@
//===-- llvm/Analysis/Passes.h - Constructors for analyses ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header file defines prototypes for accessor functions that expose passes
// in the analysis libraries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PASSES_H
#define LLVM_ANALYSIS_PASSES_H
namespace llvm {
class FunctionPass;
class ImmutablePass;
class LoopPass;
class ModulePass;
class Pass;
class PassInfo;
class LibCallInfo;
//===--------------------------------------------------------------------===//
//
// createGlobalsModRefPass - This pass provides alias and mod/ref info for
// global values that do not have their addresses taken.
//
Pass *createGlobalsModRefPass();
//===--------------------------------------------------------------------===//
//
// createAliasDebugger - This pass helps debug clients of AA
//
Pass *createAliasDebugger();
//===--------------------------------------------------------------------===//
//
// createAliasAnalysisCounterPass - This pass counts alias queries and how the
// alias analysis implementation responds.
//
ModulePass *createAliasAnalysisCounterPass();
//===--------------------------------------------------------------------===//
//
// createAAEvalPass - This pass implements a simple N^2 alias analysis
// accuracy evaluator.
//
FunctionPass *createAAEvalPass();
//===--------------------------------------------------------------------===//
//
// createNoAAPass - This pass implements a "I don't know" alias analysis.
//
ImmutablePass *createNoAAPass();
//===--------------------------------------------------------------------===//
//
// createBasicAliasAnalysisPass - This pass implements the stateless alias
// analysis.
//
ImmutablePass *createBasicAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
/// createLibCallAliasAnalysisPass - Create an alias analysis pass that knows
/// about the semantics of a set of libcalls specified by LCI. The newly
/// constructed pass takes ownership of the pointer that is provided.
///
FunctionPass *createLibCallAliasAnalysisPass(LibCallInfo *LCI);
//===--------------------------------------------------------------------===//
//
// createScalarEvolutionAliasAnalysisPass - This pass implements a simple
// alias analysis using ScalarEvolution queries.
//
FunctionPass *createScalarEvolutionAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createTypeBasedAliasAnalysisPass - This pass implements metadata-based
// type-based alias analysis.
//
ImmutablePass *createTypeBasedAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createObjCARCAliasAnalysisPass - This pass implements ObjC-ARC-based
// alias analysis.
//
ImmutablePass *createObjCARCAliasAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createProfileLoaderPass - This pass loads information from a profile dump
// file.
//
ModulePass *createProfileLoaderPass();
extern char &ProfileLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createProfileMetadataLoaderPass - This pass loads information from a
// profile dump file and sets branch weight metadata.
//
ModulePass *createProfileMetadataLoaderPass();
extern char &ProfileMetadataLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createNoProfileInfoPass - This pass implements the default "no profile".
//
ImmutablePass *createNoProfileInfoPass();
//===--------------------------------------------------------------------===//
//
// createProfileEstimatorPass - This pass estimates profiling information
// instead of loading it from a previous run.
//
FunctionPass *createProfileEstimatorPass();
extern char &ProfileEstimatorPassID;
//===--------------------------------------------------------------------===//
//
// createProfileVerifierPass - This pass verifies profiling information.
//
FunctionPass *createProfileVerifierPass();
//===--------------------------------------------------------------------===//
//
// createPathProfileLoaderPass - This pass loads information from a path
// profile dump file.
//
ModulePass *createPathProfileLoaderPass();
extern char &PathProfileLoaderPassID;
//===--------------------------------------------------------------------===//
//
// createNoPathProfileInfoPass - This pass implements the default
// "no path profile".
//
ImmutablePass *createNoPathProfileInfoPass();
//===--------------------------------------------------------------------===//
//
// createPathProfileVerifierPass - This pass verifies path profiling
// information.
//
ModulePass *createPathProfileVerifierPass();
//===--------------------------------------------------------------------===//
//
// createDSAAPass - This pass implements simple context sensitive alias
// analysis.
//
ModulePass *createDSAAPass();
//===--------------------------------------------------------------------===//
//
// createDSOptPass - This pass uses DSA to do a series of simple
// optimizations.
//
ModulePass *createDSOptPass();
//===--------------------------------------------------------------------===//
//
// createSteensgaardPass - This pass uses the data structure graphs to do a
// simple context insensitive alias analysis.
//
ModulePass *createSteensgaardPass();
//===--------------------------------------------------------------------===//
//
/// createLazyValueInfoPass - This creates an instance of the LazyValueInfo
/// pass.
FunctionPass *createLazyValueInfoPass();
//===--------------------------------------------------------------------===//
//
// createDependenceAnalysisPass - This creates an instance of the
// DependenceAnalysis pass.
//
FunctionPass *createDependenceAnalysisPass();
//===--------------------------------------------------------------------===//
//
// createCostModelAnalysisPass - This creates an instance of the
// CostModelAnalysis pass.
//
FunctionPass *createCostModelAnalysisPass();
//===--------------------------------------------------------------------===//
//
// Minor pass prototypes, allowing us to expose them through bugpoint and
// analyze.
FunctionPass *createInstCountPass();
//===--------------------------------------------------------------------===//
//
// createRegionInfoPass - This pass finds all single entry single exit regions
// in a function and builds the region hierarchy.
//
FunctionPass *createRegionInfoPass();
// Print module-level debug info metadata in human-readable form.
ModulePass *createModuleDebugInfoPrinterPass();
//===--------------------------------------------------------------------===//
//
// createMemDepPrinter - This pass exhaustively collects all memdep
// information and prints it with -analyze.
//
FunctionPass *createMemDepPrinter();
}
#endif

View File

@@ -0,0 +1,304 @@
//===- PathNumbering.h ----------------------------------------*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Ball-Larus path numbers uniquely identify paths through a directed acyclic
// graph (DAG) [Ball96]. For a CFG backedges are removed and replaced by phony
// edges to obtain a DAG, and thus the unique path numbers [Ball96].
//
// The purpose of this analysis is to enumerate the edges in a CFG in order
// to obtain paths from path numbers in a convenient manner. As described in
// [Ball96] edges can be enumerated such that given a path number by following
// the CFG and updating the path number, the path is obtained.
//
// [Ball96]
// T. Ball and J. R. Larus. "Efficient Path Profiling."
// International Symposium on Microarchitecture, pages 46-57, 1996.
// http://portal.acm.org/citation.cfm?id=243857
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
#define LLVM_ANALYSIS_PATHNUMBERING_H
#include "llvm/Analysis/ProfileInfoTypes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include <map>
#include <stack>
#include <vector>
namespace llvm {
class BallLarusNode;
class BallLarusEdge;
class BallLarusDag;
// typedefs for storage/ interators of various DAG components
typedef std::vector<BallLarusNode*> BLNodeVector;
typedef std::vector<BallLarusNode*>::iterator BLNodeIterator;
typedef std::vector<BallLarusEdge*> BLEdgeVector;
typedef std::vector<BallLarusEdge*>::iterator BLEdgeIterator;
typedef std::map<BasicBlock*, BallLarusNode*> BLBlockNodeMap;
typedef std::stack<BallLarusNode*> BLNodeStack;
// Represents a basic block with information necessary for the BallLarus
// algorithms.
class BallLarusNode {
public:
enum NodeColor { WHITE, GRAY, BLACK };
// Constructor: Initializes a new Node for the given BasicBlock
BallLarusNode(BasicBlock* BB) :
_basicBlock(BB), _numberPaths(0), _color(WHITE) {
static unsigned nextUID = 0;
_uid = nextUID++;
}
// Returns the basic block for the BallLarusNode
BasicBlock* getBlock();
// Get/set the number of paths to the exit starting at the node.
unsigned getNumberPaths();
void setNumberPaths(unsigned numberPaths);
// Get/set the NodeColor used in graph algorithms.
NodeColor getColor();
void setColor(NodeColor color);
// Iterator information for predecessor edges. Includes phony and
// backedges.
BLEdgeIterator predBegin();
BLEdgeIterator predEnd();
unsigned getNumberPredEdges();
// Iterator information for successor edges. Includes phony and
// backedges.
BLEdgeIterator succBegin();
BLEdgeIterator succEnd();
unsigned getNumberSuccEdges();
// Add an edge to the predecessor list.
void addPredEdge(BallLarusEdge* edge);
// Remove an edge from the predecessor list.
void removePredEdge(BallLarusEdge* edge);
// Add an edge to the successor list.
void addSuccEdge(BallLarusEdge* edge);
// Remove an edge from the successor list.
void removeSuccEdge(BallLarusEdge* edge);
// Returns the name of the BasicBlock being represented. If BasicBlock
// is null then returns "<null>". If BasicBlock has no name, then
// "<unnamed>" is returned. Intended for use with debug output.
std::string getName();
private:
// The corresponding underlying BB.
BasicBlock* _basicBlock;
// Holds the predecessor edges of this node.
BLEdgeVector _predEdges;
// Holds the successor edges of this node.
BLEdgeVector _succEdges;
// The number of paths from the node to the exit.
unsigned _numberPaths;
// 'Color' used by graph algorithms to mark the node.
NodeColor _color;
// Unique ID to ensure naming difference with dotgraphs
unsigned _uid;
// Removes an edge from an edgeVector. Used by removePredEdge and
// removeSuccEdge.
void removeEdge(BLEdgeVector& v, BallLarusEdge* e);
};
// Represents an edge in the Dag. For an edge, v -> w, v is the source, and
// w is the target.
class BallLarusEdge {
public:
enum EdgeType { NORMAL, BACKEDGE, SPLITEDGE,
BACKEDGE_PHONY, SPLITEDGE_PHONY, CALLEDGE_PHONY };
// Constructor: Initializes an BallLarusEdge with a source and target.
BallLarusEdge(BallLarusNode* source, BallLarusNode* target,
unsigned duplicateNumber)
: _source(source), _target(target), _weight(0), _edgeType(NORMAL),
_realEdge(NULL), _duplicateNumber(duplicateNumber) {}
// Returns the source/ target node of this edge.
BallLarusNode* getSource() const;
BallLarusNode* getTarget() const;
// Sets the type of the edge.
EdgeType getType() const;
// Gets the type of the edge.
void setType(EdgeType type);
// Returns the weight of this edge. Used to decode path numbers to
// sequences of basic blocks.
unsigned getWeight();
// Sets the weight of the edge. Used during path numbering.
void setWeight(unsigned weight);
// Gets/sets the phony edge originating at the root.
BallLarusEdge* getPhonyRoot();
void setPhonyRoot(BallLarusEdge* phonyRoot);
// Gets/sets the phony edge terminating at the exit.
BallLarusEdge* getPhonyExit();
void setPhonyExit(BallLarusEdge* phonyExit);
// Gets/sets the associated real edge if this is a phony edge.
BallLarusEdge* getRealEdge();
void setRealEdge(BallLarusEdge* realEdge);
// Returns the duplicate number of the edge.
unsigned getDuplicateNumber();
protected:
// Source node for this edge.
BallLarusNode* _source;
// Target node for this edge.
BallLarusNode* _target;
private:
// Edge weight cooresponding to path number increments before removing
// increments along a spanning tree. The sum over the edge weights gives
// the path number.
unsigned _weight;
// Type to represent for what this edge is intended
EdgeType _edgeType;
// For backedges and split-edges, the phony edge which is linked to the
// root node of the DAG. This contains a path number initialization.
BallLarusEdge* _phonyRoot;
// For backedges and split-edges, the phony edge which is linked to the
// exit node of the DAG. This contains a path counter increment, and
// potentially a path number increment.
BallLarusEdge* _phonyExit;
// If this is a phony edge, _realEdge is a link to the back or split
// edge. Otherwise, this is null.
BallLarusEdge* _realEdge;
// An ID to differentiate between those edges which have the same source
// and destination blocks.
unsigned _duplicateNumber;
};
// Represents the Ball Larus DAG for a given Function. Can calculate
// various properties required for instrumentation or analysis. E.g. the
// edge weights that determine the path number.
class BallLarusDag {
public:
// Initializes a BallLarusDag from the CFG of a given function. Must
// call init() after creation, since some initialization requires
// virtual functions.
BallLarusDag(Function &F)
: _root(NULL), _exit(NULL), _function(F) {}
// Initialization that requires virtual functions which are not fully
// functional in the constructor.
void init();
// Frees all memory associated with the DAG.
virtual ~BallLarusDag();
// Calculate the path numbers by assigning edge increments as prescribed
// in Ball-Larus path profiling.
void calculatePathNumbers();
// Returns the number of paths for the DAG.
unsigned getNumberOfPaths();
// Returns the root (i.e. entry) node for the DAG.
BallLarusNode* getRoot();
// Returns the exit node for the DAG.
BallLarusNode* getExit();
// Returns the function for the DAG.
Function& getFunction();
// Clears the node colors.
void clearColors(BallLarusNode::NodeColor color);
protected:
// All nodes in the DAG.
BLNodeVector _nodes;
// All edges in the DAG.
BLEdgeVector _edges;
// All backedges in the DAG.
BLEdgeVector _backEdges;
// Allows subclasses to determine which type of Node is created.
// Override this method to produce subclasses of BallLarusNode if
// necessary. The destructor of BallLarusDag will call free on each pointer
// created.
virtual BallLarusNode* createNode(BasicBlock* BB);
// Allows subclasses to determine which type of Edge is created.
// Override this method to produce subclasses of BallLarusEdge if
// necessary. Parameters source and target will have been created by
// createNode and can be cast to the subclass of BallLarusNode*
// returned by createNode. The destructor of BallLarusDag will call free
// on each pointer created.
virtual BallLarusEdge* createEdge(BallLarusNode* source, BallLarusNode*
target, unsigned duplicateNumber);
// Proxy to node's constructor. Updates the DAG state.
BallLarusNode* addNode(BasicBlock* BB);
// Proxy to edge's constructor. Updates the DAG state.
BallLarusEdge* addEdge(BallLarusNode* source, BallLarusNode* target,
unsigned duplicateNumber);
private:
// The root (i.e. entry) node for this DAG.
BallLarusNode* _root;
// The exit node for this DAG.
BallLarusNode* _exit;
// The function represented by this DAG.
Function& _function;
// Processes one node and its imediate edges for building the DAG.
void buildNode(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack);
// Process an edge in the CFG for DAG building.
void buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack,
BallLarusNode* currentNode, BasicBlock* succBB,
unsigned duplicateNumber);
// The weight on each edge is the increment required along any path that
// contains that edge.
void calculatePathNumbersFrom(BallLarusNode* node);
// Adds a backedge with its phony edges. Updates the DAG state.
void addBackedge(BallLarusNode* source, BallLarusNode* target,
unsigned duplicateCount);
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,112 @@
//===- PathProfileInfo.h --------------------------------------*- C++ -*---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file outlines the interface used by optimizers to load path profiles.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
#define LLVM_ANALYSIS_PATHPROFILEINFO_H
#include "llvm/Analysis/PathNumbering.h"
#include "llvm/IR/BasicBlock.h"
namespace llvm {
class ProfilePath;
class ProfilePathEdge;
class PathProfileInfo;
typedef std::vector<ProfilePathEdge> ProfilePathEdgeVector;
typedef std::vector<ProfilePathEdge>::iterator ProfilePathEdgeIterator;
typedef std::vector<BasicBlock*> ProfilePathBlockVector;
typedef std::vector<BasicBlock*>::iterator ProfilePathBlockIterator;
typedef std::map<unsigned int,ProfilePath*> ProfilePathMap;
typedef std::map<unsigned int,ProfilePath*>::iterator ProfilePathIterator;
typedef std::map<Function*,unsigned int> FunctionPathCountMap;
typedef std::map<Function*,ProfilePathMap> FunctionPathMap;
typedef std::map<Function*,ProfilePathMap>::iterator FunctionPathIterator;
class ProfilePathEdge {
public:
ProfilePathEdge(BasicBlock* source, BasicBlock* target,
unsigned duplicateNumber);
inline unsigned getDuplicateNumber() { return _duplicateNumber; }
inline BasicBlock* getSource() { return _source; }
inline BasicBlock* getTarget() { return _target; }
protected:
BasicBlock* _source;
BasicBlock* _target;
unsigned _duplicateNumber;
};
class ProfilePath {
public:
ProfilePath(unsigned int number, unsigned int count,
double countStdDev, PathProfileInfo* ppi);
double getFrequency() const;
inline unsigned int getNumber() const { return _number; }
inline unsigned int getCount() const { return _count; }
inline double getCountStdDev() const { return _countStdDev; }
ProfilePathEdgeVector* getPathEdges() const;
ProfilePathBlockVector* getPathBlocks() const;
BasicBlock* getFirstBlockInPath() const;
private:
unsigned int _number;
unsigned int _count;
double _countStdDev;
// double pointer back to the profiling info
PathProfileInfo* _ppi;
};
// TODO: overload [] operator for getting path
// Add: getFunctionCallCount()
class PathProfileInfo {
public:
PathProfileInfo();
~PathProfileInfo();
void setCurrentFunction(Function* F);
Function* getCurrentFunction() const;
BasicBlock* getCurrentFunctionEntry();
ProfilePath* getPath(unsigned int number);
unsigned int getPotentialPathCount();
ProfilePathIterator pathBegin();
ProfilePathIterator pathEnd();
unsigned int pathsRun();
static char ID; // Pass identification
std::string argList;
protected:
FunctionPathMap _functionPaths;
FunctionPathCountMap _functionPathCounts;
private:
BallLarusDag* _currentDag;
Function* _currentFunction;
friend class ProfilePath;
};
} // end namespace llvm
#endif

View File

@@ -0,0 +1,106 @@
//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation-*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file exposes interfaces to post dominance information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
#define LLVM_ANALYSIS_POSTDOMINATORS_H
#include "llvm/Analysis/Dominators.h"
namespace llvm {
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
/// compute the a post-dominator tree.
///
struct PostDominatorTree : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
DominatorTreeBase<BasicBlock>* DT;
PostDominatorTree() : FunctionPass(ID) {
initializePostDominatorTreePass(*PassRegistry::getPassRegistry());
DT = new DominatorTreeBase<BasicBlock>(true);
}
~PostDominatorTree();
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
inline const std::vector<BasicBlock*> &getRoots() const {
return DT->getRoots();
}
inline DomTreeNode *getRootNode() const {
return DT->getRootNode();
}
inline DomTreeNode *operator[](BasicBlock *BB) const {
return DT->getNode(BB);
}
inline DomTreeNode *getNode(BasicBlock *BB) const {
return DT->getNode(BB);
}
inline bool dominates(DomTreeNode* A, DomTreeNode* B) const {
return DT->dominates(A, B);
}
inline bool dominates(const BasicBlock* A, const BasicBlock* B) const {
return DT->dominates(A, B);
}
inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const {
return DT->properlyDominates(A, B);
}
inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const {
return DT->properlyDominates(A, B);
}
inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
virtual void releaseMemory() {
DT->releaseMemory();
}
virtual void print(raw_ostream &OS, const Module*) const;
};
FunctionPass* createPostDomTree();
template <> struct GraphTraits<PostDominatorTree*>
: public GraphTraits<DomTreeNode*> {
static NodeType *getEntryNode(PostDominatorTree *DT) {
return DT->getRootNode();
}
static nodes_iterator nodes_begin(PostDominatorTree *N) {
if (getEntryNode(N))
return df_begin(getEntryNode(N));
else
return df_end(getEntryNode(N));
}
static nodes_iterator nodes_end(PostDominatorTree *N) {
return df_end(getEntryNode(N));
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,140 @@
//===- ProfileDataLoader.h - Load & convert profile info ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The ProfileDataLoader class is used to load profiling data from a dump file.
// The ProfileDataT<FType, BType> class is used to store the mapping of this
// data to control flow edges.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PROFILEDATALOADER_H
#define LLVM_ANALYSIS_PROFILEDATALOADER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
class ModulePass;
class Function;
class BasicBlock;
// Helper for dumping edges to dbgs().
raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *,
const BasicBlock *> E);
/// \brief The ProfileDataT<FType, BType> class is used to store the mapping of
/// profiling data to control flow edges.
///
/// An edge is defined by its source and sink basic blocks.
template<class FType, class BType>
class ProfileDataT {
public:
// The profiling information defines an Edge by its source and sink basic
// blocks.
typedef std::pair<const BType*, const BType*> Edge;
private:
typedef DenseMap<Edge, unsigned> EdgeWeights;
/// \brief Count the number of times a transition between two blocks is
/// executed.
///
/// As a special case, we also hold an edge from the null BasicBlock to the
/// entry block to indicate how many times the function was entered.
DenseMap<const FType*, EdgeWeights> EdgeInformation;
public:
/// getFunction() - Returns the Function for an Edge.
static const FType *getFunction(Edge e) {
// e.first may be NULL
assert(((!e.first) || (e.first->getParent() == e.second->getParent()))
&& "A ProfileData::Edge can not be between two functions");
assert(e.second && "A ProfileData::Edge must have a real sink");
return e.second->getParent();
}
/// getEdge() - Creates an Edge between two BasicBlocks.
static Edge getEdge(const BType *Src, const BType *Dest) {
return Edge(Src, Dest);
}
/// getEdgeWeight - Return the number of times that a given edge was
/// executed.
unsigned getEdgeWeight(Edge e) const {
const FType *f = getFunction(e);
assert((EdgeInformation.find(f) != EdgeInformation.end())
&& "No profiling information for function");
EdgeWeights weights = EdgeInformation.find(f)->second;
assert((weights.find(e) != weights.end())
&& "No profiling information for edge");
return weights.find(e)->second;
}
/// addEdgeWeight - Add 'weight' to the already stored execution count for
/// this edge.
void addEdgeWeight(Edge e, unsigned weight) {
EdgeInformation[getFunction(e)][e] += weight;
}
};
typedef ProfileDataT<Function, BasicBlock> ProfileData;
//typedef ProfileDataT<MachineFunction, MachineBasicBlock> MachineProfileData;
/// The ProfileDataLoader class is used to load raw profiling data from the
/// dump file.
class ProfileDataLoader {
private:
/// The name of the file where the raw profiling data is stored.
const std::string &Filename;
/// A vector of the command line arguments used when the target program was
/// run to generate profiling data. One entry per program run.
SmallVector<std::string, 1> CommandLines;
/// The raw values for how many times each edge was traversed, values from
/// multiple program runs are accumulated.
SmallVector<unsigned, 32> EdgeCounts;
public:
/// ProfileDataLoader ctor - Read the specified profiling data file, exiting
/// the program if the file is invalid or broken.
ProfileDataLoader(const char *ToolName, const std::string &Filename);
/// A special value used to represent the weight of an edge which has not
/// been counted yet.
static const unsigned Uncounted;
/// getNumExecutions - Return the number of times the target program was run
/// to generate this profiling data.
unsigned getNumExecutions() const { return CommandLines.size(); }
/// getExecution - Return the command line parameters used to generate the
/// i'th set of profiling data.
const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
const std::string &getFileName() const { return Filename; }
/// getRawEdgeCounts - Return the raw profiling data, this is just a list of
/// numbers with no mappings to edges.
ArrayRef<unsigned> getRawEdgeCounts() const { return EdgeCounts; }
};
/// createProfileMetadataLoaderPass - This function returns a Pass that loads
/// the profiling information for the module from the specified filename.
ModulePass *createProfileMetadataLoaderPass(const std::string &Filename);
} // End llvm namespace
#endif

View File

@@ -0,0 +1,39 @@
/*===-- ProfileDataTypes.h - Profiling info shared constants --------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
|*===----------------------------------------------------------------------===*|
|*
|* This file defines constants shared by the various different profiling
|* runtime libraries and the LLVM C++ profile metadata loader. It must be a
|* C header because, at present, the profiling runtimes are written in C.
|*
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_ANALYSIS_PROFILEDATATYPES_H
#define LLVM_ANALYSIS_PROFILEDATATYPES_H
/* Included by libprofile. */
#if defined(__cplusplus)
extern "C" {
#endif
/* TODO: Strip out unused entries once ProfileInfo etc has been removed. */
enum ProfilingType {
ArgumentInfo = 1, /* The command line argument block */
FunctionInfo = 2, /* Function profiling information */
BlockInfo = 3, /* Block profiling information */
EdgeInfo = 4, /* Edge profiling information */
PathInfo = 5, /* Path profiling information */
BBTraceInfo = 6, /* Basic block trace information */
OptEdgeInfo = 7 /* Edge profiling information, optimal version */
};
#if defined(__cplusplus)
}
#endif
#endif /* LLVM_ANALYSIS_PROFILEDATATYPES_H */

View File

@@ -0,0 +1,247 @@
//===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the generic ProfileInfo interface, which is used as the
// common interface used by all clients of profiling information, and
// implemented either by making static guestimations, or by actually reading in
// profiling information gathered by running the program.
//
// Note that to be useful, all profile-based optimizations should preserve
// ProfileInfo, which requires that they notify it when changes to the CFG are
// made. (This is not implemented yet.)
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PROFILEINFO_H
#define LLVM_ANALYSIS_PROFILEINFO_H
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <map>
#include <set>
#include <string>
namespace llvm {
class Pass;
class raw_ostream;
class BasicBlock;
class Function;
class MachineBasicBlock;
class MachineFunction;
// Helper for dumping edges to dbgs().
raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E);
raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E);
raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB);
raw_ostream& operator<<(raw_ostream &O, const Function *F);
raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
/// ProfileInfo Class - This class holds and maintains profiling
/// information for some unit of code.
template<class FType, class BType>
class ProfileInfoT {
public:
// Types for handling profiling information.
typedef std::pair<const BType*, const BType*> Edge;
typedef std::pair<Edge, double> EdgeWeight;
typedef std::map<Edge, double> EdgeWeights;
typedef std::map<const BType*, double> BlockCounts;
typedef std::map<const BType*, const BType*> Path;
protected:
// EdgeInformation - Count the number of times a transition between two
// blocks is executed. As a special case, we also hold an edge from the
// null BasicBlock to the entry block to indicate how many times the
// function was entered.
std::map<const FType*, EdgeWeights> EdgeInformation;
// BlockInformation - Count the number of times a block is executed.
std::map<const FType*, BlockCounts> BlockInformation;
// FunctionInformation - Count the number of times a function is executed.
std::map<const FType*, double> FunctionInformation;
ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
public:
static char ID; // Class identification, replacement for typeinfo
ProfileInfoT();
~ProfileInfoT(); // We want to be subclassed
// MissingValue - The value that is returned for execution counts in case
// no value is available.
static const double MissingValue;
// getFunction() - Returns the Function for an Edge, checking for validity.
static const FType* getFunction(Edge e) {
if (e.first)
return e.first->getParent();
if (e.second)
return e.second->getParent();
llvm_unreachable("Invalid ProfileInfo::Edge");
}
// getEdge() - Creates an Edge from two BasicBlocks.
static Edge getEdge(const BType *Src, const BType *Dest) {
return std::make_pair(Src, Dest);
}
//===------------------------------------------------------------------===//
/// Profile Information Queries
///
double getExecutionCount(const FType *F);
double getExecutionCount(const BType *BB);
void setExecutionCount(const BType *BB, double w);
void addExecutionCount(const BType *BB, double w);
double getEdgeWeight(Edge e) const {
typename std::map<const FType*, EdgeWeights>::const_iterator J =
EdgeInformation.find(getFunction(e));
if (J == EdgeInformation.end()) return MissingValue;
typename EdgeWeights::const_iterator I = J->second.find(e);
if (I == J->second.end()) return MissingValue;
return I->second;
}
void setEdgeWeight(Edge e, double w) {
DEBUG_WITH_TYPE("profile-info",
dbgs() << "Creating Edge " << e
<< " (weight: " << format("%.20g",w) << ")\n");
EdgeInformation[getFunction(e)][e] = w;
}
void addEdgeWeight(Edge e, double w);
EdgeWeights &getEdgeWeights (const FType *F) {
return EdgeInformation[F];
}
//===------------------------------------------------------------------===//
/// Analysis Update Methods
///
void removeBlock(const BType *BB);
void removeEdge(Edge e);
void replaceEdge(const Edge &, const Edge &);
enum GetPathMode {
GetPathToExit = 1,
GetPathToValue = 2,
GetPathToDest = 4,
GetPathWithNewEdges = 8
};
const BType *GetPath(const BType *Src, const BType *Dest,
Path &P, unsigned Mode);
void divertFlow(const Edge &, const Edge &);
void splitEdge(const BType *FirstBB, const BType *SecondBB,
const BType *NewBB, bool MergeIdenticalEdges = false);
void splitBlock(const BType *Old, const BType* New);
void splitBlock(const BType *BB, const BType* NewBB,
BType *const *Preds, unsigned NumPreds);
void replaceAllUses(const BType *RmBB, const BType *DestBB);
void transfer(const FType *Old, const FType *New);
void repair(const FType *F);
void dump(FType *F = 0, bool real = true) {
dbgs() << "**** This is ProfileInfo " << this << " speaking:\n";
if (!real) {
typename std::set<const FType*> Functions;
dbgs() << "Functions: \n";
if (F) {
dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
Functions.insert(F);
} else {
for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(),
fe = FunctionInformation.end(); fi != fe; ++fi) {
dbgs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n";
Functions.insert(fi->first);
}
}
for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
FI != FE; ++FI) {
const FType *F = *FI;
typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F);
dbgs() << "BasicBlocks for Function " << F << ":\n";
for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) {
dbgs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n";
}
}
for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
FI != FE; ++FI) {
typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI);
dbgs() << "Edges for Function " << ei->first << ":\n";
for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end();
ewi != ewe; ++ewi) {
dbgs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n";
}
}
} else {
assert(F && "No function given, this is not supported!");
dbgs() << "Functions: \n";
dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
dbgs() << "BasicBlocks for Function " << F << ":\n";
for (typename FType::const_iterator BI = F->begin(), BE = F->end();
BI != BE; ++BI) {
const BType *BB = &(*BI);
dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n";
}
}
dbgs() << "**** ProfileInfo " << this << ", over and out.\n";
}
bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false);
bool EstimateMissingEdges(const BType *BB);
ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
if (MachineProfile == 0)
MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>();
return MachineProfile;
}
bool hasMI() const {
return (MachineProfile != 0);
}
};
typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo;
/// createProfileLoaderPass - This function returns a Pass that loads the
/// profiling information for the module from the specified filename, making
/// it available to the optimizers.
Pass *createProfileLoaderPass(const std::string &Filename);
} // End llvm namespace
#endif

View File

@@ -0,0 +1,81 @@
//===- ProfileInfoLoader.h - Load & convert profile information -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The ProfileInfoLoader class is used to load and represent profiling
// information read in from the dump file. If conversions between formats are
// needed, it can also do this.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
#include <string>
#include <utility>
#include <vector>
namespace llvm {
class Module;
class Function;
class BasicBlock;
class ProfileInfoLoader {
const std::string &Filename;
std::vector<std::string> CommandLines;
std::vector<unsigned> FunctionCounts;
std::vector<unsigned> BlockCounts;
std::vector<unsigned> EdgeCounts;
std::vector<unsigned> OptimalEdgeCounts;
std::vector<unsigned> BBTrace;
public:
// ProfileInfoLoader ctor - Read the specified profiling data file, exiting
// the program if the file is invalid or broken.
ProfileInfoLoader(const char *ToolName, const std::string &Filename);
static const unsigned Uncounted;
unsigned getNumExecutions() const { return CommandLines.size(); }
const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
const std::string &getFileName() const { return Filename; }
// getRawFunctionCounts - This method is used by consumers of function
// counting information.
//
const std::vector<unsigned> &getRawFunctionCounts() const {
return FunctionCounts;
}
// getRawBlockCounts - This method is used by consumers of block counting
// information.
//
const std::vector<unsigned> &getRawBlockCounts() const {
return BlockCounts;
}
// getEdgeCounts - This method is used by consumers of edge counting
// information.
//
const std::vector<unsigned> &getRawEdgeCounts() const {
return EdgeCounts;
}
// getEdgeOptimalCounts - This method is used by consumers of optimal edge
// counting information.
//
const std::vector<unsigned> &getRawOptimalEdgeCounts() const {
return OptimalEdgeCounts;
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,52 @@
/*===-- ProfileInfoTypes.h - Profiling info shared constants --------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
|*===----------------------------------------------------------------------===*|
|*
|* This file defines constants shared by the various different profiling
|* runtime libraries and the LLVM C++ profile info loader. It must be a
|* C header because, at present, the profiling runtimes are written in C.
|*
\*===----------------------------------------------------------------------===*/
#ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H
#define LLVM_ANALYSIS_PROFILEINFOTYPES_H
/* Included by libprofile. */
#if defined(__cplusplus)
extern "C" {
#endif
/* IDs to distinguish between those path counters stored in hashses vs arrays */
enum ProfilingStorageType {
ProfilingArray = 1,
ProfilingHash = 2
};
#include "llvm/Analysis/ProfileDataTypes.h"
/*
* The header for tables that map path numbers to path counters.
*/
typedef struct {
unsigned fnNumber; /* function number for these counters */
unsigned numEntries; /* number of entries stored */
} PathProfileHeader;
/*
* Describes an entry in a tagged table for path counters.
*/
typedef struct {
unsigned pathNumber;
unsigned pathCounter;
} PathProfileTableEntry;
#if defined(__cplusplus)
}
#endif
#endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */

View File

@@ -0,0 +1,285 @@
//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This file provides a collection of visitors which walk the (instruction)
/// uses of a pointer. These visitors all provide the same essential behavior
/// as an InstVisitor with similar template-based flexibility and
/// implementation strategies.
///
/// These can be used, for example, to quickly analyze the uses of an alloca,
/// global variable, or function argument.
///
/// FIXME: Provide a variant which doesn't track offsets and is cheaper.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
#define LLVM_ANALYSIS_PTRUSEVISITOR_H
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/InstVisitor.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
namespace detail {
/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
///
/// See \c PtrUseVisitor for the public interface and detailed comments about
/// usage. This class is just a helper base class which is not templated and
/// contains all common code to be shared between different instantiations of
/// PtrUseVisitor.
class PtrUseVisitorBase {
public:
/// \brief This class provides information about the result of a visit.
///
/// After walking all the users (recursively) of a pointer, the basic
/// infrastructure records some commonly useful information such as escape
/// analysis and whether the visit completed or aborted early.
class PtrInfo {
public:
PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {}
/// \brief Reset the pointer info, clearing all state.
void reset() {
AbortedInfo.setPointer(0);
AbortedInfo.setInt(false);
EscapedInfo.setPointer(0);
EscapedInfo.setInt(false);
}
/// \brief Did we abort the visit early?
bool isAborted() const { return AbortedInfo.getInt(); }
/// \brief Is the pointer escaped at some point?
bool isEscaped() const { return EscapedInfo.getInt(); }
/// \brief Get the instruction causing the visit to abort.
/// \returns a pointer to the instruction causing the abort if one is
/// available; otherwise returns null.
Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); }
/// \brief Get the instruction causing the pointer to escape.
/// \returns a pointer to the instruction which escapes the pointer if one
/// is available; otherwise returns null.
Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); }
/// \brief Mark the visit as aborted. Intended for use in a void return.
/// \param I The instruction which caused the visit to abort, if available.
void setAborted(Instruction *I = 0) {
AbortedInfo.setInt(true);
AbortedInfo.setPointer(I);
}
/// \brief Mark the pointer as escaped. Intended for use in a void return.
/// \param I The instruction which escapes the pointer, if available.
void setEscaped(Instruction *I = 0) {
EscapedInfo.setInt(true);
EscapedInfo.setPointer(I);
}
/// \brief Mark the pointer as escaped, and the visit as aborted. Intended
/// for use in a void return.
/// \param I The instruction which both escapes the pointer and aborts the
/// visit, if available.
void setEscapedAndAborted(Instruction *I = 0) {
setEscaped(I);
setAborted(I);
}
private:
PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo;
};
protected:
const DataLayout &DL;
/// \name Visitation infrastructure
/// @{
/// \brief The info collected about the pointer being visited thus far.
PtrInfo PI;
/// \brief A struct of the data needed to visit a particular use.
///
/// This is used to maintain a worklist fo to-visit uses. This is used to
/// make the visit be iterative rather than recursive.
struct UseToVisit {
typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair;
UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
APInt Offset;
};
/// \brief The worklist of to-visit uses.
SmallVector<UseToVisit, 8> Worklist;
/// \brief A set of visited uses to break cycles in unreachable code.
SmallPtrSet<Use *, 8> VisitedUses;
/// @}
/// \name Per-visit state
/// This state is reset for each instruction visited.
/// @{
/// \brief The use currently being visited.
Use *U;
/// \brief True if we have a known constant offset for the use currently
/// being visited.
bool IsOffsetKnown;
/// \brief The constant offset of the use if that is known.
APInt Offset;
/// @}
/// Note that the constructor is protected because this class must be a base
/// class, we can't create instances directly of this class.
PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
/// \brief Enqueue the users of this instruction in the visit worklist.
///
/// This will visit the users with the same offset of the current visit
/// (including an unknown offset if that is the current state).
void enqueueUsers(Instruction &I);
/// \brief Walk the operands of a GEP and adjust the offset as appropriate.
///
/// This routine does the heavy lifting of the pointer walk by computing
/// offsets and looking through GEPs.
bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
};
} // end namespace detail
/// \brief A base class for visitors over the uses of a pointer value.
///
/// Once constructed, a user can call \c visit on a pointer value, and this
/// will walk its uses and visit each instruction using an InstVisitor. It also
/// provides visit methods which will recurse through any pointer-to-pointer
/// transformations such as GEPs and bitcasts.
///
/// During the visit, the current Use* being visited is available to the
/// subclass, as well as the current offset from the original base pointer if
/// known.
///
/// The recursive visit of uses is accomplished with a worklist, so the only
/// ordering guarantee is that an instruction is visited before any uses of it
/// are visited. Note that this does *not* mean before any of its users are
/// visited! This is because users can be visited multiple times due to
/// multiple, different uses of pointers derived from the same base.
///
/// A particular Use will only be visited once, but a User may be visited
/// multiple times, once per Use. This visits may notably have different
/// offsets.
///
/// All visit methods on the underlying InstVisitor return a boolean. This
/// return short-circuits the visit, stopping it immediately.
///
/// FIXME: Generalize this for all values rather than just instructions.
template <typename DerivedT>
class PtrUseVisitor : protected InstVisitor<DerivedT>,
public detail::PtrUseVisitorBase {
friend class InstVisitor<DerivedT>;
typedef InstVisitor<DerivedT> Base;
public:
PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
/// \brief Recursively visit the uses of the given pointer.
/// \returns An info struct about the pointer. See \c PtrInfo for details.
PtrInfo visitPtr(Instruction &I) {
// This must be a pointer type. Get an integer type suitable to hold
// offsets on this pointer.
// FIXME: Support a vector of pointers.
assert(I.getType()->isPointerTy());
IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType()));
IsOffsetKnown = true;
Offset = APInt(IntPtrTy->getBitWidth(), 0);
PI.reset();
// Enqueue the uses of this pointer.
enqueueUsers(I);
// Visit all the uses off the worklist until it is empty.
while (!Worklist.empty()) {
UseToVisit ToVisit = Worklist.pop_back_val();
U = ToVisit.UseAndIsOffsetKnown.getPointer();
IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
if (IsOffsetKnown)
Offset = llvm_move(ToVisit.Offset);
Instruction *I = cast<Instruction>(U->getUser());
static_cast<DerivedT*>(this)->visit(I);
if (PI.isAborted())
break;
}
return PI;
}
protected:
void visitStoreInst(StoreInst &SI) {
if (SI.getValueOperand() == U->get())
PI.setEscaped(&SI);
}
void visitBitCastInst(BitCastInst &BC) {
enqueueUsers(BC);
}
void visitPtrToIntInst(PtrToIntInst &I) {
PI.setEscaped(&I);
}
void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
if (GEPI.use_empty())
return;
// If we can't walk the GEP, clear the offset.
if (!adjustOffsetForGEP(GEPI)) {
IsOffsetKnown = false;
Offset = APInt();
}
// Enqueue the users now that the offset has been adjusted.
enqueueUsers(GEPI);
}
// No-op intrinsics which we know don't escape the pointer to to logic in
// some other function.
void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {}
void visitMemIntrinsic(MemIntrinsic &I) {}
void visitIntrinsicInst(IntrinsicInst &II) {
switch (II.getIntrinsicID()) {
default:
return Base::visitIntrinsicInst(II);
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
return; // No-op intrinsics.
}
}
// Generically, arguments to calls and invokes escape the pointer to some
// other function. Mark that.
void visitCallSite(CallSite CS) {
PI.setEscaped(CS.getInstruction());
Base::visitCallSite(CS);
}
};
}
#endif

View File

@@ -0,0 +1,739 @@
//===- RegionInfo.h - SESE region analysis ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Calculate a program structure tree built out of single entry single exit
// regions.
// The basic ideas are taken from "The Program Structure Tree - Richard Johnson,
// David Pearson, Keshav Pingali - 1994", however enriched with ideas from "The
// Refined Process Structure Tree - Jussi Vanhatalo, Hagen Voelyer, Jana
// Koehler - 2009".
// The algorithm to calculate these data structures however is completely
// different, as it takes advantage of existing information already available
// in (Post)dominace tree and dominance frontier passes. This leads to a simpler
// and in practice hopefully better performing algorithm. The runtime of the
// algorithms described in the papers above are both linear in graph size,
// O(V+E), whereas this algorithm is not, as the dominance frontier information
// itself is not, but in practice runtime seems to be in the order of magnitude
// of dominance tree calculation.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONINFO_H
#define LLVM_ANALYSIS_REGIONINFO_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/DominanceFrontier.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Support/Allocator.h"
#include <map>
namespace llvm {
class Region;
class RegionInfo;
class raw_ostream;
class Loop;
class LoopInfo;
/// @brief Marker class to iterate over the elements of a Region in flat mode.
///
/// The class is used to either iterate in Flat mode or by not using it to not
/// iterate in Flat mode. During a Flat mode iteration all Regions are entered
/// and the iteration returns every BasicBlock. If the Flat mode is not
/// selected for SubRegions just one RegionNode containing the subregion is
/// returned.
template <class GraphType>
class FlatIt {};
/// @brief A RegionNode represents a subregion or a BasicBlock that is part of a
/// Region.
class RegionNode {
RegionNode(const RegionNode &) LLVM_DELETED_FUNCTION;
const RegionNode &operator=(const RegionNode &) LLVM_DELETED_FUNCTION;
protected:
/// This is the entry basic block that starts this region node. If this is a
/// BasicBlock RegionNode, then entry is just the basic block, that this
/// RegionNode represents. Otherwise it is the entry of this (Sub)RegionNode.
///
/// In the BBtoRegionNode map of the parent of this node, BB will always map
/// to this node no matter which kind of node this one is.
///
/// The node can hold either a Region or a BasicBlock.
/// Use one bit to save, if this RegionNode is a subregion or BasicBlock
/// RegionNode.
PointerIntPair<BasicBlock*, 1, bool> entry;
/// @brief The parent Region of this RegionNode.
/// @see getParent()
Region* parent;
public:
/// @brief Create a RegionNode.
///
/// @param Parent The parent of this RegionNode.
/// @param Entry The entry BasicBlock of the RegionNode. If this
/// RegionNode represents a BasicBlock, this is the
/// BasicBlock itself. If it represents a subregion, this
/// is the entry BasicBlock of the subregion.
/// @param isSubRegion If this RegionNode represents a SubRegion.
inline RegionNode(Region* Parent, BasicBlock* Entry, bool isSubRegion = 0)
: entry(Entry, isSubRegion), parent(Parent) {}
/// @brief Get the parent Region of this RegionNode.
///
/// The parent Region is the Region this RegionNode belongs to. If for
/// example a BasicBlock is element of two Regions, there exist two
/// RegionNodes for this BasicBlock. Each with the getParent() function
/// pointing to the Region this RegionNode belongs to.
///
/// @return Get the parent Region of this RegionNode.
inline Region* getParent() const { return parent; }
/// @brief Get the entry BasicBlock of this RegionNode.
///
/// If this RegionNode represents a BasicBlock this is just the BasicBlock
/// itself, otherwise we return the entry BasicBlock of the Subregion
///
/// @return The entry BasicBlock of this RegionNode.
inline BasicBlock* getEntry() const { return entry.getPointer(); }
/// @brief Get the content of this RegionNode.
///
/// This can be either a BasicBlock or a subregion. Before calling getNodeAs()
/// check the type of the content with the isSubRegion() function call.
///
/// @return The content of this RegionNode.
template<class T>
inline T* getNodeAs() const;
/// @brief Is this RegionNode a subregion?
///
/// @return True if it contains a subregion. False if it contains a
/// BasicBlock.
inline bool isSubRegion() const {
return entry.getInt();
}
};
/// Print a RegionNode.
inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node);
template<>
inline BasicBlock* RegionNode::getNodeAs<BasicBlock>() const {
assert(!isSubRegion() && "This is not a BasicBlock RegionNode!");
return getEntry();
}
template<>
inline Region* RegionNode::getNodeAs<Region>() const {
assert(isSubRegion() && "This is not a subregion RegionNode!");
return reinterpret_cast<Region*>(const_cast<RegionNode*>(this));
}
//===----------------------------------------------------------------------===//
/// @brief A single entry single exit Region.
///
/// A Region is a connected subgraph of a control flow graph that has exactly
/// two connections to the remaining graph. It can be used to analyze or
/// optimize parts of the control flow graph.
///
/// A <em> simple Region </em> is connected to the remaining graph by just two
/// edges. One edge entering the Region and another one leaving the Region.
///
/// An <em> extended Region </em> (or just Region) is a subgraph that can be
/// transform into a simple Region. The transformation is done by adding
/// BasicBlocks that merge several entry or exit edges so that after the merge
/// just one entry and one exit edge exists.
///
/// The \e Entry of a Region is the first BasicBlock that is passed after
/// entering the Region. It is an element of the Region. The entry BasicBlock
/// dominates all BasicBlocks in the Region.
///
/// The \e Exit of a Region is the first BasicBlock that is passed after
/// leaving the Region. It is not an element of the Region. The exit BasicBlock,
/// postdominates all BasicBlocks in the Region.
///
/// A <em> canonical Region </em> cannot be constructed by combining smaller
/// Regions.
///
/// Region A is the \e parent of Region B, if B is completely contained in A.
///
/// Two canonical Regions either do not intersect at all or one is
/// the parent of the other.
///
/// The <em> Program Structure Tree</em> is a graph (V, E) where V is the set of
/// Regions in the control flow graph and E is the \e parent relation of these
/// Regions.
///
/// Example:
///
/// \verbatim
/// A simple control flow graph, that contains two regions.
///
/// 1
/// / |
/// 2 |
/// / \ 3
/// 4 5 |
/// | | |
/// 6 7 8
/// \ | /
/// \ |/ Region A: 1 -> 9 {1,2,3,4,5,6,7,8}
/// 9 Region B: 2 -> 9 {2,4,5,6,7}
/// \endverbatim
///
/// You can obtain more examples by either calling
///
/// <tt> "opt -regions -analyze anyprogram.ll" </tt>
/// or
/// <tt> "opt -view-regions-only anyprogram.ll" </tt>
///
/// on any LLVM file you are interested in.
///
/// The first call returns a textual representation of the program structure
/// tree, the second one creates a graphical representation using graphviz.
class Region : public RegionNode {
friend class RegionInfo;
Region(const Region &) LLVM_DELETED_FUNCTION;
const Region &operator=(const Region &) LLVM_DELETED_FUNCTION;
// Information necessary to manage this Region.
RegionInfo* RI;
DominatorTree *DT;
// The exit BasicBlock of this region.
// (The entry BasicBlock is part of RegionNode)
BasicBlock *exit;
typedef std::vector<Region*> RegionSet;
// The subregions of this region.
RegionSet children;
typedef std::map<BasicBlock*, RegionNode*> BBNodeMapT;
// Save the BasicBlock RegionNodes that are element of this Region.
mutable BBNodeMapT BBNodeMap;
/// verifyBBInRegion - Check if a BB is in this Region. This check also works
/// if the region is incorrectly built. (EXPENSIVE!)
void verifyBBInRegion(BasicBlock* BB) const;
/// verifyWalk - Walk over all the BBs of the region starting from BB and
/// verify that all reachable basic blocks are elements of the region.
/// (EXPENSIVE!)
void verifyWalk(BasicBlock* BB, std::set<BasicBlock*>* visitedBB) const;
/// verifyRegionNest - Verify if the region and its children are valid
/// regions (EXPENSIVE!)
void verifyRegionNest() const;
public:
/// @brief Create a new region.
///
/// @param Entry The entry basic block of the region.
/// @param Exit The exit basic block of the region.
/// @param RI The region info object that is managing this region.
/// @param DT The dominator tree of the current function.
/// @param Parent The surrounding region or NULL if this is a top level
/// region.
Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
DominatorTree *DT, Region *Parent = 0);
/// Delete the Region and all its subregions.
~Region();
/// @brief Get the entry BasicBlock of the Region.
/// @return The entry BasicBlock of the region.
BasicBlock *getEntry() const { return RegionNode::getEntry(); }
/// @brief Replace the entry basic block of the region with the new basic
/// block.
///
/// @param BB The new entry basic block of the region.
void replaceEntry(BasicBlock *BB);
/// @brief Replace the exit basic block of the region with the new basic
/// block.
///
/// @param BB The new exit basic block of the region.
void replaceExit(BasicBlock *BB);
/// @brief Recursively replace the entry basic block of the region.
///
/// This function replaces the entry basic block with a new basic block. It
/// also updates all child regions that have the same entry basic block as
/// this region.
///
/// @param NewEntry The new entry basic block.
void replaceEntryRecursive(BasicBlock *NewEntry);
/// @brief Recursively replace the exit basic block of the region.
///
/// This function replaces the exit basic block with a new basic block. It
/// also updates all child regions that have the same exit basic block as
/// this region.
///
/// @param NewExit The new exit basic block.
void replaceExitRecursive(BasicBlock *NewExit);
/// @brief Get the exit BasicBlock of the Region.
/// @return The exit BasicBlock of the Region, NULL if this is the TopLevel
/// Region.
BasicBlock *getExit() const { return exit; }
/// @brief Get the parent of the Region.
/// @return The parent of the Region or NULL if this is a top level
/// Region.
Region *getParent() const { return RegionNode::getParent(); }
/// @brief Get the RegionNode representing the current Region.
/// @return The RegionNode representing the current Region.
RegionNode* getNode() const {
return const_cast<RegionNode*>(reinterpret_cast<const RegionNode*>(this));
}
/// @brief Get the nesting level of this Region.
///
/// An toplevel Region has depth 0.
///
/// @return The depth of the region.
unsigned getDepth() const;
/// @brief Check if a Region is the TopLevel region.
///
/// The toplevel region represents the whole function.
bool isTopLevelRegion() const { return exit == NULL; }
/// @brief Return a new (non canonical) region, that is obtained by joining
/// this region with its predecessors.
///
/// @return A region also starting at getEntry(), but reaching to the next
/// basic block that forms with getEntry() a (non canonical) region.
/// NULL if such a basic block does not exist.
Region *getExpandedRegion() const;
/// @brief Return the first block of this region's single entry edge,
/// if existing.
///
/// @return The BasicBlock starting this region's single entry edge,
/// else NULL.
BasicBlock *getEnteringBlock() const;
/// @brief Return the first block of this region's single exit edge,
/// if existing.
///
/// @return The BasicBlock starting this region's single exit edge,
/// else NULL.
BasicBlock *getExitingBlock() const;
/// @brief Is this a simple region?
///
/// A region is simple if it has exactly one exit and one entry edge.
///
/// @return True if the Region is simple.
bool isSimple() const;
/// @brief Returns the name of the Region.
/// @return The Name of the Region.
std::string getNameStr() const;
/// @brief Return the RegionInfo object, that belongs to this Region.
RegionInfo *getRegionInfo() const {
return RI;
}
/// PrintStyle - Print region in difference ways.
enum PrintStyle { PrintNone, PrintBB, PrintRN };
/// @brief Print the region.
///
/// @param OS The output stream the Region is printed to.
/// @param printTree Print also the tree of subregions.
/// @param level The indentation level used for printing.
void print(raw_ostream& OS, bool printTree = true, unsigned level = 0,
enum PrintStyle Style = PrintNone) const;
/// @brief Print the region to stderr.
void dump() const;
/// @brief Check if the region contains a BasicBlock.
///
/// @param BB The BasicBlock that might be contained in this Region.
/// @return True if the block is contained in the region otherwise false.
bool contains(const BasicBlock *BB) const;
/// @brief Check if the region contains another region.
///
/// @param SubRegion The region that might be contained in this Region.
/// @return True if SubRegion is contained in the region otherwise false.
bool contains(const Region *SubRegion) const {
// Toplevel Region.
if (!getExit())
return true;
return contains(SubRegion->getEntry())
&& (contains(SubRegion->getExit()) || SubRegion->getExit() == getExit());
}
/// @brief Check if the region contains an Instruction.
///
/// @param Inst The Instruction that might be contained in this region.
/// @return True if the Instruction is contained in the region otherwise false.
bool contains(const Instruction *Inst) const {
return contains(Inst->getParent());
}
/// @brief Check if the region contains a loop.
///
/// @param L The loop that might be contained in this region.
/// @return True if the loop is contained in the region otherwise false.
/// In case a NULL pointer is passed to this function the result
/// is false, except for the region that describes the whole function.
/// In that case true is returned.
bool contains(const Loop *L) const;
/// @brief Get the outermost loop in the region that contains a loop.
///
/// Find for a Loop L the outermost loop OuterL that is a parent loop of L
/// and is itself contained in the region.
///
/// @param L The loop the lookup is started.
/// @return The outermost loop in the region, NULL if such a loop does not
/// exist or if the region describes the whole function.
Loop *outermostLoopInRegion(Loop *L) const;
/// @brief Get the outermost loop in the region that contains a basic block.
///
/// Find for a basic block BB the outermost loop L that contains BB and is
/// itself contained in the region.
///
/// @param LI A pointer to a LoopInfo analysis.
/// @param BB The basic block surrounded by the loop.
/// @return The outermost loop in the region, NULL if such a loop does not
/// exist or if the region describes the whole function.
Loop *outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const;
/// @brief Get the subregion that starts at a BasicBlock
///
/// @param BB The BasicBlock the subregion should start.
/// @return The Subregion if available, otherwise NULL.
Region* getSubRegionNode(BasicBlock *BB) const;
/// @brief Get the RegionNode for a BasicBlock
///
/// @param BB The BasicBlock at which the RegionNode should start.
/// @return If available, the RegionNode that represents the subregion
/// starting at BB. If no subregion starts at BB, the RegionNode
/// representing BB.
RegionNode* getNode(BasicBlock *BB) const;
/// @brief Get the BasicBlock RegionNode for a BasicBlock
///
/// @param BB The BasicBlock for which the RegionNode is requested.
/// @return The RegionNode representing the BB.
RegionNode* getBBNode(BasicBlock *BB) const;
/// @brief Add a new subregion to this Region.
///
/// @param SubRegion The new subregion that will be added.
/// @param moveChildren Move the children of this region, that are also
/// contained in SubRegion into SubRegion.
void addSubRegion(Region *SubRegion, bool moveChildren = false);
/// @brief Remove a subregion from this Region.
///
/// The subregion is not deleted, as it will probably be inserted into another
/// region.
/// @param SubRegion The SubRegion that will be removed.
Region *removeSubRegion(Region *SubRegion);
/// @brief Move all direct child nodes of this Region to another Region.
///
/// @param To The Region the child nodes will be transferred to.
void transferChildrenTo(Region *To);
/// @brief Verify if the region is a correct region.
///
/// Check if this is a correctly build Region. This is an expensive check, as
/// the complete CFG of the Region will be walked.
void verifyRegion() const;
/// @brief Clear the cache for BB RegionNodes.
///
/// After calling this function the BasicBlock RegionNodes will be stored at
/// different memory locations. RegionNodes obtained before this function is
/// called are therefore not comparable to RegionNodes abtained afterwords.
void clearNodeCache();
/// @name Subregion Iterators
///
/// These iterators iterator over all subregions of this Region.
//@{
typedef RegionSet::iterator iterator;
typedef RegionSet::const_iterator const_iterator;
iterator begin() { return children.begin(); }
iterator end() { return children.end(); }
const_iterator begin() const { return children.begin(); }
const_iterator end() const { return children.end(); }
//@}
/// @name BasicBlock Iterators
///
/// These iterators iterate over all BasicBlocks that are contained in this
/// Region. The iterator also iterates over BasicBlocks that are elements of
/// a subregion of this Region. It is therefore called a flat iterator.
//@{
template <bool IsConst>
class block_iterator_wrapper
: public df_iterator<typename conditional<IsConst,
const BasicBlock,
BasicBlock>::type*> {
typedef df_iterator<typename conditional<IsConst,
const BasicBlock,
BasicBlock>::type*>
super;
public:
typedef block_iterator_wrapper<IsConst> Self;
typedef typename super::pointer pointer;
// Construct the begin iterator.
block_iterator_wrapper(pointer Entry, pointer Exit) : super(df_begin(Entry))
{
// Mark the exit of the region as visited, so that the children of the
// exit and the exit itself, i.e. the block outside the region will never
// be visited.
super::Visited.insert(Exit);
}
// Construct the end iterator.
block_iterator_wrapper() : super(df_end<pointer>((BasicBlock *)0)) {}
/*implicit*/ block_iterator_wrapper(super I) : super(I) {}
// FIXME: Even a const_iterator returns a non-const BasicBlock pointer.
// This was introduced for backwards compatibility, but should
// be removed as soon as all users are fixed.
BasicBlock *operator*() const {
return const_cast<BasicBlock*>(super::operator*());
}
};
typedef block_iterator_wrapper<false> block_iterator;
typedef block_iterator_wrapper<true> const_block_iterator;
block_iterator block_begin() {
return block_iterator(getEntry(), getExit());
}
block_iterator block_end() {
return block_iterator();
}
const_block_iterator block_begin() const {
return const_block_iterator(getEntry(), getExit());
}
const_block_iterator block_end() const {
return const_block_iterator();
}
//@}
/// @name Element Iterators
///
/// These iterators iterate over all BasicBlock and subregion RegionNodes that
/// are direct children of this Region. It does not iterate over any
/// RegionNodes that are also element of a subregion of this Region.
//@{
typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
GraphTraits<RegionNode*> > element_iterator;
typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
false, GraphTraits<const RegionNode*> >
const_element_iterator;
element_iterator element_begin();
element_iterator element_end();
const_element_iterator element_begin() const;
const_element_iterator element_end() const;
//@}
};
//===----------------------------------------------------------------------===//
/// @brief Analysis that detects all canonical Regions.
///
/// The RegionInfo pass detects all canonical regions in a function. The Regions
/// are connected using the parent relation. This builds a Program Structure
/// Tree.
class RegionInfo : public FunctionPass {
typedef DenseMap<BasicBlock*,BasicBlock*> BBtoBBMap;
typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
typedef SmallPtrSet<Region*, 4> RegionSet;
RegionInfo(const RegionInfo &) LLVM_DELETED_FUNCTION;
const RegionInfo &operator=(const RegionInfo &) LLVM_DELETED_FUNCTION;
DominatorTree *DT;
PostDominatorTree *PDT;
DominanceFrontier *DF;
/// The top level region.
Region *TopLevelRegion;
/// Map every BB to the smallest region, that contains BB.
BBtoRegionMap BBtoRegion;
// isCommonDomFrontier - Returns true if BB is in the dominance frontier of
// entry, because it was inherited from exit. In the other case there is an
// edge going from entry to BB without passing exit.
bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
BasicBlock* exit) const;
// isRegion - Check if entry and exit surround a valid region, based on
// dominance tree and dominance frontier.
bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
// insertShortCut - Saves a shortcut pointing from entry to exit.
// This function may extend this shortcut if possible.
void insertShortCut(BasicBlock* entry, BasicBlock* exit,
BBtoBBMap* ShortCut) const;
// getNextPostDom - Returns the next BB that postdominates N, while skipping
// all post dominators that cannot finish a canonical region.
DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
// isTrivialRegion - A region is trivial, if it contains only one BB.
bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
// createRegion - Creates a single entry single exit region.
Region *createRegion(BasicBlock *entry, BasicBlock *exit);
// findRegionsWithEntry - Detect all regions starting with bb 'entry'.
void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
// scanForRegions - Detects regions in F.
void scanForRegions(Function &F, BBtoBBMap *ShortCut);
// getTopMostParent - Get the top most parent with the same entry block.
Region *getTopMostParent(Region *region);
// buildRegionsTree - build the region hierarchy after all region detected.
void buildRegionsTree(DomTreeNode *N, Region *region);
// Calculate - detecte all regions in function and build the region tree.
void Calculate(Function& F);
void releaseMemory();
// updateStatistics - Update statistic about created regions.
void updateStatistics(Region *R);
// isSimple - Check if a region is a simple region with exactly one entry
// edge and exactly one exit edge.
bool isSimple(Region* R) const;
public:
static char ID;
explicit RegionInfo();
~RegionInfo();
/// @name FunctionPass interface
//@{
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module *) const;
virtual void verifyAnalysis() const;
//@}
/// @brief Get the smallest region that contains a BasicBlock.
///
/// @param BB The basic block.
/// @return The smallest region, that contains BB or NULL, if there is no
/// region containing BB.
Region *getRegionFor(BasicBlock *BB) const;
/// @brief Set the smallest region that surrounds a basic block.
///
/// @param BB The basic block surrounded by a region.
/// @param R The smallest region that surrounds BB.
void setRegionFor(BasicBlock *BB, Region *R);
/// @brief A shortcut for getRegionFor().
///
/// @param BB The basic block.
/// @return The smallest region, that contains BB or NULL, if there is no
/// region containing BB.
Region *operator[](BasicBlock *BB) const;
/// @brief Return the exit of the maximal refined region, that starts at a
/// BasicBlock.
///
/// @param BB The BasicBlock the refined region starts.
BasicBlock *getMaxRegionExit(BasicBlock *BB) const;
/// @brief Find the smallest region that contains two regions.
///
/// @param A The first region.
/// @param B The second region.
/// @return The smallest region containing A and B.
Region *getCommonRegion(Region* A, Region *B) const;
/// @brief Find the smallest region that contains two basic blocks.
///
/// @param A The first basic block.
/// @param B The second basic block.
/// @return The smallest region that contains A and B.
Region* getCommonRegion(BasicBlock* A, BasicBlock *B) const {
return getCommonRegion(getRegionFor(A), getRegionFor(B));
}
/// @brief Find the smallest region that contains a set of regions.
///
/// @param Regions A vector of regions.
/// @return The smallest region that contains all regions in Regions.
Region* getCommonRegion(SmallVectorImpl<Region*> &Regions) const;
/// @brief Find the smallest region that contains a set of basic blocks.
///
/// @param BBs A vector of basic blocks.
/// @return The smallest region that contains all basic blocks in BBS.
Region* getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const;
Region *getTopLevelRegion() const {
return TopLevelRegion;
}
/// @brief Update RegionInfo after a basic block was split.
///
/// @param NewBB The basic block that was created before OldBB.
/// @param OldBB The old basic block.
void splitBlock(BasicBlock* NewBB, BasicBlock *OldBB);
/// @brief Clear the Node Cache for all Regions.
///
/// @see Region::clearNodeCache()
void clearNodeCache() {
if (TopLevelRegion)
TopLevelRegion->clearNodeCache();
}
};
inline raw_ostream &operator<<(raw_ostream &OS, const RegionNode &Node) {
if (Node.isSubRegion())
return OS << Node.getNodeAs<Region>()->getNameStr();
else
return OS << Node.getNodeAs<BasicBlock>()->getName();
}
} // End llvm namespace
#endif

View File

@@ -0,0 +1,342 @@
//===- RegionIterator.h - Iterators to iteratate over Regions ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
#define LLVM_ANALYSIS_REGIONITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
//===----------------------------------------------------------------------===//
/// @brief Hierarchical RegionNode successor iterator.
///
/// This iterator iterates over all successors of a RegionNode.
///
/// For a BasicBlock RegionNode it skips all BasicBlocks that are not part of
/// the parent Region. Furthermore for BasicBlocks that start a subregion, a
/// RegionNode representing the subregion is returned.
///
/// For a subregion RegionNode there is just one successor. The RegionNode
/// representing the exit of the subregion.
template<class NodeType>
class RNSuccIterator : public std::iterator<std::forward_iterator_tag,
NodeType, ptrdiff_t>
{
typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
// The iterator works in two modes, bb mode or region mode.
enum ItMode{
// In BB mode it returns all successors of this BasicBlock as its
// successors.
ItBB,
// In region mode there is only one successor, thats the regionnode mapping
// to the exit block of the regionnode
ItRgBegin, // At the beginning of the regionnode successor.
ItRgEnd // At the end of the regionnode successor.
};
// Use two bit to represent the mode iterator.
PointerIntPair<NodeType*, 2, enum ItMode> Node;
// The block successor iterator.
succ_iterator BItor;
// advanceRegionSucc - A region node has only one successor. It reaches end
// once we advance it.
void advanceRegionSucc() {
assert(Node.getInt() == ItRgBegin && "Cannot advance region successor!");
Node.setInt(ItRgEnd);
}
NodeType* getNode() const{ return Node.getPointer(); }
// isRegionMode - Is the current iterator in region mode?
bool isRegionMode() const { return Node.getInt() != ItBB; }
// Get the immediate successor. This function may return a Basic Block
// RegionNode or a subregion RegionNode.
RegionNode* getISucc(BasicBlock* BB) const {
RegionNode *succ;
succ = getNode()->getParent()->getNode(BB);
assert(succ && "BB not in Region or entered subregion!");
return succ;
}
// getRegionSucc - Return the successor basic block of a SubRegion RegionNode.
inline BasicBlock* getRegionSucc() const {
assert(Node.getInt() == ItRgBegin && "Cannot get the region successor!");
return getNode()->template getNodeAs<Region>()->getExit();
}
// isExit - Is this the exit BB of the Region?
inline bool isExit(BasicBlock* BB) const {
return getNode()->getParent()->getExit() == BB;
}
public:
typedef RNSuccIterator<NodeType> Self;
typedef typename super::pointer pointer;
/// @brief Create begin iterator of a RegionNode.
inline RNSuccIterator(NodeType* node)
: Node(node, node->isSubRegion() ? ItRgBegin : ItBB),
BItor(succ_begin(node->getEntry())) {
// Skip the exit block
if (!isRegionMode())
while (succ_end(node->getEntry()) != BItor && isExit(*BItor))
++BItor;
if (isRegionMode() && isExit(getRegionSucc()))
advanceRegionSucc();
}
/// @brief Create an end iterator.
inline RNSuccIterator(NodeType* node, bool)
: Node(node, node->isSubRegion() ? ItRgEnd : ItBB),
BItor(succ_end(node->getEntry())) {}
inline bool operator==(const Self& x) const {
assert(isRegionMode() == x.isRegionMode() && "Broken iterator!");
if (isRegionMode())
return Node.getInt() == x.Node.getInt();
else
return BItor == x.BItor;
}
inline bool operator!=(const Self& x) const { return !operator==(x); }
inline pointer operator*() const {
BasicBlock* BB = isRegionMode() ? getRegionSucc() : *BItor;
assert(!isExit(BB) && "Iterator out of range!");
return getISucc(BB);
}
inline Self& operator++() {
if(isRegionMode()) {
// The Region only has 1 successor.
advanceRegionSucc();
} else {
// Skip the exit.
do
++BItor;
while (BItor != succ_end(getNode()->getEntry())
&& isExit(*BItor));
}
return *this;
}
inline Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
inline const Self &operator=(const Self &I) {
if (this != &I) {
assert(getNode()->getParent() == I.getNode()->getParent()
&& "Cannot assign iterators of two different regions!");
Node = I.Node;
BItor = I.BItor;
}
return *this;
}
};
//===----------------------------------------------------------------------===//
/// @brief Flat RegionNode iterator.
///
/// The Flat Region iterator will iterate over all BasicBlock RegionNodes that
/// are contained in the Region and its subregions. This is close to a virtual
/// control flow graph of the Region.
template<class NodeType>
class RNSuccIterator<FlatIt<NodeType> >
: public std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t>
{
typedef std::iterator<std::forward_iterator_tag, NodeType, ptrdiff_t> super;
NodeType* Node;
succ_iterator Itor;
public:
typedef RNSuccIterator<FlatIt<NodeType> > Self;
typedef typename super::pointer pointer;
/// @brief Create the iterator from a RegionNode.
///
/// Note that the incoming node must be a bb node, otherwise it will trigger
/// an assertion when we try to get a BasicBlock.
inline RNSuccIterator(NodeType* node) : Node(node),
Itor(succ_begin(node->getEntry())) {
assert(!Node->isSubRegion()
&& "Subregion node not allowed in flat iterating mode!");
assert(Node->getParent() && "A BB node must have a parent!");
// Skip the exit block of the iterating region.
while (succ_end(Node->getEntry()) != Itor
&& Node->getParent()->getExit() == *Itor)
++Itor;
}
/// @brief Create an end iterator
inline RNSuccIterator(NodeType* node, bool) : Node(node),
Itor(succ_end(node->getEntry())) {
assert(!Node->isSubRegion()
&& "Subregion node not allowed in flat iterating mode!");
}
inline bool operator==(const Self& x) const {
assert(Node->getParent() == x.Node->getParent()
&& "Cannot compare iterators of different regions!");
return Itor == x.Itor && Node == x.Node;
}
inline bool operator!=(const Self& x) const { return !operator==(x); }
inline pointer operator*() const {
BasicBlock* BB = *Itor;
// Get the iterating region.
Region* Parent = Node->getParent();
// The only case that the successor reaches out of the region is it reaches
// the exit of the region.
assert(Parent->getExit() != BB && "iterator out of range!");
return Parent->getBBNode(BB);
}
inline Self& operator++() {
// Skip the exit block of the iterating region.
do
++Itor;
while (Itor != succ_end(Node->getEntry())
&& Node->getParent()->getExit() == *Itor);
return *this;
}
inline Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
inline const Self &operator=(const Self &I) {
if (this != &I) {
assert(Node->getParent() == I.Node->getParent()
&& "Cannot assign iterators to two different regions!");
Node = I.Node;
Itor = I.Itor;
}
return *this;
}
};
template<class NodeType>
inline RNSuccIterator<NodeType> succ_begin(NodeType* Node) {
return RNSuccIterator<NodeType>(Node);
}
template<class NodeType>
inline RNSuccIterator<NodeType> succ_end(NodeType* Node) {
return RNSuccIterator<NodeType>(Node, true);
}
//===--------------------------------------------------------------------===//
// RegionNode GraphTraits specialization so the bbs in the region can be
// iterate by generic graph iterators.
//
// NodeT can either be region node or const region node, otherwise child_begin
// and child_end fail.
#define RegionNodeGraphTraits(NodeT) \
template<> struct GraphTraits<NodeT*> { \
typedef NodeT NodeType; \
typedef RNSuccIterator<NodeType> ChildIteratorType; \
static NodeType *getEntryNode(NodeType* N) { return N; } \
static inline ChildIteratorType child_begin(NodeType *N) { \
return RNSuccIterator<NodeType>(N); \
} \
static inline ChildIteratorType child_end(NodeType *N) { \
return RNSuccIterator<NodeType>(N, true); \
} \
}; \
template<> struct GraphTraits<FlatIt<NodeT*> > { \
typedef NodeT NodeType; \
typedef RNSuccIterator<FlatIt<NodeT> > ChildIteratorType; \
static NodeType *getEntryNode(NodeType* N) { return N; } \
static inline ChildIteratorType child_begin(NodeType *N) { \
return RNSuccIterator<FlatIt<NodeType> >(N); \
} \
static inline ChildIteratorType child_end(NodeType *N) { \
return RNSuccIterator<FlatIt<NodeType> >(N, true); \
} \
}
#define RegionGraphTraits(RegionT, NodeT) \
template<> struct GraphTraits<RegionT*> \
: public GraphTraits<NodeT*> { \
typedef df_iterator<NodeType*> nodes_iterator; \
static NodeType *getEntryNode(RegionT* R) { \
return R->getNode(R->getEntry()); \
} \
static nodes_iterator nodes_begin(RegionT* R) { \
return nodes_iterator::begin(getEntryNode(R)); \
} \
static nodes_iterator nodes_end(RegionT* R) { \
return nodes_iterator::end(getEntryNode(R)); \
} \
}; \
template<> struct GraphTraits<FlatIt<RegionT*> > \
: public GraphTraits<FlatIt<NodeT*> > { \
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false, \
GraphTraits<FlatIt<NodeType*> > > nodes_iterator; \
static NodeType *getEntryNode(RegionT* R) { \
return R->getBBNode(R->getEntry()); \
} \
static nodes_iterator nodes_begin(RegionT* R) { \
return nodes_iterator::begin(getEntryNode(R)); \
} \
static nodes_iterator nodes_end(RegionT* R) { \
return nodes_iterator::end(getEntryNode(R)); \
} \
}
RegionNodeGraphTraits(RegionNode);
RegionNodeGraphTraits(const RegionNode);
RegionGraphTraits(Region, RegionNode);
RegionGraphTraits(const Region, const RegionNode);
template <> struct GraphTraits<RegionInfo*>
: public GraphTraits<FlatIt<RegionNode*> > {
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
GraphTraits<FlatIt<NodeType*> > > nodes_iterator;
static NodeType *getEntryNode(RegionInfo *RI) {
return GraphTraits<FlatIt<Region*> >::getEntryNode(RI->getTopLevelRegion());
}
static nodes_iterator nodes_begin(RegionInfo* RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
static nodes_iterator nodes_end(RegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
};
} // End namespace llvm
#endif

View File

@@ -0,0 +1,127 @@
//===- RegionPass.h - RegionPass class ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the RegionPass class. All region based analysis,
// optimization and transformation passes are derived from RegionPass.
// This class is implemented following the some ideas of the LoopPass.h class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONPASS_H
#define LLVM_ANALYSIS_REGIONPASS_H
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
#include <deque>
namespace llvm {
class RGPassManager;
class Function;
//===----------------------------------------------------------------------===//
/// @brief A pass that runs on each Region in a function.
///
/// RegionPass is managed by RGPassManager.
class RegionPass : public Pass {
public:
explicit RegionPass(char &pid) : Pass(PT_Region, pid) {}
//===--------------------------------------------------------------------===//
/// @name To be implemented by every RegionPass
///
//@{
/// @brief Run the pass on a specific Region
///
/// Accessing regions not contained in the current region is not allowed.
///
/// @param R The region this pass is run on.
/// @param RGM The RegionPassManager that manages this Pass.
///
/// @return True if the pass modifies this Region.
virtual bool runOnRegion(Region *R, RGPassManager &RGM) = 0;
/// @brief Get a pass to print the LLVM IR in the region.
///
/// @param O The ouput stream to print the Region.
/// @param Banner The banner to separate different printed passes.
///
/// @return The pass to print the LLVM IR in the region.
Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const;
using llvm::Pass::doInitialization;
using llvm::Pass::doFinalization;
virtual bool doInitialization(Region *R, RGPassManager &RGM) { return false; }
virtual bool doFinalization() { return false; }
//@}
//===--------------------------------------------------------------------===//
/// @name PassManager API
///
//@{
void preparePassManager(PMStack &PMS);
virtual void assignPassManager(PMStack &PMS,
PassManagerType PMT = PMT_RegionPassManager);
virtual PassManagerType getPotentialPassManagerType() const {
return PMT_RegionPassManager;
}
//@}
};
/// @brief The pass manager to schedule RegionPasses.
class RGPassManager : public FunctionPass, public PMDataManager {
std::deque<Region*> RQ;
bool skipThisRegion;
bool redoThisRegion;
RegionInfo *RI;
Region *CurrentRegion;
public:
static char ID;
explicit RGPassManager();
/// @brief Execute all of the passes scheduled for execution.
///
/// @return True if any of the passes modifies the function.
bool runOnFunction(Function &F);
/// Pass Manager itself does not invalidate any analysis info.
/// RGPassManager needs RegionInfo.
void getAnalysisUsage(AnalysisUsage &Info) const;
virtual const char *getPassName() const {
return "Region Pass Manager";
}
virtual PMDataManager *getAsPMDataManager() { return this; }
virtual Pass *getAsPass() { return this; }
/// @brief Print passes managed by this manager.
void dumpPassStructure(unsigned Offset);
/// @brief Get passes contained by this manager.
Pass *getContainedPass(unsigned N) {
assert(N < PassVector.size() && "Pass number out of range!");
Pass *FP = static_cast<Pass *>(PassVector[N]);
return FP;
}
virtual PassManagerType getPassManagerType() const {
return PMT_RegionPassManager;
}
};
} // End llvm namespace
#endif

View File

@@ -0,0 +1,26 @@
//===-- RegionPrinter.h - Region printer external interface -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines external functions that can be called to explicitly
// instantiate the region printer.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_REGIONPRINTER_H
#define LLVM_ANALYSIS_REGIONPRINTER_H
namespace llvm {
class FunctionPass;
FunctionPass *createRegionViewerPass();
FunctionPass *createRegionOnlyViewerPass();
FunctionPass *createRegionPrinterPass();
FunctionPass *createRegionOnlyPrinterPass();
} // End llvm namespace
#endif

View File

@@ -0,0 +1,893 @@
//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The ScalarEvolution class is an LLVM pass which can be used to analyze and
// categorize scalar expressions in loops. It specializes in recognizing
// general induction variables, representing them with the abstract and opaque
// SCEV class. Given this analysis, trip counts of loops and other important
// properties can be obtained.
//
// This analysis is primarily useful for induction variable substitution and
// strength reduction.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
#define LLVM_ANALYSIS_SCALAREVOLUTION_H
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Operator.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
namespace llvm {
class APInt;
class Constant;
class ConstantInt;
class DominatorTree;
class Type;
class ScalarEvolution;
class DataLayout;
class TargetLibraryInfo;
class LLVMContext;
class Loop;
class LoopInfo;
class Operator;
class SCEVUnknown;
class SCEV;
template<> struct FoldingSetTrait<SCEV>;
/// SCEV - This class represents an analyzed expression in the program. These
/// are opaque objects that the client is not allowed to do much with
/// directly.
///
class SCEV : public FoldingSetNode {
friend struct FoldingSetTrait<SCEV>;
/// FastID - A reference to an Interned FoldingSetNodeID for this node.
/// The ScalarEvolution's BumpPtrAllocator holds the data.
FoldingSetNodeIDRef FastID;
// The SCEV baseclass this node corresponds to
const unsigned short SCEVType;
protected:
/// SubclassData - This field is initialized to zero and may be used in
/// subclasses to store miscellaneous information.
unsigned short SubclassData;
private:
SCEV(const SCEV &) LLVM_DELETED_FUNCTION;
void operator=(const SCEV &) LLVM_DELETED_FUNCTION;
public:
/// NoWrapFlags are bitfield indices into SubclassData.
///
/// Add and Mul expressions may have no-unsigned-wrap <NUW> or
/// no-signed-wrap <NSW> properties, which are derived from the IR
/// operator. NSW is a misnomer that we use to mean no signed overflow or
/// underflow.
///
/// AddRec expression may have a no-self-wraparound <NW> property if the
/// result can never reach the start value. This property is independent of
/// the actual start value and step direction. Self-wraparound is defined
/// purely in terms of the recurrence's loop, step size, and
/// bitwidth. Formally, a recurrence with no self-wraparound satisfies:
/// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth).
///
/// Note that NUW and NSW are also valid properties of a recurrence, and
/// either implies NW. For convenience, NW will be set for a recurrence
/// whenever either NUW or NSW are set.
enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee.
FlagNW = (1 << 0), // No self-wrap.
FlagNUW = (1 << 1), // No unsigned wrap.
FlagNSW = (1 << 2), // No signed wrap.
NoWrapMask = (1 << 3) -1 };
explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) :
FastID(ID), SCEVType(SCEVTy), SubclassData(0) {}
unsigned getSCEVType() const { return SCEVType; }
/// getType - Return the LLVM type of this SCEV expression.
///
Type *getType() const;
/// isZero - Return true if the expression is a constant zero.
///
bool isZero() const;
/// isOne - Return true if the expression is a constant one.
///
bool isOne() const;
/// isAllOnesValue - Return true if the expression is a constant
/// all-ones value.
///
bool isAllOnesValue() const;
/// isNonConstantNegative - Return true if the specified scev is negated,
/// but not a constant.
bool isNonConstantNegative() const;
/// print - Print out the internal representation of this scalar to the
/// specified stream. This should really only be used for debugging
/// purposes.
void print(raw_ostream &OS) const;
/// dump - This method is used for debugging.
///
void dump() const;
};
// Specialize FoldingSetTrait for SCEV to avoid needing to compute
// temporary FoldingSetNodeID values.
template<> struct FoldingSetTrait<SCEV> : DefaultFoldingSetTrait<SCEV> {
static void Profile(const SCEV &X, FoldingSetNodeID& ID) {
ID = X.FastID;
}
static bool Equals(const SCEV &X, const FoldingSetNodeID &ID,
unsigned IDHash, FoldingSetNodeID &TempID) {
return ID == X.FastID;
}
static unsigned ComputeHash(const SCEV &X, FoldingSetNodeID &TempID) {
return X.FastID.ComputeHash();
}
};
inline raw_ostream &operator<<(raw_ostream &OS, const SCEV &S) {
S.print(OS);
return OS;
}
/// SCEVCouldNotCompute - An object of this class is returned by queries that
/// could not be answered. For example, if you ask for the number of
/// iterations of a linked-list traversal loop, you will get one of these.
/// None of the standard SCEV operations are valid on this class, it is just a
/// marker.
struct SCEVCouldNotCompute : public SCEV {
SCEVCouldNotCompute();
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S);
};
/// ScalarEvolution - This class is the main scalar evolution driver. Because
/// client code (intentionally) can't do much with the SCEV objects directly,
/// they must ask this class for services.
///
class ScalarEvolution : public FunctionPass {
public:
/// LoopDisposition - An enum describing the relationship between a
/// SCEV and a loop.
enum LoopDisposition {
LoopVariant, ///< The SCEV is loop-variant (unknown).
LoopInvariant, ///< The SCEV is loop-invariant.
LoopComputable ///< The SCEV varies predictably with the loop.
};
/// BlockDisposition - An enum describing the relationship between a
/// SCEV and a basic block.
enum BlockDisposition {
DoesNotDominateBlock, ///< The SCEV does not dominate the block.
DominatesBlock, ///< The SCEV dominates the block.
ProperlyDominatesBlock ///< The SCEV properly dominates the block.
};
/// Convenient NoWrapFlags manipulation that hides enum casts and is
/// visible in the ScalarEvolution name space.
static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) {
return (SCEV::NoWrapFlags)(Flags & Mask);
}
static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OnFlags) {
return (SCEV::NoWrapFlags)(Flags | OnFlags);
}
static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags,
SCEV::NoWrapFlags OffFlags) {
return (SCEV::NoWrapFlags)(Flags & ~OffFlags);
}
private:
/// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be
/// notified whenever a Value is deleted.
class SCEVCallbackVH : public CallbackVH {
ScalarEvolution *SE;
virtual void deleted();
virtual void allUsesReplacedWith(Value *New);
public:
SCEVCallbackVH(Value *V, ScalarEvolution *SE = 0);
};
friend class SCEVCallbackVH;
friend class SCEVExpander;
friend class SCEVUnknown;
/// F - The function we are analyzing.
///
Function *F;
/// LI - The loop information for the function we are currently analyzing.
///
LoopInfo *LI;
/// TD - The target data information for the target we are targeting.
///
DataLayout *TD;
/// TLI - The target library information for the target we are targeting.
///
TargetLibraryInfo *TLI;
/// DT - The dominator tree.
///
DominatorTree *DT;
/// CouldNotCompute - This SCEV is used to represent unknown trip
/// counts and things.
SCEVCouldNotCompute CouldNotCompute;
/// ValueExprMapType - The typedef for ValueExprMap.
///
typedef DenseMap<SCEVCallbackVH, const SCEV *, DenseMapInfo<Value *> >
ValueExprMapType;
/// ValueExprMap - This is a cache of the values we have analyzed so far.
///
ValueExprMapType ValueExprMap;
/// Mark predicate values currently being processed by isImpliedCond.
DenseSet<Value*> PendingLoopPredicates;
/// ExitLimit - Information about the number of loop iterations for
/// which a loop exit's branch condition evaluates to the not-taken path.
/// This is a temporary pair of exact and max expressions that are
/// eventually summarized in ExitNotTakenInfo and BackedgeTakenInfo.
struct ExitLimit {
const SCEV *Exact;
const SCEV *Max;
/*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {}
ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {}
/// hasAnyInfo - Test whether this ExitLimit contains any computed
/// information, or whether it's all SCEVCouldNotCompute values.
bool hasAnyInfo() const {
return !isa<SCEVCouldNotCompute>(Exact) ||
!isa<SCEVCouldNotCompute>(Max);
}
};
/// ExitNotTakenInfo - Information about the number of times a particular
/// loop exit may be reached before exiting the loop.
struct ExitNotTakenInfo {
AssertingVH<BasicBlock> ExitingBlock;
const SCEV *ExactNotTaken;
PointerIntPair<ExitNotTakenInfo*, 1> NextExit;
ExitNotTakenInfo() : ExitingBlock(0), ExactNotTaken(0) {}
/// isCompleteList - Return true if all loop exits are computable.
bool isCompleteList() const {
return NextExit.getInt() == 0;
}
void setIncomplete() { NextExit.setInt(1); }
/// getNextExit - Return a pointer to the next exit's not-taken info.
ExitNotTakenInfo *getNextExit() const {
return NextExit.getPointer();
}
void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); }
};
/// BackedgeTakenInfo - Information about the backedge-taken count
/// of a loop. This currently includes an exact count and a maximum count.
///
class BackedgeTakenInfo {
/// ExitNotTaken - A list of computable exits and their not-taken counts.
/// Loops almost never have more than one computable exit.
ExitNotTakenInfo ExitNotTaken;
/// Max - An expression indicating the least maximum backedge-taken
/// count of the loop that is known, or a SCEVCouldNotCompute.
const SCEV *Max;
public:
BackedgeTakenInfo() : Max(0) {}
/// Initialize BackedgeTakenInfo from a list of exact exit counts.
BackedgeTakenInfo(
SmallVectorImpl< std::pair<BasicBlock *, const SCEV *> > &ExitCounts,
bool Complete, const SCEV *MaxCount);
/// hasAnyInfo - Test whether this BackedgeTakenInfo contains any
/// computed information, or whether it's all SCEVCouldNotCompute
/// values.
bool hasAnyInfo() const {
return ExitNotTaken.ExitingBlock || !isa<SCEVCouldNotCompute>(Max);
}
/// getExact - Return an expression indicating the exact backedge-taken
/// count of the loop if it is known, or SCEVCouldNotCompute
/// otherwise. This is the number of times the loop header can be
/// guaranteed to execute, minus one.
const SCEV *getExact(ScalarEvolution *SE) const;
/// getExact - Return the number of times this loop exit may fall through
/// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not
/// to exit via this block before this number of iterations, but may exit
/// via another block.
const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const;
/// getMax - Get the max backedge taken count for the loop.
const SCEV *getMax(ScalarEvolution *SE) const;
/// Return true if any backedge taken count expressions refer to the given
/// subexpression.
bool hasOperand(const SCEV *S, ScalarEvolution *SE) const;
/// clear - Invalidate this result and free associated memory.
void clear();
};
/// BackedgeTakenCounts - Cache the backedge-taken count of the loops for
/// this function as they are computed.
DenseMap<const Loop*, BackedgeTakenInfo> BackedgeTakenCounts;
/// ConstantEvolutionLoopExitValue - This map contains entries for all of
/// the PHI instructions that we attempt to compute constant evolutions for.
/// This allows us to avoid potentially expensive recomputation of these
/// properties. An instruction maps to null if we are unable to compute its
/// exit value.
DenseMap<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
/// ValuesAtScopes - This map contains entries for all the expressions
/// that we attempt to compute getSCEVAtScope information for, which can
/// be expensive in extreme cases.
DenseMap<const SCEV *,
std::map<const Loop *, const SCEV *> > ValuesAtScopes;
/// LoopDispositions - Memoized computeLoopDisposition results.
DenseMap<const SCEV *,
std::map<const Loop *, LoopDisposition> > LoopDispositions;
/// computeLoopDisposition - Compute a LoopDisposition value.
LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);
/// BlockDispositions - Memoized computeBlockDisposition results.
DenseMap<const SCEV *,
std::map<const BasicBlock *, BlockDisposition> > BlockDispositions;
/// computeBlockDisposition - Compute a BlockDisposition value.
BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
/// UnsignedRanges - Memoized results from getUnsignedRange
DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
/// SignedRanges - Memoized results from getSignedRange
DenseMap<const SCEV *, ConstantRange> SignedRanges;
/// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
const ConstantRange &setUnsignedRange(const SCEV *S,
const ConstantRange &CR) {
std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
UnsignedRanges.insert(std::make_pair(S, CR));
if (!Pair.second)
Pair.first->second = CR;
return Pair.first->second;
}
/// setUnsignedRange - Set the memoized signed range for the given SCEV.
const ConstantRange &setSignedRange(const SCEV *S,
const ConstantRange &CR) {
std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
SignedRanges.insert(std::make_pair(S, CR));
if (!Pair.second)
Pair.first->second = CR;
return Pair.first->second;
}
/// createSCEV - We know that there is no SCEV for the specified value.
/// Analyze the expression.
const SCEV *createSCEV(Value *V);
/// createNodeForPHI - Provide the special handling we need to analyze PHI
/// SCEVs.
const SCEV *createNodeForPHI(PHINode *PN);
/// createNodeForGEP - Provide the special handling we need to analyze GEP
/// SCEVs.
const SCEV *createNodeForGEP(GEPOperator *GEP);
/// computeSCEVAtScope - Implementation code for getSCEVAtScope; called
/// at most once for each SCEV+Loop pair.
///
const SCEV *computeSCEVAtScope(const SCEV *S, const Loop *L);
/// ForgetSymbolicValue - This looks up computed SCEV values for all
/// instructions that depend on the given instruction and removes them from
/// the ValueExprMap map if they reference SymName. This is used during PHI
/// resolution.
void ForgetSymbolicName(Instruction *I, const SCEV *SymName);
/// getBECount - Subtract the end and start values and divide by the step,
/// rounding up, to get the number of times the backedge is executed. Return
/// CouldNotCompute if an intermediate computation overflows.
const SCEV *getBECount(const SCEV *Start,
const SCEV *End,
const SCEV *Step,
bool NoWrap);
/// getBackedgeTakenInfo - Return the BackedgeTakenInfo for the given
/// loop, lazily computing new values if the loop hasn't been analyzed
/// yet.
const BackedgeTakenInfo &getBackedgeTakenInfo(const Loop *L);
/// ComputeBackedgeTakenCount - Compute the number of times the specified
/// loop will iterate.
BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L);
/// ComputeExitLimit - Compute the number of times the backedge of the
/// specified loop will execute if it exits via the specified block.
ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock);
/// ComputeExitLimitFromCond - Compute the number of times the backedge of
/// the specified loop will execute if its exit condition were a conditional
/// branch of ExitCond, TBB, and FBB.
ExitLimit ComputeExitLimitFromCond(const Loop *L,
Value *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeExitLimitFromICmp - Compute the number of times the backedge of
/// the specified loop will execute if its exit condition were a conditional
/// branch of the ICmpInst ExitCond, TBB, and FBB.
ExitLimit ComputeExitLimitFromICmp(const Loop *L,
ICmpInst *ExitCond,
BasicBlock *TBB,
BasicBlock *FBB);
/// ComputeLoadConstantCompareExitLimit - Given an exit condition
/// of 'icmp op load X, cst', try to see if we can compute the
/// backedge-taken count.
ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI,
Constant *RHS,
const Loop *L,
ICmpInst::Predicate p);
/// ComputeExitCountExhaustively - If the loop is known to execute a
/// constant number of times (the condition evolves only from constants),
/// try to evaluate a few iterations of the loop until we get the exit
/// condition gets a value of ExitWhen (true or false). If we cannot
/// evaluate the exit count of the loop, return CouldNotCompute.
const SCEV *ComputeExitCountExhaustively(const Loop *L,
Value *Cond,
bool ExitWhen);
/// HowFarToZero - Return the number of times an exit condition comparing
/// the specified value to zero will execute. If not computable, return
/// CouldNotCompute.
ExitLimit HowFarToZero(const SCEV *V, const Loop *L);
/// HowFarToNonZero - Return the number of times an exit condition checking
/// the specified value for nonzero will execute. If not computable, return
/// CouldNotCompute.
ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L);
/// HowManyLessThans - Return the number of times an exit condition
/// containing the specified less-than comparison will execute. If not
/// computable, return CouldNotCompute. isSigned specifies whether the
/// less-than is signed.
ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool isSigned);
/// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB
/// (which may not be an immediate predecessor) which has exactly one
/// successor from which BB is reachable, or null if no such block is
/// found.
std::pair<BasicBlock *, BasicBlock *>
getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
/// isImpliedCond - Test whether the condition described by Pred, LHS, and
/// RHS is true whenever the given FoundCondValue value evaluates to true.
bool isImpliedCond(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
Value *FoundCondValue,
bool Inverse);
/// isImpliedCondOperands - Test whether the condition described by Pred,
/// LHS, and RHS is true whenever the condition described by Pred, FoundLHS,
/// and FoundRHS is true.
bool isImpliedCondOperands(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS, const SCEV *FoundRHS);
/// isImpliedCondOperandsHelper - Test whether the condition described by
/// Pred, LHS, and RHS is true whenever the condition described by Pred,
/// FoundLHS, and FoundRHS is true.
bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS,
const SCEV *FoundLHS,
const SCEV *FoundRHS);
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
/// constant number of times, and the PHI node is just a recurrence
/// involving constants, fold it.
Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
const Loop *L);
/// isKnownPredicateWithRanges - Test if the given expression is known to
/// satisfy the condition described by Pred and the known constant ranges
/// of LHS and RHS.
///
bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
/// forgetMemoizedResults - Drop memoized information computed for S.
void forgetMemoizedResults(const SCEV *S);
public:
static char ID; // Pass identification, replacement for typeid
ScalarEvolution();
LLVMContext &getContext() const { return F->getContext(); }
/// isSCEVable - Test if values of the given type are analyzable within
/// the SCEV framework. This primarily includes integer types, and it
/// can optionally include pointer types if the ScalarEvolution class
/// has access to target-specific information.
bool isSCEVable(Type *Ty) const;
/// getTypeSizeInBits - Return the size in bits of the specified type,
/// for which isSCEVable must return true.
uint64_t getTypeSizeInBits(Type *Ty) const;
/// getEffectiveSCEVType - Return a type with the same bitwidth as
/// the given type and which represents how SCEV will treat the given
/// type, for which isSCEVable must return true. For pointer types,
/// this is the pointer-sized integer type.
Type *getEffectiveSCEVType(Type *Ty) const;
/// getSCEV - Return a SCEV expression for the full generality of the
/// specified expression.
const SCEV *getSCEV(Value *V);
const SCEV *getConstant(ConstantInt *V);
const SCEV *getConstant(const APInt& Val);
const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false);
const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty);
const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty);
const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getAddExpr(Ops, Flags);
}
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 3> Ops;
Ops.push_back(Op0);
Ops.push_back(Op1);
Ops.push_back(Op2);
return getAddExpr(Ops, Flags);
}
const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap)
{
SmallVector<const SCEV *, 2> Ops;
Ops.push_back(LHS);
Ops.push_back(RHS);
return getMulExpr(Ops, Flags);
}
const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) {
SmallVector<const SCEV *, 3> Ops;
Ops.push_back(Op0);
Ops.push_back(Op1);
Ops.push_back(Op2);
return getMulExpr(Ops, Flags);
}
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step,
const Loop *L, SCEV::NoWrapFlags Flags);
const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands,
const Loop *L, SCEV::NoWrapFlags Flags);
const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands,
const Loop *L, SCEV::NoWrapFlags Flags) {
SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end());
return getAddRecExpr(NewOp, L, Flags);
}
const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getUMaxExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUnknown(Value *V);
const SCEV *getCouldNotCompute();
/// getSizeOfExpr - Return an expression for sizeof on the given type.
///
const SCEV *getSizeOfExpr(Type *AllocTy);
/// getAlignOfExpr - Return an expression for alignof on the given type.
///
const SCEV *getAlignOfExpr(Type *AllocTy);
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
///
const SCEV *getOffsetOfExpr(StructType *STy, unsigned FieldNo);
/// getOffsetOfExpr - Return an expression for offsetof on the given field.
///
const SCEV *getOffsetOfExpr(Type *CTy, Constant *FieldNo);
/// getNegativeSCEV - Return the SCEV object corresponding to -V.
///
const SCEV *getNegativeSCEV(const SCEV *V);
/// getNotSCEV - Return the SCEV object corresponding to ~V.
///
const SCEV *getNotSCEV(const SCEV *V);
/// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap);
/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be
/// extended, it is zero extended.
const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty);
/// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion
/// of the input value to the specified type. If the type must be
/// extended, it is sign extended.
const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty);
/// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is zero extended. The conversion must not be narrowing.
const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty);
/// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is sign extended. The conversion must not be narrowing.
const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty);
/// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of
/// the input value to the specified type. If the type must be extended,
/// it is extended with unspecified bits. The conversion must not be
/// narrowing.
const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty);
/// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the
/// input value to the specified type. The conversion must not be
/// widening.
const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty);
/// getUMaxFromMismatchedTypes - Promote the operands to the wider of
/// the types using zero-extension, and then perform a umax operation
/// with them.
const SCEV *getUMaxFromMismatchedTypes(const SCEV *LHS,
const SCEV *RHS);
/// getUMinFromMismatchedTypes - Promote the operands to the wider of
/// the types using zero-extension, and then perform a umin operation
/// with them.
const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS,
const SCEV *RHS);
/// getPointerBase - Transitively follow the chain of pointer-type operands
/// until reaching a SCEV that does not have a single pointer operand. This
/// returns a SCEVUnknown pointer for well-formed pointer-type expressions,
/// but corner cases do exist.
const SCEV *getPointerBase(const SCEV *V);
/// getSCEVAtScope - Return a SCEV expression for the specified value
/// at the specified scope in the program. The L value specifies a loop
/// nest to evaluate the expression at, where null is the top-level or a
/// specified loop is immediately inside of the loop.
///
/// This method can be used to compute the exit value for a variable defined
/// in a loop by querying what the value will hold in the parent loop.
///
/// In the case that a relevant loop exit value cannot be computed, the
/// original value V is returned.
const SCEV *getSCEVAtScope(const SCEV *S, const Loop *L);
/// getSCEVAtScope - This is a convenience function which does
/// getSCEVAtScope(getSCEV(V), L).
const SCEV *getSCEVAtScope(Value *V, const Loop *L);
/// isLoopEntryGuardedByCond - Test whether entry to the loop is protected
/// by a conditional between LHS and RHS. This is used to help avoid max
/// expressions in loop trip counts, and to eliminate casts.
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
/// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is
/// protected by a conditional between LHS and RHS. This is used to
/// to eliminate casts.
bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
/// getSmallConstantTripCount - Returns the maximum trip count of this loop
/// as a normal unsigned value. Returns 0 if the trip count is unknown or
/// not constant. This "trip count" assumes that control exits via
/// ExitingBlock. More precisely, it is the number of times that control may
/// reach ExitingBlock before taking the branch. For loops with multiple
/// exits, it may not be the number times that the loop header executes if
/// the loop exits prematurely via another branch.
unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitingBlock);
/// getSmallConstantTripMultiple - Returns the largest constant divisor of
/// the trip count of this loop as a normal unsigned value, if
/// possible. This means that the actual trip count is always a multiple of
/// the returned value (don't forget the trip count could very well be zero
/// as well!). As explained in the comments for getSmallConstantTripCount,
/// this assumes that control exits the loop via ExitingBlock.
unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitingBlock);
// getExitCount - Get the expression for the number of loop iterations for
// which this loop is guaranteed not to exit via ExitingBlock. Otherwise
// return SCEVCouldNotCompute.
const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock);
/// getBackedgeTakenCount - If the specified loop has a predictable
/// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute
/// object. The backedge-taken count is the number of times the loop header
/// will be branched to from within the loop. This is one less than the
/// trip count of the loop, since it doesn't count the first iteration,
/// when the header is branched to from outside the loop.
///
/// Note that it is not valid to call this method on a loop without a
/// loop-invariant backedge-taken count (see
/// hasLoopInvariantBackedgeTakenCount).
///
const SCEV *getBackedgeTakenCount(const Loop *L);
/// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except
/// return the least SCEV value that is known never to be less than the
/// actual backedge taken count.
const SCEV *getMaxBackedgeTakenCount(const Loop *L);
/// hasLoopInvariantBackedgeTakenCount - Return true if the specified loop
/// has an analyzable loop-invariant backedge-taken count.
bool hasLoopInvariantBackedgeTakenCount(const Loop *L);
/// forgetLoop - This method should be called by the client when it has
/// changed a loop in a way that may effect ScalarEvolution's ability to
/// compute a trip count, or if the loop is deleted.
void forgetLoop(const Loop *L);
/// forgetValue - This method should be called by the client when it has
/// changed a value in a way that may effect its value, or which may
/// disconnect it from a def-use chain linking it to a loop.
void forgetValue(Value *V);
/// GetMinTrailingZeros - Determine the minimum number of zero bits that S
/// is guaranteed to end in (at every loop iteration). It is, at the same
/// time, the minimum number of times S is divisible by 2. For example,
/// given {4,+,8} it returns 2. If S is guaranteed to be 0, it returns the
/// bitwidth of S.
uint32_t GetMinTrailingZeros(const SCEV *S);
/// getUnsignedRange - Determine the unsigned range for a particular SCEV.
///
ConstantRange getUnsignedRange(const SCEV *S);
/// getSignedRange - Determine the signed range for a particular SCEV.
///
ConstantRange getSignedRange(const SCEV *S);
/// isKnownNegative - Test if the given expression is known to be negative.
///
bool isKnownNegative(const SCEV *S);
/// isKnownPositive - Test if the given expression is known to be positive.
///
bool isKnownPositive(const SCEV *S);
/// isKnownNonNegative - Test if the given expression is known to be
/// non-negative.
///
bool isKnownNonNegative(const SCEV *S);
/// isKnownNonPositive - Test if the given expression is known to be
/// non-positive.
///
bool isKnownNonPositive(const SCEV *S);
/// isKnownNonZero - Test if the given expression is known to be
/// non-zero.
///
bool isKnownNonZero(const SCEV *S);
/// isKnownPredicate - Test if the given expression is known to satisfy
/// the condition described by Pred, LHS, and RHS.
///
bool isKnownPredicate(ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
/// predicate Pred. Return true iff any changes were made. If the
/// operands are provably equal or unequal, LHS and RHS are set to
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
///
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
const SCEV *&LHS,
const SCEV *&RHS,
unsigned Depth = 0);
/// getLoopDisposition - Return the "disposition" of the given SCEV with
/// respect to the given loop.
LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L);
/// isLoopInvariant - Return true if the value of the given SCEV is
/// unchanging in the specified loop.
bool isLoopInvariant(const SCEV *S, const Loop *L);
/// hasComputableLoopEvolution - Return true if the given SCEV changes value
/// in a known way in the specified loop. This property being true implies
/// that the value is variant in the loop AND that we can emit an expression
/// to compute the value of the expression at any particular loop iteration.
bool hasComputableLoopEvolution(const SCEV *S, const Loop *L);
/// getLoopDisposition - Return the "disposition" of the given SCEV with
/// respect to the given block.
BlockDisposition getBlockDisposition(const SCEV *S, const BasicBlock *BB);
/// dominates - Return true if elements that makes up the given SCEV
/// dominate the specified basic block.
bool dominates(const SCEV *S, const BasicBlock *BB);
/// properlyDominates - Return true if elements that makes up the given SCEV
/// properly dominate the specified basic block.
bool properlyDominates(const SCEV *S, const BasicBlock *BB);
/// hasOperand - Test whether the given SCEV has Op as a direct or
/// indirect operand.
bool hasOperand(const SCEV *S, const SCEV *Op) const;
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual void print(raw_ostream &OS, const Module* = 0) const;
virtual void verifyAnalysis() const;
private:
FoldingSet<SCEV> UniqueSCEVs;
BumpPtrAllocator SCEVAllocator;
/// FirstUnknown - The head of a linked list of all SCEVUnknown
/// values that have been allocated. This is used by releaseMemory
/// to locate them all and call their destructors.
SCEVUnknown *FirstUnknown;
};
}
#endif

View File

@@ -0,0 +1,271 @@
//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the classes used to generate code from scalar expressions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/TargetFolder.h"
#include "llvm/Support/ValueHandle.h"
#include <set>
namespace llvm {
class TargetTransformInfo;
/// Return true if the given expression is safe to expand in the sense that
/// all materialized values are safe to speculate.
bool isSafeToExpand(const SCEV *S);
/// SCEVExpander - This class uses information about analyze scalars to
/// rewrite expressions in canonical form.
///
/// Clients should create an instance of this class when rewriting is needed,
/// and destroy it when finished to allow the release of the associated
/// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
// New instructions receive a name to identifies them with the current pass.
const char* IVName;
// InsertedExpressions caches Values for reuse, so must track RAUW.
std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
InsertedExpressions;
// InsertedValues only flags inserted instructions so needs no RAUW.
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
/// RelevantLoops - A memoization of the "relevant" loop for a given SCEV.
DenseMap<const SCEV *, const Loop *> RelevantLoops;
/// PostIncLoops - Addrecs referring to any of the given loops are expanded
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
/// returns the add instruction that adds one to the phi for {0,+,1}<L>,
/// as opposed to a new phi starting at 1. This is only supported in
/// non-canonical mode.
PostIncLoopSet PostIncLoops;
/// IVIncInsertPos - When this is non-null, addrecs expanded in the
/// loop it indicates should be inserted with increments at
/// IVIncInsertPos.
const Loop *IVIncInsertLoop;
/// IVIncInsertPos - When expanding addrecs in the IVIncInsertLoop loop,
/// insert the IV increment at this position.
Instruction *IVIncInsertPos;
/// Phis that complete an IV chain. Reuse
std::set<AssertingVH<PHINode> > ChainedPhis;
/// CanonicalMode - When true, expressions are expanded in "canonical"
/// form. In particular, addrecs are expanded as arithmetic based on
/// a canonical induction variable. When false, expression are expanded
/// in a more literal form.
bool CanonicalMode;
/// When invoked from LSR, the expander is in "strength reduction" mode. The
/// only difference is that phi's are only reused if they are already in
/// "expanded" form.
bool LSRMode;
typedef IRBuilder<true, TargetFolder> BuilderType;
BuilderType Builder;
#ifndef NDEBUG
const char *DebugType;
#endif
friend struct SCEVVisitor<SCEVExpander, Value*>;
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
explicit SCEVExpander(ScalarEvolution &se, const char *name)
: SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0),
CanonicalMode(true), LSRMode(false),
Builder(se.getContext(), TargetFolder(se.TD)) {
#ifndef NDEBUG
DebugType = "";
#endif
}
#ifndef NDEBUG
void setDebugType(const char* s) { DebugType = s; }
#endif
/// clear - Erase the contents of the InsertedExpressions map so that users
/// trying to expand the same expression into multiple BasicBlocks or
/// different places within the same BasicBlock can do so.
void clear() {
InsertedExpressions.clear();
InsertedValues.clear();
InsertedPostIncValues.clear();
ChainedPhis.clear();
}
/// getOrInsertCanonicalInductionVariable - This method returns the
/// canonical induction variable of the specified type for the specified
/// loop (inserting one if there is none). A canonical induction variable
/// starts at zero and steps by one on each iteration.
PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty);
/// getIVIncOperand - Return the induction variable increment's IV operand.
Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos,
bool allowScale);
/// hoistIVInc - Utility for hoisting an IV increment.
bool hoistIVInc(Instruction *IncV, Instruction *InsertPos);
/// replaceCongruentIVs - replace congruent phis with their most canonical
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
const TargetTransformInfo *TTI = NULL);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// specified block.
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
/// setIVIncInsertPos - Set the current IV increment loop and position.
void setIVIncInsertPos(const Loop *L, Instruction *Pos) {
assert(!CanonicalMode &&
"IV increment positions are not supported in CanonicalMode");
IVIncInsertLoop = L;
IVIncInsertPos = Pos;
}
/// setPostInc - Enable post-inc expansion for addrecs referring to the
/// given loops. Post-inc expansion is only supported in non-canonical
/// mode.
void setPostInc(const PostIncLoopSet &L) {
assert(!CanonicalMode &&
"Post-inc expansion is not supported in CanonicalMode");
PostIncLoops = L;
}
/// clearPostInc - Disable all post-inc expansion.
void clearPostInc() {
PostIncLoops.clear();
// When we change the post-inc loop set, cached expansions may no
// longer be valid.
InsertedPostIncValues.clear();
}
/// disableCanonicalMode - Disable the behavior of expanding expressions in
/// canonical form rather than in a more literal form. Non-canonical mode
/// is useful for late optimization passes.
void disableCanonicalMode() { CanonicalMode = false; }
void enableLSRMode() { LSRMode = true; }
/// clearInsertPoint - Clear the current insertion point. This is useful
/// if the instruction that had been serving as the insertion point may
/// have been deleted.
void clearInsertPoint() {
Builder.ClearInsertionPoint();
}
/// isInsertedInstruction - Return true if the specified instruction was
/// inserted by the code rewriter. If so, the client should not modify the
/// instruction.
bool isInsertedInstruction(Instruction *I) const {
return InsertedValues.count(I) || InsertedPostIncValues.count(I);
}
void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
private:
LLVMContext &getContext() const { return SE.getContext(); }
/// InsertBinop - Insert the specified binary operator, doing a small amount
/// of work to avoid inserting an obviously redundant operation.
Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS);
/// ReuseOrCreateCast - Arange for there to be a cast of V to Ty at IP,
/// reusing an existing cast if a suitable one exists, moving an existing
/// cast if a suitable one exists but isn't in the right place, or
/// or creating a new one.
Value *ReuseOrCreateCast(Value *V, Type *Ty,
Instruction::CastOps Op,
BasicBlock::iterator IP);
/// InsertNoopCastOfTo - Insert a cast of V to the specified type,
/// which must be possible with a noop cast, doing what we can to
/// share the casts.
Value *InsertNoopCastOfTo(Value *V, Type *Ty);
/// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP
/// instead of using ptrtoint+arithmetic+inttoptr.
Value *expandAddToGEP(const SCEV *const *op_begin,
const SCEV *const *op_end,
PointerType *PTy, Type *Ty, Value *V);
Value *expand(const SCEV *S);
/// expandCodeFor - Insert code to directly compute the specified SCEV
/// expression into the program. The inserted code is inserted into the
/// SCEVExpander's current insertion point. If a type is specified, the
/// result will be expanded to have that type, with a cast if necessary.
Value *expandCodeFor(const SCEV *SH, Type *Ty = 0);
/// getRelevantLoop - Determine the most "relevant" loop for the given SCEV.
const Loop *getRelevantLoop(const SCEV *);
Value *visitConstant(const SCEVConstant *S) {
return S->getValue();
}
Value *visitTruncateExpr(const SCEVTruncateExpr *S);
Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S);
Value *visitSignExtendExpr(const SCEVSignExtendExpr *S);
Value *visitAddExpr(const SCEVAddExpr *S);
Value *visitMulExpr(const SCEVMulExpr *S);
Value *visitUDivExpr(const SCEVUDivExpr *S);
Value *visitAddRecExpr(const SCEVAddRecExpr *S);
Value *visitSMaxExpr(const SCEVSMaxExpr *S);
Value *visitUMaxExpr(const SCEVUMaxExpr *S);
Value *visitUnknown(const SCEVUnknown *S) {
return S->getValue();
}
void rememberInstruction(Value *I);
void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I);
bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L);
Value *expandAddRecExprLiterally(const SCEVAddRecExpr *);
PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
const Loop *L,
Type *ExpandTy,
Type *IntTy);
Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
Type *ExpandTy, Type *IntTy, bool useSubtract);
};
}
#endif

View File

@@ -0,0 +1,698 @@
//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the classes used to represent and build scalar expressions.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class ConstantInt;
class ConstantRange;
class DominatorTree;
enum SCEVTypes {
// These should be ordered in terms of increasing complexity to make the
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
scUnknown, scCouldNotCompute
};
//===--------------------------------------------------------------------===//
/// SCEVConstant - This class represents a constant integer value.
///
class SCEVConstant : public SCEV {
friend class ScalarEvolution;
ConstantInt *V;
SCEVConstant(const FoldingSetNodeIDRef ID, ConstantInt *v) :
SCEV(ID, scConstant), V(v) {}
public:
ConstantInt *getValue() const { return V; }
Type *getType() const { return V->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scConstant;
}
};
//===--------------------------------------------------------------------===//
/// SCEVCastExpr - This is the base class for unary cast operator classes.
///
class SCEVCastExpr : public SCEV {
protected:
const SCEV *Op;
Type *Ty;
SCEVCastExpr(const FoldingSetNodeIDRef ID,
unsigned SCEVTy, const SCEV *op, Type *ty);
public:
const SCEV *getOperand() const { return Op; }
Type *getType() const { return Ty; }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate ||
S->getSCEVType() == scZeroExtend ||
S->getSCEVType() == scSignExtend;
}
};
//===--------------------------------------------------------------------===//
/// SCEVTruncateExpr - This class represents a truncation of an integer value
/// to a smaller integer value.
///
class SCEVTruncateExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVTruncateExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scTruncate;
}
};
//===--------------------------------------------------------------------===//
/// SCEVZeroExtendExpr - This class represents a zero extension of a small
/// integer value to a larger integer value.
///
class SCEVZeroExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scZeroExtend;
}
};
//===--------------------------------------------------------------------===//
/// SCEVSignExtendExpr - This class represents a sign extension of a small
/// integer value to a larger integer value.
///
class SCEVSignExtendExpr : public SCEVCastExpr {
friend class ScalarEvolution;
SCEVSignExtendExpr(const FoldingSetNodeIDRef ID,
const SCEV *op, Type *ty);
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSignExtend;
}
};
//===--------------------------------------------------------------------===//
/// SCEVNAryExpr - This node is a base class providing common
/// functionality for n'ary operators.
///
class SCEVNAryExpr : public SCEV {
protected:
// Since SCEVs are immutable, ScalarEvolution allocates operand
// arrays with its SCEVAllocator, so this class just needs a simple
// pointer rather than a more elaborate vector-like data structure.
// This also avoids the need for a non-trivial destructor.
const SCEV *const *Operands;
size_t NumOperands;
SCEVNAryExpr(const FoldingSetNodeIDRef ID,
enum SCEVTypes T, const SCEV *const *O, size_t N)
: SCEV(ID, T), Operands(O), NumOperands(N) {}
public:
size_t getNumOperands() const { return NumOperands; }
const SCEV *getOperand(unsigned i) const {
assert(i < NumOperands && "Operand index out of range!");
return Operands[i];
}
typedef const SCEV *const *op_iterator;
op_iterator op_begin() const { return Operands; }
op_iterator op_end() const { return Operands + NumOperands; }
Type *getType() const { return getOperand(0)->getType(); }
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
return (NoWrapFlags)(SubclassData & Mask);
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
S->getSCEVType() == scSMaxExpr ||
S->getSCEVType() == scUMaxExpr ||
S->getSCEVType() == scAddRecExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVCommutativeExpr - This node is the base class for n'ary commutative
/// operators.
///
class SCEVCommutativeExpr : public SCEVNAryExpr {
protected:
SCEVCommutativeExpr(const FoldingSetNodeIDRef ID,
enum SCEVTypes T, const SCEV *const *O, size_t N)
: SCEVNAryExpr(ID, T, O, N) {}
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr ||
S->getSCEVType() == scMulExpr ||
S->getSCEVType() == scSMaxExpr ||
S->getSCEVType() == scUMaxExpr;
}
/// Set flags for a non-recurrence without clearing previously set flags.
void setNoWrapFlags(NoWrapFlags Flags) {
SubclassData |= Flags;
}
};
//===--------------------------------------------------------------------===//
/// SCEVAddExpr - This node represents an addition of some number of SCEVs.
///
class SCEVAddExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVAddExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scAddExpr, O, N) {
}
public:
Type *getType() const {
// Use the type of the last operand, which is likely to be a pointer
// type, if there is one. This doesn't usually matter, but it can help
// reduce casts when the expressions are expanded.
return getOperand(getNumOperands() - 1)->getType();
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
///
class SCEVMulExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVMulExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scMulExpr, O, N) {
}
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scMulExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVUDivExpr - This class represents a binary unsigned division operation.
///
class SCEVUDivExpr : public SCEV {
friend class ScalarEvolution;
const SCEV *LHS;
const SCEV *RHS;
SCEVUDivExpr(const FoldingSetNodeIDRef ID, const SCEV *lhs, const SCEV *rhs)
: SCEV(ID, scUDivExpr), LHS(lhs), RHS(rhs) {}
public:
const SCEV *getLHS() const { return LHS; }
const SCEV *getRHS() const { return RHS; }
Type *getType() const {
// In most cases the types of LHS and RHS will be the same, but in some
// crazy cases one or the other may be a pointer. ScalarEvolution doesn't
// depend on the type for correctness, but handling types carefully can
// avoid extra casts in the SCEVExpander. The LHS is more likely to be
// a pointer type than the RHS, so use the RHS' type here.
return getRHS()->getType();
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUDivExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
/// count of the specified loop. This is the primary focus of the
/// ScalarEvolution framework; all the other SCEV subclasses are mostly just
/// supporting infrastructure to allow SCEVAddRecExpr expressions to be
/// created and analyzed.
///
/// All operands of an AddRec are required to be loop invariant.
///
class SCEVAddRecExpr : public SCEVNAryExpr {
friend class ScalarEvolution;
const Loop *L;
SCEVAddRecExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N, const Loop *l)
: SCEVNAryExpr(ID, scAddRecExpr, O, N), L(l) {}
public:
const SCEV *getStart() const { return Operands[0]; }
const Loop *getLoop() const { return L; }
/// getStepRecurrence - This method constructs and returns the recurrence
/// indicating how much this expression steps by. If this is a polynomial
/// of degree N, it returns a chrec of degree N-1.
/// We cannot determine whether the step recurrence has self-wraparound.
const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
if (isAffine()) return getOperand(1);
return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
op_end()),
getLoop(), FlagAnyWrap);
}
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
/// an expressions A+B*x where A and B are loop invariant values.
bool isAffine() const {
// We know that the start value is invariant. This expression is thus
// affine iff the step is also invariant.
return getNumOperands() == 2;
}
/// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
/// represents an expressions A+B*x+C*x^2 where A, B and C are loop
/// invariant values. This corresponds to an addrec of the form {L,+,M,+,N}
bool isQuadratic() const {
return getNumOperands() == 3;
}
/// Set flags for a recurrence without clearing any previously set flags.
/// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
/// to make it easier to propagate flags.
void setNoWrapFlags(NoWrapFlags Flags) {
if (Flags & (FlagNUW | FlagNSW))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= Flags;
}
/// evaluateAtIteration - Return the value of this chain of recurrences at
/// the specified iteration number.
const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
/// getNumIterationsInRange - Return the number of iterations of this loop
/// that produce values in the specified constant range. Another way of
/// looking at this is that it returns the first iteration number where the
/// value is not in the condition, thus computing the exit count. If the
/// iteration count can't be computed, an instance of SCEVCouldNotCompute is
/// returned.
const SCEV *getNumIterationsInRange(ConstantRange Range,
ScalarEvolution &SE) const;
/// getPostIncExpr - Return an expression representing the value of
/// this expression one iteration of the loop ahead.
const SCEVAddRecExpr *getPostIncExpr(ScalarEvolution &SE) const {
return cast<SCEVAddRecExpr>(SE.getAddExpr(this, getStepRecurrence(SE)));
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scAddRecExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVSMaxExpr - This class represents a signed maximum selection.
///
class SCEVSMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVSMaxExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
// Max never overflows.
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scSMaxExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVUMaxExpr - This class represents an unsigned maximum selection.
///
class SCEVUMaxExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
SCEVUMaxExpr(const FoldingSetNodeIDRef ID,
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
// Max never overflows.
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUMaxExpr;
}
};
//===--------------------------------------------------------------------===//
/// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
/// value, and only represent it as its LLVM Value. This is the "bottom"
/// value for the analysis.
///
class SCEVUnknown : public SCEV, private CallbackVH {
friend class ScalarEvolution;
// Implement CallbackVH.
virtual void deleted();
virtual void allUsesReplacedWith(Value *New);
/// SE - The parent ScalarEvolution value. This is used to update
/// the parent's maps when the value associated with a SCEVUnknown
/// is deleted or RAUW'd.
ScalarEvolution *SE;
/// Next - The next pointer in the linked list of all
/// SCEVUnknown instances owned by a ScalarEvolution.
SCEVUnknown *Next;
SCEVUnknown(const FoldingSetNodeIDRef ID, Value *V,
ScalarEvolution *se, SCEVUnknown *next) :
SCEV(ID, scUnknown), CallbackVH(V), SE(se), Next(next) {}
public:
Value *getValue() const { return getValPtr(); }
/// isSizeOf, isAlignOf, isOffsetOf - Test whether this is a special
/// constant representing a type size, alignment, or field offset in
/// a target-independent manner, and hasn't happened to have been
/// folded with other operations into something unrecognizable. This
/// is mainly only useful for pretty-printing and other situations
/// where it isn't absolutely required for these to succeed.
bool isSizeOf(Type *&AllocTy) const;
bool isAlignOf(Type *&AllocTy) const;
bool isOffsetOf(Type *&STy, Constant *&FieldNo) const;
Type *getType() const { return getValPtr()->getType(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SCEV *S) {
return S->getSCEVType() == scUnknown;
}
};
/// SCEVVisitor - This class defines a simple visitor class that may be used
/// for various SCEV analysis purposes.
template<typename SC, typename RetVal=void>
struct SCEVVisitor {
RetVal visit(const SCEV *S) {
switch (S->getSCEVType()) {
case scConstant:
return ((SC*)this)->visitConstant((const SCEVConstant*)S);
case scTruncate:
return ((SC*)this)->visitTruncateExpr((const SCEVTruncateExpr*)S);
case scZeroExtend:
return ((SC*)this)->visitZeroExtendExpr((const SCEVZeroExtendExpr*)S);
case scSignExtend:
return ((SC*)this)->visitSignExtendExpr((const SCEVSignExtendExpr*)S);
case scAddExpr:
return ((SC*)this)->visitAddExpr((const SCEVAddExpr*)S);
case scMulExpr:
return ((SC*)this)->visitMulExpr((const SCEVMulExpr*)S);
case scUDivExpr:
return ((SC*)this)->visitUDivExpr((const SCEVUDivExpr*)S);
case scAddRecExpr:
return ((SC*)this)->visitAddRecExpr((const SCEVAddRecExpr*)S);
case scSMaxExpr:
return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
case scUMaxExpr:
return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
case scUnknown:
return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
case scCouldNotCompute:
return ((SC*)this)->visitCouldNotCompute((const SCEVCouldNotCompute*)S);
default:
llvm_unreachable("Unknown SCEV type!");
}
}
RetVal visitCouldNotCompute(const SCEVCouldNotCompute *S) {
llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
}
};
/// Visit all nodes in the expression tree using worklist traversal.
///
/// Visitor implements:
/// // return true to follow this node.
/// bool follow(const SCEV *S);
/// // return true to terminate the search.
/// bool isDone();
template<typename SV>
class SCEVTraversal {
SV &Visitor;
SmallVector<const SCEV *, 8> Worklist;
SmallPtrSet<const SCEV *, 8> Visited;
void push(const SCEV *S) {
if (Visited.insert(S) && Visitor.follow(S))
Worklist.push_back(S);
}
public:
SCEVTraversal(SV& V): Visitor(V) {}
void visitAll(const SCEV *Root) {
push(Root);
while (!Worklist.empty() && !Visitor.isDone()) {
const SCEV *S = Worklist.pop_back_val();
switch (S->getSCEVType()) {
case scConstant:
case scUnknown:
break;
case scTruncate:
case scZeroExtend:
case scSignExtend:
push(cast<SCEVCastExpr>(S)->getOperand());
break;
case scAddExpr:
case scMulExpr:
case scSMaxExpr:
case scUMaxExpr:
case scAddRecExpr: {
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(),
E = NAry->op_end(); I != E; ++I) {
push(*I);
}
break;
}
case scUDivExpr: {
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
push(UDiv->getLHS());
push(UDiv->getRHS());
break;
}
case scCouldNotCompute:
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
default:
llvm_unreachable("Unknown SCEV kind!");
}
}
}
};
/// Use SCEVTraversal to visit all nodes in the givien expression tree.
template<typename SV>
void visitAll(const SCEV *Root, SV& Visitor) {
SCEVTraversal<SV> T(Visitor);
T.visitAll(Root);
}
/// The SCEVRewriter takes a scalar evolution expression and copies all its
/// components. The result after a rewrite is an identical SCEV.
struct SCEVRewriter
: public SCEVVisitor<SCEVRewriter, const SCEV*> {
public:
SCEVRewriter(ScalarEvolution &S) : SE(S) {}
virtual ~SCEVRewriter() {}
virtual const SCEV *visitConstant(const SCEVConstant *Constant) {
return Constant;
}
virtual const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
const SCEV *Operand = visit(Expr->getOperand());
return SE.getTruncateExpr(Operand, Expr->getType());
}
virtual const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
const SCEV *Operand = visit(Expr->getOperand());
return SE.getZeroExtendExpr(Operand, Expr->getType());
}
virtual const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
const SCEV *Operand = visit(Expr->getOperand());
return SE.getSignExtendExpr(Operand, Expr->getType());
}
virtual const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
return SE.getAddExpr(Operands);
}
virtual const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
return SE.getMulExpr(Operands);
}
virtual const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
}
virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
return SE.getAddRecExpr(Operands, Expr->getLoop(),
Expr->getNoWrapFlags());
}
virtual const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
return SE.getSMaxExpr(Operands);
}
virtual const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
return SE.getUMaxExpr(Operands);
}
virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
return Expr;
}
virtual const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
return Expr;
}
protected:
ScalarEvolution &SE;
};
typedef DenseMap<const Value*, Value*> ValueToValueMap;
/// The SCEVParameterRewriter takes a scalar evolution expression and updates
/// the SCEVUnknown components following the Map (Value -> Value).
struct SCEVParameterRewriter: public SCEVRewriter {
public:
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
ValueToValueMap &Map) {
SCEVParameterRewriter Rewriter(SE, Map);
return Rewriter.visit(Scev);
}
SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M)
: SCEVRewriter(S), Map(M) {}
virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
Value *V = Expr->getValue();
if (Map.count(V))
return SE.getUnknown(Map[V]);
return Expr;
}
private:
ValueToValueMap &Map;
};
typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT;
/// The SCEVApplyRewriter takes a scalar evolution expression and applies
/// the Map (Loop -> SCEV) to all AddRecExprs.
struct SCEVApplyRewriter: public SCEVRewriter {
public:
static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
ScalarEvolution &SE) {
SCEVApplyRewriter Rewriter(SE, Map);
return Rewriter.visit(Scev);
}
SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M)
: SCEVRewriter(S), Map(M) {}
virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
SmallVector<const SCEV *, 2> Operands;
for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
Operands.push_back(visit(Expr->getOperand(i)));
const Loop *L = Expr->getLoop();
const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
if (0 == Map.count(L))
return Res;
const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res;
return Rec->evaluateAtIteration(Map[L], SE);
}
private:
LoopToScevMapT &Map;
};
/// Applies the Map (Loop -> SCEV) to the given Scev.
static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map,
ScalarEvolution &SE) {
return SCEVApplyRewriter::rewrite(Scev, Map, SE);
}
}
#endif

View File

@@ -0,0 +1,78 @@
//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines utilities for working with "normalized" ScalarEvolution
// expressions.
//
// The following example illustrates post-increment uses and how normalized
// expressions help.
//
// for (i=0; i!=n; ++i) {
// ...
// }
// use(i);
//
// While the expression for most uses of i inside the loop is {0,+,1}<%L>, the
// expression for the use of i outside the loop is {1,+,1}<%L>, since i is
// incremented at the end of the loop body. This is inconveient, since it
// suggests that we need two different induction variables, one that starts
// at 0 and one that starts at 1. We'd prefer to be able to think of these as
// the same induction variable, with uses inside the loop using the
// "pre-incremented" value, and uses after the loop using the
// "post-incremented" value.
//
// Expressions for post-incremented uses are represented as an expression
// paired with a set of loops for which the expression is in "post-increment"
// mode (there may be multiple loops).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
class Instruction;
class DominatorTree;
class Loop;
class ScalarEvolution;
class SCEV;
class Value;
/// TransformKind - Different types of transformations that
/// TransformForPostIncUse can do.
enum TransformKind {
/// Normalize - Normalize according to the given loops.
Normalize,
/// NormalizeAutodetect - Detect post-inc opportunities on new expressions,
/// update the given loop set, and normalize.
NormalizeAutodetect,
/// Denormalize - Perform the inverse transform on the expression with the
/// given loop set.
Denormalize
};
/// PostIncLoopSet - A set of loops.
typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
/// TransformForPostIncUse - Transform the given expression according to the
/// given transformation kind.
const SCEV *TransformForPostIncUse(TransformKind Kind,
const SCEV *S,
Instruction *User,
Value *OperandValToReplace,
PostIncLoopSet &Loops,
ScalarEvolution &SE,
DominatorTree &DT);
}
#endif

View File

@@ -0,0 +1,206 @@
//===- SparsePropagation.h - Sparse Conditional Property Propagation ------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements an abstract sparse conditional propagation algorithm,
// modeled after SCCP, but with a customizable lattice function.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H
#define LLVM_ANALYSIS_SPARSEPROPAGATION_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <set>
#include <vector>
namespace llvm {
class Value;
class Constant;
class Argument;
class Instruction;
class PHINode;
class TerminatorInst;
class BasicBlock;
class Function;
class SparseSolver;
class raw_ostream;
template<typename T> class SmallVectorImpl;
/// AbstractLatticeFunction - This class is implemented by the dataflow instance
/// to specify what the lattice values are and how they handle merges etc.
/// This gives the client the power to compute lattice values from instructions,
/// constants, etc. The requirement is that lattice values must all fit into
/// a void*. If a void* is not sufficient, the implementation should use this
/// pointer to be a pointer into a uniquing set or something.
///
class AbstractLatticeFunction {
public:
typedef void *LatticeVal;
private:
LatticeVal UndefVal, OverdefinedVal, UntrackedVal;
public:
AbstractLatticeFunction(LatticeVal undefVal, LatticeVal overdefinedVal,
LatticeVal untrackedVal) {
UndefVal = undefVal;
OverdefinedVal = overdefinedVal;
UntrackedVal = untrackedVal;
}
virtual ~AbstractLatticeFunction();
LatticeVal getUndefVal() const { return UndefVal; }
LatticeVal getOverdefinedVal() const { return OverdefinedVal; }
LatticeVal getUntrackedVal() const { return UntrackedVal; }
/// IsUntrackedValue - If the specified Value is something that is obviously
/// uninteresting to the analysis (and would always return UntrackedVal),
/// this function can return true to avoid pointless work.
virtual bool IsUntrackedValue(Value *V) {
return false;
}
/// ComputeConstant - Given a constant value, compute and return a lattice
/// value corresponding to the specified constant.
virtual LatticeVal ComputeConstant(Constant *C) {
return getOverdefinedVal(); // always safe
}
/// IsSpecialCasedPHI - Given a PHI node, determine whether this PHI node is
/// one that the we want to handle through ComputeInstructionState.
virtual bool IsSpecialCasedPHI(PHINode *PN) {
return false;
}
/// GetConstant - If the specified lattice value is representable as an LLVM
/// constant value, return it. Otherwise return null. The returned value
/// must be in the same LLVM type as Val.
virtual Constant *GetConstant(LatticeVal LV, Value *Val, SparseSolver &SS) {
return 0;
}
/// ComputeArgument - Given a formal argument value, compute and return a
/// lattice value corresponding to the specified argument.
virtual LatticeVal ComputeArgument(Argument *I) {
return getOverdefinedVal(); // always safe
}
/// MergeValues - Compute and return the merge of the two specified lattice
/// values. Merging should only move one direction down the lattice to
/// guarantee convergence (toward overdefined).
virtual LatticeVal MergeValues(LatticeVal X, LatticeVal Y) {
return getOverdefinedVal(); // always safe, never useful.
}
/// ComputeInstructionState - Given an instruction and a vector of its operand
/// values, compute the result value of the instruction.
virtual LatticeVal ComputeInstructionState(Instruction &I, SparseSolver &SS) {
return getOverdefinedVal(); // always safe, never useful.
}
/// PrintValue - Render the specified lattice value to the specified stream.
virtual void PrintValue(LatticeVal V, raw_ostream &OS);
};
/// SparseSolver - This class is a general purpose solver for Sparse Conditional
/// Propagation with a programmable lattice function.
///
class SparseSolver {
typedef AbstractLatticeFunction::LatticeVal LatticeVal;
/// LatticeFunc - This is the object that knows the lattice and how to do
/// compute transfer functions.
AbstractLatticeFunction *LatticeFunc;
DenseMap<Value*, LatticeVal> ValueState; // The state each value is in.
SmallPtrSet<BasicBlock*, 16> BBExecutable; // The bbs that are executable.
std::vector<Instruction*> InstWorkList; // Worklist of insts to process.
std::vector<BasicBlock*> BBWorkList; // The BasicBlock work list
/// KnownFeasibleEdges - Entries in this set are edges which have already had
/// PHI nodes retriggered.
typedef std::pair<BasicBlock*,BasicBlock*> Edge;
std::set<Edge> KnownFeasibleEdges;
SparseSolver(const SparseSolver&) LLVM_DELETED_FUNCTION;
void operator=(const SparseSolver&) LLVM_DELETED_FUNCTION;
public:
explicit SparseSolver(AbstractLatticeFunction *Lattice)
: LatticeFunc(Lattice) {}
~SparseSolver() {
delete LatticeFunc;
}
/// Solve - Solve for constants and executable blocks.
///
void Solve(Function &F);
void Print(Function &F, raw_ostream &OS) const;
/// getLatticeState - Return the LatticeVal object that corresponds to the
/// value. If an value is not in the map, it is returned as untracked,
/// unlike the getOrInitValueState method.
LatticeVal getLatticeState(Value *V) const {
DenseMap<Value*, LatticeVal>::const_iterator I = ValueState.find(V);
return I != ValueState.end() ? I->second : LatticeFunc->getUntrackedVal();
}
/// getOrInitValueState - Return the LatticeVal object that corresponds to the
/// value, initializing the value's state if it hasn't been entered into the
/// map yet. This function is necessary because not all values should start
/// out in the underdefined state... Arguments should be overdefined, and
/// constants should be marked as constants.
///
LatticeVal getOrInitValueState(Value *V);
/// isEdgeFeasible - Return true if the control flow edge from the 'From'
/// basic block to the 'To' basic block is currently feasible. If
/// AggressiveUndef is true, then this treats values with unknown lattice
/// values as undefined. This is generally only useful when solving the
/// lattice, not when querying it.
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To,
bool AggressiveUndef = false);
/// isBlockExecutable - Return true if there are any known feasible
/// edges into the basic block. This is generally only useful when
/// querying the lattice.
bool isBlockExecutable(BasicBlock *BB) const {
return BBExecutable.count(BB);
}
private:
/// UpdateState - When the state for some instruction is potentially updated,
/// this function notices and adds I to the worklist if needed.
void UpdateState(Instruction &Inst, LatticeVal V);
/// MarkBlockExecutable - This method can be used by clients to mark all of
/// the blocks that are known to be intrinsically live in the processed unit.
void MarkBlockExecutable(BasicBlock *BB);
/// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
/// work list if it is not already executable.
void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
/// getFeasibleSuccessors - Return a vector of booleans to indicate which
/// successors are reachable from a given terminator instruction.
void getFeasibleSuccessors(TerminatorInst &TI, SmallVectorImpl<bool> &Succs,
bool AggressiveUndef);
void visitInst(Instruction &I);
void visitPHINode(PHINode &I);
void visitTerminatorInst(TerminatorInst &TI);
};
} // end namespace llvm
#endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H

View File

@@ -0,0 +1,349 @@
//===- llvm/Analysis/TargetTransformInfo.h ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass exposes codegen information to IR-level passes. Every
// transformation that uses codegen information is broken into three parts:
// 1. The IR-level analysis pass.
// 2. The IR-level transformation interface which provides the needed
// information.
// 3. Codegen-level implementation which uses target-specific hooks.
//
// This file defines #2, which is the interface that IR-level transformations
// use for querying the codegen.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
#include "llvm/IR/Intrinsics.h"
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class GlobalValue;
class Type;
class User;
class Value;
/// TargetTransformInfo - This pass provides access to the codegen
/// interfaces that are needed for IR-level transformations.
class TargetTransformInfo {
protected:
/// \brief The TTI instance one level down the stack.
///
/// This is used to implement the default behavior all of the methods which
/// is to delegate up through the stack of TTIs until one can answer the
/// query.
TargetTransformInfo *PrevTTI;
/// \brief The top of the stack of TTI analyses available.
///
/// This is a convenience routine maintained as TTI analyses become available
/// that complements the PrevTTI delegation chain. When one part of an
/// analysis pass wants to query another part of the analysis pass it can use
/// this to start back at the top of the stack.
TargetTransformInfo *TopTTI;
/// All pass subclasses must in their initializePass routine call
/// pushTTIStack with themselves to update the pointers tracking the previous
/// TTI instance in the analysis group's stack, and the top of the analysis
/// group's stack.
void pushTTIStack(Pass *P);
/// All pass subclasses must in their finalizePass routine call popTTIStack
/// to update the pointers tracking the previous TTI instance in the analysis
/// group's stack, and the top of the analysis group's stack.
void popTTIStack();
/// All pass subclasses must call TargetTransformInfo::getAnalysisUsage.
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
public:
/// This class is intended to be subclassed by real implementations.
virtual ~TargetTransformInfo() = 0;
/// \name Generic Target Information
/// @{
/// \brief Underlying constants for 'cost' values in this interface.
///
/// Many APIs in this interface return a cost. This enum defines the
/// fundamental values that should be used to interpret (and produce) those
/// costs. The costs are returned as an unsigned rather than a member of this
/// enumeration because it is expected that the cost of one IR instruction
/// may have a multiplicative factor to it or otherwise won't fit directly
/// into the enum. Moreover, it is common to sum or average costs which works
/// better as simple integral values. Thus this enum only provides constants.
///
/// Note that these costs should usually reflect the intersection of code-size
/// cost and execution cost. A free instruction is typically one that folds
/// into another instruction. For example, reg-to-reg moves can often be
/// skipped by renaming the registers in the CPU, but they still are encoded
/// and thus wouldn't be considered 'free' here.
enum TargetCostConstants {
TCC_Free = 0, ///< Expected to fold away in lowering.
TCC_Basic = 1, ///< The cost of a typical 'add' instruction.
TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86.
};
/// \brief Estimate the cost of a specific operation when lowered.
///
/// Note that this is designed to work on an arbitrary synthetic opcode, and
/// thus work for hypothetical queries before an instruction has even been
/// formed. However, this does *not* work for GEPs, and must not be called
/// for a GEP instruction. Instead, use the dedicated getGEPCost interface as
/// analyzing a GEP's cost required more information.
///
/// Typically only the result type is required, and the operand type can be
/// omitted. However, if the opcode is one of the cast instructions, the
/// operand type is required.
///
/// The returned cost is defined in terms of \c TargetCostConstants, see its
/// comments for a detailed explanation of the cost values.
virtual unsigned getOperationCost(unsigned Opcode, Type *Ty,
Type *OpTy = 0) const;
/// \brief Estimate the cost of a GEP operation when lowered.
///
/// The contract for this function is the same as \c getOperationCost except
/// that it supports an interface that provides extra information specific to
/// the GEP operation.
virtual unsigned getGEPCost(const Value *Ptr,
ArrayRef<const Value *> Operands) const;
/// \brief Estimate the cost of a function call when lowered.
///
/// The contract for this is the same as \c getOperationCost except that it
/// supports an interface that provides extra information specific to call
/// instructions.
///
/// This is the most basic query for estimating call cost: it only knows the
/// function type and (potentially) the number of arguments at the call site.
/// The latter is only interesting for varargs function types.
virtual unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const;
/// \brief Estimate the cost of calling a specific function when lowered.
///
/// This overload adds the ability to reason about the particular function
/// being called in the event it is a library call with special lowering.
virtual unsigned getCallCost(const Function *F, int NumArgs = -1) const;
/// \brief Estimate the cost of calling a specific function when lowered.
///
/// This overload allows specifying a set of candidate argument values.
virtual unsigned getCallCost(const Function *F,
ArrayRef<const Value *> Arguments) const;
/// \brief Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<Type *> ParamTys) const;
/// \brief Estimate the cost of an intrinsic when lowered.
///
/// Mirrors the \c getCallCost method but uses an intrinsic identifier.
virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
ArrayRef<const Value *> Arguments) const;
/// \brief Estimate the cost of a given IR user when lowered.
///
/// This can estimate the cost of either a ConstantExpr or Instruction when
/// lowered. It has two primary advantages over the \c getOperationCost and
/// \c getGEPCost above, and one significant disadvantage: it can only be
/// used when the IR construct has already been formed.
///
/// The advantages are that it can inspect the SSA use graph to reason more
/// accurately about the cost. For example, all-constant-GEPs can often be
/// folded into a load or other instruction, but if they are used in some
/// other context they may not be folded. This routine can distinguish such
/// cases.
///
/// The returned cost is defined in terms of \c TargetCostConstants, see its
/// comments for a detailed explanation of the cost values.
virtual unsigned getUserCost(const User *U) const;
/// \brief Test whether calls to a function lower to actual program function
/// calls.
///
/// The idea is to test whether the program is likely to require a 'call'
/// instruction or equivalent in order to call the given function.
///
/// FIXME: It's not clear that this is a good or useful query API. Client's
/// should probably move to simpler cost metrics using the above.
/// Alternatively, we could split the cost interface into distinct code-size
/// and execution-speed costs. This would allow modelling the core of this
/// query more accurately as the a call is a single small instruction, but
/// incurs significant execution cost.
virtual bool isLoweredToCall(const Function *F) const;
/// @}
/// \name Scalar Target Information
/// @{
/// \brief Flags indicating the kind of support for population count.
///
/// Compared to the SW implementation, HW support is supposed to
/// significantly boost the performance when the population is dense, and it
/// may or may not degrade performance if the population is sparse. A HW
/// support is considered as "Fast" if it can outperform, or is on a par
/// with, SW implementation when the population is sparse; otherwise, it is
/// considered as "Slow".
enum PopcntSupportKind {
PSK_Software,
PSK_SlowHardware,
PSK_FastHardware
};
/// isLegalAddImmediate - Return true if the specified immediate is legal
/// add immediate, that is the target has add instructions which can add
/// a register with the immediate without having to materialize the
/// immediate into a register.
virtual bool isLegalAddImmediate(int64_t Imm) const;
/// isLegalICmpImmediate - Return true if the specified immediate is legal
/// icmp immediate, that is the target has icmp instructions which can compare
/// a register against the immediate without having to materialize the
/// immediate into a register.
virtual bool isLegalICmpImmediate(int64_t Imm) const;
/// isLegalAddressingMode - Return true if the addressing mode represented by
/// AM is legal for this target, for a load/store of the specified type.
/// The type may be VoidTy, in which case only return true if the addressing
/// mode is legal for a load/store of any legal type.
/// TODO: Handle pre/postinc as well.
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale) const;
/// isTruncateFree - Return true if it's free to truncate a value of
/// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in
/// register EAX to i16 by referencing its sub-register AX.
virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
/// Is this type legal.
virtual bool isTypeLegal(Type *Ty) const;
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
virtual unsigned getJumpBufAlignment() const;
/// getJumpBufSize - returns the target's jmp_buf size in bytes.
virtual unsigned getJumpBufSize() const;
/// shouldBuildLookupTables - Return true if switches should be turned into
/// lookup tables for the target.
virtual bool shouldBuildLookupTables() const;
/// getPopcntSupport - Return hardware support for population count.
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
/// getIntImmCost - Return the expected cost of materializing the given
/// integer immediate of the specified type.
virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
/// @}
/// \name Vector Target Information
/// @{
/// \brief The various kinds of shuffle patterns for vector queries.
enum ShuffleKind {
SK_Broadcast, ///< Broadcast element 0 to all other elements.
SK_Reverse, ///< Reverse the order of the vector.
SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
SK_ExtractSubvector ///< ExtractSubvector Index indicates start offset.
};
/// \brief Additonal information about an operand's possible values.
enum OperandValueKind {
OK_AnyValue, // Operand can have any value.
OK_UniformValue, // Operand is uniform (splat of a value).
OK_UniformConstantValue // Operand is uniform constant.
};
/// \return The number of scalar or vector registers that the target has.
/// If 'Vectors' is true, it returns the number of vector registers. If it is
/// set to false, it returns the number of scalar registers.
virtual unsigned getNumberOfRegisters(bool Vector) const;
/// \return The width of the largest scalar or vector register type.
virtual unsigned getRegisterBitWidth(bool Vector) const;
/// \return The maximum unroll factor that the vectorizer should try to
/// perform for this target. This number depends on the level of parallelism
/// and the number of execution units in the CPU.
virtual unsigned getMaximumUnrollFactor() const;
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
OperandValueKind Opd1Info = OK_AnyValue,
OperandValueKind Opd2Info = OK_AnyValue) const;
/// \return The cost of a shuffle instruction of kind Kind and of type Tp.
/// The index and subtype parameters are used by the subvector insertion and
/// extraction shuffle kinds.
virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
Type *SubTp = 0) const;
/// \return The expected cost of cast instructions, such as bitcast, trunc,
/// zext, etc.
virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
Type *Src) const;
/// \return The expected cost of control-flow related instructions such as
/// Phi, Ret, Br.
virtual unsigned getCFInstrCost(unsigned Opcode) const;
/// \returns The expected cost of compare and select instructions.
virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
Type *CondTy = 0) const;
/// \return The expected cost of vector Insert and Extract.
/// Use -1 to indicate that there is no information on the index value.
virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
unsigned Index = -1) const;
/// \return The cost of Load and Store instructions.
virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
unsigned AddressSpace) const;
/// \returns The cost of Intrinsic instructions.
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
ArrayRef<Type *> Tys) const;
/// \returns The number of pieces into which the provided type must be
/// split during legalization. Zero is returned when the answer is unknown.
virtual unsigned getNumberOfParts(Type *Tp) const;
/// \returns The cost of the address computation. For most targets this can be
/// merged into the instruction indexing mode. Some targets might want to
/// distinguish between address computation for memory operations on vector
/// types and scalar types. Such targets should override this function.
virtual unsigned getAddressComputationCost(Type *Ty) const;
/// @}
/// Analysis group identification.
static char ID;
};
/// \brief Create the base case instance of a pass in the TTI analysis group.
///
/// This class provides the base case for the stack of TTI analyzes. It doesn't
/// delegate to anything and uses the STTI and VTTI objects passed in to
/// satisfy the queries.
ImmutablePass *createNoTargetTransformInfoPass();
} // End llvm namespace
#endif

View File

@@ -0,0 +1,119 @@
//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class represents a single trace of LLVM basic blocks. A trace is a
// single entry, multiple exit, region of code that is often hot. Trace-based
// optimizations treat traces almost like they are a large, strange, basic
// block: because the trace path is assumed to be hot, optimizations for the
// fall-through path are made at the expense of the non-fall-through paths.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_TRACE_H
#define LLVM_ANALYSIS_TRACE_H
#include <cassert>
#include <vector>
namespace llvm {
class BasicBlock;
class Function;
class Module;
class raw_ostream;
class Trace {
typedef std::vector<BasicBlock *> BasicBlockListType;
BasicBlockListType BasicBlocks;
public:
/// Trace ctor - Make a new trace from a vector of basic blocks,
/// residing in the function which is the parent of the first
/// basic block in the vector.
///
Trace(const std::vector<BasicBlock *> &vBB) : BasicBlocks (vBB) {}
/// getEntryBasicBlock - Return the entry basic block (first block)
/// of the trace.
///
BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; }
/// operator[]/getBlock - Return basic block N in the trace.
///
BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; }
BasicBlock *getBlock(unsigned i) const { return BasicBlocks[i]; }
/// getFunction - Return this trace's parent function.
///
Function *getFunction () const;
/// getModule - Return this Module that contains this trace's parent
/// function.
///
Module *getModule () const;
/// getBlockIndex - Return the index of the specified basic block in the
/// trace, or -1 if it is not in the trace.
int getBlockIndex(const BasicBlock *X) const {
for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
if (BasicBlocks[i] == X)
return i;
return -1;
}
/// contains - Returns true if this trace contains the given basic
/// block.
///
bool contains(const BasicBlock *X) const {
return getBlockIndex(X) != -1;
}
/// Returns true if B1 occurs before B2 in the trace, or if it is the same
/// block as B2.. Both blocks must be in the trace.
///
bool dominates(const BasicBlock *B1, const BasicBlock *B2) const {
int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2);
assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!");
return B1Idx <= B2Idx;
}
// BasicBlock iterators...
typedef BasicBlockListType::iterator iterator;
typedef BasicBlockListType::const_iterator const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
iterator begin() { return BasicBlocks.begin(); }
const_iterator begin() const { return BasicBlocks.begin(); }
iterator end () { return BasicBlocks.end(); }
const_iterator end () const { return BasicBlocks.end(); }
reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
reverse_iterator rend () { return BasicBlocks.rend(); }
const_reverse_iterator rend () const { return BasicBlocks.rend(); }
unsigned size() const { return BasicBlocks.size(); }
bool empty() const { return BasicBlocks.empty(); }
iterator erase(iterator q) { return BasicBlocks.erase (q); }
iterator erase(iterator q1, iterator q2) { return BasicBlocks.erase (q1, q2); }
/// print - Write trace to output stream.
///
void print(raw_ostream &O) const;
/// dump - Debugger convenience method; writes trace to standard error
/// output stream.
///
void dump() const;
};
} // end namespace llvm
#endif // LLVM_ANALYSIS_TRACE_H

View File

@@ -0,0 +1,193 @@
//===- llvm/Analysis/ValueTracking.h - Walk computations --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains routines that help analyze properties that chains of
// computations have.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
#define LLVM_ANALYSIS_VALUETRACKING_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class Value;
class Instruction;
class APInt;
class DataLayout;
class StringRef;
class MDNode;
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bit sets. This code only analyzes bits in Mask, in order to short-circuit
/// processing.
///
/// This function is defined on values with integer type, values with pointer
/// type (but only if TD is non-null), and vectors of integers. In the case
/// where V is a vector, the mask, known zero, and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void ComputeMaskedBits(Value *V, APInt &KnownZero, APInt &KnownOne,
const DataLayout *TD = 0, unsigned Depth = 0);
void computeMaskedBitsLoad(const MDNode &Ranges, APInt &KnownZero);
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around ComputeMaskedBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
const DataLayout *TD = 0, unsigned Depth = 0);
/// isKnownToBeAPowerOfTwo - Return true if the given value is known to have
/// exactly one bit set when defined. For vectors return true if every
/// element is known to be a power of two when defined. Supports values with
/// integer or pointer type and vectors of integers. If 'OrZero' is set then
/// returns true if the given value is either a power of two or zero.
bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0);
/// isKnownNonZero - Return true if the given value is known to be non-zero
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
bool isKnownNonZero(Value *V, const DataLayout *TD = 0, unsigned Depth = 0);
/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero. We use
/// this predicate to simplify operations downstream. Mask is known to be
/// zero for bits that V cannot have.
///
/// This function is defined on values with integer type, values with pointer
/// type (but only if TD is non-null), and vectors of integers. In the case
/// where V is a vector, the mask, known zero, and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
bool MaskedValueIsZero(Value *V, const APInt &Mask,
const DataLayout *TD = 0, unsigned Depth = 0);
/// ComputeNumSignBits - Return the number of times the sign bit of the
/// register is replicated into the other bits. We know that at least 1 bit
/// is always equal to the sign bit (itself), but other cases can give us
/// information. For example, immediately after an "ashr X, 2", we know that
/// the top 3 bits are all equal to each other, so we return 3.
///
/// 'Op' must have a scalar integer type.
///
unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = 0,
unsigned Depth = 0);
/// ComputeMultiple - This function computes the integer multiple of Base that
/// equals V. If successful, it returns true and returns the multiple in
/// Multiple. If unsuccessful, it returns false. Also, if V can be
/// simplified to an integer, then the simplified V is returned in Val. Look
/// through sext only if LookThroughSExt=true.
bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
bool LookThroughSExt = false,
unsigned Depth = 0);
/// CannotBeNegativeZero - Return true if we can prove that the specified FP
/// value is never equal to -0.0.
///
bool CannotBeNegativeZero(const Value *V, unsigned Depth = 0);
/// isBytewiseValue - If the specified value can be set by repeating the same
/// byte in memory, return the i8 value that it is represented with. This is
/// true for all i8 values obviously, but is also true for i32 0, i32 -1,
/// i16 0xF0F0, double 0.0 etc. If the value can't be handled with a repeated
/// byte store (e.g. i16 0x1234), return null.
Value *isBytewiseValue(Value *V);
/// FindInsertedValue - Given an aggregrate and an sequence of indices, see if
/// the scalar value indexed is already around as a register, for example if
/// it were inserted directly into the aggregrate.
///
/// If InsertBefore is not null, this function will duplicate (modified)
/// insertvalues when a part of a nested struct is extracted.
Value *FindInsertedValue(Value *V,
ArrayRef<unsigned> idx_range,
Instruction *InsertBefore = 0);
/// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
const DataLayout *TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
const DataLayout *TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
/// getConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V. If successful, it returns true
/// and returns the string in Str. If unsuccessful, it returns false. This
/// does not include the trailing nul character by default. If TrimAtNul is
/// set to false, then this returns any trailing nul characters as well as any
/// other characters that come after it.
bool getConstantStringInfo(const Value *V, StringRef &Str,
uint64_t Offset = 0, bool TrimAtNul = true);
/// GetStringLength - If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
uint64_t GetStringLength(Value *V);
/// GetUnderlyingObject - This method strips off any GEP address adjustments
/// and pointer casts from the specified value, returning the original object
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
Value *GetUnderlyingObject(Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6);
static inline const Value *
GetUnderlyingObject(const Value *V, const DataLayout *TD = 0,
unsigned MaxLookup = 6) {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
/// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
/// except that it can look through phi and select instructions and return
/// multiple objects.
void GetUnderlyingObjects(Value *V,
SmallVectorImpl<Value *> &Objects,
const DataLayout *TD = 0,
unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
bool onlyUsedByLifetimeMarkers(const Value *V);
/// isSafeToSpeculativelyExecute - Return true if the instruction does not
/// have any effects besides calculating the result and does not have
/// undefined behavior.
///
/// This method never returns true for an instruction that returns true for
/// mayHaveSideEffects; however, this method also does some other checks in
/// addition. It checks for undefined behavior, like dividing by zero or
/// loading from an invalid pointer (but not for undefined results, like a
/// shift with a shift amount larger than the width of the result). It checks
/// for malloc and alloca because speculatively executing them might cause a
/// memory leak. It also returns false for instructions related to control
/// flow, specifically terminators and PHI nodes.
///
/// This method only looks at the instruction itself and its operands, so if
/// this method returns true, it is safe to move the instruction as long as
/// the correct dominance relationships for the operands and users hold.
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
bool isSafeToSpeculativelyExecute(const Value *V,
const DataLayout *TD = 0);
/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
/// its definition. This returns true for allocas, non-extern-weak globals
/// and byval arguments.
bool isKnownNonNull(const Value *V);
} // end namespace llvm
#endif

View File

@@ -0,0 +1,75 @@
//===-- llvm/Analysis/Verifier.h - LLVM IR Verifier -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the function verifier interface, that can be used for some
// sanity checking of input to the system, and for checking that transformations
// haven't done something bad.
//
// Note that this does not provide full 'java style' security and verifications,
// instead it just tries to ensure that code is well formed.
//
// To see what specifically is checked, look at the top of Verifier.cpp
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_VERIFIER_H
#define LLVM_ANALYSIS_VERIFIER_H
#include <string>
namespace llvm {
class FunctionPass;
class Module;
class Function;
/// @brief An enumeration to specify the action to be taken if errors found.
///
/// This enumeration is used in the functions below to indicate what should
/// happen if the verifier finds errors. Each of the functions that uses
/// this enumeration as an argument provides a default value for it. The
/// actions are listed below.
enum VerifierFailureAction {
AbortProcessAction, ///< verifyModule will print to stderr and abort()
PrintMessageAction, ///< verifyModule will print to stderr and return true
ReturnStatusAction ///< verifyModule will just return true
};
/// @brief Create a verifier pass.
///
/// Check a module or function for validity. When the pass is used, the
/// action indicated by the \p action argument will be used if errors are
/// found.
FunctionPass *createVerifierPass(
VerifierFailureAction action = AbortProcessAction ///< Action to take
);
/// @brief Check a module for errors.
///
/// If there are no errors, the function returns false. If an error is found,
/// the action taken depends on the \p action parameter.
/// This should only be used for debugging, because it plays games with
/// PassManagers and stuff.
bool verifyModule(
const Module &M, ///< The module to be verified
VerifierFailureAction action = AbortProcessAction, ///< Action to take
std::string *ErrorInfo = 0 ///< Information about failures.
);
// verifyFunction - Check a function for errors, useful for use when debugging a
// pass.
bool verifyFunction(
const Function &F, ///< The function to be verified
VerifierFailureAction action = AbortProcessAction ///< Action to take
);
} // End llvm namespace
#endif