mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 22:50:47 +00:00
cc4d3b25f3
start using them in a trivial way when -enable-jump-threading-lvi is passed. enable-jump-threading-lvi will be my playground for awhile. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86789 91177308-0d34-0410-b5e6-96231b3b80d8
147 lines
4.4 KiB
C++
147 lines
4.4 KiB
C++
//===- LazyValueInfo.cpp - Value constraint analysis ----------------------===//
|
|
//
|
|
// 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.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Analysis/LazyValueInfo.h"
|
|
#include "llvm/Constants.h"
|
|
#include "llvm/Instructions.h"
|
|
#include "llvm/Analysis/ConstantFolding.h"
|
|
#include "llvm/Target/TargetData.h"
|
|
#include "llvm/ADT/PointerIntPair.h"
|
|
using namespace llvm;
|
|
|
|
char LazyValueInfo::ID = 0;
|
|
static RegisterPass<LazyValueInfo>
|
|
X("lazy-value-info", "Lazy Value Information Analysis", false, true);
|
|
|
|
namespace llvm {
|
|
FunctionPass *createLazyValueInfoPass() { return new LazyValueInfo(); }
|
|
}
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// LVILatticeVal
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// LVILatticeVal - This is the information tracked by LazyValueInfo for each
|
|
/// value.
|
|
///
|
|
/// FIXME: This is basically just for bringup, this can be made a lot more rich
|
|
/// in the future.
|
|
///
|
|
namespace {
|
|
class LVILatticeVal {
|
|
enum LatticeValueTy {
|
|
/// undefined - This LLVM Value has no known value yet.
|
|
undefined,
|
|
/// constant - This LLVM Value has a specific constant value.
|
|
constant,
|
|
/// overdefined - This instruction is not known to be constant, and we know
|
|
/// it has a value.
|
|
overdefined
|
|
};
|
|
|
|
/// Val: This stores the current lattice value along with the Constant* for
|
|
/// the constant if this is a 'constant' value.
|
|
PointerIntPair<Constant *, 2, LatticeValueTy> Val;
|
|
|
|
public:
|
|
LVILatticeVal() : Val(0, undefined) {}
|
|
|
|
bool isUndefined() const { return Val.getInt() == undefined; }
|
|
bool isConstant() const { return Val.getInt() == constant; }
|
|
bool isOverdefined() const { return Val.getInt() == overdefined; }
|
|
|
|
Constant *getConstant() const {
|
|
assert(isConstant() && "Cannot get the constant of a non-constant!");
|
|
return Val.getPointer();
|
|
}
|
|
|
|
/// getConstantInt - If this is a constant with a ConstantInt value, return it
|
|
/// otherwise return null.
|
|
ConstantInt *getConstantInt() const {
|
|
if (isConstant())
|
|
return dyn_cast<ConstantInt>(getConstant());
|
|
return 0;
|
|
}
|
|
|
|
/// markOverdefined - Return true if this is a change in status.
|
|
bool markOverdefined() {
|
|
if (isOverdefined())
|
|
return false;
|
|
Val.setInt(overdefined);
|
|
return true;
|
|
}
|
|
|
|
/// markConstant - Return true if this is a change in status.
|
|
bool markConstant(Constant *V) {
|
|
if (isConstant()) {
|
|
assert(getConstant() == V && "Marking constant with different value");
|
|
return false;
|
|
}
|
|
|
|
assert(isUndefined());
|
|
Val.setInt(constant);
|
|
assert(V && "Marking constant with NULL");
|
|
Val.setPointer(V);
|
|
}
|
|
|
|
};
|
|
|
|
} // end anonymous namespace.
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// LazyValueInfo Impl
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
bool LazyValueInfo::runOnFunction(Function &F) {
|
|
TD = getAnalysisIfAvailable<TargetData>();
|
|
// Fully lazy.
|
|
return false;
|
|
}
|
|
|
|
void LazyValueInfo::releaseMemory() {
|
|
// No caching yet.
|
|
}
|
|
|
|
|
|
/// isEqual - Determine whether the specified value is known to be equal or
|
|
/// not-equal to the specified constant at the end of the specified block.
|
|
LazyValueInfo::Tristate
|
|
LazyValueInfo::isEqual(Value *V, Constant *C, BasicBlock *BB) {
|
|
// If already a constant, we can use constant folding.
|
|
if (Constant *VC = dyn_cast<Constant>(V)) {
|
|
// Ignore FP for now. TODO, consider what form of equality we want.
|
|
if (C->getType()->isFPOrFPVector())
|
|
return Unknown;
|
|
|
|
Constant *Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ, VC,C,TD);
|
|
if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
|
|
return ResCI->isZero() ? No : Yes;
|
|
}
|
|
|
|
// Not a very good implementation.
|
|
return Unknown;
|
|
}
|
|
|
|
Constant *LazyValueInfo::getConstant(Value *V, BasicBlock *BB) {
|
|
// If already a constant, return it.
|
|
if (Constant *VC = dyn_cast<Constant>(V))
|
|
return VC;
|
|
|
|
// Not a very good implementation.
|
|
return 0;
|
|
}
|
|
|