mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 00:21:03 +00:00
* Do not refer to ActualCallees in CBU, when we can do it locally.
* *DO NOT* print CBU graphs when asked to print our own. This is just FREAKING confusing and misleading: it's better to not print anything. * Simplify and clean up some code * Add some more paranoia assertion checking code that I found to track down this bug: * Fix a nasty bug that was causing us to crash on Prolangs-C++/objects, where we were missing processing some graphs. This hunk is the bugfix: - if (!I->isExternal() && !FoldedGraphsMap.count(I)) + if (!I->isExternal() && !ValMap.count(I)) urg! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17386 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -52,6 +52,10 @@ namespace PA {
|
|||||||
|
|
||||||
// FoldedGraphsMap, one graph for each function
|
// FoldedGraphsMap, one graph for each function
|
||||||
hash_map<const Function*, DSGraph*> FoldedGraphsMap;
|
hash_map<const Function*, DSGraph*> FoldedGraphsMap;
|
||||||
|
|
||||||
|
/// ActualCallees - The actual functions callable from indirect call sites.
|
||||||
|
///
|
||||||
|
hash_multimap<Instruction*, Function*> ActualCallees;
|
||||||
|
|
||||||
// Equivalence class where functions that can potentially be called via the
|
// Equivalence class where functions that can potentially be called via the
|
||||||
// same function pointer are in the same class.
|
// same function pointer are in the same class.
|
||||||
@@ -122,9 +126,9 @@ namespace PA {
|
|||||||
return *GlobalsGraph;
|
return *GlobalsGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef llvm::BUDataStructures::ActualCalleesTy ActualCalleesTy;
|
typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
|
||||||
const ActualCalleesTy &getActualCallees() const {
|
const ActualCalleesTy &getActualCallees() const {
|
||||||
return CBU->getActualCallees();
|
return ActualCallees;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
@@ -134,7 +138,7 @@ namespace PA {
|
|||||||
|
|
||||||
/// print - Print out the analysis results...
|
/// print - Print out the analysis results...
|
||||||
///
|
///
|
||||||
void print(std::ostream &O, const Module *M) const { CBU->print(O, M); }
|
void print(std::ostream &O, const Module *M) const {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void buildIndirectFunctionSets(Module &M);
|
void buildIndirectFunctionSets(Module &M);
|
||||||
|
@@ -37,6 +37,25 @@ namespace {
|
|||||||
"Number of graphs inlined");
|
"Number of graphs inlined");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
template<typename GT>
|
||||||
|
static void CheckAllGraphs(Module *M, GT &ECGraphs) {
|
||||||
|
DSGraph &GG = ECGraphs.getGlobalsGraph();
|
||||||
|
|
||||||
|
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||||
|
if (!I->isExternal()) {
|
||||||
|
DSGraph &G = ECGraphs.getDSGraph(*I);
|
||||||
|
|
||||||
|
DSGraph::NodeMapTy GlobalsGraphNodeMapping;
|
||||||
|
for (DSScalarMap::global_iterator I = G.getScalarMap().global_begin(),
|
||||||
|
E = G.getScalarMap().global_end(); I != E; ++I)
|
||||||
|
DSGraph::computeNodeMapping(G.getNodeForValue(*I),
|
||||||
|
GG.getNodeForValue(*I),
|
||||||
|
GlobalsGraphNodeMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// getDSGraphForCallSite - Return the common data structure graph for
|
// getDSGraphForCallSite - Return the common data structure graph for
|
||||||
// callees at the specified call site.
|
// callees at the specified call site.
|
||||||
//
|
//
|
||||||
@@ -56,10 +75,13 @@ getSomeCalleeForCallSite(const CallSite &CS) const {
|
|||||||
//
|
//
|
||||||
bool PA::EquivClassGraphs::runOnModule(Module &M) {
|
bool PA::EquivClassGraphs::runOnModule(Module &M) {
|
||||||
CBU = &getAnalysis<CompleteBUDataStructures>();
|
CBU = &getAnalysis<CompleteBUDataStructures>();
|
||||||
|
CheckAllGraphs(&M, *CBU);
|
||||||
|
|
||||||
GlobalsGraph = new DSGraph(CBU->getGlobalsGraph());
|
GlobalsGraph = new DSGraph(CBU->getGlobalsGraph());
|
||||||
GlobalsGraph->setPrintAuxCalls();
|
GlobalsGraph->setPrintAuxCalls();
|
||||||
|
|
||||||
|
ActualCallees = CBU->getActualCallees();
|
||||||
|
|
||||||
// Find equivalence classes of functions called from common call sites.
|
// Find equivalence classes of functions called from common call sites.
|
||||||
// Fold the CBU graphs for all functions in an equivalence class.
|
// Fold the CBU graphs for all functions in an equivalence class.
|
||||||
buildIndirectFunctionSets(M);
|
buildIndirectFunctionSets(M);
|
||||||
@@ -77,9 +99,11 @@ bool PA::EquivClassGraphs::runOnModule(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||||
if (!I->isExternal() && !FoldedGraphsMap.count(I))
|
if (!I->isExternal() && !ValMap.count(I))
|
||||||
processSCC(getOrCreateGraph(*I), *I, Stack, NextID, ValMap);
|
processSCC(getOrCreateGraph(*I), *I, Stack, NextID, ValMap);
|
||||||
|
|
||||||
|
DEBUG(CheckAllGraphs(&M, *this));
|
||||||
|
|
||||||
getGlobalsGraph().removeTriviallyDeadNodes();
|
getGlobalsGraph().removeTriviallyDeadNodes();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -237,7 +261,7 @@ DSGraph &PA::EquivClassGraphs::getOrCreateGraph(Function &F) {
|
|||||||
DSGraph *PA::EquivClassGraphs::cloneGraph(Function &F) {
|
DSGraph *PA::EquivClassGraphs::cloneGraph(Function &F) {
|
||||||
DSGraph *&Graph = FoldedGraphsMap[&F];
|
DSGraph *&Graph = FoldedGraphsMap[&F];
|
||||||
DSGraph &CBUGraph = CBU->getDSGraph(F);
|
DSGraph &CBUGraph = CBU->getDSGraph(F);
|
||||||
assert((Graph == NULL || Graph == &CBUGraph) && "Cloning a graph twice?");
|
assert(Graph == 0 && "Cloning a graph twice?");
|
||||||
|
|
||||||
// Copy the CBU graph...
|
// Copy the CBU graph...
|
||||||
Graph = new DSGraph(CBUGraph); // updates the map via reference
|
Graph = new DSGraph(CBUGraph); // updates the map via reference
|
||||||
@@ -280,11 +304,9 @@ unsigned PA::EquivClassGraphs::processSCC(DSGraph &FG, Function &F,
|
|||||||
ActualCalleesTy::const_iterator I, E;
|
ActualCalleesTy::const_iterator I, E;
|
||||||
for (tie(I, E) = getActualCallees().equal_range(Call); I != E; ++I)
|
for (tie(I, E) = getActualCallees().equal_range(Call); I != E; ++I)
|
||||||
if (!I->second->isExternal()) {
|
if (!I->second->isExternal()) {
|
||||||
DSGraph &CalleeG = getOrCreateGraph(*I->second);
|
// Process the callee as necessary.
|
||||||
|
unsigned M = processSCC(getOrCreateGraph(*I->second), *I->second,
|
||||||
// Have we visited the destination function yet?
|
Stack, NextID, ValMap);
|
||||||
std::map<Function*, unsigned>::iterator It = ValMap.find(I->second);
|
|
||||||
unsigned M = processSCC(CalleeG, *I->second, Stack, NextID, ValMap);
|
|
||||||
if (M < Min) Min = M;
|
if (M < Min) Min = M;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,22 +318,17 @@ unsigned PA::EquivClassGraphs::processSCC(DSGraph &FG, Function &F,
|
|||||||
// If this is a new SCC, process it now.
|
// If this is a new SCC, process it now.
|
||||||
bool IsMultiNodeSCC = false;
|
bool IsMultiNodeSCC = false;
|
||||||
while (Stack.back() != &F) {
|
while (Stack.back() != &F) {
|
||||||
DSGraph *NG = &getOrCreateGraph(* Stack.back());
|
DSGraph *NG = &getOrCreateGraph(*Stack.back());
|
||||||
ValMap[Stack.back()] = ~0U;
|
ValMap[Stack.back()] = ~0U;
|
||||||
|
|
||||||
// Since all SCCs must be the same as those found in CBU, we do not need to
|
// Since all SCCs must be the same as those found in CBU, we do not need to
|
||||||
// do any merging. Make sure all functions in the SCC share the same graph.
|
// do any merging. Make sure all functions in the SCC share the same graph.
|
||||||
assert(NG == &FG &&
|
assert(NG == &FG && "ECG discovered different SCC's than the CBU pass?");
|
||||||
"FoldGraphs: Functions in the same SCC have different graphs?");
|
|
||||||
|
|
||||||
Stack.pop_back();
|
Stack.pop_back();
|
||||||
IsMultiNodeSCC = true;
|
IsMultiNodeSCC = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up the graph before we start inlining a bunch again...
|
|
||||||
if (IsMultiNodeSCC)
|
|
||||||
FG.removeTriviallyDeadNodes();
|
|
||||||
|
|
||||||
Stack.pop_back();
|
Stack.pop_back();
|
||||||
|
|
||||||
processGraph(FG, F);
|
processGraph(FG, F);
|
||||||
@@ -392,17 +409,14 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute the Incomplete markers
|
// Recompute the Incomplete markers.
|
||||||
if (CallerGraph != NULL) {
|
assert(CallerGraph->getInlinedGlobals().empty());
|
||||||
assert(CallerGraph->getInlinedGlobals().empty());
|
CallerGraph->maskIncompleteMarkers();
|
||||||
CallerGraph->maskIncompleteMarkers();
|
CallerGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
|
||||||
CallerGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
|
|
||||||
|
// Delete dead nodes. Treat globals that are unreachable but that can
|
||||||
// Delete dead nodes. Treat globals that are unreachable but that can
|
// reach live nodes as live.
|
||||||
// reach live nodes as live.
|
CallerGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
|
||||||
CallerGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// When this graph is finalized, clone the globals in the graph into the
|
// When this graph is finalized, clone the globals in the graph into the
|
||||||
// globals graph to make sure it has everything, from all graphs.
|
// globals graph to make sure it has everything, from all graphs.
|
||||||
@@ -416,7 +430,6 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
|
|||||||
E = MainSM.global_end(); I != E; ++I)
|
E = MainSM.global_end(); I != E; ++I)
|
||||||
RC.getClonedNH(MainSM[*I]);
|
RC.getClonedNH(MainSM[*I]);
|
||||||
|
|
||||||
|
DEBUG(std::cerr << " -- DONE ProcessGraph for function "
|
||||||
DEBUG(std::cerr << " --DONE ProcessGraph for function "
|
|
||||||
<< F.getName() << "\n");
|
<< F.getName() << "\n");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user