diff options
Diffstat (limited to 'contrib/llvm/lib/Target/PIC16/PIC16Passes')
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 |