diff options
author | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-10-21 10:42:44 +0000 |
---|---|---|
committer | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-10-21 10:42:44 +0000 |
commit | 00e8f5a671512a8647a3ac418b9d269e3a77ea63 (patch) | |
tree | bc65d3b7f488e1336a7b582b8fa7441daa4c4ec4 | |
parent | 9da99aa14b010c5fe3f9e52f53636d7c73181b2d (diff) | |
download | external_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.cpp | 50 | ||||
-rw-r--r-- | lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/Makefile | 2 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16ABINames.h | 15 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Passes/Makefile | 17 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp | 181 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Passes/PIC16Overlay.h | 55 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Section.cpp | 9 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Section.h | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16TargetObjectFile.cpp | 12 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16TargetObjectFile.h | 4 |
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; |