c282521be324137144f52ffa2ab54a64fc899c5f
[oota-llvm.git] / lib / Target / PIC16 / PIC16Passes / PIC16Cloner.cpp
1 //===-- PIC16Cloner.cpp - PIC16 LLVM Cloner for shared functions -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains code to clone all functions that are shared between
11 // the main line code (ML) and interrupt line code (IL). It clones all such
12 // shared functions and their automatic global vars by adding the .IL suffix. 
13 //
14 // This pass is supposed to be run on the linked .bc module.
15 // It traveses the module call graph twice. Once starting from the main function
16 // and marking each reached function as "ML". Again, starting from the ISR
17 // and cloning any reachable function that was marked as "ML". After cloning
18 // the function, it remaps all the call sites in IL functions to call the
19 // cloned functions. 
20 //===----------------------------------------------------------------------===//
21
22 #include "llvm/Analysis/CallGraph.h"
23 #include "llvm/Pass.h"
24 #include "llvm/Module.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/Transforms/Utils/Cloning.h"
28 #include "PIC16Cloner.h"
29 #include "../PIC16ABINames.h"
30 #include <vector>
31
32 using namespace llvm;
33 using std::vector;
34 using std::string;
35 using std::map;
36
37 namespace llvm {
38   char PIC16Cloner::ID = 0;
39
40   ModulePass *createPIC16ClonerPass() { return new PIC16Cloner(); }
41 }
42
43 // We currently intend to run these passes in opt, which does not have any
44 // diagnostic support. So use these functions for now. In future
45 // we will probably write our own driver tool.
46 //
47 void PIC16Cloner::reportError(string ErrorString) {
48   errs() << "ERROR : " << ErrorString << "\n";
49   exit(1);
50 }
51
52 void PIC16Cloner::
53 reportError (string ErrorString, vector<string> &Values) {
54   unsigned ValCount = Values.size();
55   string TargetString;
56   for (unsigned i=0; i<ValCount; ++i) {
57     TargetString = "%";
58     TargetString += ((char)i + '0');
59     ErrorString.replace(ErrorString.find(TargetString), TargetString.length(), 
60                         Values[i]);
61   }
62   errs() << "ERROR : " << ErrorString << "\n";
63   exit(1);
64 }
65
66
67 // Entry point
68 //
69 bool PIC16Cloner::runOnModule(Module &M) {
70    CallGraph &CG = getAnalysis<CallGraph>();
71
72    // Search for the "main" and "ISR" functions.
73    CallGraphNode *mainCGN = NULL, *isrCGN = NULL;
74    for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
75    {
76      // External calling node doesn't have any function associated with it.
77      if (! it->first)
78        continue;
79      
80      if (it->first->getName().str() == "main") {
81        mainCGN = it->second;
82      }
83
84      if (PAN::isISR(it->first->getSection())) {
85        isrCGN = it->second;
86      }
87  
88      // Don't search further if we've found both.
89      if (mainCGN && isrCGN)
90        break;
91    }
92
93    // We have nothing to do if any of the main or ISR is missing.
94    if (! mainCGN || ! isrCGN) return false;
95        
96    // Time for some diagnostics.
97    // See if the main itself is interrupt function then report an error.
98    if (PAN::isISR(mainCGN->getFunction()->getSection())) {
99      reportError("Function 'main' can't be interrupt function");
100    }
101
102     
103    // Mark all reachable functions from main as ML.
104    markCallGraph(mainCGN, "ML");
105
106    // And then all the functions reachable from ISR will be cloned.
107    cloneSharedFunctions(isrCGN);
108
109    return true;
110 }
111
112 // Mark all reachable functions from the given node, with the given mark.
113 //
114 void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
115   // Mark the top node first.
116   Function *thisF = CGN->getFunction();
117
118   thisF->setSection(StringMark);
119
120   // Mark all the called functions
121   for(CallGraphNode::iterator cgn_it = CGN->begin();
122               cgn_it != CGN->end(); ++cgn_it) {
123      Function *CalledF = cgn_it->second->getFunction();
124
125      // If calling an external function then CallGraphNode
126      // will not be associated with any function.
127      if (! CalledF)
128        continue;
129   
130      // Issue diagnostic if interrupt function is being called.
131      if (PAN::isISR(CalledF->getSection())) {
132        vector<string> Values;
133        Values.push_back(CalledF->getName().str());
134        reportError("Interrupt function (%0) can't be called", Values); 
135      }
136
137      // Has already been mark 
138      if (CalledF->getSection().find(StringMark) != string::npos) {
139        // Should we do anything here?
140      } else {
141        // Mark now
142        CalledF->setSection(StringMark);
143      }
144
145      // Before going any further mark all the called function by current
146      // function.
147      markCallGraph(cgn_it->second ,StringMark);
148   } // end of loop of all called functions.
149 }
150
151
152 // For PIC16, automatic variables of a function are emitted as globals.
153 // Clone the auto variables of a function  and put them in ValueMap, 
154 // this ValueMap will be used while
155 // Cloning the code of function itself.
156 //
157 void PIC16Cloner::CloneAutos(Function *F) {
158   // We'll need to update module's globals list as well. So keep a reference
159   // handy.
160   Module *M = F->getParent();
161   Module::GlobalListType &Globals = M->getGlobalList();
162
163   // Clear the leftovers in ValueMap by any previous cloning.
164   ValueMap.clear();
165
166   // Find the auto globls for this function and clone them, and put them
167   // in ValueMap.
168   std::string FnName = F->getName().str();
169   std::string VarName, ClonedVarName;
170   for (Module::global_iterator I = M->global_begin(), E = M->global_end();
171        I != E; ++I) {
172     VarName = I->getName().str();
173     if (PAN::isLocalToFunc(FnName, VarName)) {
174       // Auto variable for current function found. Clone it.
175       const GlobalVariable *GV = I;
176
177       const Type *InitTy = GV->getInitializer()->getType();
178       GlobalVariable *ClonedGV = 
179         new GlobalVariable(InitTy, false, GV->getLinkage(), 
180                            GV->getInitializer());
181       ClonedGV->setName(PAN::getCloneVarName(FnName, VarName));
182       // Add these new globals to module's globals list.
183       Globals.push_back(ClonedGV);
184  
185       // Update ValueMap.
186       ValueMap[GV] = ClonedGV;
187      }
188   }
189 }
190
191
192 // Clone all functions that are reachable from ISR and are already 
193 // marked as ML.
194 //
195 void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) {
196
197   // Check all the called functions from ISR.
198   for(CallGraphNode::iterator cgn_it = CGN->begin(); 
199               cgn_it != CGN->end(); ++cgn_it) {
200      Function *CalledF = cgn_it->second->getFunction();
201
202      // If calling an external function then CallGraphNode
203      // will not be associated with any function.
204      if (!CalledF)
205        continue;
206   
207      // Issue diagnostic if interrupt function is being called.
208      if (PAN::isISR(CalledF->getSection())) {
209        vector<string> Values;
210        Values.push_back(CalledF->getName().str());
211        reportError("Interrupt function (%0) can't be called", Values); 
212      }
213
214      if (CalledF->getSection().find("ML") != string::npos) {
215        // Function is alternatively marked. It should be a shared one.
216        // Create IL copy. Passing called function as first argument
217        // and the caller as the second argument.
218
219        // Before making IL copy, first ensure that this function has a 
220        // body. If the function does have a body. It can't be cloned.
221        // Such a case may occur when the function has been declarated
222        // in the C source code but its body exists in assembly file.
223        if (!CalledF->isDeclaration()) {
224          Function *cf = cloneFunction(CalledF);
225          remapAllSites(CGN->getFunction(), CalledF, cf);
226        }  else {
227          // It is called only from ISR. Still mark it as we need this info
228          // in code gen while calling intrinsics.Function is not marked.
229          CalledF->setSection("IL");
230        }
231      }
232      // Before going any further clone all the shared function reachaable 
233      // by current function.
234      cloneSharedFunctions(cgn_it->second);
235   } // end of loop of all called functions.
236 }
237
238 // Clone the given function and return it.
239 // Note: it uses the ValueMap member of the class, which is already populated
240 // by cloneAutos by the time we reach here. 
241 // FIXME: Should we just pass ValueMap's ref as a parameter here? rather
242 // than keeping the ValueMap as a member.
243 Function *
244 PIC16Cloner::cloneFunction(Function *OrgF) {
245    Function *ClonedF;
246
247    // See if we already cloned it. Return that. 
248    cloned_map_iterator cm_it = ClonedFunctionMap.find(OrgF);
249    if(cm_it != ClonedFunctionMap.end()) {
250      ClonedF = cm_it->second;
251      return ClonedF;
252    }
253
254    // Clone does not exist. 
255    // First clone the autos, and populate ValueMap.
256    CloneAutos(OrgF);
257
258    // Now create the clone.
259    ClonedF = CloneFunction(OrgF, ValueMap);
260
261    // The new function should be for interrupt line. Therefore should have 
262    // the name suffixed with IL and section attribute marked with IL. 
263    ClonedF->setName(PAN::getCloneFnName(OrgF->getName()));
264    ClonedF->setSection("IL");
265
266    // Add the newly created function to the module.
267    OrgF->getParent()->getFunctionList().push_back(ClonedF);
268
269    // Update the ClonedFunctionMap to record this cloning activity.
270    ClonedFunctionMap[OrgF] = ClonedF;
271
272    return ClonedF;
273 }
274
275
276 // Remap the call sites of shared functions, that are in IL.
277 // Change the IL call site of a shared function to its clone.
278 //
279 void PIC16Cloner::
280 remapAllSites(Function *Caller, Function *OrgF, Function *Clone) {
281   // First find the caller to update. If the caller itself is cloned
282   // then use the cloned caller. Otherwise use it.
283   cloned_map_iterator cm_it = ClonedFunctionMap.find(Caller);
284   if (cm_it != ClonedFunctionMap.end())
285     Caller = cm_it->second;
286
287   // For the lack of a better call site finding mechanism, iterate over 
288   // all insns to find the uses of original fn.
289   for (Function::iterator BI = Caller->begin(); BI != Caller->end(); ++BI) {
290     BasicBlock &BB = *BI;
291     for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ++II) {
292       if (II->getNumOperands() > 0 && II->getOperand(0) == OrgF)
293           II->setOperand(0, Clone);
294     }
295   }
296 }
297
298
299