aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjiv Gupta <sanjiv.gupta@microchip.com>2009-10-21 10:42:44 +0000
committerSanjiv Gupta <sanjiv.gupta@microchip.com>2009-10-21 10:42:44 +0000
commit00e8f5a671512a8647a3ac418b9d269e3a77ea63 (patch)
treebc65d3b7f488e1336a7b582b8fa7441daa4c4ec4
parent9da99aa14b010c5fe3f9e52f53636d7c73181b2d (diff)
downloadexternal_llvm-00e8f5a671512a8647a3ac418b9d269e3a77ea63.zip
external_llvm-00e8f5a671512a8647a3ac418b9d269e3a77ea63.tar.gz
external_llvm-00e8f5a671512a8647a3ac418b9d269e3a77ea63.tar.bz2
Add a pass to overlay pic16 data sections for function frame and automatic
variables. This pass can be invoked by llvm-ld or opt to traverse over the call graph to detect what function frames and their automatic variables can be overlaid. Currently this builds an archive , but needs to be changed to a loadable module. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84753 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp50
-rw-r--r--lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h1
-rw-r--r--lib/Target/PIC16/Makefile2
-rw-r--r--lib/Target/PIC16/PIC16ABINames.h15
-rw-r--r--lib/Target/PIC16/PIC16Passes/Makefile17
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp181
-rw-r--r--lib/Target/PIC16/PIC16Passes/PIC16Overlay.h55
-rw-r--r--lib/Target/PIC16/PIC16Section.cpp9
-rw-r--r--lib/Target/PIC16/PIC16Section.h1
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.cpp12
-rw-r--r--lib/Target/PIC16/PIC16TargetObjectFile.h4
11 files changed, 341 insertions, 6 deletions
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
index 3f719b9..08b49c8 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp
@@ -53,6 +53,45 @@ bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
return true;
}
+static int getFunctionColor(const Function *F) {
+ if (F->hasSection()) {
+ std::string Sectn = F->getSection();
+ std::string StrToFind = "Overlay=";
+ unsigned Pos = Sectn.find(StrToFind);
+
+ // Retreive the color number if the key is found.
+ if (Pos != std::string::npos) {
+ Pos += StrToFind.length();
+ std::string Color = "";
+ char c = Sectn.at(Pos);
+ // A Color can only consist of digits.
+ while (c >= '0' && c<= '9') {
+ Color.append(1,c);
+ Pos++;
+ if (Pos >= Sectn.length())
+ break;
+ c = Sectn.at(Pos);
+ }
+ return atoi(Color.c_str());
+ }
+ }
+
+ // Color was not set for function, so return -1.
+ return -1;
+}
+
+// Color the Auto section of the given function.
+void PIC16AsmPrinter::ColorAutoSection(const Function *F) {
+ std::string SectionName = PAN::getAutosSectionName(CurrentFnName);
+ PIC16Section* Section = PTOF->findPIC16Section(SectionName);
+ if (Section != NULL) {
+ int Color = getFunctionColor(F);
+ if (Color >= 0)
+ Section->setColor(Color);
+ }
+}
+
+
/// runOnMachineFunction - This emits the frame section, autos section and
/// assembly for each instruction. Also takes care of function begin debug
/// directive and file begin debug directive (if required) for the function.
@@ -68,6 +107,9 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction();
CurrentFnName = Mang->getMangledName(F);
+ // Put the color information from function to its auto section.
+ ColorAutoSection(F);
+
// Emit the function frame (args and temps).
EmitFunctionFrame(MF);
@@ -255,7 +297,6 @@ bool PIC16AsmPrinter::doInitialization(Module &M) {
EmitDefinedVars(M);
EmitIData(M);
EmitUData(M);
- EmitAllAutos(M);
EmitRomData(M);
EmitUserSections(M);
return Result;
@@ -330,6 +371,7 @@ void PIC16AsmPrinter::EmitRomData(Module &M) {
}
bool PIC16AsmPrinter::doFinalization(Module &M) {
+ EmitAllAutos(M);
printLibcallDecls();
DbgInfo.EndModule(M);
O << "\n\t" << "END\n";
@@ -343,8 +385,10 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) {
// Emit the data section name.
O << "\n";
- const MCSection *fPDataSection =
- getObjFileLowering().SectionForFrame(CurrentFnName);
+ PIC16Section *fPDataSection = const_cast<PIC16Section *>(getObjFileLowering().
+ SectionForFrame(CurrentFnName));
+
+ fPDataSection->setColor(getFunctionColor(F));
OutStreamer.SwitchSection(fPDataSection);
// Emit function frame label
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
index 580e2fd..b13d9ce 100644
--- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
+++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h
@@ -63,6 +63,7 @@ namespace llvm {
void EmitSingleSection(const PIC16Section *S);
void EmitSectionList(Module &M,
const std::vector< PIC16Section *> &SList);
+ void ColorAutoSection(const Function *F);
protected:
bool doInitialization(Module &M);
bool doFinalization(Module &M);
diff --git a/lib/Target/PIC16/Makefile b/lib/Target/PIC16/Makefile
index f913675..4382eba 100644
--- a/lib/Target/PIC16/Makefile
+++ b/lib/Target/PIC16/Makefile
@@ -17,7 +17,7 @@ BUILT_SOURCES = PIC16GenRegisterInfo.h.inc PIC16GenRegisterNames.inc \
PIC16GenDAGISel.inc PIC16GenCallingConv.inc \
PIC16GenSubtarget.inc
-DIRS = AsmPrinter TargetInfo
+DIRS = AsmPrinter TargetInfo PIC16Passes
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PIC16/PIC16ABINames.h b/lib/Target/PIC16/PIC16ABINames.h
index 7fa1721..7f4c2f1 100644
--- a/lib/Target/PIC16/PIC16ABINames.h
+++ b/lib/Target/PIC16/PIC16ABINames.h
@@ -304,6 +304,21 @@ namespace llvm {
}
}
}
+
+ /// Return Overlay Name for the section.
+ /// The ABI Convention is: @<Color>.##.<section_tag>
+ /// The section_tag is retrieved from the SectName parameter and
+ /// and Color is passed in parameter.
+ static inline std::string getOverlayName(std::string SectName, int Color) {
+ // FIXME: Only autos_section and frame_section are colored.
+ // So check and assert if the passed SectName does not have AUTOS_SECTION
+ // or FRAME_SECTION tag in it.
+ std::ostringstream o;
+ o << getTagName(PREFIX_SYMBOL) << Color << ".##"
+ << SectName.substr(SectName.find("."));
+
+ return o.str();
+ }
}; // class PAN.
} // end namespace llvm;
diff --git a/lib/Target/PIC16/PIC16Passes/Makefile b/lib/Target/PIC16/PIC16Passes/Makefile
new file mode 100644
index 0000000..cbb34b3
--- /dev/null
+++ b/lib/Target/PIC16/PIC16Passes/Makefile
@@ -0,0 +1,17 @@
+##===- lib/Target/PIC16/PIC16Passes/Makefile -----------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+LEVEL = ../../../..
+TARGET = PIC16
+LIBRARYNAME = LLVMpic16passes
+BUILD_ARCHIVE = 1
+
+
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
new file mode 100644
index 0000000..197c398
--- /dev/null
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
@@ -0,0 +1,181 @@
+//===-- PIC16Overlay.cpp - Implementation for PIC16 Frame Overlay===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PIC16 Frame Overlay implementation.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Value.h"
+#include "PIC16Overlay.h"
+#include "llvm/Function.h"
+#include <cstdlib>
+#include <sstream>
+using namespace llvm;
+
+namespace llvm {
+ char PIC16FrameOverlay::ID = 0;
+ ModulePass *createPIC16OverlayPass() { return new PIC16FrameOverlay(); }
+}
+
+void PIC16FrameOverlay::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<CallGraph>();
+}
+
+void PIC16FrameOverlay::DFSTraverse(CallGraphNode *CGN, unsigned Depth) {
+ // Do not set any color for external calling node.
+ if (Depth != 0 && CGN->getFunction()) {
+ unsigned Color = getColor(CGN->getFunction());
+
+ // Handle indirectly called functions
+ if (Color >= PIC16Overlay::StartIndirectCallColor ||
+ Depth >= PIC16Overlay::StartIndirectCallColor) {
+ // All functions called from an indirectly called function are given
+ // an unique color.
+ if (Color < PIC16Overlay::StartIndirectCallColor &&
+ Depth >= PIC16Overlay::StartIndirectCallColor)
+ setColor(CGN->getFunction(), Depth);
+
+ for (unsigned int i = 0; i < CGN->size(); i++)
+ DFSTraverse((*CGN)[i], ++IndirectCallColor);
+ return;
+ }
+ // Just return if the node already has a color greater than the current
+ // depth. A node must be colored with the maximum depth that it has.
+ if (Color >= Depth)
+ return;
+
+ Depth = ModifyDepthForInterrupt(CGN, Depth);
+ setColor(CGN->getFunction(), Depth);
+ }
+
+ // Color all children of this node with color depth+1.
+ for (unsigned int i = 0; i < CGN->size(); i++)
+ DFSTraverse((*CGN)[i], Depth+1);
+}
+
+unsigned PIC16FrameOverlay::ModifyDepthForInterrupt(CallGraphNode *CGN,
+ unsigned Depth) {
+ Function *Fn = CGN->getFunction();
+
+ // Return original Depth if function or section for function do not exist.
+ if (!Fn || !Fn->hasSection())
+ return Depth;
+
+ // Return original Depth if this function is not marked as interrupt.
+ if (Fn->getSection().find("interrupt") == string::npos)
+ return Depth;
+
+ Depth = Depth + InterruptDepth;
+ return Depth;
+}
+
+void PIC16FrameOverlay::setColor(Function *Fn, unsigned Color) {
+ std::string Section = "";
+ if (Fn->hasSection())
+ Section = Fn->getSection();
+
+ size_t Pos = Section.find(OverlayStr);
+
+ // Convert Color to string.
+ std::stringstream ss;
+ ss << Color;
+ std::string ColorString = ss.str();
+
+ // If color is already set then reset it with the new value. Else append
+ // the Color string to section.
+ if (Pos != std::string::npos) {
+ Pos += OverlayStr.length();
+ char c = Section.at(Pos);
+ unsigned OldColorLength = 0;
+ while (c >= '0' && c<= '9') {
+ OldColorLength++;
+ if (Pos < Section.length() - 1)
+ Pos++;
+ else
+ break;
+ c = Section.at(Pos);
+ }
+ // Replace old color with new one.
+ Section.replace(Pos-OldColorLength +1, OldColorLength, ColorString);
+ }
+ else {
+ // Append Color information to section string.
+ if (Fn->hasSection())
+ Section.append(" ");
+ Section.append(OverlayStr + ColorString);
+ }
+ Fn->setSection(Section);
+}
+
+unsigned PIC16FrameOverlay::getColor(Function *Fn) {
+ int Color = 0;
+ if (!Fn->hasSection())
+ return 0;
+
+ std::string Section = Fn->getSection();
+ size_t Pos = Section.find(OverlayStr);
+
+ // Return 0 if Color is not set.
+ if (Pos == std::string::npos)
+ return 0;
+
+ // Set Pos to after "Overlay=".
+ Pos += OverlayStr.length();
+ char c = Section.at(Pos);
+ std::string ColorString = "";
+
+ // Find the string representing Color. A Color can only consist of digits.
+ while (c >= '0' && c<= '9') {
+ ColorString.append(1,c);
+ if (Pos < Section.length() - 1)
+ Pos++;
+ else
+ break;
+ c = Section.at(Pos);
+ }
+ Color = atoi(ColorString.c_str());
+
+ return Color;
+}
+
+bool PIC16FrameOverlay::runOnModule(Module &M) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+ CallGraphNode *ECN = CG.getExternalCallingNode();
+
+ MarkIndirectlyCalledFunctions(M);
+ // Since External Calling Node is the base function, do a depth first
+ // traversal of CallGraph with ECN as root. Each node with be marked with
+ // a color that is max(color(callers)) + 1.
+ if(ECN) {
+ DFSTraverse(ECN, 0);
+ }
+ return false;
+}
+
+void PIC16FrameOverlay::MarkIndirectlyCalledFunctions(Module &M) {
+ // If the use of a function is not a call instruction then this
+ // function might be called indirectly. In that case give it
+ // an unique color.
+ for (Module::iterator MI = M.begin(), E = M.end(); MI != E; ++MI) {
+ for (Value::use_iterator I = MI->use_begin(), E = MI->use_end(); I != E;
+ ++I) {
+ if ((!isa<CallInst>(I) && !isa<InvokeInst>(I))
+ || !CallSite(cast<Instruction>(I)).isCallee(I)) {
+ setColor(MI, ++IndirectCallColor);
+ break;
+ }
+ }
+ }
+}
diff --git a/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
new file mode 100644
index 0000000..d70c4e7
--- /dev/null
+++ b/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
@@ -0,0 +1,55 @@
+//===-- PIC16FrameOverlay.h - Interface for PIC16 Frame Overlay -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the PIC16 Overlay infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PIC16FRAMEOVERLAY_H
+#define PIC16FRAMEOVERLAY_H
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Pass.h"
+#include "llvm/CallGraphSCCPass.h"
+
+using std::string;
+using namespace llvm;
+
+namespace llvm {
+ namespace PIC16Overlay {
+ enum OverlayConsts {
+ StartInterruptColor = 200,
+ StartIndirectCallColor = 300
+ };
+ }
+ class PIC16FrameOverlay : public ModulePass {
+ std::string OverlayStr;
+ unsigned InterruptDepth;
+ unsigned IndirectCallColor;
+ public:
+ static char ID; // Class identification
+ PIC16FrameOverlay() : ModulePass(&ID) {
+ OverlayStr = "Overlay=";
+ InterruptDepth = PIC16Overlay::StartInterruptColor;
+ IndirectCallColor = PIC16Overlay::StartIndirectCallColor;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual bool runOnModule(Module &M);
+
+ private:
+ unsigned getColor(Function *Fn);
+ void setColor(Function *Fn, unsigned Color);
+ unsigned ModifyDepthForInterrupt(CallGraphNode *CGN, unsigned Depth);
+ void MarkIndirectlyCalledFunctions(Module &M);
+ void DFSTraverse(CallGraphNode *CGN, unsigned Depth);
+ };
+} // End of namespace
+
+#endif
diff --git a/lib/Target/PIC16/PIC16Section.cpp b/lib/Target/PIC16/PIC16Section.cpp
index 7029501..a96ebb8 100644
--- a/lib/Target/PIC16/PIC16Section.cpp
+++ b/lib/Target/PIC16/PIC16Section.cpp
@@ -68,8 +68,13 @@ PIC16Section *PIC16Section::Create(const StringRef &Name,
// A generic way to print all types of sections.
void PIC16Section::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
- // Print name.
- OS << getName() << '\t';
+
+ // If the section is overlaid(i.e. it has a color), print overlay name for
+ // it. Otherwise print its normal name.
+ if (Color != -1)
+ OS << PAN::getOverlayName(getName(), Color) << '\t';
+ else
+ OS << getName() << '\t';
// Print type.
switch (getType()) {
diff --git a/lib/Target/PIC16/PIC16Section.h b/lib/Target/PIC16/PIC16Section.h
index 693ac3a..3a8bbfb 100644
--- a/lib/Target/PIC16/PIC16Section.h
+++ b/lib/Target/PIC16/PIC16Section.h
@@ -57,6 +57,7 @@ namespace llvm {
/// Return the Color of the section.
int getColor() const { return Color; }
+ void setColor(int color) { Color = color; }
/// Return the size of the section.
unsigned getSize() const { return Size; }
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
index 11c579c..7eedf7f 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.cpp
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.cpp
@@ -25,6 +25,18 @@ PIC16TargetObjectFile::PIC16TargetObjectFile() {
PIC16TargetObjectFile::~PIC16TargetObjectFile() {
}
+/// Find a pic16 section. Return null if not found. Do not create one.
+PIC16Section *PIC16TargetObjectFile::
+findPIC16Section(const std::string &Name) {
+ /// Return if we have an already existing one.
+ PIC16Section *Entry = SectionsByName[Name];
+ if (Entry)
+ return Entry;
+
+ return NULL;
+}
+
+
/// Find a pic16 section. If not found, create one.
PIC16Section *PIC16TargetObjectFile::
getPIC16Section(const std::string &Name, PIC16SectionType Ty,
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h
index 6ec5512..ca07bed 100644
--- a/lib/Target/PIC16/PIC16TargetObjectFile.h
+++ b/lib/Target/PIC16/PIC16TargetObjectFile.h
@@ -116,6 +116,9 @@ namespace llvm {
~PIC16TargetObjectFile();
void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ /// Return the section with the given Name. Null if not found.
+ PIC16Section *findPIC16Section(const std::string &Name);
+
/// Override section allocations for user specified sections.
virtual const MCSection *
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
@@ -127,6 +130,7 @@ namespace llvm {
Mangler *Mang,
const TargetMachine&) const;
+
/// Return a code section for a function.
const PIC16Section *SectionForCode (const std::string &FnName) const;