summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/PIC16/PIC16Passes
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/PIC16/PIC16Passes')
-rw-r--r--contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp299
-rw-r--r--contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h83
-rw-r--r--contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp182
-rw-r--r--contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h60
4 files changed, 0 insertions, 624 deletions
diff --git a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp b/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp
deleted file mode 100644
index 56f0211..0000000
--- a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-//===-- PIC16Cloner.cpp - PIC16 LLVM Cloner for shared functions -*- 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 code to clone all functions that are shared between
-// the main line code (ML) and interrupt line code (IL). It clones all such
-// shared functions and their automatic global vars by adding the .IL suffix.
-//
-// This pass is supposed to be run on the linked .bc module.
-// It traveses the module call graph twice. Once starting from the main function
-// and marking each reached function as "ML". Again, starting from the ISR
-// and cloning any reachable function that was marked as "ML". After cloning
-// the function, it remaps all the call sites in IL functions to call the
-// cloned functions.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Pass.h"
-#include "llvm/Module.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "PIC16Cloner.h"
-#include "../PIC16ABINames.h"
-#include <vector>
-
-using namespace llvm;
-using std::vector;
-using std::string;
-using std::map;
-
-namespace llvm {
- char PIC16Cloner::ID = 0;
-
- ModulePass *createPIC16ClonerPass() { return new PIC16Cloner(); }
-}
-
-// We currently intend to run these passes in opt, which does not have any
-// diagnostic support. So use these functions for now. In future
-// we will probably write our own driver tool.
-//
-void PIC16Cloner::reportError(string ErrorString) {
- errs() << "ERROR : " << ErrorString << "\n";
- exit(1);
-}
-
-void PIC16Cloner::
-reportError (string ErrorString, vector<string> &Values) {
- unsigned ValCount = Values.size();
- string TargetString;
- for (unsigned i=0; i<ValCount; ++i) {
- TargetString = "%";
- TargetString += ((char)i + '0');
- ErrorString.replace(ErrorString.find(TargetString), TargetString.length(),
- Values[i]);
- }
- errs() << "ERROR : " << ErrorString << "\n";
- exit(1);
-}
-
-
-// Entry point
-//
-bool PIC16Cloner::runOnModule(Module &M) {
- CallGraph &CG = getAnalysis<CallGraph>();
-
- // Search for the "main" and "ISR" functions.
- CallGraphNode *mainCGN = NULL, *isrCGN = NULL;
- for (CallGraph::iterator it = CG.begin() ; it != CG.end(); it++)
- {
- // External calling node doesn't have any function associated with it.
- if (! it->first)
- continue;
-
- if (it->first->getName().str() == "main") {
- mainCGN = it->second;
- }
-
- if (PAN::isISR(it->first->getSection())) {
- isrCGN = it->second;
- }
-
- // Don't search further if we've found both.
- if (mainCGN && isrCGN)
- break;
- }
-
- // We have nothing to do if any of the main or ISR is missing.
- if (! mainCGN || ! isrCGN) return false;
-
- // Time for some diagnostics.
- // See if the main itself is interrupt function then report an error.
- if (PAN::isISR(mainCGN->getFunction()->getSection())) {
- reportError("Function 'main' can't be interrupt function");
- }
-
-
- // Mark all reachable functions from main as ML.
- markCallGraph(mainCGN, "ML");
-
- // And then all the functions reachable from ISR will be cloned.
- cloneSharedFunctions(isrCGN);
-
- return true;
-}
-
-// Mark all reachable functions from the given node, with the given mark.
-//
-void PIC16Cloner::markCallGraph(CallGraphNode *CGN, string StringMark) {
- // Mark the top node first.
- Function *thisF = CGN->getFunction();
-
- thisF->setSection(StringMark);
-
- // Mark all the called functions
- for(CallGraphNode::iterator cgn_it = CGN->begin();
- cgn_it != CGN->end(); ++cgn_it) {
- Function *CalledF = cgn_it->second->getFunction();
-
- // If calling an external function then CallGraphNode
- // will not be associated with any function.
- if (! CalledF)
- continue;
-
- // Issue diagnostic if interrupt function is being called.
- if (PAN::isISR(CalledF->getSection())) {
- vector<string> Values;
- Values.push_back(CalledF->getName().str());
- reportError("Interrupt function (%0) can't be called", Values);
- }
-
- // Has already been mark
- if (CalledF->getSection().find(StringMark) != string::npos) {
- // Should we do anything here?
- } else {
- // Mark now
- CalledF->setSection(StringMark);
- }
-
- // Before going any further mark all the called function by current
- // function.
- markCallGraph(cgn_it->second ,StringMark);
- } // end of loop of all called functions.
-}
-
-
-// For PIC16, automatic variables of a function are emitted as globals.
-// Clone the auto variables of a function and put them in VMap,
-// this VMap will be used while
-// Cloning the code of function itself.
-//
-void PIC16Cloner::CloneAutos(Function *F) {
- // We'll need to update module's globals list as well. So keep a reference
- // handy.
- Module *M = F->getParent();
- Module::GlobalListType &Globals = M->getGlobalList();
-
- // Clear the leftovers in VMap by any previous cloning.
- VMap.clear();
-
- // Find the auto globls for this function and clone them, and put them
- // in VMap.
- std::string FnName = F->getName().str();
- std::string VarName, ClonedVarName;
- for (Module::global_iterator I = M->global_begin(), E = M->global_end();
- I != E; ++I) {
- VarName = I->getName().str();
- if (PAN::isLocalToFunc(FnName, VarName)) {
- // Auto variable for current function found. Clone it.
- const GlobalVariable *GV = I;
-
- const Type *InitTy = GV->getInitializer()->getType();
- GlobalVariable *ClonedGV =
- new GlobalVariable(InitTy, false, GV->getLinkage(),
- GV->getInitializer());
- ClonedGV->setName(PAN::getCloneVarName(FnName, VarName));
- // Add these new globals to module's globals list.
- Globals.push_back(ClonedGV);
-
- // Update VMap.
- VMap[GV] = ClonedGV;
- }
- }
-}
-
-
-// Clone all functions that are reachable from ISR and are already
-// marked as ML.
-//
-void PIC16Cloner::cloneSharedFunctions(CallGraphNode *CGN) {
-
- // Check all the called functions from ISR.
- for(CallGraphNode::iterator cgn_it = CGN->begin();
- cgn_it != CGN->end(); ++cgn_it) {
- Function *CalledF = cgn_it->second->getFunction();
-
- // If calling an external function then CallGraphNode
- // will not be associated with any function.
- if (!CalledF)
- continue;
-
- // Issue diagnostic if interrupt function is being called.
- if (PAN::isISR(CalledF->getSection())) {
- vector<string> Values;
- Values.push_back(CalledF->getName().str());
- reportError("Interrupt function (%0) can't be called", Values);
- }
-
- if (CalledF->getSection().find("ML") != string::npos) {
- // Function is alternatively marked. It should be a shared one.
- // Create IL copy. Passing called function as first argument
- // and the caller as the second argument.
-
- // Before making IL copy, first ensure that this function has a
- // body. If the function does have a body. It can't be cloned.
- // Such a case may occur when the function has been declarated
- // in the C source code but its body exists in assembly file.
- if (!CalledF->isDeclaration()) {
- Function *cf = cloneFunction(CalledF);
- remapAllSites(CGN->getFunction(), CalledF, cf);
- } else {
- // It is called only from ISR. Still mark it as we need this info
- // in code gen while calling intrinsics.Function is not marked.
- CalledF->setSection("IL");
- }
- }
- // Before going any further clone all the shared function reachaable
- // by current function.
- cloneSharedFunctions(cgn_it->second);
- } // end of loop of all called functions.
-}
-
-// Clone the given function and return it.
-// Note: it uses the VMap member of the class, which is already populated
-// by cloneAutos by the time we reach here.
-// FIXME: Should we just pass VMap's ref as a parameter here? rather
-// than keeping the VMap as a member.
-Function *
-PIC16Cloner::cloneFunction(Function *OrgF) {
- Function *ClonedF;
-
- // See if we already cloned it. Return that.
- cloned_map_iterator cm_it = ClonedFunctionMap.find(OrgF);
- if(cm_it != ClonedFunctionMap.end()) {
- ClonedF = cm_it->second;
- return ClonedF;
- }
-
- // Clone does not exist.
- // First clone the autos, and populate VMap.
- CloneAutos(OrgF);
-
- // Now create the clone.
- ClonedF = CloneFunction(OrgF, VMap, /*ModuleLevelChanges=*/false);
-
- // The new function should be for interrupt line. Therefore should have
- // the name suffixed with IL and section attribute marked with IL.
- ClonedF->setName(PAN::getCloneFnName(OrgF->getName()));
- ClonedF->setSection("IL");
-
- // Add the newly created function to the module.
- OrgF->getParent()->getFunctionList().push_back(ClonedF);
-
- // Update the ClonedFunctionMap to record this cloning activity.
- ClonedFunctionMap[OrgF] = ClonedF;
-
- return ClonedF;
-}
-
-
-// Remap the call sites of shared functions, that are in IL.
-// Change the IL call site of a shared function to its clone.
-//
-void PIC16Cloner::
-remapAllSites(Function *Caller, Function *OrgF, Function *Clone) {
- // First find the caller to update. If the caller itself is cloned
- // then use the cloned caller. Otherwise use it.
- cloned_map_iterator cm_it = ClonedFunctionMap.find(Caller);
- if (cm_it != ClonedFunctionMap.end())
- Caller = cm_it->second;
-
- // For the lack of a better call site finding mechanism, iterate over
- // all insns to find the uses of original fn.
- for (Function::iterator BI = Caller->begin(); BI != Caller->end(); ++BI) {
- BasicBlock &BB = *BI;
- for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ++II) {
- if (II->getNumOperands() > 0 && II->getOperand(0) == OrgF)
- II->setOperand(0, Clone);
- }
- }
-}
-
-
-
diff --git a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h b/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h
deleted file mode 100644
index e7d67ce..0000000
--- a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Cloner.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- PIC16Cloner.h - PIC16 LLVM Cloner for shared functions --*- 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 declaration of a cloner class clone all functions that
-// are shared between the main line code (ML) and interrupt line code (IL).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef PIC16CLONER_H
-#define PIC16CLONER_H
-
-#include "llvm/ADT/ValueMap.h"
-
-using namespace llvm;
-using std::vector;
-using std::string;
-using std::map;
-
-namespace llvm {
- // forward classes.
- class Value;
- class Function;
- class Module;
- class ModulePass;
- class CallGraph;
- class CallGraphNode;
- class AnalysisUsage;
-
- class PIC16Cloner : public ModulePass {
- public:
- static char ID; // Class identification
- PIC16Cloner() : ModulePass(ID) {}
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<CallGraph>();
- }
- virtual bool runOnModule(Module &M);
-
- private: // Functions
- // Mark reachable functions for the MainLine or InterruptLine.
- void markCallGraph(CallGraphNode *CGN, string StringMark);
-
- // Clone auto variables of function specified.
- void CloneAutos(Function *F);
-
- // Clone the body of a function.
- Function *cloneFunction(Function *F);
-
- // Clone all shared functions.
- void cloneSharedFunctions(CallGraphNode *isrCGN);
-
- // Remap all call sites to the shared function.
- void remapAllSites(Function *Caller, Function *OrgF, Function *Clone);
-
- // Error reporting for PIC16Pass
- void reportError(string ErrorString, vector<string> &Values);
- void reportError(string ErrorString);
-
- private: //data
- // Records if the interrupt function has already been found.
- // If more than one interrupt function is found then an error
- // should be thrown.
- bool foundISR;
-
- // This ValueMap maps the auto variables of the original functions with
- // the corresponding cloned auto variable of the cloned function.
- // This value map is passed during the function cloning so that all the
- // uses of auto variables be updated properly.
- ValueMap<const Value*, Value*> VMap;
-
- // Map of a already cloned functions.
- map<Function *, Function *> ClonedFunctionMap;
- typedef map<Function *, Function *>::iterator cloned_map_iterator;
- };
-} // End of anonymous namespace
-
-#endif
diff --git a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp b/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
deleted file mode 100644
index 0f8928a..0000000
--- a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- 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 PIC16Overlay::ID = 0;
- ModulePass *createPIC16OverlayPass() { return new PIC16Overlay(); }
-}
-
-void PIC16Overlay::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<CallGraph>();
-}
-
-void PIC16Overlay::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 PIC16Overlay::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 PIC16Overlay::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 PIC16Overlay::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 PIC16Overlay::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 PIC16Overlay::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) {
- User *U = *I;
- if ((!isa<CallInst>(U) && !isa<InvokeInst>(U))
- || !CallSite(cast<Instruction>(U)).isCallee(I)) {
- setColor(MI, ++IndirectCallColor);
- break;
- }
- }
- }
-}
diff --git a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h b/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
deleted file mode 100644
index 2f611e6..0000000
--- a/contrib/llvm/lib/Target/PIC16/PIC16Passes/PIC16Overlay.h
+++ /dev/null
@@ -1,60 +0,0 @@
-//===-- PIC16Overlay.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
-
-
-using std::string;
-using namespace llvm;
-
-namespace llvm {
- // Forward declarations.
- class Function;
- class Module;
- class ModulePass;
- class AnalysisUsage;
- class CallGraphNode;
- class CallGraph;
-
- namespace PIC16OVERLAY {
- enum OverlayConsts {
- StartInterruptColor = 200,
- StartIndirectCallColor = 300
- };
- }
- class PIC16Overlay : public ModulePass {
- std::string OverlayStr;
- unsigned InterruptDepth;
- unsigned IndirectCallColor;
- public:
- static char ID; // Class identification
- PIC16Overlay() : 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
OpenPOWER on IntegriCloud