X86: Call ulldiv and ftol2 on Windows instead of their libgcc eqivilents.
[oota-llvm.git] / lib / Target / PIC16 / PIC16Passes / PIC16Overlay.cpp
1 //===-- PIC16Overlay.cpp - Implementation for PIC16 Frame Overlay===//
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 the PIC16 Frame Overlay implementation.
11 //
12 //===----------------------------------------------------------------------===//
13
14
15 #include "llvm/Analysis/CallGraph.h"
16 #include "llvm/Pass.h"
17 #include "llvm/Module.h"
18 #include "llvm/Instructions.h"
19 #include "llvm/Value.h"
20 #include "PIC16Overlay.h"
21 #include "llvm/Function.h"
22 #include <cstdlib>
23 #include <sstream>
24 using namespace llvm;
25
26 namespace llvm {
27   char PIC16Overlay::ID = 0;
28   ModulePass *createPIC16OverlayPass() { return new PIC16Overlay(); }
29 }
30
31 void PIC16Overlay::getAnalysisUsage(AnalysisUsage &AU) const {
32   AU.setPreservesAll();
33   AU.addRequired<CallGraph>();
34 }
35
36 void PIC16Overlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) {
37   // Do not set any color for external calling node.
38   if (Depth != 0 && CGN->getFunction()) {
39     unsigned Color = getColor(CGN->getFunction());
40
41     // Handle indirectly called functions
42     if (Color >= PIC16OVERLAY::StartIndirectCallColor || 
43         Depth >= PIC16OVERLAY::StartIndirectCallColor) {
44       // All functions called from an indirectly called function are given
45       // an unique color.
46       if (Color < PIC16OVERLAY::StartIndirectCallColor &&
47           Depth >= PIC16OVERLAY::StartIndirectCallColor)
48         setColor(CGN->getFunction(), Depth);
49
50       for (unsigned int i = 0; i < CGN->size(); i++)
51         DFSTraverse((*CGN)[i], ++IndirectCallColor);
52       return;
53     }
54     // Just return if the node already has a color greater than the current 
55     // depth. A node must be colored with the maximum depth that it has.
56     if (Color >= Depth)
57       return;
58     
59     Depth = ModifyDepthForInterrupt(CGN, Depth);  
60     setColor(CGN->getFunction(), Depth);
61   }
62   
63   // Color all children of this node with color depth+1.
64   for (unsigned int i = 0; i < CGN->size(); i++)
65     DFSTraverse((*CGN)[i], Depth+1);
66 }
67
68 unsigned PIC16Overlay::ModifyDepthForInterrupt(CallGraphNode *CGN,
69                                                     unsigned Depth) {
70   Function *Fn = CGN->getFunction();
71
72   // Return original Depth if function or section for function do not exist.
73   if (!Fn || !Fn->hasSection())
74     return Depth;
75
76   // Return original Depth if this function is not marked as interrupt.
77   if (Fn->getSection().find("interrupt") == string::npos)
78     return Depth;
79
80   Depth = Depth + InterruptDepth;
81   return Depth;
82 }
83
84 void PIC16Overlay::setColor(Function *Fn, unsigned Color) {
85   std::string Section = "";
86   if (Fn->hasSection())
87     Section = Fn->getSection();
88
89   size_t Pos = Section.find(OverlayStr);
90
91   // Convert Color to string.
92   std::stringstream ss;
93   ss << Color;
94   std::string ColorString = ss.str();
95
96   // If color is already set then reset it with the new value. Else append 
97   // the Color string to section.
98   if (Pos != std::string::npos) {
99     Pos += OverlayStr.length();
100     char c = Section.at(Pos);
101     unsigned OldColorLength = 0;  
102     while (c >= '0' && c<= '9') {
103       OldColorLength++;    
104       if (Pos < Section.length() - 1)
105         Pos++;
106       else
107         break;
108       c = Section.at(Pos);
109     }
110     // Replace old color with new one.
111     Section.replace(Pos-OldColorLength +1, OldColorLength, ColorString); 
112   }
113   else {
114     // Append Color information to section string.
115     if (Fn->hasSection())
116       Section.append(" ");
117     Section.append(OverlayStr + ColorString);
118   }
119   Fn->setSection(Section);
120 }
121
122 unsigned PIC16Overlay::getColor(Function *Fn) {
123   int Color = 0;
124   if (!Fn->hasSection())
125     return 0;
126
127   std::string Section = Fn->getSection();
128   size_t Pos = Section.find(OverlayStr);
129   
130   // Return 0 if Color is not set.
131   if (Pos == std::string::npos)
132     return 0;
133
134   // Set Pos to after "Overlay=".
135   Pos += OverlayStr.length();
136   char c = Section.at(Pos);
137   std::string ColorString = "";
138
139   // Find the string representing Color. A Color can only consist of digits.
140   while (c >= '0' && c<= '9') { 
141     ColorString.append(1,c);
142     if (Pos < Section.length() - 1)
143       Pos++;
144     else
145       break;
146     c = Section.at(Pos);
147   }
148   Color = atoi(ColorString.c_str());
149   
150   return Color;    
151 }
152
153 bool PIC16Overlay::runOnModule(Module &M) {
154   CallGraph &CG = getAnalysis<CallGraph>();
155   CallGraphNode *ECN = CG.getExternalCallingNode();
156
157   MarkIndirectlyCalledFunctions(M); 
158   // Since External Calling Node is the base function, do a depth first 
159   // traversal of CallGraph with ECN as root. Each node with be marked with 
160   // a color that is max(color(callers)) + 1.
161   if(ECN) {
162     DFSTraverse(ECN, 0);
163   }
164   return false;
165 }
166
167 void PIC16Overlay::MarkIndirectlyCalledFunctions(Module &M) {
168   // If the use of a function is not a call instruction then this
169   // function might be called indirectly. In that case give it
170   // an unique color.
171   for (Module::iterator MI = M.begin(), E = M.end(); MI != E; ++MI) {
172     for (Value::use_iterator I = MI->use_begin(), E = MI->use_end(); I != E;
173          ++I) {
174       User *U = *I;
175       if ((!isa<CallInst>(U) && !isa<InvokeInst>(U))
176           || !CallSite(cast<Instruction>(U)).isCallee(I)) {
177         setColor(MI, ++IndirectCallColor);
178         break;
179       }
180     }
181   }
182 }