mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-22 23:24:59 +00:00
Re-factoring.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96589 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -68,56 +68,84 @@ reportError (string ErrorString, vector<string> &Values) {
|
|||||||
//
|
//
|
||||||
bool PIC16Cloner::runOnModule(Module &M) {
|
bool PIC16Cloner::runOnModule(Module &M) {
|
||||||
CallGraph &CG = getAnalysis<CallGraph>();
|
CallGraph &CG = getAnalysis<CallGraph>();
|
||||||
// Initially record that no interrupt has been found
|
|
||||||
foundISR = false;
|
|
||||||
|
|
||||||
// First mark the MainLine.
|
// Search for the "main" and "ISR" functions.
|
||||||
|
CallGraphNode *mainCGN = NULL, *isrCGN = NULL;
|
||||||
for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
|
for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
|
||||||
{
|
{
|
||||||
// External calling node doesn't have any function associated
|
// External calling node doesn't have any function associated with it.
|
||||||
// with it
|
if (! it->first)
|
||||||
if (!it->first)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (it->first->getName().str() == "main") {
|
if (it->first->getName().str() == "main") {
|
||||||
// See if the main itself is interrupt function then report an error.
|
mainCGN = it->second;
|
||||||
if (PAN::isISR(it->first->getSection()))
|
}
|
||||||
reportError("Function 'main' can't be interrupt function");
|
|
||||||
else {
|
|
||||||
// Function main itself is MainLine function.
|
|
||||||
it->second->getFunction()->setSection("ML");
|
|
||||||
// mark the hierarchy
|
|
||||||
markCallGraph(it->second, "ML");
|
|
||||||
// MainLine has been marked now break ; don't search any further.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// When the MainLine has been marked only then mark the InterruptLine.
|
|
||||||
for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
|
|
||||||
{
|
|
||||||
// External calling node doesn't have any function associated
|
|
||||||
// with it
|
|
||||||
if (!it->first)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (PAN::isISR(it->first->getSection())) {
|
if (PAN::isISR(it->first->getSection())) {
|
||||||
|
isrCGN = it->second;
|
||||||
if (foundISR)
|
|
||||||
reportError("More than one interrupt functions defined in the module");
|
|
||||||
|
|
||||||
foundISR = true;
|
|
||||||
|
|
||||||
markCallGraph(it->second, "IL");
|
|
||||||
// InterruptLine handled now break; don't search any further.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// Don't search further if we've found both.
|
||||||
return true;
|
if (mainCGN && isrCGN)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Time for some diagnostics.
|
||||||
|
// See if the main itself is interrupt function then report an error.
|
||||||
|
if (PAN::isISR(mainCGN->getFunction()->getSection())) {
|
||||||
|
reportError("Function 'main' can't be interrupt function");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mark all reachable functions from main as ML.
|
||||||
|
markCallGraph(mainCGN, "ML");
|
||||||
|
|
||||||
|
// And then all the functions reachable from ISR will be cloned.
|
||||||
|
cloneSharedFunctions(isrCGN);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark all reachable functions from the given node, with the given mark.
|
||||||
|
//
|
||||||
|
void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
|
||||||
|
// Mark the top node first.
|
||||||
|
Function *thisF = CGN->getFunction();
|
||||||
|
|
||||||
|
thisF->setSection(StringMark);
|
||||||
|
|
||||||
|
// Mark all the called functions
|
||||||
|
for(CallGraphNode::iterator cgn_it = CGN->begin();
|
||||||
|
cgn_it != CGN->end(); ++cgn_it) {
|
||||||
|
Function *CalledF = cgn_it->second->getFunction();
|
||||||
|
|
||||||
|
// If calling an external function then CallGraphNode
|
||||||
|
// will not be associated with any function.
|
||||||
|
if (! CalledF)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Issue diagnostic if interrupt function is being called.
|
||||||
|
if (PAN::isISR(CalledF->getSection())) {
|
||||||
|
vector<string> Values;
|
||||||
|
Values.push_back(CalledF->getName().str());
|
||||||
|
reportError("Interrupt function (%0) can't be called", Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Has already been mark
|
||||||
|
if (CalledF->getSection().find(StringMark) != string::npos) {
|
||||||
|
// Should we do anything here?
|
||||||
|
} else {
|
||||||
|
// Mark now
|
||||||
|
CalledF->setSection(StringMark);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Before going any further mark all the called function by current
|
||||||
|
// function.
|
||||||
|
markCallGraph(cgn_it->second ,StringMark);
|
||||||
|
} // end of loop of all called functions.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// For PIC16, automatic variables of a function are emitted as globals.
|
// For PIC16, automatic variables of a function are emitted as globals.
|
||||||
// Clone the auto variables of a function and put them in ValueMap,
|
// Clone the auto variables of a function and put them in ValueMap,
|
||||||
// this ValueMap will be used while
|
// this ValueMap will be used while
|
||||||
@@ -158,16 +186,12 @@ void PIC16Cloner::CloneAutos(Function *F) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mark all reachable functions from the given node, with the given mark.
|
// Clone all functions that are reachable from ISR and are already
|
||||||
|
// marked as ML.
|
||||||
//
|
//
|
||||||
void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
|
void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) {
|
||||||
string AlternateMark;
|
|
||||||
if (StringMark == "ML")
|
|
||||||
AlternateMark = "IL";
|
|
||||||
else
|
|
||||||
AlternateMark = "ML";
|
|
||||||
|
|
||||||
// Mark all the called functions
|
// Check all the called functions from ISR.
|
||||||
for(CallGraphNode::iterator cgn_it = CGN->begin();
|
for(CallGraphNode::iterator cgn_it = CGN->begin();
|
||||||
cgn_it != CGN->end(); ++cgn_it) {
|
cgn_it != CGN->end(); ++cgn_it) {
|
||||||
Function *CalledF = cgn_it->second->getFunction();
|
Function *CalledF = cgn_it->second->getFunction();
|
||||||
@@ -184,31 +208,27 @@ void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
|
|||||||
reportError("Interrupt function (%0) can't be called", Values);
|
reportError("Interrupt function (%0) can't be called", Values);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has already been mark
|
if (CalledF->getSection().find("ML") != string::npos) {
|
||||||
if (CalledF->getSection().find(StringMark) != string::npos) {
|
// Function is alternatively marked. It should be a shared one.
|
||||||
// Should we do anything here?
|
// Create IL copy. Passing called function as first argument
|
||||||
} else {
|
// and the caller as the second argument.
|
||||||
// Mark now
|
|
||||||
if (CalledF->getSection().find(AlternateMark) != string::npos) {
|
|
||||||
// Function is alternatively marked. It should be a shared one.
|
|
||||||
// Create IL copy. Passing called function as first argument
|
|
||||||
// and the caller as the second argument.
|
|
||||||
|
|
||||||
// Before making IL copy, first ensure that this function has a
|
// Before making IL copy, first ensure that this function has a
|
||||||
// body. If the function does have a body. It can't be cloned.
|
// body. If the function does have a body. It can't be cloned.
|
||||||
// Such a case may occur when the function has been declarated
|
// Such a case may occur when the function has been declarated
|
||||||
// in the C source code but its body exists in assembly file.
|
// in the C source code but its body exists in assembly file.
|
||||||
if (!CalledF->isDeclaration()) {
|
if (!CalledF->isDeclaration()) {
|
||||||
// FIXME: Not implemented yet. Clone the function here.
|
cloneFunction(CalledF);
|
||||||
}
|
// FIXME: remap all the call sites here.
|
||||||
} else {
|
} else {
|
||||||
// Function is not marked. It should be marked now.
|
// It is called only from ISR. Still mark it as we need this info
|
||||||
CalledF->setSection(StringMark);
|
// in code gen while calling intrinsics.Function is not marked.
|
||||||
|
CalledF->setSection("IL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Before going any further mark all the called function by current
|
// Before going any further clone all the shared function reachaable
|
||||||
// function.
|
// by current function.
|
||||||
markCallGraph(cgn_it->second ,StringMark);
|
cloneSharedFunctions(cgn_it->second);
|
||||||
} // end of loop of all called functions.
|
} // end of loop of all called functions.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,6 +52,9 @@ namespace llvm {
|
|||||||
// Clone the body of a function.
|
// Clone the body of a function.
|
||||||
Function *cloneFunction(Function *F);
|
Function *cloneFunction(Function *F);
|
||||||
|
|
||||||
|
// Clone all shared functions.
|
||||||
|
void cloneSharedFunctions(CallGraphNode *isrCGN);
|
||||||
|
|
||||||
// Error reporting for PIC16Pass
|
// Error reporting for PIC16Pass
|
||||||
void reportError(string ErrorString, vector<string> &Values);
|
void reportError(string ErrorString, vector<string> &Values);
|
||||||
void reportError(string ErrorString);
|
void reportError(string ErrorString);
|
||||||
|
Reference in New Issue
Block a user