Make data structure acurately get ALL edges, even loads of null fields of

nodes that are not shadow nodes

This fixes em3d to be _correct_ if not optimial


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2274 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-04-17 03:24:59 +00:00
parent a146183c21
commit fe14568a81
3 changed files with 30 additions and 29 deletions

View File

@ -20,22 +20,30 @@
// chain..
// FIXME: This should not take a FunctionRepBuilder as an argument!
//
ShadowDSNode *ShadowDSNode::synthesizeNode(const Type *Ty,
FunctionRepBuilder *Rep) {
ShadowDSNode *DSNode::synthesizeNode(const Type *Ty,
FunctionRepBuilder *Rep) {
// If we are a derived shadow node, defer to our parent to synthesize the node
if (ShadowParent) return ShadowParent->synthesizeNode(Ty, Rep);
if (ShadowDSNode *Th = dyn_cast<ShadowDSNode>(this))
if (Th->getShadowParent())
return Th->getShadowParent()->synthesizeNode(Ty, Rep);
// See if we have already synthesized a node of this type...
for (unsigned i = 0, e = SynthNodes.size(); i != e; ++i)
if (SynthNodes[i].first == Ty) return SynthNodes[i].second;
// No we haven't. Do so now and add it to our list of saved nodes...
ShadowDSNode *SN = new ShadowDSNode(Ty, Mod, this);
ShadowDSNode *SN = Rep->makeSynthesizedShadow(Ty, this);
SynthNodes.push_back(make_pair(Ty, SN));
Rep->addShadowNode(SN);
return SN;
}
ShadowDSNode *FunctionRepBuilder::makeSynthesizedShadow(const Type *Ty,
DSNode *Parent) {
ShadowDSNode *Result = new ShadowDSNode(Ty, F->getFunction()->getParent(),
Parent);
ShadowNodes.push_back(Result);
return Result;
}
@ -195,7 +203,6 @@ PointerVal FunctionRepBuilder::getIndexedPointerDest(const PointerVal &InP,
static PointerValSet &getField(const PointerVal &DestPtr) {
assert(DestPtr.Node != 0);
return DestPtr.Node->getLink(DestPtr.Index);
}
@ -232,8 +239,8 @@ void FunctionRepBuilder::visitReturnInst(ReturnInst *RI) {
void FunctionRepBuilder::visitLoadInst(LoadInst *LI) {
// Only loads that return pointers are interesting...
if (!isa<PointerType>(LI->getType())) return;
const PointerType *DestTy = cast<PointerType>(LI->getType());
const PointerType *DestTy = dyn_cast<PointerType>(LI->getType());
if (DestTy == 0) return;
const PointerValSet &SrcPVS = ValueMap[LI->getOperand(0)];
PointerValSet &LIPVS = ValueMap[LI];
@ -245,12 +252,12 @@ void FunctionRepBuilder::visitLoadInst(LoadInst *LI) {
if (Field.size()) { // Field loaded wasn't null?
Changed |= LIPVS.add(Field);
} else if (ShadowDSNode *Shad = dyn_cast<ShadowDSNode>(Ptr.Node)) {
} else {
// If we are loading a null field out of a shadow node, we need to
// synthesize a new shadow node and link it in...
//
ShadowDSNode *SynthNode =
Shad->synthesizeNode(DestTy->getElementType(), this);
Ptr.Node->synthesizeNode(DestTy->getElementType(), this);
Field.add(SynthNode);
Changed |= LIPVS.add(Field);

View File

@ -12,7 +12,7 @@
#include "llvm/Support/InstVisitor.h"
// DEBUG_DATA_STRUCTURE_CONSTRUCTION - Define this to 1 if you want debug output
#define DEBUG_DATA_STRUCTURE_CONSTRUCTION 0
//#define DEBUG_DATA_STRUCTURE_CONSTRUCTION 1
class FunctionRepBuilder;
@ -82,7 +82,8 @@ public:
const std::vector<GlobalDSNode*> &getGlobalNodes() const {return GlobalNodes;}
const std::vector<CallDSNode*> &getCallNodes() const { return CallNodes; }
void addShadowNode(ShadowDSNode *SN) { ShadowNodes.push_back(SN); }
ShadowDSNode *makeSynthesizedShadow(const Type *Ty, DSNode *Parent);
const PointerValSet &getRetNode() const { return RetNode; }
@ -96,12 +97,12 @@ private:
// While the worklist still has instructions to process, process them!
while (!WorkList.empty()) {
Instruction *I = WorkList.back(); WorkList.pop_back();
#if DEBUG_DATA_STRUCTURE_CONSTRUCTION
#ifdef DEBUG_DATA_STRUCTURE_CONSTRUCTION
cerr << "Processing worklist inst: " << I;
#endif
visit(I); // Dispatch to a visitXXX function based on instruction type...
#if DEBUG_DATA_STRUCTURE_CONSTRUCTION
#ifdef DEBUG_DATA_STRUCTURE_CONSTRUCTION
if (I->hasName() && ValueMap.count(I)) {
cerr << "Inst %" << I->getName() << " value is:\n";
ValueMap[I].print(cerr);

View File

@ -208,6 +208,13 @@ void DSNode::mapNode(map<const DSNode*, DSNode*> &NodeMap, const DSNode *Old) {
"Cloned nodes do not have the same number of links!");
for (unsigned j = 0, je = FieldLinks.size(); j != je; ++j)
MapPVS(FieldLinks[j], Old->FieldLinks[j], NodeMap);
// Map our SynthNodes...
assert(SynthNodes.empty() && "Synthnodes already mapped?");
SynthNodes.reserve(Old->SynthNodes.size());
for (unsigned i = 0, e = Old->SynthNodes.size(); i != e; ++i)
SynthNodes.push_back(std::make_pair(Old->SynthNodes[i].first,
(ShadowDSNode*)NodeMap[Old->SynthNodes[i].second]));
}
AllocDSNode::AllocDSNode(AllocationInst *V)
@ -251,7 +258,7 @@ ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M) : DSNode(ShadowNode, Ty) {
ShadowParent = 0;
}
ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, ShadowDSNode *ShadParent)
ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, DSNode *ShadParent)
: DSNode(ShadowNode, Ty) {
Mod = M;
ShadowParent = ShadParent;
@ -264,20 +271,6 @@ std::string ShadowDSNode::getCaption() const {
return OS.str();
}
void ShadowDSNode::mapNode(map<const DSNode*, DSNode*> &NodeMap,
const DSNode *O) {
const ShadowDSNode *Old = (ShadowDSNode*)O;
DSNode::mapNode(NodeMap, Old); // Map base portions first...
// Map our SynthNodes...
assert(SynthNodes.empty() && "Synthnodes already mapped?");
SynthNodes.reserve(Old->SynthNodes.size());
for (unsigned i = 0, e = Old->SynthNodes.size(); i != e; ++i)
SynthNodes.push_back(std::make_pair(Old->SynthNodes[i].first,
(ShadowDSNode*)NodeMap[Old->SynthNodes[i].second]));
}
CallDSNode::CallDSNode(CallInst *ci) : DSNode(CallNode, ci->getType()), CI(ci) {
unsigned NumPtrs = 0;
for (unsigned i = 0, e = ci->getNumOperands(); i != e; ++i)