diff options
-rw-r--r-- | lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp | 38 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Passes/PIC16Cloner.h | 7 |
2 files changed, 45 insertions, 0 deletions
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp index 79f4946542..06e56a6e80 100644 --- a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp +++ b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp @@ -212,3 +212,41 @@ void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) { } // end of loop of all called functions. } +// Clone the given function and return it. +// Note: it uses the ValueMap member of the class, which is already populated +// by cloneAutos by the time we reach here. +// FIXME: Should we just pass ValueMap's ref as a parameter here? rather +// than keeping the ValueMap as a member. +Function * +PIC16Cloner::cloneFunction(Function *OrgF) { + Function *ClonedF; + + // See if we already cloned it. Return that. + cloned_map_iterator cm_it = ClonedFunctionMap.find(OrgF); + if(cm_it != ClonedFunctionMap.end()) { + ClonedF = cm_it->second; + return ClonedF; + } + + // Clone does not exist. + // First clone the autos, and populate ValueMap. + CloneAutos(OrgF); + + // Now create the clone. + ClonedF = CloneFunction(OrgF, ValueMap); + + // The new function should be for interrupt line. Therefore should have + // the name suffixed with IL and section attribute marked with IL. + ClonedF->setName(PAN::getCloneFnName(OrgF->getName())); + ClonedF->setSection("IL"); + + // Add the newly created function to the module. + OrgF->getParent()->getFunctionList().push_back(ClonedF); + + // Update the ClonedFunctionMap to record this cloning activity. + ClonedFunctionMap[OrgF] = ClonedF; + + return ClonedF; +} + + diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h index beeef7d25d..19f1856110 100644 --- a/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h +++ b/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h @@ -48,6 +48,9 @@ namespace llvm { // Clone auto variables of function specified. void CloneAutos(Function *F); + + // Clone the body of a function. + Function *cloneFunction(Function *F); // Error reporting for PIC16Pass void reportError(string ErrorString, vector<string> &Values); @@ -64,6 +67,10 @@ namespace llvm { // This value map is passed during the function cloning so that all the // uses of auto variables be updated properly. DenseMap<const Value*, Value*> ValueMap; + + // Map of a already cloned functions. + map<Function *, Function *> ClonedFunctionMap; + typedef map<Function *, Function *>::iterator cloned_map_iterator; }; } // End of anonymous namespace |