Add a pass to do call graph analyis to overlay the autos and frame sections of
[oota-llvm.git] / lib / Target / PIC16 / PIC16TargetObjectFile.cpp
1 //===-- PIC16TargetObjectFile.cpp - PIC16 object files --------------------===//
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 #include "PIC16TargetObjectFile.h"
11 #include "MCSectionPIC16.h"
12 #include "PIC16ISelLowering.h"
13 #include "PIC16TargetMachine.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/Module.h"
16 #include "llvm/MC/MCSection.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/Support/raw_ostream.h"
19 using namespace llvm;
20
21
22 MCSectionPIC16 *MCSectionPIC16::Create(const StringRef &Name, 
23                                        SectionKind K, MCContext &Ctx) {
24   return new (Ctx) MCSectionPIC16(Name, K);
25 }
26
27
28 void MCSectionPIC16::PrintSwitchToSection(const TargetAsmInfo &TAI,
29                                           raw_ostream &OS) const {
30   OS << getName() << '\n';
31 }
32
33
34
35
36 PIC16TargetObjectFile::PIC16TargetObjectFile()
37   : ExternalVarDecls(0), ExternalVarDefs(0) {
38 }
39
40 const MCSectionPIC16 *PIC16TargetObjectFile::
41 getPIC16Section(const char *Name, SectionKind Kind) const {
42   MCSectionPIC16 *&Entry = SectionsByName[Name];
43   if (Entry)
44     return Entry;
45
46   return Entry = MCSectionPIC16::Create(Name, Kind, getContext());
47 }
48
49
50 void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
51   TargetLoweringObjectFile::Initialize(Ctx, tm);
52   TM = &tm;
53   
54   BSSSection = getPIC16Section("udata.# UDATA", SectionKind::getBSS());
55   ReadOnlySection = getPIC16Section("romdata.# ROMDATA", 
56                                     SectionKind::getReadOnly());
57   DataSection = getPIC16Section("idata.# IDATA", SectionKind::getDataRel());
58   
59   // Need because otherwise a .text symbol is emitted by DwarfWriter
60   // in BeginModule, and gpasm cribbs for that .text symbol.
61   TextSection = getPIC16Section("", SectionKind::getText());
62
63   ROSections.push_back(new PIC16Section((MCSectionPIC16*)ReadOnlySection));
64   
65   // FIXME: I don't know what the classification of these sections really is.
66   ExternalVarDecls = new PIC16Section(getPIC16Section("ExternalVarDecls",
67                                       SectionKind::getMetadata()));
68   ExternalVarDefs = new PIC16Section(getPIC16Section("ExternalVarDefs",
69                                       SectionKind::getMetadata()));
70 }
71
72 const MCSection *PIC16TargetObjectFile::
73 getSectionForFunction(const std::string &FnName, bool isInterrupt) const {
74   std::string T = PAN::getCodeSectionName(FnName, isInterrupt);
75   return getPIC16Section(T.c_str(), SectionKind::getText());
76 }
77
78
79 const MCSection *PIC16TargetObjectFile::
80 getSectionForFunctionFrame(const std::string &FnName) const {
81   std::string T = PAN::getFrameSectionName(FnName);
82   return getPIC16Section(T.c_str(), SectionKind::getDataRel());
83 }
84
85 std::string PIC16TargetObjectFile::getNameForFunctFrame(const Function *F,
86                                                           bool IsAutosSection) {
87   std::string SectionName = F->getName();
88   if (F->hasSection()) {
89     std::string Sectn = F->getSection();
90     std::string StrToFind = "Overlay=";
91     unsigned Pos = Sectn.find(StrToFind);
92     if (Pos != std::string::npos) {
93       Pos += StrToFind.length();
94       std::string Color = "";
95       char c = Sectn.at(Pos);
96       // A Color can only consist on upper case letters or underscore.
97       while ((c >= 'A' && c<= 'Z') || c == '_') {
98         Color.append(1,c);
99         Pos++;
100         if (Pos >= Sectn.length())
101           break;
102         c = Sectn.at(Pos);
103       }
104       // Autos Section need to be given a different name from function frame. 
105       if (IsAutosSection)
106         SectionName = PAN::getAutosSectionForColor(Color);
107       else
108         SectionName = Color;
109     }
110   }
111   return SectionName;
112 }
113
114 const MCSection *
115 PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
116   assert(GV->hasInitializer() && "This global doesn't need space");
117   Constant *C = GV->getInitializer();
118   assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
119
120   // Find how much space this global needs.
121   const TargetData *TD = TM->getTargetData();
122   const Type *Ty = C->getType(); 
123   unsigned ValSize = TD->getTypeAllocSize(Ty);
124  
125   // Go through all BSS Sections and assign this variable
126   // to the first available section having enough space.
127   PIC16Section *FoundBSS = NULL;
128   for (unsigned i = 0; i < BSSSections.size(); i++) {
129     if (DataBankSize - BSSSections[i]->Size >= ValSize) {
130       FoundBSS = BSSSections[i];
131       break;
132     }
133   }
134
135   // No BSS section spacious enough was found. Crate a new one.
136   if (!FoundBSS) {
137     std::string name = PAN::getUdataSectionName(BSSSections.size());
138     const MCSectionPIC16 *NewSection
139       = getPIC16Section(name.c_str(), /*FIXME*/ SectionKind::getMetadata());
140
141     FoundBSS = new PIC16Section(NewSection);
142
143     // Add this newly created BSS section to the list of BSSSections.
144     BSSSections.push_back(FoundBSS);
145   }
146   
147   // Insert the GV into this BSS.
148   FoundBSS->Items.push_back(GV);
149   FoundBSS->Size += ValSize;
150   return FoundBSS->S_;
151
152
153 const MCSection *
154 PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
155   assert(GV->hasInitializer() && "This global doesn't need space");
156   Constant *C = GV->getInitializer();
157   assert(!C->isNullValue() && "initialized globals has zero initializer");
158   assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
159          "can split initialized RAM data only");
160
161   // Find how much space this global needs.
162   const TargetData *TD = TM->getTargetData();
163   const Type *Ty = C->getType(); 
164   unsigned ValSize = TD->getTypeAllocSize(Ty);
165  
166   // Go through all IDATA Sections and assign this variable
167   // to the first available section having enough space.
168   PIC16Section *FoundIDATA = NULL;
169   for (unsigned i = 0; i < IDATASections.size(); i++) {
170     if (DataBankSize - IDATASections[i]->Size >= ValSize) {
171       FoundIDATA = IDATASections[i]; 
172       break;
173     }
174   }
175
176   // No IDATA section spacious enough was found. Crate a new one.
177   if (!FoundIDATA) {
178     std::string name = PAN::getIdataSectionName(IDATASections.size());
179     const MCSectionPIC16 *NewSection =
180       getPIC16Section(name.c_str(), /*FIXME*/ SectionKind::getMetadata());
181
182     FoundIDATA = new PIC16Section(NewSection);
183
184     // Add this newly created IDATA section to the list of IDATASections.
185     IDATASections.push_back(FoundIDATA);
186   }
187   
188   // Insert the GV into this IDATA.
189   FoundIDATA->Items.push_back(GV);
190   FoundIDATA->Size += ValSize;
191   return FoundIDATA->S_;
192
193
194 // Get the section for an automatic variable of a function.
195 // For PIC16 they are globals only with mangled names.
196 const MCSection *
197 PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
198
199   const std::string name = PAN::getSectionNameForSym(GV->getName());
200
201   // Go through all Auto Sections and assign this variable
202   // to the appropriate section.
203   PIC16Section *FoundAutoSec = NULL;
204   for (unsigned i = 0; i < AutosSections.size(); i++) {
205     if (AutosSections[i]->S_->getName() == name) {
206       FoundAutoSec = AutosSections[i];
207       break;
208     }
209   }
210
211   // No Auto section was found. Crate a new one.
212   if (!FoundAutoSec) {
213     const MCSectionPIC16 *NewSection =
214       getPIC16Section(name.c_str(), /*FIXME*/ SectionKind::getMetadata());
215
216     FoundAutoSec = new PIC16Section(NewSection);
217
218     // Add this newly created autos section to the list of AutosSections.
219     AutosSections.push_back(FoundAutoSec);
220   }
221
222   // Insert the auto into this section.
223   FoundAutoSec->Items.push_back(GV);
224
225   return FoundAutoSec->S_;
226 }
227
228 void PIC16TargetObjectFile::createClonedSectionForAutos(const std::string &SecName) {
229
230   // If the function is cloned then it will have ".IL" in its name
231   // If this function is not cloned then return;
232   if (SecName.find(".IL") == std::string::npos) 
233       return;
234
235   // Come here if the function is cloned.
236   // Get the name of the original section from which it has been cloned.
237   std::string OrigName = SecName;
238   OrigName.replace(SecName.find(".IL"),3,"");
239
240   // Find original section
241   PIC16Section *FoundAutoSec = NULL;
242   for (unsigned i = 0; i < AutosSections.size(); i++) {
243     if (AutosSections[i]->S_->getName() == OrigName) {
244       FoundAutoSec = AutosSections[i];
245       break; 
246     }
247   }
248
249   // No auto section exists for the original function.
250   if (!FoundAutoSec)
251     return;
252
253   // Create new section for the cloned function 
254   const MCSectionPIC16 *NewSection =
255       getPIC16Section(SecName.c_str(), SectionKind::getMetadata());
256   
257   PIC16Section *NewAutoSec = new PIC16Section(NewSection);
258   // Add this newly created autos section to the list of AutosSections.
259   AutosSections.push_back(NewAutoSec);
260
261   // Add the items from the original section to the new section
262   // Donot mangle them here. Because mangling them here will distort 
263   // the original names. 
264   // These names will be mangled them at the time of printing only
265   const std::vector<const GlobalVariable*> &Items = FoundAutoSec->Items;
266   for (unsigned j = 0; j < Items.size(); j++) {
267     NewAutoSec->Items.push_back(Items[j]); 
268   }
269 }
270
271 // Override default implementation to put the true globals into
272 // multiple data sections if required.
273 const MCSection *
274 PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
275                                               SectionKind Kind,
276                                               Mangler *Mang,
277                                               const TargetMachine &TM) const {
278   // We select the section based on the initializer here, so it really
279   // has to be a GlobalVariable.
280   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
281   if (!GV)
282     return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
283
284   // Record External Var Decls.
285   if (GV->isDeclaration()) {
286     ExternalVarDecls->Items.push_back(GV);
287     return ExternalVarDecls->S_;
288   }
289     
290   assert(GV->hasInitializer() && "A def without initializer?");
291
292   // First, if this is an automatic variable for a function, get the section
293   // name for it and return.
294   std::string name = GV->getName();
295   if (PAN::isLocalName(name))
296     return getSectionForAuto(GV);
297
298   // Record Exteranl Var Defs.
299   if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
300     ExternalVarDefs->Items.push_back(GV);
301
302   // See if this is an uninitialized global.
303   const Constant *C = GV->getInitializer();
304   if (C->isNullValue()) 
305     return getBSSSectionForGlobal(GV); 
306
307   // If this is initialized data in RAM. Put it in the correct IDATA section.
308   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
309     return getIDATASectionForGlobal(GV);
310
311   // This is initialized data in rom, put it in the readonly section.
312   if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
313     return getROSectionForGlobal(GV);
314
315   // Else let the default implementation take care of it.
316   return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
317 }
318
319 PIC16TargetObjectFile::~PIC16TargetObjectFile() {
320   for (unsigned i = 0; i < BSSSections.size(); i++)
321     delete BSSSections[i]; 
322   for (unsigned i = 0; i < IDATASections.size(); i++)
323     delete IDATASections[i]; 
324   for (unsigned i = 0; i < AutosSections.size(); i++)
325     delete AutosSections[i]; 
326   for (unsigned i = 0; i < ROSections.size(); i++)
327     delete ROSections[i];
328   delete ExternalVarDecls;
329   delete ExternalVarDefs;
330 }
331
332
333 /// getSpecialCasedSectionGlobals - Allow the target to completely override
334 /// section assignment of a global.
335 const MCSection *PIC16TargetObjectFile::
336 getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, 
337                          Mangler *Mang, const TargetMachine &TM) const {
338   assert(GV->hasSection());
339   
340   if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
341     std::string SectName = GVar->getSection();
342     // If address for a variable is specified, get the address and create
343     // section.
344     std::string AddrStr = "Address=";
345     if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
346       std::string SectAddr = SectName.substr(AddrStr.length());
347       return CreateSectionForGlobal(GVar, Mang, SectAddr);
348     }
349      
350     // Create the section specified with section attribute. 
351     return CreateSectionForGlobal(GVar, Mang);
352   }
353
354   return getPIC16Section(GV->getSection().c_str(), Kind);
355 }
356
357 // Create a new section for global variable. If Addr is given then create
358 // section at that address else create by name.
359 const MCSection *
360 PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
361                                               Mangler *Mang,
362                                               const std::string &Addr) const {
363   // See if this is an uninitialized global.
364   const Constant *C = GV->getInitializer();
365   if (C->isNullValue())
366     return CreateBSSSectionForGlobal(GV, Addr);
367
368   // If this is initialized data in RAM. Put it in the correct IDATA section.
369   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
370     return CreateIDATASectionForGlobal(GV, Addr);
371
372   // This is initialized data in rom, put it in the readonly section.
373   if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
374     return CreateROSectionForGlobal(GV, Addr);
375
376   // Else let the default implementation take care of it.
377   return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
378 }
379
380 // Create uninitialized section for a variable.
381 const MCSection *
382 PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
383                                                  std::string Addr) const {
384   assert(GV->hasInitializer() && "This global doesn't need space");
385   assert(GV->getInitializer()->isNullValue() &&
386          "Unitialized global has non-zero initializer");
387   std::string Name;
388   // If address is given then create a section at that address else create a
389   // section by section name specified in GV.
390   PIC16Section *FoundBSS = NULL;
391   if (Addr.empty()) { 
392     Name = GV->getSection() + " UDATA";
393     for (unsigned i = 0; i < BSSSections.size(); i++) {
394       if (BSSSections[i]->S_->getName() == Name) {
395         FoundBSS = BSSSections[i];
396         break;
397       }
398     }
399   } else {
400     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
401     Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
402   }
403   
404   PIC16Section *NewBSS = FoundBSS;
405   if (NewBSS == NULL) {
406     const MCSectionPIC16 *NewSection =
407       getPIC16Section(Name.c_str(), SectionKind::getBSS());
408     NewBSS = new PIC16Section(NewSection);
409     BSSSections.push_back(NewBSS);
410   }
411
412   // Insert the GV into this BSS.
413   NewBSS->Items.push_back(GV);
414
415   // We do not want to put any  GV without explicit section into this section
416   // so set its size to DatabankSize.
417   NewBSS->Size = DataBankSize;
418   return NewBSS->S_;
419 }
420
421 // Get rom section for a variable. Currently there can be only one rom section
422 // unless a variable explicitly requests a section.
423 const MCSection *
424 PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
425   ROSections[0]->Items.push_back(GV);
426   return ROSections[0]->S_;
427 }
428
429 // Create initialized data section for a variable.
430 const MCSection *
431 PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
432                                                    std::string Addr) const {
433   assert(GV->hasInitializer() && "This global doesn't need space");
434   assert(!GV->getInitializer()->isNullValue() &&
435          "initialized global has zero initializer");
436   assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
437          "can be used for initialized RAM data only");
438
439   std::string Name;
440   // If address is given then create a section at that address else create a
441   // section by section name specified in GV.
442   PIC16Section *FoundIDATASec = NULL;
443   if (Addr.empty()) {
444     Name = GV->getSection() + " IDATA";
445     for (unsigned i = 0; i < IDATASections.size(); i++) {
446       if (IDATASections[i]->S_->getName() == Name) {
447         FoundIDATASec = IDATASections[i];
448         break;
449       }
450     }
451   } else {
452     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
453     Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
454   }
455
456   PIC16Section *NewIDATASec = FoundIDATASec;
457   if (NewIDATASec == NULL) {
458     const MCSectionPIC16 *NewSection =
459       getPIC16Section(Name.c_str(), /* FIXME */SectionKind::getMetadata());
460     NewIDATASec = new PIC16Section(NewSection);
461     IDATASections.push_back(NewIDATASec);
462   }
463   // Insert the GV into this IDATA Section.
464   NewIDATASec->Items.push_back(GV);
465   // We do not want to put any  GV without explicit section into this section 
466   // so set its size to DatabankSize.
467   NewIDATASec->Size = DataBankSize;
468   return NewIDATASec->S_;
469 }
470
471 // Create a section in rom for a variable.
472 const MCSection *
473 PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
474                                                 std::string Addr) const {
475   assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
476          "can be used for ROM data only");
477
478   std::string Name;
479   // If address is given then create a section at that address else create a
480   // section by section name specified in GV.
481   PIC16Section *FoundROSec = NULL;
482   if (Addr.empty()) {
483     Name = GV->getSection() + " ROMDATA";
484     for (unsigned i = 1; i < ROSections.size(); i++) {
485       if (ROSections[i]->S_->getName() == Name) {
486         FoundROSec = ROSections[i];
487         break;
488       }
489     }
490   } else {
491     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
492     Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
493   }
494
495   PIC16Section *NewRomSec = FoundROSec;
496   if (NewRomSec == NULL) {
497     const MCSectionPIC16 *NewSection =
498       getPIC16Section(Name.c_str(), SectionKind::getReadOnly());
499     NewRomSec = new PIC16Section(NewSection);
500     ROSections.push_back(NewRomSec);
501   }
502
503   // Insert the GV into this ROM Section.
504   NewRomSec->Items.push_back(GV);
505   return NewRomSec->S_;
506 }
507