mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-21 12:38:45 +00:00
Use TargetData to find the size of a type.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35718 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8ac40dd747
commit
b01c77e137
@ -75,7 +75,8 @@
|
|||||||
//
|
//
|
||||||
// It never stores an empty range, because that means that the code is
|
// It never stores an empty range, because that means that the code is
|
||||||
// unreachable. It never stores a single-element range since that's an equality
|
// unreachable. It never stores a single-element range since that's an equality
|
||||||
// relationship and better stored in the InequalityGraph.
|
// relationship and better stored in the InequalityGraph, nor an empty range
|
||||||
|
// since that is better stored in UnreachableBlocks.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@ -97,6 +98,7 @@
|
|||||||
#include "llvm/Support/ConstantRange.h"
|
#include "llvm/Support/ConstantRange.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -669,6 +671,8 @@ namespace {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TargetData *TD;
|
||||||
|
|
||||||
std::vector<ScopedRange> Ranges;
|
std::vector<ScopedRange> Ranges;
|
||||||
typedef std::vector<ScopedRange>::iterator iterator;
|
typedef std::vector<ScopedRange>::iterator iterator;
|
||||||
|
|
||||||
@ -810,10 +814,15 @@ namespace {
|
|||||||
return Range;
|
return Range;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rangeFromValue - converts a Value into a range. If the value is a
|
||||||
|
// constant it constructs the single element range, otherwise it performs
|
||||||
|
// a lookup. The width W must be retrieved from typeToWidth and may not
|
||||||
|
// be zero.
|
||||||
ConstantRange rangeFromValue(Value *V, ETNode *Subtree, uint32_t W) {
|
ConstantRange rangeFromValue(Value *V, ETNode *Subtree, uint32_t W) {
|
||||||
ConstantInt *C = dyn_cast<ConstantInt>(V);
|
if (ConstantInt *C = dyn_cast<ConstantInt>(V)) {
|
||||||
if (C) {
|
|
||||||
return ConstantRange(C->getValue());
|
return ConstantRange(C->getValue());
|
||||||
|
} else if (isa<ConstantPointerNull>(V)) {
|
||||||
|
return ConstantRange(APInt::getNullValue(W));
|
||||||
} else {
|
} else {
|
||||||
iterator I = find(V, Subtree);
|
iterator I = find(V, Subtree);
|
||||||
if (I != end())
|
if (I != end())
|
||||||
@ -822,14 +831,15 @@ namespace {
|
|||||||
return ConstantRange(W);
|
return ConstantRange(W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t widthOfValue(Value *V) {
|
// typeToWidth - returns the number of bits necessary to store a value of
|
||||||
const Type *Ty = V->getType();
|
// this type, or zero if unknown.
|
||||||
|
uint32_t typeToWidth(const Type *Ty) const {
|
||||||
|
if (TD)
|
||||||
|
return TD->getTypeSizeInBits(Ty);
|
||||||
|
|
||||||
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
|
if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
|
||||||
return ITy->getBitWidth();
|
return ITy->getBitWidth();
|
||||||
|
|
||||||
// XXX: I'd like to transform T* into the appropriate integer by
|
|
||||||
// bit length, however that data may not be available.
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,8 +849,10 @@ namespace {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
explicit ValueRanges(TargetData *TD) : TD(TD) {}
|
||||||
|
|
||||||
bool isRelatedBy(Value *V1, Value *V2, ETNode *Subtree, LatticeVal LV) {
|
bool isRelatedBy(Value *V1, Value *V2, ETNode *Subtree, LatticeVal LV) {
|
||||||
uint32_t W = widthOfValue(V1);
|
uint32_t W = typeToWidth(V1->getType());
|
||||||
if (!W) return false;
|
if (!W) return false;
|
||||||
|
|
||||||
ConstantRange CR1 = rangeFromValue(V1, Subtree, W);
|
ConstantRange CR1 = rangeFromValue(V1, Subtree, W);
|
||||||
@ -901,7 +913,7 @@ namespace {
|
|||||||
VRPSolver *VRP) {
|
VRPSolver *VRP) {
|
||||||
assert(isCanonical(New, Subtree, VRP) && "Best choice not canonical?");
|
assert(isCanonical(New, Subtree, VRP) && "Best choice not canonical?");
|
||||||
|
|
||||||
uint32_t W = widthOfValue(New);
|
uint32_t W = typeToWidth(New->getType());
|
||||||
if (!W) return;
|
if (!W) return;
|
||||||
|
|
||||||
ConstantRange CR_New = rangeFromValue(New, Subtree, W);
|
ConstantRange CR_New = rangeFromValue(New, Subtree, W);
|
||||||
@ -933,7 +945,7 @@ namespace {
|
|||||||
// XXX: except in the case where isSingleElement and equal to either
|
// XXX: except in the case where isSingleElement and equal to either
|
||||||
// Lower or Upper. That's probably not profitable. (Type::Int1Ty?)
|
// Lower or Upper. That's probably not profitable. (Type::Int1Ty?)
|
||||||
|
|
||||||
uint32_t W = widthOfValue(V1);
|
uint32_t W = typeToWidth(V1->getType());
|
||||||
if (!W) return;
|
if (!W) return;
|
||||||
|
|
||||||
ConstantRange CR1 = rangeFromValue(V1, Subtree, W);
|
ConstantRange CR1 = rangeFromValue(V1, Subtree, W);
|
||||||
@ -1103,6 +1115,9 @@ namespace {
|
|||||||
bool makeEqual(Value *V1, Value *V2) {
|
bool makeEqual(Value *V1, Value *V2) {
|
||||||
DOUT << "makeEqual(" << *V1 << ", " << *V2 << ")\n";
|
DOUT << "makeEqual(" << *V1 << ", " << *V2 << ")\n";
|
||||||
|
|
||||||
|
assert(V1->getType() == V2->getType() &&
|
||||||
|
"Can't make two values with different types equal.");
|
||||||
|
|
||||||
if (V1 == V2) return true;
|
if (V1 == V2) return true;
|
||||||
|
|
||||||
if (isa<Constant>(V1) && isa<Constant>(V2))
|
if (isa<Constant>(V1) && isa<Constant>(V2))
|
||||||
@ -1421,6 +1436,9 @@ namespace {
|
|||||||
else DOUT << " default context";
|
else DOUT << " default context";
|
||||||
DOUT << "\n";
|
DOUT << "\n";
|
||||||
|
|
||||||
|
assert(V1->getType() == V2->getType() &&
|
||||||
|
"Can't relate two values with different types.");
|
||||||
|
|
||||||
WorkList.push_back(Operation());
|
WorkList.push_back(Operation());
|
||||||
Operation &O = WorkList.back();
|
Operation &O = WorkList.back();
|
||||||
O.LHS = V1, O.RHS = V2, O.Op = Pred, O.ContextInst = I;
|
O.LHS = V1, O.RHS = V2, O.Op = Pred, O.ContextInst = I;
|
||||||
@ -1703,7 +1721,6 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// solve - process the work queue
|
/// solve - process the work queue
|
||||||
/// Return false if a logical contradiction occurs.
|
|
||||||
void solve() {
|
void solve() {
|
||||||
//DOUT << "WorkList entry, size: " << WorkList.size() << "\n";
|
//DOUT << "WorkList entry, size: " << WorkList.size() << "\n";
|
||||||
while (!WorkList.empty()) {
|
while (!WorkList.empty()) {
|
||||||
@ -1862,6 +1879,8 @@ namespace {
|
|||||||
AU.addRequiredID(BreakCriticalEdgesID);
|
AU.addRequiredID(BreakCriticalEdgesID);
|
||||||
AU.addRequired<DominatorTree>();
|
AU.addRequired<DominatorTree>();
|
||||||
AU.addRequired<ETForest>();
|
AU.addRequired<ETForest>();
|
||||||
|
AU.addRequired<TargetData>();
|
||||||
|
AU.addPreserved<TargetData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -1980,6 +1999,8 @@ namespace {
|
|||||||
DT = &getAnalysis<DominatorTree>();
|
DT = &getAnalysis<DominatorTree>();
|
||||||
Forest = &getAnalysis<ETForest>();
|
Forest = &getAnalysis<ETForest>();
|
||||||
|
|
||||||
|
TargetData *TD = &getAnalysis<TargetData>();
|
||||||
|
|
||||||
Forest->updateDFSNumbers(); // XXX: should only act when numbers are out of date
|
Forest->updateDFSNumbers(); // XXX: should only act when numbers are out of date
|
||||||
|
|
||||||
DOUT << "Entering Function: " << F.getName() << "\n";
|
DOUT << "Entering Function: " << F.getName() << "\n";
|
||||||
@ -1987,7 +2008,7 @@ namespace {
|
|||||||
modified = false;
|
modified = false;
|
||||||
BasicBlock *RootBlock = &F.getEntryBlock();
|
BasicBlock *RootBlock = &F.getEntryBlock();
|
||||||
IG = new InequalityGraph(Forest->getNodeForBlock(RootBlock));
|
IG = new InequalityGraph(Forest->getNodeForBlock(RootBlock));
|
||||||
VR = new ValueRanges();
|
VR = new ValueRanges(TD);
|
||||||
WorkList.push_back(DT->getRootNode());
|
WorkList.push_back(DT->getRootNode());
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user